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:
Dustin Carlino 2020-07-09 15:14:08 -07:00
parent 19409dfc8c
commit 3639379313
7 changed files with 92 additions and 129 deletions

View File

@ -17,13 +17,41 @@ pub struct Options {
pub city_name: String, pub city_name: String,
pub name: String, pub name: String,
pub parking_shapes: Option<String>, // The path to an osmosis boundary polygon. Highly recommended.
pub public_offstreet_parking: Option<String>,
pub private_offstreet_parking: PrivateOffstreetParking,
pub sidewalks: Option<String>,
pub elevation: Option<String>,
pub clip: Option<String>, pub clip: Option<String>,
pub drive_on_right: bool, 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 // 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); use_amenities(&mut map, amenities, timer);
if let Some(ref path) = opts.parking_shapes { match opts.onstreet_parking {
OnstreetParking::JustOSM => {}
OnstreetParking::Blockface(ref path) => {
use_parking_hints(&mut map, path.clone(), timer); use_parking_hints(&mut map, path.clone(), timer);
} }
if let Some(ref path) = opts.public_offstreet_parking { 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());
}
}
}
}
}
match opts.public_offstreet_parking {
PublicOffstreetParking::None => {}
PublicOffstreetParking::GIS(ref path) => {
use_offstreet_parking(&mut map, path.clone(), timer); 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);
} }
apply_private_offstreet_parking(&mut map, opts.private_offstreet_parking);
if let Some(ref path) = opts.elevation { if let Some(ref path) = opts.elevation {
use_elevation(&mut map, path, timer); 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) { 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()); let mut closest: FindClosest<OriginalBuilding> = FindClosest::new(&map.gps_bounds.to_bounds());
for (id, b) in &map.buildings { for (id, b) in &map.buildings {

View File

@ -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.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/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_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/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/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 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.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/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/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/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/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/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.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/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_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/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/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 data/system/maps/montlake.bin,50c92ff0b5bca1f86432cdfbd220c035,https://www.dropbox.com/s/4xd14op12txfi8h/montlake.bin.zip?dl=0

View File

@ -22,16 +22,16 @@ pub fn osm_to_raw(name: &str) {
city_name: "austin".to_string(), city_name: "austin".to_string(),
name: name.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!( clip: Some(abstutil::path(format!(
"input/austin/polygons/{}.poly", "input/austin/polygons/{}.poly",
name name
))), ))),
drive_on_right: true, 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(), &mut abstutil::Timer::throwaway(),
); );

View File

@ -22,16 +22,16 @@ pub fn osm_to_raw(name: &str) {
city_name: "krakow".to_string(), city_name: "krakow".to_string(),
name: name.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!( clip: Some(abstutil::path(format!(
"input/krakow/polygons/{}.poly", "input/krakow/polygons/{}.poly",
name name
))), ))),
drive_on_right: true, 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(), &mut abstutil::Timer::throwaway(),
); );

View File

@ -161,13 +161,13 @@ fn oneshot(osm_path: String, clip: Option<String>, drive_on_right: bool) {
city_name: "oneshot".to_string(), city_name: "oneshot".to_string(),
name: name.clone(), name: name.clone(),
parking_shapes: None,
public_offstreet_parking: None,
private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(1),
sidewalks: None,
elevation: None,
clip, clip,
drive_on_right, 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, &mut timer,
); );

View File

@ -22,12 +22,7 @@ fn input() {
"input/seattle/blockface.bin", "input/seattle/blockface.bin",
"https://opendata.arcgis.com/datasets/a1458ad1abca41869b81f7c0db0cd777_0.kml", "https://opendata.arcgis.com/datasets/a1458ad1abca41869b81f7c0db0cd777_0.kml",
); );
// From https://data-seattlecitygis.opendata.arcgis.com/datasets/sidewalks // From https://data-seattlecitygis.opendata.arcgis.com/datasets/public-garages-or-parking-lots
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
download("input/seattle/offstreet_parking.bin", "http://data-seattlecitygis.opendata.arcgis.com/datasets/8e52dfde6d5d45948f7a90654c8d50cd_0.kml"); 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(), city_name: "seattle".to_string(),
name: name.to_string(), name: name.to_string(),
parking_shapes: Some(abstutil::path("input/seattle/blockface.bin")), clip: Some(abstutil::path(format!(
public_offstreet_parking: Some(abstutil::path("input/seattle/offstreet_parking.bin")), "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( private_offstreet_parking: convert_osm::PrivateOffstreetParking::FixedPerBldg(
// TODO Utter guesses // TODO Utter guesses
match name { match name {
@ -57,14 +62,7 @@ pub fn osm_to_raw(name: &str) {
_ => 1, _ => 1,
}, },
), ),
// TODO These're buggy.
sidewalks: None,
elevation: Some(abstutil::path("input/seattle/N47W122.hgt")), 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(), &mut abstutil::Timer::throwaway(),
); );

View File

@ -266,7 +266,7 @@ impl Manifest {
"huge_seattle" => map == "huge_seattle", "huge_seattle" => map == "huge_seattle",
"austin" => map == "downtown_atx" || map == "huge_austin", "austin" => map == "downtown_atx" || map == "huge_austin",
"krakow" => map == "huge_krakow", "krakow" => map == "huge_krakow",
_ => panic!("Unknown city {}", city), _ => panic!("Unknown city {}. Check your data/config", city),
} }
} }