mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 17:37:22 +03:00
importer option to assume onstreet parking on some residential roads, if OSM doesnt say anything. give 50% of residential roads in krakow some parking. fixes #171
also clean up the seattle sidewalks dataset for now; the matching code is quite bad, and not planning to use this anytime soon
This commit is contained in:
parent
19409dfc8c
commit
3639379313
@ -17,13 +17,41 @@ pub struct Options {
|
||||
pub city_name: String,
|
||||
pub name: String,
|
||||
|
||||
pub parking_shapes: Option<String>,
|
||||
pub public_offstreet_parking: Option<String>,
|
||||
pub private_offstreet_parking: PrivateOffstreetParking,
|
||||
pub sidewalks: Option<String>,
|
||||
pub elevation: Option<String>,
|
||||
// The path to an osmosis boundary polygon. Highly recommended.
|
||||
pub clip: Option<String>,
|
||||
pub drive_on_right: bool,
|
||||
|
||||
pub onstreet_parking: OnstreetParking,
|
||||
pub public_offstreet_parking: PublicOffstreetParking,
|
||||
pub private_offstreet_parking: PrivateOffstreetParking,
|
||||
// If provided, pull elevation data from this SRTM file. The SRTM parser is incorrect, so the
|
||||
// results will be nonsense.
|
||||
pub elevation: Option<String>,
|
||||
}
|
||||
|
||||
// What roads will have on-street parking lanes? Data from
|
||||
// https://wiki.openstreetmap.org/wiki/Key:parking:lane is always used if available.
|
||||
pub enum OnstreetParking {
|
||||
// If not tagged, there won't be parking.
|
||||
JustOSM,
|
||||
// If OSM data is missing, then try to match data from
|
||||
// http://data-seattlecitygis.opendata.arcgis.com/datasets/blockface. This is Seattle specific.
|
||||
Blockface(String),
|
||||
// If OSM data is missing, then infer parking lanes on some percentage of
|
||||
// "highway=residential" roads.
|
||||
SomeResidential {
|
||||
// [0, 100]
|
||||
pct: usize,
|
||||
},
|
||||
}
|
||||
|
||||
// How many spots are available in public parking garages?
|
||||
pub enum PublicOffstreetParking {
|
||||
None,
|
||||
// Pull data from
|
||||
// https://data-seattlecitygis.opendata.arcgis.com/datasets/public-garages-or-parking-lots, a
|
||||
// Seattle-specific data source.
|
||||
GIS(String),
|
||||
}
|
||||
|
||||
// If a building doesn't have anything from public_offstreet_parking, how many private spots should
|
||||
@ -57,16 +85,37 @@ pub fn convert(opts: Options, timer: &mut abstutil::Timer) -> RawMap {
|
||||
|
||||
use_amenities(&mut map, amenities, timer);
|
||||
|
||||
if let Some(ref path) = opts.parking_shapes {
|
||||
use_parking_hints(&mut map, path.clone(), timer);
|
||||
match opts.onstreet_parking {
|
||||
OnstreetParking::JustOSM => {}
|
||||
OnstreetParking::Blockface(ref path) => {
|
||||
use_parking_hints(&mut map, path.clone(), timer);
|
||||
}
|
||||
OnstreetParking::SomeResidential { pct } => {
|
||||
let pct = pct as i64;
|
||||
for (id, r) in map.roads.iter_mut() {
|
||||
if r.osm_tags.contains_key(osm::INFERRED_PARKING)
|
||||
&& r.osm_tags.get(osm::HIGHWAY) == Some(&"residential".to_string())
|
||||
&& id.osm_way_id % 100 <= pct
|
||||
{
|
||||
if r.osm_tags.get("oneway") == Some(&"yes".to_string()) {
|
||||
r.osm_tags.remove(osm::PARKING_BOTH);
|
||||
r.osm_tags
|
||||
.insert(osm::PARKING_RIGHT.to_string(), "parallel".to_string());
|
||||
} else {
|
||||
r.osm_tags
|
||||
.insert(osm::PARKING_BOTH.to_string(), "parallel".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref path) = opts.public_offstreet_parking {
|
||||
use_offstreet_parking(&mut map, path.clone(), timer);
|
||||
match opts.public_offstreet_parking {
|
||||
PublicOffstreetParking::None => {}
|
||||
PublicOffstreetParking::GIS(ref path) => {
|
||||
use_offstreet_parking(&mut map, path.clone(), timer);
|
||||
}
|
||||
}
|
||||
apply_private_offstreet_parking(&mut map, opts.private_offstreet_parking);
|
||||
if let Some(ref path) = opts.sidewalks {
|
||||
use_sidewalk_hints(&mut map, path.clone(), timer);
|
||||
}
|
||||
if let Some(ref path) = opts.elevation {
|
||||
use_elevation(&mut map, path, timer);
|
||||
}
|
||||
@ -237,88 +286,6 @@ fn apply_private_offstreet_parking(map: &mut RawMap, policy: PrivateOffstreetPar
|
||||
}
|
||||
}
|
||||
|
||||
fn use_sidewalk_hints(map: &mut RawMap, path: String, timer: &mut Timer) {
|
||||
timer.start("apply sidewalk hints");
|
||||
let shapes: ExtraShapes = abstutil::read_binary(path, timer);
|
||||
|
||||
// Match shapes with the nearest road + direction (true for forwards)
|
||||
let mut closest: FindClosest<(OriginalRoad, bool)> =
|
||||
FindClosest::new(&map.gps_bounds.to_bounds());
|
||||
for (id, r) in &map.roads {
|
||||
if r.is_light_rail() {
|
||||
continue;
|
||||
}
|
||||
let center = PolyLine::new(r.center_points.clone());
|
||||
closest.add(
|
||||
(*id, true),
|
||||
map.driving_side
|
||||
.right_shift(center.clone(), DIRECTED_ROAD_THICKNESS)
|
||||
.get(timer)
|
||||
.points(),
|
||||
);
|
||||
closest.add(
|
||||
(*id, false),
|
||||
map.driving_side
|
||||
.left_shift(center, DIRECTED_ROAD_THICKNESS)
|
||||
.get(timer)
|
||||
.points(),
|
||||
);
|
||||
}
|
||||
|
||||
for s in shapes.shapes.into_iter() {
|
||||
let pts = if let Some(pts) = map.gps_bounds.try_convert(&s.points) {
|
||||
pts
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
if pts.len() <= 1 {
|
||||
continue;
|
||||
}
|
||||
// The endpoints will be close to other roads, so match based on the middle of the
|
||||
// blockface.
|
||||
// TODO Long lines sometimes cover two roads. Should maybe find ALL matches within the
|
||||
// threshold distance?
|
||||
if let Some(middle) = PolyLine::maybe_new(pts).map(|pl| pl.middle()) {
|
||||
if let Some(((r, fwds), _)) = closest.closest_pt(middle, DIRECTED_ROAD_THICKNESS * 5.0)
|
||||
{
|
||||
let osm_tags = &mut map.roads.get_mut(&r).unwrap().osm_tags;
|
||||
|
||||
// Skip if the road already has this mapped.
|
||||
if !osm_tags.contains_key(osm::INFERRED_SIDEWALKS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let definitely_no_sidewalks = match osm_tags.get(osm::HIGHWAY) {
|
||||
Some(hwy) => hwy == "motorway" || hwy == "motorway_link",
|
||||
None => false,
|
||||
};
|
||||
if definitely_no_sidewalks {
|
||||
timer.warn(format!(
|
||||
"Sidewalks shapefile says there's something along motorway {}, ignoring",
|
||||
r
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
if fwds {
|
||||
if osm_tags.get(osm::SIDEWALK) == Some(&"left".to_string()) {
|
||||
osm_tags.insert(osm::SIDEWALK.to_string(), "both".to_string());
|
||||
} else {
|
||||
osm_tags.insert(osm::SIDEWALK.to_string(), "right".to_string());
|
||||
}
|
||||
} else {
|
||||
if osm_tags.get(osm::SIDEWALK) == Some(&"right".to_string()) {
|
||||
osm_tags.insert(osm::SIDEWALK.to_string(), "both".to_string());
|
||||
} else {
|
||||
osm_tags.insert(osm::SIDEWALK.to_string(), "left".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
timer.stop("apply sidewalk hints");
|
||||
}
|
||||
|
||||
fn use_amenities(map: &mut RawMap, amenities: Vec<(Pt2D, String, String)>, timer: &mut Timer) {
|
||||
let mut closest: FindClosest<OriginalBuilding> = FindClosest::new(&map.gps_bounds.to_bounds());
|
||||
for (id, b) in &map.buildings {
|
||||
|
@ -7,7 +7,7 @@ data/input/raw_maps/ballard.bin,eeb376efa9a87e3a7f8cea5a0a1795c2,https://www.dro
|
||||
data/input/raw_maps/downtown.bin,4560307f46e64e2b4495494a4406e458,https://www.dropbox.com/s/20zw8valbf35tci/downtown.bin.zip?dl=0
|
||||
data/input/raw_maps/downtown_atx.bin,cf2cd0fea92b70e5555ac693b2d4a653,https://www.dropbox.com/s/02moxvh1gn41x5s/downtown_atx.bin.zip?dl=0
|
||||
data/input/raw_maps/huge_austin.bin,d37364ac2da4e9d44de886457ba915ed,https://www.dropbox.com/s/updgay4ia9dsbot/huge_austin.bin.zip?dl=0
|
||||
data/input/raw_maps/huge_krakow.bin,1324c55f870307b5b8e77ff37a66ef7b,https://www.dropbox.com/s/8l6dyjca08rejhf/huge_krakow.bin.zip?dl=0
|
||||
data/input/raw_maps/huge_krakow.bin,ce8340583a51ac371084455717ab5926,https://www.dropbox.com/s/jpi5fewb4fex3ej/huge_krakow.bin.zip?dl=0
|
||||
data/input/raw_maps/huge_seattle.bin,5c06f78dd172f5717895283ac1ea0f65,https://www.dropbox.com/s/mst2n74jqjknyv5/huge_seattle.bin.zip?dl=0
|
||||
data/input/raw_maps/lakeslice.bin,f3b6e1820abf31f77d30a8cce3963f0d,https://www.dropbox.com/s/6jz3aisto2rhsjj/lakeslice.bin.zip?dl=0
|
||||
data/input/raw_maps/montlake.bin,749507726d6acc94fbde892bf78bd137,https://www.dropbox.com/s/q7w9lwitdrv3ln2/montlake.bin.zip?dl=0
|
||||
@ -35,15 +35,13 @@ data/input/seattle/osm/west_seattle.osm,ce708f4701cd9118c2e9de0573e69457,https:/
|
||||
data/input/seattle/parcels.bin,5fd9e42c47827328a067a43b83686a1a,https://www.dropbox.com/s/4lql4s0fo3n5smf/parcels.bin.zip?dl=0
|
||||
data/input/seattle/parcels_urbansim.txt,db63d7d606e8702d12f9399e87e6a00f,https://www.dropbox.com/s/6g8rbsf200dssj3/parcels_urbansim.txt.zip?dl=0
|
||||
data/input/seattle/popdat.bin,b607f9990528d0ca2fbeec9f02a5755e,https://www.dropbox.com/s/hcf80kvl66a4yai/popdat.bin.zip?dl=0
|
||||
data/input/seattle/sidewalks.bin,034dd47ab77902dbc81c0107f13d8965,https://www.dropbox.com/s/ma9bmisijc7v7xa/sidewalks.bin.zip?dl=0
|
||||
data/input/seattle/sidewalks.kml,94d385ba03ef1b57a5ba10965913ec6c,https://www.dropbox.com/s/vn8amar9xi6vbvh/sidewalks.kml.zip?dl=0
|
||||
data/input/seattle/trips_2014.csv,d4a8e733045b28c0385fb81359d6df03,https://www.dropbox.com/s/5ppravwmk6bf20d/trips_2014.csv.zip?dl=0
|
||||
data/system/cities/seattle.bin,d8e88217584d6ece7abaf1ec4222c7e6,https://www.dropbox.com/s/s1i208j6oy5pd5o/seattle.bin.zip?dl=0
|
||||
data/system/maps/ballard.bin,3ee77b40b60ce5f95e80251956ca823a,https://www.dropbox.com/s/6f3nlghhqhrf8e4/ballard.bin.zip?dl=0
|
||||
data/system/maps/downtown.bin,e2e739e380416cae1b733704be5b2dc2,https://www.dropbox.com/s/b8vso3pfevmdm5f/downtown.bin.zip?dl=0
|
||||
data/system/maps/downtown_atx.bin,a76df031940aa3f5d9f680fa82846f26,https://www.dropbox.com/s/umfhjtr0mw058l2/downtown_atx.bin.zip?dl=0
|
||||
data/system/maps/huge_austin.bin,87be99eeaa1b1c6d9d074a23df872240,https://www.dropbox.com/s/g25smuci2uta2h2/huge_austin.bin.zip?dl=0
|
||||
data/system/maps/huge_krakow.bin,0d97a27aa4afbaba3f9e71c6a3f1286d,https://www.dropbox.com/s/ya9cvv3ydm3d27s/huge_krakow.bin.zip?dl=0
|
||||
data/system/maps/huge_krakow.bin,1f7d1f91ec180499edcd629148975332,https://www.dropbox.com/s/h78wsd9071bkz73/huge_krakow.bin.zip?dl=0
|
||||
data/system/maps/huge_seattle.bin,767b051c74b6c3a07aba02e0d540afbe,https://www.dropbox.com/s/rod1ohltfkkfh9f/huge_seattle.bin.zip?dl=0
|
||||
data/system/maps/lakeslice.bin,c89ec7b553f609e6ededfd3a60571126,https://www.dropbox.com/s/bpjsehxrzh82at9/lakeslice.bin.zip?dl=0
|
||||
data/system/maps/montlake.bin,50c92ff0b5bca1f86432cdfbd220c035,https://www.dropbox.com/s/4xd14op12txfi8h/montlake.bin.zip?dl=0
|
||||
|
@ -22,16 +22,16 @@ pub fn osm_to_raw(name: &str) {
|
||||
city_name: "austin".to_string(),
|
||||
name: name.to_string(),
|
||||
|
||||
parking_shapes: None,
|
||||
public_offstreet_parking: None,
|
||||
private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(1),
|
||||
sidewalks: None,
|
||||
elevation: None,
|
||||
clip: Some(abstutil::path(format!(
|
||||
"input/austin/polygons/{}.poly",
|
||||
name
|
||||
))),
|
||||
drive_on_right: true,
|
||||
|
||||
onstreet_parking: convert_osm::OnstreetParking::JustOSM,
|
||||
public_offstreet_parking: convert_osm::PublicOffstreetParking::None,
|
||||
private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(1),
|
||||
elevation: None,
|
||||
},
|
||||
&mut abstutil::Timer::throwaway(),
|
||||
);
|
||||
|
@ -22,16 +22,16 @@ pub fn osm_to_raw(name: &str) {
|
||||
city_name: "krakow".to_string(),
|
||||
name: name.to_string(),
|
||||
|
||||
parking_shapes: None,
|
||||
public_offstreet_parking: None,
|
||||
private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(1),
|
||||
sidewalks: None,
|
||||
elevation: None,
|
||||
clip: Some(abstutil::path(format!(
|
||||
"input/krakow/polygons/{}.poly",
|
||||
name
|
||||
))),
|
||||
drive_on_right: true,
|
||||
|
||||
onstreet_parking: convert_osm::OnstreetParking::SomeResidential { pct: 50 },
|
||||
public_offstreet_parking: convert_osm::PublicOffstreetParking::None,
|
||||
private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(1),
|
||||
elevation: None,
|
||||
},
|
||||
&mut abstutil::Timer::throwaway(),
|
||||
);
|
||||
|
@ -161,13 +161,13 @@ fn oneshot(osm_path: String, clip: Option<String>, drive_on_right: bool) {
|
||||
city_name: "oneshot".to_string(),
|
||||
name: name.clone(),
|
||||
|
||||
parking_shapes: None,
|
||||
public_offstreet_parking: None,
|
||||
private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(1),
|
||||
sidewalks: None,
|
||||
elevation: None,
|
||||
clip,
|
||||
drive_on_right,
|
||||
|
||||
onstreet_parking: convert_osm::OnstreetParking::JustOSM,
|
||||
public_offstreet_parking: convert_osm::PublicOffstreetParking::None,
|
||||
private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(1),
|
||||
elevation: None,
|
||||
},
|
||||
&mut timer,
|
||||
);
|
||||
|
@ -22,12 +22,7 @@ fn input() {
|
||||
"input/seattle/blockface.bin",
|
||||
"https://opendata.arcgis.com/datasets/a1458ad1abca41869b81f7c0db0cd777_0.kml",
|
||||
);
|
||||
// From https://data-seattlecitygis.opendata.arcgis.com/datasets/sidewalks
|
||||
download(
|
||||
"input/seattle/sidewalks.bin",
|
||||
"https://opendata.arcgis.com/datasets/ee6d0642d2a04e35892d0eab77d971d6_2.kml",
|
||||
);
|
||||
// From https://data.seattle.gov/Transportation/Public-Garages-or-Parking-Lots/xefx-khzm
|
||||
// From https://data-seattlecitygis.opendata.arcgis.com/datasets/public-garages-or-parking-lots
|
||||
download("input/seattle/offstreet_parking.bin", "http://data-seattlecitygis.opendata.arcgis.com/datasets/8e52dfde6d5d45948f7a90654c8d50cd_0.kml");
|
||||
}
|
||||
|
||||
@ -46,8 +41,18 @@ pub fn osm_to_raw(name: &str) {
|
||||
city_name: "seattle".to_string(),
|
||||
name: name.to_string(),
|
||||
|
||||
parking_shapes: Some(abstutil::path("input/seattle/blockface.bin")),
|
||||
public_offstreet_parking: Some(abstutil::path("input/seattle/offstreet_parking.bin")),
|
||||
clip: Some(abstutil::path(format!(
|
||||
"input/seattle/polygons/{}.poly",
|
||||
name
|
||||
))),
|
||||
drive_on_right: true,
|
||||
|
||||
onstreet_parking: convert_osm::OnstreetParking::Blockface(abstutil::path(
|
||||
"input/seattle/blockface.bin",
|
||||
)),
|
||||
public_offstreet_parking: convert_osm::PublicOffstreetParking::GIS(abstutil::path(
|
||||
"input/seattle/offstreet_parking.bin",
|
||||
)),
|
||||
private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(
|
||||
// TODO Utter guesses
|
||||
match name {
|
||||
@ -57,14 +62,7 @@ pub fn osm_to_raw(name: &str) {
|
||||
_ => 1,
|
||||
},
|
||||
),
|
||||
// TODO These're buggy.
|
||||
sidewalks: None,
|
||||
elevation: Some(abstutil::path("input/seattle/N47W122.hgt")),
|
||||
clip: Some(abstutil::path(format!(
|
||||
"input/seattle/polygons/{}.poly",
|
||||
name
|
||||
))),
|
||||
drive_on_right: true,
|
||||
},
|
||||
&mut abstutil::Timer::throwaway(),
|
||||
);
|
||||
|
@ -266,7 +266,7 @@ impl Manifest {
|
||||
"huge_seattle" => map == "huge_seattle",
|
||||
"austin" => map == "downtown_atx" || map == "huge_austin",
|
||||
"krakow" => map == "huge_krakow",
|
||||
_ => panic!("Unknown city {}", city),
|
||||
_ => panic!("Unknown city {}. Check your data/config", city),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user