organizing osm keys

This commit is contained in:
Dustin Carlino 2019-09-17 17:14:09 -07:00
parent ad8f984359
commit 6f1ac3969e
11 changed files with 94 additions and 66 deletions

View File

@ -1,6 +1,6 @@
use abstutil::{FileWithProgress, Timer};
use geom::{GPSBounds, HashablePt2D, LonLat, Polygon, Pt2D};
use map_model::{raw_data, AreaType};
use map_model::{osm, raw_data, AreaType};
use osm_xml;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::fs::File;
@ -46,7 +46,7 @@ pub fn extract_osm(
for node in doc.nodes.values() {
timer.next();
let tags = tags_to_map(&node.tags);
if tags.get("highway") == Some(&"traffic_signals".to_string()) {
if tags.get(osm::HIGHWAY) == Some(&"traffic_signals".to_string()) {
traffic_signals.insert(
Pt2D::forcibly_from_gps(LonLat::new(node.lon, node.lat), &map.gps_bounds)
.to_hashable(),
@ -76,7 +76,7 @@ pub fn extract_osm(
}
let pts = map.gps_bounds.forcibly_convert(&gps_pts);
let mut tags = tags_to_map(&way.tags);
tags.insert("abst:osm_way_id".to_string(), way.id.to_string());
tags.insert(osm::OSM_WAY_ID.to_string(), way.id.to_string());
if is_road(&tags) {
roads.push(raw_data::Road {
osm_way_id: way.id,
@ -128,7 +128,7 @@ pub fn extract_osm(
for rel in doc.relations.values() {
timer.next();
let mut tags = tags_to_map(&rel.tags);
tags.insert("abst:osm_rel_id".to_string(), rel.id.to_string());
tags.insert(osm::OSM_REL_ID.to_string(), rel.id.to_string());
if let Some(at) = get_area_type(&tags) {
if tags.get("type") == Some(&"multipolygon".to_string()) {
let mut ok = true;
@ -213,7 +213,7 @@ fn tags_to_map(raw_tags: &[osm_xml::Tag]) -> BTreeMap<String, String> {
}
fn is_road(tags: &BTreeMap<String, String>) -> bool {
if !tags.contains_key("highway") {
if !tags.contains_key(osm::HIGHWAY) {
return false;
}
@ -243,7 +243,7 @@ fn is_road(tags: &BTreeMap<String, String>) -> bool {
"planned",
"razed",
] {
if tags.get("highway") == Some(&String::from(value)) {
if tags.get(osm::HIGHWAY) == Some(&String::from(value)) {
return false;
}
}

View File

@ -1,6 +1,6 @@
use abstutil::{Counter, Timer};
use geom::{HashablePt2D, Pt2D};
use map_model::{raw_data, IntersectionType};
use map_model::{osm, raw_data, IntersectionType};
use std::collections::{HashMap, HashSet};
pub fn split_up_roads(
@ -123,11 +123,11 @@ pub fn split_up_roads(
r.i2 = *i2;
if r.i1 == endpt1 {
r.osm_tags
.insert("abst:endpt_back".to_string(), "true".to_string());
.insert(osm::ENDPT_BACK.to_string(), "true".to_string());
}
if r.i2 == endpt2 {
r.osm_tags
.insert("abst:endpt_fwd".to_string(), "true".to_string());
.insert(osm::ENDPT_FWD.to_string(), "true".to_string());
}
r.orig_id.pt1 = pts[0].forcibly_to_gps(&map.gps_bounds);
r.orig_id.pt2 = pts.last().unwrap().forcibly_to_gps(&map.gps_bounds);
@ -135,8 +135,8 @@ pub fn split_up_roads(
// Start a new road
map.roads
.insert(raw_data::StableRoadID(map.roads.len()), r.clone());
r.osm_tags.remove("abst:endpt_fwd");
r.osm_tags.remove("abst:endpt_back");
r.osm_tags.remove(osm::ENDPT_FWD);
r.osm_tags.remove(osm::ENDPT_BACK);
r.i1 = *i2;
pts.push(*pt);
}

View File

@ -1,4 +1,4 @@
use crate::{LaneID, Position};
use crate::{osm, LaneID, Position};
use abstutil;
use geom::{Line, Polygon, Pt2D};
use serde_derive::{Deserialize, Serialize};
@ -63,7 +63,7 @@ impl Building {
(None, Some(st)) => format!("??? {}", st),
_ => "???".to_string(),
};
if let Some(name) = self.osm_tags.get("name") {
if let Some(name) = self.osm_tags.get(osm::NAME) {
format!("{} (at {})", name, address)
} else {
address

View File

@ -1,4 +1,6 @@
use crate::{BuildingID, BusStopID, DirectedRoadID, IntersectionID, Map, Road, RoadID, TurnType};
use crate::{
osm, BuildingID, BusStopID, DirectedRoadID, IntersectionID, Map, Road, RoadID, TurnType,
};
use abstutil;
use geom::{Angle, Distance, Line, PolyLine, Pt2D};
use serde_derive::{Deserialize, Serialize};
@ -170,11 +172,11 @@ impl Lane {
}
let (dir, offset) = road.dir_and_offset(self.id);
let all = if dir && road.osm_tags.contains_key("abst:endpt_fwd") {
let all = if dir && road.osm_tags.contains_key(osm::ENDPT_FWD) {
road.osm_tags
.get("turn:lanes:forward")
.or_else(|| road.osm_tags.get("turn:lanes"))?
} else if !dir && road.osm_tags.contains_key("abst:endpt_back") {
} else if !dir && road.osm_tags.contains_key(osm::ENDPT_BACK) {
road.osm_tags.get("turn:lanes:backward")?
} else {
return None;

View File

@ -7,6 +7,7 @@ mod lane;
mod make;
mod map;
mod neighborhood;
pub mod osm;
mod pathfind;
pub mod raw_data;
mod road;

View File

@ -1,5 +1,5 @@
use crate::make::sidewalk_finder::find_sidewalk_points;
use crate::{raw_data, Building, BuildingID, FrontPath, Lane, LaneID, Position, Road};
use crate::{osm, raw_data, Building, BuildingID, FrontPath, Lane, LaneID, Position, Road};
use abstutil::Timer;
use geom::{Bounds, Distance, FindClosest, HashablePt2D, Line, Polygon};
use std::collections::{BTreeMap, HashSet};
@ -32,7 +32,7 @@ pub fn make_all_buildings(
continue;
}
let tags = &roads[l.parent.0].osm_tags;
if tags.get("highway") == Some(&"motorway".to_string())
if tags.get(osm::HIGHWAY) == Some(&"motorway".to_string())
|| tags.get("tunnel") == Some(&"yes".to_string())
{
continue;

View File

@ -1,4 +1,4 @@
use crate::LaneType;
use crate::{osm, LaneType};
use serde_derive::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::iter;
@ -9,12 +9,11 @@ pub fn get_lane_types(
parking_lane_fwd: bool,
parking_lane_back: bool,
) -> (Vec<LaneType>, Vec<LaneType>) {
// The raw_data might come from the synthetic map editor.
if let Some(s) = osm_tags.get("abst:synthetic_lanes") {
if let Some(s) = osm_tags.get(osm::SYNTHETIC_LANES) {
if let Some(spec) = RoadSpec::parse(s.to_string()) {
return (spec.fwd, spec.back);
} else {
panic!("Bad abst:synthetic_lanes RoadSpec: {}", s);
panic!("Bad {} RoadSpec: {}", osm::SYNTHETIC_LANES, s);
}
}
@ -22,7 +21,7 @@ pub fn get_lane_types(
if osm_tags.get("junction") == Some(&"roundabout".to_string()) {
return (vec![LaneType::Driving, LaneType::Sidewalk], Vec::new());
}
if osm_tags.get("highway") == Some(&"footway".to_string()) {
if osm_tags.get(osm::HIGHWAY) == Some(&"footway".to_string()) {
return (vec![LaneType::Sidewalk], Vec::new());
}
@ -105,7 +104,7 @@ pub fn get_lane_types(
}
// TODO Should we warn when a link road has parking assigned to it from the blockface?
let is_link = match osm_tags.get("highway") {
let is_link = match osm_tags.get(osm::HIGHWAY) {
Some(hwy) => hwy.ends_with("_link"),
None => false,
};
@ -116,13 +115,13 @@ pub fn get_lane_types(
back_side.push(LaneType::Parking);
}
let has_sidewalk = osm_tags.get("highway") != Some(&"motorway".to_string())
&& osm_tags.get("highway") != Some(&"motorway_link".to_string());
let has_sidewalk = osm_tags.get(osm::HIGHWAY) != Some(&"motorway".to_string())
&& osm_tags.get(osm::HIGHWAY) != Some(&"motorway_link".to_string());
if has_sidewalk {
fwd_side.push(LaneType::Sidewalk);
if oneway {
// Only residential streets have a sidewalk on the other side of a one-way.
if osm_tags.get("highway") == Some(&"residential".to_string())
if osm_tags.get(osm::HIGHWAY) == Some(&"residential".to_string())
|| osm_tags.get("sidewalk") == Some(&"both".to_string())
{
back_side.push(LaneType::Sidewalk);

View File

@ -1,10 +1,10 @@
use crate::make::get_lane_types;
use crate::pathfind::Pathfinder;
use crate::{
make, raw_data, Area, AreaID, Building, BuildingID, BusRoute, BusRouteID, BusStop, BusStopID,
ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID, IntersectionType, Lane,
LaneID, LaneType, MapEdits, Path, PathRequest, Position, Road, RoadID, Turn, TurnID,
TurnPriority,
make, osm, raw_data, Area, AreaID, Building, BuildingID, BusRoute, BusRouteID, BusStop,
BusStopID, ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID,
IntersectionType, Lane, LaneID, LaneType, MapEdits, Path, PathRequest, Position, Road, RoadID,
Turn, TurnID, TurnPriority,
};
use abstutil;
use abstutil::{deserialize_btreemap, serialize_btreemap, Error, Timer};
@ -499,7 +499,7 @@ impl Map {
pub fn bldg(&self, label: &str) -> &Building {
for b in &self.buildings {
if b.osm_tags.get("label") == Some(&label.to_string()) {
if b.osm_tags.get(osm::LABEL) == Some(&label.to_string()) {
return b;
}
}
@ -512,9 +512,9 @@ impl Map {
continue;
}
let r = self.get_parent(l.id);
if (r.is_forwards(l.id) && r.osm_tags.get("abst:fwd_label") == Some(&label.to_string()))
if (r.is_forwards(l.id) && r.osm_tags.get(osm::FWD_LABEL) == Some(&label.to_string()))
|| (r.is_backwards(l.id)
&& r.osm_tags.get("abst:back_label") == Some(&label.to_string()))
&& r.osm_tags.get(osm::BACK_LABEL) == Some(&label.to_string()))
{
return l;
}
@ -528,9 +528,9 @@ impl Map {
continue;
}
let r = self.get_parent(l.id);
if (r.is_forwards(l.id) && r.osm_tags.get("abst:fwd_label") == Some(&label.to_string()))
if (r.is_forwards(l.id) && r.osm_tags.get(osm::FWD_LABEL) == Some(&label.to_string()))
|| (r.is_backwards(l.id)
&& r.osm_tags.get("abst:back_label") == Some(&label.to_string()))
&& r.osm_tags.get(osm::BACK_LABEL) == Some(&label.to_string()))
{
let actual_spots = l.number_parking_spots();
if expected_spots != actual_spots {

26
map_model/src/osm.rs Normal file
View File

@ -0,0 +1,26 @@
// These are common OSM keys. Keys used in just one or two places don't really need to be defined
// here.
// These're normal OSM keys.
pub const NAME: &str = "name";
pub const HIGHWAY: &str = "highway";
// The rest of these are all inserted by A/B Street to plumb data between different stages of map
// construction. They could be plumbed another way, but this is the most convenient.
// Just a copy of OSM IDs, so that things displaying/searching tags will also pick these up.
pub const OSM_WAY_ID: &str = "abst:osm_way_id";
pub const OSM_REL_ID: &str = "abst:osm_rel_id";
// OSM ways are split into multiple roads. The first and last road are marked, which is important
// for interpreting turn restrictions.
pub const ENDPT_FWD: &str = "abst:endpt_fwd";
pub const ENDPT_BACK: &str = "abst:endpt_back";
// Synthetic roads have (some of) these.
pub const SYNTHETIC: &str = "abst:synthetic";
pub const SYNTHETIC_LANES: &str = "abst:synthetic_lanes";
pub const FWD_LABEL: &str = "abst:fwd_label";
pub const BACK_LABEL: &str = "abst:back_label";
// Synthetic buildings may have these.
pub const LABEL: &str = "abst:label";

View File

@ -1,4 +1,4 @@
use crate::{raw_data, BusStopID, IntersectionID, LaneID, LaneType, Map, LANE_THICKNESS};
use crate::{osm, raw_data, BusStopID, IntersectionID, LaneID, LaneType, Map, LANE_THICKNESS};
use abstutil::{Error, Warn};
use geom::{Distance, PolyLine, Polygon, Speed};
use serde_derive::{Deserialize, Serialize};
@ -196,8 +196,8 @@ impl Road {
}
}
if self.osm_tags.get("highway") == Some(&"primary".to_string())
|| self.osm_tags.get("highway") == Some(&"secondary".to_string())
if self.osm_tags.get(osm::HIGHWAY) == Some(&"primary".to_string())
|| self.osm_tags.get(osm::HIGHWAY) == Some(&"secondary".to_string())
{
return Speed::miles_per_hour(40.0);
}
@ -349,7 +349,7 @@ impl Road {
}
pub fn get_name(&self) -> String {
if let Some(name) = self.osm_tags.get("name") {
if let Some(name) = self.osm_tags.get(osm::NAME) {
return name.to_string();
}
if let Some(name) = self.osm_tags.get("ref") {
@ -357,7 +357,7 @@ impl Road {
}
if self
.osm_tags
.get("highway")
.get(osm::HIGHWAY)
.map(|hwy| hwy.ends_with("_link"))
.unwrap_or(false)
{
@ -376,7 +376,7 @@ impl Road {
}
pub fn get_rank(&self) -> usize {
if let Some(highway) = self.osm_tags.get("highway") {
if let Some(highway) = self.osm_tags.get(osm::HIGHWAY) {
match highway.as_ref() {
"motorway" => 20,
"motorway_link" => 19,

View File

@ -3,7 +3,7 @@ use ezgui::world::{Object, ObjectID, World};
use ezgui::{Color, EventCtx, GfxCtx, Line, Prerender, Text};
use geom::{Bounds, Circle, Distance, PolyLine, Polygon, Pt2D};
use map_model::raw_data::{MapFixes, StableBuildingID, StableIntersectionID, StableRoadID};
use map_model::{raw_data, IntersectionType, LaneType, RoadSpec, LANE_THICKNESS};
use map_model::{osm, raw_data, IntersectionType, LaneType, RoadSpec, LANE_THICKNESS};
use std::collections::BTreeMap;
use std::mem;
@ -121,7 +121,7 @@ impl Model {
}
}
for r in self.map.roads.values() {
if r.osm_tags.get("abst:synthetic") == Some(&"true".to_string()) {
if r.osm_tags.get(osm::SYNTHETIC) == Some(&"true".to_string()) {
fixes.add_roads.push(r.clone());
}
}
@ -323,19 +323,19 @@ impl Model {
}
let mut osm_tags = BTreeMap::new();
osm_tags.insert("abst:synthetic".to_string(), "true".to_string());
osm_tags.insert(osm::SYNTHETIC.to_string(), "true".to_string());
osm_tags.insert(
"abst:synthetic_lanes".to_string(),
osm::SYNTHETIC_LANES.to_string(),
RoadSpec {
fwd: vec![LaneType::Driving, LaneType::Parking, LaneType::Sidewalk],
back: vec![LaneType::Driving, LaneType::Parking, LaneType::Sidewalk],
}
.to_string(),
);
osm_tags.insert("abst:endpt_fwd".to_string(), "true".to_string());
osm_tags.insert("abst:endpt_back".to_string(), "true".to_string());
osm_tags.insert(osm::ENDPT_FWD.to_string(), "true".to_string());
osm_tags.insert(osm::ENDPT_BACK.to_string(), "true".to_string());
osm_tags.insert(
"abst:osm_way_id".to_string(),
osm::OSM_WAY_ID.to_string(),
SYNTHETIC_OSM_WAY_ID.to_string(),
);
let center_points = vec![
@ -376,7 +376,7 @@ impl Model {
.get_mut(&id)
.unwrap()
.osm_tags
.insert("abst:synthetic_lanes".to_string(), s.to_string());
.insert(osm::SYNTHETIC_LANES.to_string(), s.to_string());
} else {
println!("Bad RoadSpec: {}", spec);
}
@ -391,15 +391,15 @@ impl Model {
let mut lanes = r.get_spec();
mem::swap(&mut lanes.fwd, &mut lanes.back);
r.osm_tags
.insert("abst:synthetic_lanes".to_string(), lanes.to_string());
.insert(osm::SYNTHETIC_LANES.to_string(), lanes.to_string());
let fwd_label = r.osm_tags.remove("abst:fwd_label");
let back_label = r.osm_tags.remove("abst:back_label");
let fwd_label = r.osm_tags.remove(osm::FWD_LABEL);
let back_label = r.osm_tags.remove(osm::BACK_LABEL);
if let Some(l) = fwd_label {
r.osm_tags.insert("abst:back_label".to_string(), l);
r.osm_tags.insert(osm::BACK_LABEL.to_string(), l);
}
if let Some(l) = back_label {
r.osm_tags.insert("abst:fwd_label".to_string(), l);
r.osm_tags.insert(osm::FWD_LABEL.to_string(), l);
}
self.road_added(id, prerender);
@ -416,10 +416,10 @@ impl Model {
let r = self.map.roads.get_mut(&pair.0).unwrap();
if pair.1 {
r.osm_tags
.insert("abst:fwd_label".to_string(), label.to_string());
.insert(osm::FWD_LABEL.to_string(), label.to_string());
} else {
r.osm_tags
.insert("abst:back_label".to_string(), label.to_string());
.insert(osm::BACK_LABEL.to_string(), label.to_string());
}
self.road_added(pair.0, prerender);
@ -428,9 +428,9 @@ impl Model {
pub fn get_r_label(&self, pair: (StableRoadID, Direction)) -> Option<String> {
let r = &self.map.roads[&pair.0];
if pair.1 {
r.osm_tags.get("abst:fwd_label").cloned()
r.osm_tags.get(osm::FWD_LABEL).cloned()
} else {
r.osm_tags.get("abst:back_label").cloned()
r.osm_tags.get(osm::BACK_LABEL).cloned()
}
}
@ -456,7 +456,7 @@ impl Model {
let r = &self.map.roads[&id];
let mut tooltip = Text::new();
if let Some(name) = r.osm_tags.get("name") {
if let Some(name) = r.osm_tags.get(osm::NAME) {
tooltip.add(Line(name));
} else if let Some(name) = r.osm_tags.get("ref") {
tooltip.add(Line(name));
@ -465,7 +465,7 @@ impl Model {
}
let mut result = Vec::new();
let synthetic = r.osm_tags.get("abst:synthetic") == Some(&"true".to_string());
let synthetic = r.osm_tags.get(osm::SYNTHETIC) == Some(&"true".to_string());
let spec = r.get_spec();
let center_pts = PolyLine::new(r.center_points.clone());
for (idx, lt) in spec.fwd.iter().enumerate() {
@ -484,7 +484,7 @@ impl Model {
);
}
if idx == spec.fwd.len() / 2 {
obj = obj.maybe_label(r.osm_tags.get("abst:fwd_label").cloned());
obj = obj.maybe_label(r.osm_tags.get(osm::FWD_LABEL).cloned());
}
result.push(obj.tooltip(tooltip.clone()));
}
@ -499,7 +499,7 @@ impl Model {
.make_polygons(LANE_THICKNESS),
);
if idx == spec.back.len() / 2 {
obj = obj.maybe_label(r.osm_tags.get("abst:back_label").cloned());
obj = obj.maybe_label(r.osm_tags.get(osm::BACK_LABEL).cloned());
}
result.push(obj.tooltip(tooltip.clone()));
}
@ -530,7 +530,7 @@ impl Model {
self.world.add(
prerender,
Object::new(ID::Building(id), Color::BLUE, b.polygon.clone())
.maybe_label(b.osm_tags.get("abst:label").cloned()),
.maybe_label(b.osm_tags.get(osm::LABEL).cloned()),
);
}
@ -571,13 +571,13 @@ impl Model {
.get_mut(&id)
.unwrap()
.osm_tags
.insert("abst:label".to_string(), label);
.insert(osm::LABEL.to_string(), label);
self.bldg_added(id, prerender);
}
pub fn get_b_label(&self, id: StableBuildingID) -> Option<String> {
self.map.buildings[&id].osm_tags.get("abst:label").cloned()
self.map.buildings[&id].osm_tags.get(osm::LABEL).cloned()
}
pub fn delete_b(&mut self, id: StableBuildingID) {