mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
prep before bringing in king county sidewalks. clean up lane type
calculation, move motorway/parking filter earlier. stop bringing in street signs.
This commit is contained in:
parent
d5c82a63e0
commit
9cab5bf903
@ -3,7 +3,7 @@ mod neighborhoods;
|
||||
mod osm_reader;
|
||||
mod split_ways;
|
||||
|
||||
use abstutil::{prettyprint_usize, Timer};
|
||||
use abstutil::Timer;
|
||||
use geom::{Distance, FindClosest, Line, PolyLine, Pt2D};
|
||||
use kml::ExtraShapes;
|
||||
use map_model::raw::{RawMap, StableBuildingID, StableRoadID};
|
||||
@ -13,7 +13,6 @@ use std::collections::BTreeMap;
|
||||
pub struct Flags {
|
||||
pub osm: String,
|
||||
pub parking_shapes: Option<String>,
|
||||
pub street_signs: Option<String>,
|
||||
pub offstreet_parking: Option<String>,
|
||||
pub gtfs: Option<String>,
|
||||
pub neighborhoods: Option<String>,
|
||||
@ -36,9 +35,6 @@ pub fn convert(flags: &Flags, timer: &mut abstutil::Timer) -> RawMap {
|
||||
if let Some(ref path) = flags.parking_shapes {
|
||||
use_parking_hints(&mut map, path, timer);
|
||||
}
|
||||
if let Some(ref path) = flags.street_signs {
|
||||
use_street_signs(&mut map, path, timer);
|
||||
}
|
||||
if let Some(ref path) = flags.offstreet_parking {
|
||||
use_offstreet_parking(&mut map, path, timer);
|
||||
}
|
||||
@ -112,109 +108,59 @@ fn use_parking_hints(map: &mut RawMap, path: &str, timer: &mut Timer) {
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
if pts.len() > 1 {
|
||||
// The blockface line endpoints will be close to other roads, so match based on the
|
||||
// middle of the blockface.
|
||||
// TODO Long blockfaces sometimes cover two roads. Should maybe find ALL matches within
|
||||
// the threshold distance?
|
||||
let middle = PolyLine::new(pts).middle();
|
||||
if let Some(((r, fwds), _)) = closest.closest_pt(middle, LANE_THICKNESS * 5.0) {
|
||||
// Skip if the road already has this mapped.
|
||||
if !map.roads[&r].osm_tags.contains_key(osm::INFERRED_PARKING) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let category = s.attributes.get("PARKING_CATEGORY");
|
||||
let has_parking = category != Some(&"None".to_string())
|
||||
&& category != Some(&"No Parking Allowed".to_string());
|
||||
// Blindly override prior values.
|
||||
map.roads.get_mut(&r).unwrap().osm_tags.insert(
|
||||
if fwds {
|
||||
osm::PARKING_RIGHT.to_string()
|
||||
} else {
|
||||
osm::PARKING_LEFT.to_string()
|
||||
},
|
||||
if has_parking {
|
||||
"parallel".to_string()
|
||||
} else {
|
||||
"no_parking".to_string()
|
||||
},
|
||||
);
|
||||
map.roads
|
||||
.get_mut(&r)
|
||||
.unwrap()
|
||||
.osm_tags
|
||||
.remove(osm::PARKING_BOTH);
|
||||
if pts.len() <= 1 {
|
||||
continue;
|
||||
}
|
||||
// The blockface line endpoints will be close to other roads, so match based on the
|
||||
// middle of the blockface.
|
||||
// TODO Long blockfaces sometimes cover two roads. Should maybe find ALL matches within
|
||||
// the threshold distance?
|
||||
let middle = PolyLine::new(pts).middle();
|
||||
if let Some(((r, fwds), _)) = closest.closest_pt(middle, LANE_THICKNESS * 5.0) {
|
||||
// Skip if the road already has this mapped.
|
||||
if !map.roads[&r].osm_tags.contains_key(osm::INFERRED_PARKING) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let category = s.attributes.get("PARKING_CATEGORY");
|
||||
let has_parking = category != Some(&"None".to_string())
|
||||
&& category != Some(&"No Parking Allowed".to_string());
|
||||
|
||||
let definitely_no_parking = match map.roads[&r].osm_tags.get(osm::HIGHWAY) {
|
||||
Some(hwy) => hwy == "motorway" || hwy == "motorway_link",
|
||||
None => false,
|
||||
};
|
||||
if has_parking && definitely_no_parking {
|
||||
timer.warn(format!(
|
||||
"Blockface says there's parking along motorway {}, ignoring",
|
||||
r
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Blindly override prior values.
|
||||
map.roads.get_mut(&r).unwrap().osm_tags.insert(
|
||||
if fwds {
|
||||
osm::PARKING_RIGHT.to_string()
|
||||
} else {
|
||||
osm::PARKING_LEFT.to_string()
|
||||
},
|
||||
if has_parking {
|
||||
"parallel".to_string()
|
||||
} else {
|
||||
"no_parking".to_string()
|
||||
},
|
||||
);
|
||||
map.roads
|
||||
.get_mut(&r)
|
||||
.unwrap()
|
||||
.osm_tags
|
||||
.remove(osm::PARKING_BOTH);
|
||||
}
|
||||
}
|
||||
timer.stop("apply parking hints");
|
||||
}
|
||||
|
||||
fn use_street_signs(map: &mut RawMap, path: &str, timer: &mut Timer) {
|
||||
timer.start("apply street signs to override parking hints");
|
||||
let shapes: ExtraShapes =
|
||||
abstutil::read_binary(path, timer).expect("loading street_signs failed");
|
||||
|
||||
// Match shapes with the nearest road + direction (true for forwards)
|
||||
let mut closest: FindClosest<(StableRoadID, bool)> =
|
||||
FindClosest::new(&map.gps_bounds.to_bounds());
|
||||
for (id, r) in &map.roads {
|
||||
let center = PolyLine::new(r.center_points.clone());
|
||||
closest.add(
|
||||
(*id, true),
|
||||
center.shift_right(LANE_THICKNESS).get(timer).points(),
|
||||
);
|
||||
closest.add(
|
||||
(*id, false),
|
||||
center.shift_left(LANE_THICKNESS).get(timer).points(),
|
||||
);
|
||||
}
|
||||
|
||||
let mut applied = 0;
|
||||
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 {
|
||||
if let Some(((r, fwds), _)) = closest.closest_pt(pts[0], LANE_THICKNESS * 5.0) {
|
||||
// Skip if the road already has this mapped.
|
||||
if !map.roads[&r].osm_tags.contains_key(osm::INFERRED_PARKING) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO Model RPZ, paid on-street spots, limited times, etc.
|
||||
let no_parking =
|
||||
s.attributes.get("TEXT") == Some(&"NO PARKING ANYTIME".to_string());
|
||||
if no_parking {
|
||||
applied += 1;
|
||||
map.roads.get_mut(&r).unwrap().osm_tags.insert(
|
||||
if fwds {
|
||||
osm::PARKING_RIGHT
|
||||
} else {
|
||||
osm::PARKING_LEFT
|
||||
}
|
||||
.to_string(),
|
||||
"no_parking".to_string(),
|
||||
);
|
||||
map.roads
|
||||
.get_mut(&r)
|
||||
.unwrap()
|
||||
.osm_tags
|
||||
.remove(osm::PARKING_BOTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
timer.note(format!(
|
||||
"Applied {} street signs",
|
||||
prettyprint_usize(applied)
|
||||
));
|
||||
timer.stop("apply street signs to override parking hints");
|
||||
}
|
||||
|
||||
fn use_offstreet_parking(map: &mut RawMap, path: &str, timer: &mut Timer) {
|
||||
timer.start("match offstreet parking points");
|
||||
let shapes = kml::load(path, &map.gps_bounds, timer).expect("loading offstreet_parking failed");
|
||||
|
@ -6,7 +6,6 @@ fn main() {
|
||||
let flags = Flags {
|
||||
osm: args.required("--osm"),
|
||||
parking_shapes: args.optional("--parking_shapes"),
|
||||
street_signs: args.optional("--street_signs"),
|
||||
offstreet_parking: args.optional("--offstreet_parking"),
|
||||
gtfs: args.optional("--gtfs"),
|
||||
neighborhoods: args.optional("--neighborhoods"),
|
||||
|
@ -1,21 +1,21 @@
|
||||
e1a6e14f3b585a99d70f4d3d9afc97ea ../data/screenshots/pending_montlake/01x01_i53.png
|
||||
e1a6e14f3b585a99d70f4d3d9afc97ea ../data/screenshots/pending_montlake/01x01_i52.png
|
||||
0f008347ce29e2f80006699858f5b024 ../data/screenshots/pending_montlake/02x01_i1.png
|
||||
b3cf25e0c4382a7c91f8a12c5abfc023 ../data/screenshots/pending_montlake/03x01_i0.png
|
||||
f2c7083a2e0e2a6039f0ce3fc75823b0 ../data/screenshots/pending_montlake/01x02_i7.png
|
||||
4bd77b889539e91216c39917610091fe ../data/screenshots/pending_montlake/02x02_i126.png
|
||||
d8f709a41a307871389c3e05a3fa66ec ../data/screenshots/pending_montlake/03x02_i31.png
|
||||
75c7bba069f59f245d05c79588891538 ../data/screenshots/pending_montlake/01x03_i97.png
|
||||
1af3029a2c2c64af9568760ada59c9f5 ../data/screenshots/pending_montlake/02x02_i125.png
|
||||
c4b0cf4d2389d9f1d4dbad1a3f95adce ../data/screenshots/pending_montlake/03x02_i30.png
|
||||
75c7bba069f59f245d05c79588891538 ../data/screenshots/pending_montlake/01x03_i96.png
|
||||
96a8b52e299032c187ff395bf96e3a54 ../data/screenshots/pending_montlake/02x03_i5.png
|
||||
c25dd6296e4b034fa971909b028116eb ../data/screenshots/pending_montlake/03x03_i14.png
|
||||
c25dd6296e4b034fa971909b028116eb ../data/screenshots/pending_montlake/03x03_i13.png
|
||||
615e04c96503dc3a0eec27ae1b9e953e ../data/screenshots/pending_montlake/01x04_i3.png
|
||||
515cbe5b6ad4545f5771dd7f9cee297e ../data/screenshots/pending_montlake/02x04_i27.png
|
||||
24cfe9e237b59ba7ef61d7348bd6a683 ../data/screenshots/pending_montlake/03x04_i13.png
|
||||
bb7b19d3ec9435ded8a5f00a2c4ad04d ../data/screenshots/pending_montlake/01x05_i42.png
|
||||
81261d07f7af826511941b9b9019d08d ../data/screenshots/pending_montlake/02x05_i41.png
|
||||
20744688172dfca19683a621438b6825 ../data/screenshots/pending_montlake/03x05_i21.png
|
||||
cbd1dc516addd9cff0434a1a39773e8c ../data/screenshots/pending_montlake/01x06_i11.png
|
||||
515cbe5b6ad4545f5771dd7f9cee297e ../data/screenshots/pending_montlake/02x04_i26.png
|
||||
24cfe9e237b59ba7ef61d7348bd6a683 ../data/screenshots/pending_montlake/03x04_i12.png
|
||||
bb7b19d3ec9435ded8a5f00a2c4ad04d ../data/screenshots/pending_montlake/01x05_i41.png
|
||||
81261d07f7af826511941b9b9019d08d ../data/screenshots/pending_montlake/02x05_i40.png
|
||||
20744688172dfca19683a621438b6825 ../data/screenshots/pending_montlake/03x05_i20.png
|
||||
96108b40fb32b44ab64cf569941e5faf ../data/screenshots/pending_montlake/01x06_i11.png
|
||||
d66a4f0e23bd6662201ddad433476e73 ../data/screenshots/pending_montlake/02x06_i9.png
|
||||
75bb186a8bee1eae263a6085ee20a7ba ../data/screenshots/pending_montlake/03x06_i17.png
|
||||
228d874db835c89248966a4eda679465 ../data/screenshots/pending_montlake/01x07_i104.png
|
||||
ddbd185ea6e662c014be4b35b101a29c ../data/screenshots/pending_montlake/02x07_i19.png
|
||||
50e1b4fb5206edbeed33c44a9c3f7765 ../data/screenshots/pending_montlake/03x07_i18.png
|
||||
75bb186a8bee1eae263a6085ee20a7ba ../data/screenshots/pending_montlake/03x06_i16.png
|
||||
228d874db835c89248966a4eda679465 ../data/screenshots/pending_montlake/01x07_i103.png
|
||||
ddbd185ea6e662c014be4b35b101a29c ../data/screenshots/pending_montlake/02x07_i18.png
|
||||
50e1b4fb5206edbeed33c44a9c3f7765 ../data/screenshots/pending_montlake/03x07_i17.png
|
||||
|
12
import.sh
12
import.sh
@ -73,14 +73,14 @@ if [ ! -f data/shapes/blockface.bin ]; then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if [ ! -f data/shapes/street_signs.bin ]; then
|
||||
# From http://data-seattlecitygis.opendata.arcgis.com/datasets/411a96b39c834a2380a256b8afa5003b_0
|
||||
get_if_needed https://opendata.arcgis.com/datasets/411a96b39c834a2380a256b8afa5003b_0.kml data/input/street_signs.kml;
|
||||
if [ ! -f data/shapes/sidewalks.bin ]; then
|
||||
# From https://data-seattlecitygis.opendata.arcgis.com/datasets/sidewalks
|
||||
get_if_needed https://opendata.arcgis.com/datasets/ee6d0642d2a04e35892d0eab77d971d6_2.kml data/input/sidewalks.kml;
|
||||
|
||||
cd kml
|
||||
time cargo run --release -- \
|
||||
--input=../data/input/street_signs.kml \
|
||||
--output=../data/shapes/street_signs.bin
|
||||
--input=../data/input/sidewalks.kml \
|
||||
--output=../data/shapes/sidewalks.bin
|
||||
cd ..
|
||||
fi
|
||||
|
||||
@ -123,6 +123,4 @@ for poly in `ls ../data/polygons/`; do
|
||||
--neighborhoods=../data/input/neighborhoods.geojson \
|
||||
--clip=../data/polygons/$name.poly \
|
||||
--output=../data/raw_maps/$name.bin
|
||||
# Disabled, because it removes lots of parking that's really there.
|
||||
#--street_signs=../data/shapes/street_signs.bin \
|
||||
done
|
||||
|
@ -13,16 +13,6 @@ pub fn get_lane_types(osm_tags: &BTreeMap<String, String>) -> (Vec<LaneType>, Ve
|
||||
}
|
||||
}
|
||||
|
||||
fn has_parking(value: Option<&String>) -> bool {
|
||||
value == Some(&"parallel".to_string())
|
||||
|| value == Some(&"diagonal".to_string())
|
||||
|| value == Some(&"perpendicular".to_string())
|
||||
}
|
||||
let parking_lane_fwd = has_parking(osm_tags.get(osm::PARKING_RIGHT))
|
||||
|| has_parking(osm_tags.get(osm::PARKING_BOTH));
|
||||
let parking_lane_back = has_parking(osm_tags.get(osm::PARKING_LEFT))
|
||||
|| has_parking(osm_tags.get(osm::PARKING_BOTH));
|
||||
|
||||
// Easy special cases first.
|
||||
if osm_tags.get("junction") == Some(&"roundabout".to_string()) {
|
||||
return (vec![LaneType::Driving, LaneType::Sidewalk], Vec::new());
|
||||
@ -121,15 +111,19 @@ pub fn get_lane_types(osm_tags: &BTreeMap<String, String>) -> (Vec<LaneType>, Ve
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Should we warn when one of these has parking assigned to it from the blockface?
|
||||
let definitely_no_parking = match osm_tags.get(osm::HIGHWAY) {
|
||||
Some(hwy) => hwy.ends_with("_link") || hwy == "motorway",
|
||||
None => false,
|
||||
};
|
||||
if parking_lane_fwd && !definitely_no_parking {
|
||||
fn has_parking(value: Option<&String>) -> bool {
|
||||
value == Some(&"parallel".to_string())
|
||||
|| value == Some(&"diagonal".to_string())
|
||||
|| value == Some(&"perpendicular".to_string())
|
||||
}
|
||||
let parking_lane_fwd = has_parking(osm_tags.get(osm::PARKING_RIGHT))
|
||||
|| has_parking(osm_tags.get(osm::PARKING_BOTH));
|
||||
let parking_lane_back = has_parking(osm_tags.get(osm::PARKING_LEFT))
|
||||
|| has_parking(osm_tags.get(osm::PARKING_BOTH));
|
||||
if parking_lane_fwd {
|
||||
fwd_side.push(LaneType::Parking);
|
||||
}
|
||||
if parking_lane_back && !definitely_no_parking {
|
||||
if parking_lane_back {
|
||||
back_side.push(LaneType::Parking);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ pub fn run(t: &mut TestRunner) {
|
||||
let flags = convert_osm::Flags {
|
||||
osm: "../data/input/montlake.osm".to_string(),
|
||||
parking_shapes: Some("../data/shapes/blockface.bin".to_string()),
|
||||
street_signs: Some("../data/shapes/street_signs.bin".to_string()),
|
||||
offstreet_parking: Some("../data/input/offstreet_parking.kml".to_string()),
|
||||
gtfs: Some("../data/input/google_transit_2018_18_08".to_string()),
|
||||
neighborhoods: Some("../data/input/neighborhoods.geojson".to_string()),
|
||||
|
Loading…
Reference in New Issue
Block a user