mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
refactor for #231: use typed OSM IDs everywhere, dedupe URL code
have to regen, the binary format has changed
This commit is contained in:
parent
84e913a642
commit
d1e9e38e82
@ -1,4 +1,4 @@
|
|||||||
use crate::reader::{Document, Member, NodeID, Relation, RelationID, WayID};
|
use crate::reader::{Document, Relation};
|
||||||
use crate::Options;
|
use crate::Options;
|
||||||
use abstutil::{retain_btreemap, Tags, Timer};
|
use abstutil::{retain_btreemap, Tags, Timer};
|
||||||
use geom::{HashablePt2D, PolyLine, Polygon, Pt2D, Ring};
|
use geom::{HashablePt2D, PolyLine, Polygon, Pt2D, Ring};
|
||||||
@ -8,6 +8,7 @@ use map_model::raw::{
|
|||||||
RawParkingLot, RawRoad, RestrictionType,
|
RawParkingLot, RawRoad, RestrictionType,
|
||||||
};
|
};
|
||||||
use map_model::{osm, AreaType};
|
use map_model::{osm, AreaType};
|
||||||
|
use osm::{NodeID, OsmID, RelationID, WayID};
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
@ -137,7 +138,9 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
|
|
||||||
if is_bldg(&way.tags) {
|
if is_bldg(&way.tags) {
|
||||||
map.buildings.insert(
|
map.buildings.insert(
|
||||||
OriginalBuilding { osm_way_id: id.0 },
|
OriginalBuilding {
|
||||||
|
osm_id: OsmID::Way(id),
|
||||||
|
},
|
||||||
RawBuilding {
|
RawBuilding {
|
||||||
polygon,
|
polygon,
|
||||||
public_garage_name: None,
|
public_garage_name: None,
|
||||||
@ -149,7 +152,7 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
} else if let Some(at) = get_area_type(&way.tags) {
|
} else if let Some(at) = get_area_type(&way.tags) {
|
||||||
map.areas.push(RawArea {
|
map.areas.push(RawArea {
|
||||||
area_type: at,
|
area_type: at,
|
||||||
osm_id: id.0,
|
osm_id: OsmID::Way(id),
|
||||||
polygon,
|
polygon,
|
||||||
osm_tags: way.tags.clone(),
|
osm_tags: way.tags.clone(),
|
||||||
});
|
});
|
||||||
@ -157,7 +160,7 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
// TODO Verify parking = surface or handle other cases?
|
// TODO Verify parking = surface or handle other cases?
|
||||||
map.parking_lots.push(RawParkingLot {
|
map.parking_lots.push(RawParkingLot {
|
||||||
polygon,
|
polygon,
|
||||||
osm_id: id.0,
|
osm_id: OsmID::Way(id),
|
||||||
});
|
});
|
||||||
} else if way.tags.is("historic", "memorial") {
|
} else if way.tags.is("historic", "memorial") {
|
||||||
memorial_areas.push(polygon);
|
memorial_areas.push(polygon);
|
||||||
@ -202,7 +205,7 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
{
|
{
|
||||||
map.areas.push(RawArea {
|
map.areas.push(RawArea {
|
||||||
area_type,
|
area_type,
|
||||||
osm_id: id.0,
|
osm_id: OsmID::Relation(id),
|
||||||
polygon,
|
polygon,
|
||||||
osm_tags: rel.tags.clone(),
|
osm_tags: rel.tags.clone(),
|
||||||
});
|
});
|
||||||
@ -215,7 +218,7 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
let mut to_way_id: Option<WayID> = None;
|
let mut to_way_id: Option<WayID> = None;
|
||||||
for (role, member) in &rel.members {
|
for (role, member) in &rel.members {
|
||||||
match member {
|
match member {
|
||||||
Member::Way(w) => {
|
OsmID::Way(w) => {
|
||||||
if role == "from" {
|
if role == "from" {
|
||||||
from_way_id = Some(*w);
|
from_way_id = Some(*w);
|
||||||
} else if role == "to" {
|
} else if role == "to" {
|
||||||
@ -224,7 +227,7 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
via_way_id = Some(*w);
|
via_way_id = Some(*w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Member::Node(n) => {
|
OsmID::Node(n) => {
|
||||||
if role == "via" {
|
if role == "via" {
|
||||||
via_node_id = Some(*n);
|
via_node_id = Some(*n);
|
||||||
}
|
}
|
||||||
@ -256,7 +259,9 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
match multipoly_geometry(id, rel, &doc) {
|
match multipoly_geometry(id, rel, &doc) {
|
||||||
Ok(polygon) => {
|
Ok(polygon) => {
|
||||||
map.buildings.insert(
|
map.buildings.insert(
|
||||||
OriginalBuilding { osm_way_id: id.0 },
|
OriginalBuilding {
|
||||||
|
osm_id: OsmID::Relation(id),
|
||||||
|
},
|
||||||
RawBuilding {
|
RawBuilding {
|
||||||
polygon,
|
polygon,
|
||||||
public_garage_name: None,
|
public_garage_name: None,
|
||||||
@ -282,7 +287,7 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
if role != "outer" {
|
if role != "outer" {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Member::Way(w) = member {
|
if let OsmID::Way(w) = member {
|
||||||
if let Ok(ring) = Ring::new(doc.ways[w].pts.clone()) {
|
if let Ok(ring) = Ring::new(doc.ways[w].pts.clone()) {
|
||||||
amenity_areas.push((name.clone(), amenity.clone(), ring.to_polygon()));
|
amenity_areas.push((name.clone(), amenity.clone(), ring.to_polygon()));
|
||||||
}
|
}
|
||||||
@ -292,14 +297,14 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
let mut stops = Vec::new();
|
let mut stops = Vec::new();
|
||||||
let mut platform: Option<Pt2D> = None;
|
let mut platform: Option<Pt2D> = None;
|
||||||
for (role, member) in &rel.members {
|
for (role, member) in &rel.members {
|
||||||
if let Member::Node(n) = member {
|
if let OsmID::Node(n) = member {
|
||||||
let pt = doc.nodes[n].pt;
|
let pt = doc.nodes[n].pt;
|
||||||
if role == "stop" {
|
if role == "stop" {
|
||||||
stops.push(pt);
|
stops.push(pt);
|
||||||
} else if role == "platform" {
|
} else if role == "platform" {
|
||||||
platform = Some(pt);
|
platform = Some(pt);
|
||||||
}
|
}
|
||||||
} else if let Member::Way(w) = member {
|
} else if let OsmID::Way(w) = member {
|
||||||
if role == "platform" {
|
if role == "platform" {
|
||||||
platform = Some(Pt2D::center(&doc.ways[w].pts));
|
platform = Some(Pt2D::center(&doc.ways[w].pts));
|
||||||
}
|
}
|
||||||
@ -323,7 +328,7 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
|
|||||||
0,
|
0,
|
||||||
RawArea {
|
RawArea {
|
||||||
area_type: AreaType::Water,
|
area_type: AreaType::Water,
|
||||||
osm_id: -1,
|
osm_id: OsmID::Relation(RelationID(-1)),
|
||||||
polygon,
|
polygon,
|
||||||
osm_tags,
|
osm_tags,
|
||||||
},
|
},
|
||||||
@ -537,7 +542,7 @@ fn get_multipolygon_members(
|
|||||||
) -> Vec<(WayID, Vec<Pt2D>)> {
|
) -> Vec<(WayID, Vec<Pt2D>)> {
|
||||||
let mut pts_per_way = Vec::new();
|
let mut pts_per_way = Vec::new();
|
||||||
for (role, member) in &rel.members {
|
for (role, member) in &rel.members {
|
||||||
if let Member::Way(w) = member {
|
if let OsmID::Way(w) = member {
|
||||||
if role == "outer" {
|
if role == "outer" {
|
||||||
pts_per_way.push((*w, doc.ways[w].pts.clone()));
|
pts_per_way.push((*w, doc.ways[w].pts.clone()));
|
||||||
} else {
|
} else {
|
||||||
@ -676,7 +681,7 @@ fn extract_route(
|
|||||||
let mut all_pts = Vec::new();
|
let mut all_pts = Vec::new();
|
||||||
for (role, member) in &rel.members {
|
for (role, member) in &rel.members {
|
||||||
if role == "stop" {
|
if role == "stop" {
|
||||||
if let Member::Node(n) = member {
|
if let OsmID::Node(n) = member {
|
||||||
let node = &doc.nodes[n];
|
let node = &doc.nodes[n];
|
||||||
stops.push(RawBusStop {
|
stops.push(RawBusStop {
|
||||||
name: node
|
name: node
|
||||||
@ -690,7 +695,7 @@ fn extract_route(
|
|||||||
}
|
}
|
||||||
} else if role == "platform" {
|
} else if role == "platform" {
|
||||||
let (platform_name, pt) = match member {
|
let (platform_name, pt) = match member {
|
||||||
Member::Node(n) => {
|
OsmID::Node(n) => {
|
||||||
let node = &doc.nodes[n];
|
let node = &doc.nodes[n];
|
||||||
(
|
(
|
||||||
node.tags
|
node.tags
|
||||||
@ -700,7 +705,7 @@ fn extract_route(
|
|||||||
node.pt,
|
node.pt,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Member::Way(w) => {
|
OsmID::Way(w) => {
|
||||||
let way = &doc.ways[w];
|
let way = &doc.ways[w];
|
||||||
(
|
(
|
||||||
way.tags
|
way.tags
|
||||||
@ -713,10 +718,10 @@ fn extract_route(
|
|||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
platforms.insert(platform_name, pt);
|
platforms.insert(platform_name, pt);
|
||||||
} else if let Member::Way(w) = member {
|
} else if let OsmID::Way(w) = member {
|
||||||
// The order of nodes might be wrong, doesn't matter
|
// The order of nodes might be wrong, doesn't matter
|
||||||
for n in &doc.ways[w].nodes {
|
for n in &doc.ways[w].nodes {
|
||||||
all_pts.push(OriginalIntersection { osm_node_id: n.0 });
|
all_pts.push(OriginalIntersection { osm_node_id: *n });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -758,7 +763,7 @@ fn extract_route(
|
|||||||
full_name,
|
full_name,
|
||||||
short_name,
|
short_name,
|
||||||
is_bus,
|
is_bus,
|
||||||
osm_rel_id: rel_id.0,
|
osm_rel_id: rel_id,
|
||||||
gtfs_trip_marker: rel.tags.get("gtfs:trip_marker").cloned(),
|
gtfs_trip_marker: rel.tags.get("gtfs:trip_marker").cloned(),
|
||||||
stops: keep_stops,
|
stops: keep_stops,
|
||||||
border_start: None,
|
border_start: None,
|
||||||
@ -775,7 +780,7 @@ fn multipoly_geometry(
|
|||||||
let mut outer: Vec<Vec<Pt2D>> = Vec::new();
|
let mut outer: Vec<Vec<Pt2D>> = Vec::new();
|
||||||
let mut inner: Vec<Vec<Pt2D>> = Vec::new();
|
let mut inner: Vec<Vec<Pt2D>> = Vec::new();
|
||||||
for (role, member) in &rel.members {
|
for (role, member) in &rel.members {
|
||||||
if let Member::Way(w) = member {
|
if let OsmID::Way(w) = member {
|
||||||
let mut deduped = doc.ways[w].pts.clone();
|
let mut deduped = doc.ways[w].pts.clone();
|
||||||
deduped.dedup();
|
deduped.dedup();
|
||||||
if deduped.len() < 3 {
|
if deduped.len() < 3 {
|
||||||
|
@ -23,7 +23,7 @@ pub fn apply_parking(map: &mut RawMap, opts: &Options, timer: &mut Timer) {
|
|||||||
&& r.osm_tags
|
&& r.osm_tags
|
||||||
.is_any(osm::HIGHWAY, vec!["residential", "tertiary"])
|
.is_any(osm::HIGHWAY, vec!["residential", "tertiary"])
|
||||||
&& !r.osm_tags.is("foot", "no")
|
&& !r.osm_tags.is("foot", "no")
|
||||||
&& id.osm_way_id % 100 <= pct
|
&& id.osm_way_id.0 % 100 <= pct
|
||||||
&& PolyLine::unchecked_new(r.center_points.clone()).length()
|
&& PolyLine::unchecked_new(r.center_points.clone()).length()
|
||||||
>= Distance::meters(20.0)
|
>= Distance::meters(20.0)
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use abstutil::{prettyprint_usize, slurp_file, Tags, Timer};
|
use abstutil::{prettyprint_usize, slurp_file, Tags, Timer};
|
||||||
use geom::{GPSBounds, LonLat, Pt2D};
|
use geom::{GPSBounds, LonLat, Pt2D};
|
||||||
|
use map_model::osm::{NodeID, OsmID, RelationID, WayID};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
// References to missing objects are just filtered out.
|
// References to missing objects are just filtered out.
|
||||||
// Per https://wiki.openstreetmap.org/wiki/OSM_XML#Certainties_and_Uncertainties, we assume
|
// Per https://wiki.openstreetmap.org/wiki/OSM_XML#Certainties_and_Uncertainties, we assume
|
||||||
@ -10,7 +10,7 @@ use std::fmt;
|
|||||||
//
|
//
|
||||||
// TODO Filter out visible=false
|
// TODO Filter out visible=false
|
||||||
// TODO NodeID, WayID, RelationID are nice. Plumb forward through map_model.
|
// TODO NodeID, WayID, RelationID are nice. Plumb forward through map_model.
|
||||||
// TODO Replicate IDs in each object, and change Member to just hold a reference to the object
|
// TODO Replicate IDs in each object, and change members to just hold a reference to the object
|
||||||
// (which is guaranteed to exist).
|
// (which is guaranteed to exist).
|
||||||
|
|
||||||
pub struct Document {
|
pub struct Document {
|
||||||
@ -35,13 +35,7 @@ pub struct Way {
|
|||||||
pub struct Relation {
|
pub struct Relation {
|
||||||
pub tags: Tags,
|
pub tags: Tags,
|
||||||
// Role, member
|
// Role, member
|
||||||
pub members: Vec<(String, Member)>,
|
pub members: Vec<(String, OsmID)>,
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Member {
|
|
||||||
Node(NodeID),
|
|
||||||
Way(WayID),
|
|
||||||
Relation(RelationID),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(
|
pub fn read(
|
||||||
@ -145,7 +139,7 @@ pub fn read(
|
|||||||
if !doc.nodes.contains_key(&n) {
|
if !doc.nodes.contains_key(&n) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Member::Node(n)
|
OsmID::Node(n)
|
||||||
}
|
}
|
||||||
"way" => {
|
"way" => {
|
||||||
let w =
|
let w =
|
||||||
@ -153,7 +147,7 @@ pub fn read(
|
|||||||
if !doc.ways.contains_key(&w) {
|
if !doc.ways.contains_key(&w) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Member::Way(w)
|
OsmID::Way(w)
|
||||||
}
|
}
|
||||||
"relation" => {
|
"relation" => {
|
||||||
let r = RelationID(
|
let r = RelationID(
|
||||||
@ -162,7 +156,7 @@ pub fn read(
|
|||||||
if !doc.relations.contains_key(&r) {
|
if !doc.relations.contains_key(&r) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Member::Relation(r)
|
OsmID::Relation(r)
|
||||||
}
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
@ -212,26 +206,3 @@ fn scrape_bounds(doc: &roxmltree::Document) -> GPSBounds {
|
|||||||
}
|
}
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
|
||||||
pub struct NodeID(pub i64);
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
|
||||||
pub struct WayID(pub i64);
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
|
||||||
pub struct RelationID(pub i64);
|
|
||||||
|
|
||||||
impl fmt::Display for NodeID {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "https://www.openstreetmap.org/node/{}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl fmt::Display for WayID {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "https://www.openstreetmap.org/way/{}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl fmt::Display for RelationID {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "https://www.openstreetmap.org/relation/{}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -24,7 +24,7 @@ pub fn split_up_roads(
|
|||||||
if count == 2 || idx == 0 || idx == r.center_points.len() - 1 {
|
if count == 2 || idx == 0 || idx == r.center_points.len() - 1 {
|
||||||
if !pt_to_intersection.contains_key(&pt) {
|
if !pt_to_intersection.contains_key(&pt) {
|
||||||
let id = OriginalIntersection {
|
let id = OriginalIntersection {
|
||||||
osm_node_id: input.osm_node_ids[&pt].0,
|
osm_node_id: input.osm_node_ids[&pt],
|
||||||
};
|
};
|
||||||
pt_to_intersection.insert(pt, id);
|
pt_to_intersection.insert(pt, id);
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ pub fn split_up_roads(
|
|||||||
// Start a new road
|
// Start a new road
|
||||||
map.roads.insert(
|
map.roads.insert(
|
||||||
OriginalRoad {
|
OriginalRoad {
|
||||||
osm_way_id: osm_way_id.0,
|
osm_way_id: *osm_way_id,
|
||||||
i1,
|
i1,
|
||||||
i2: *i2,
|
i2: *i2,
|
||||||
},
|
},
|
||||||
@ -95,13 +95,13 @@ pub fn split_up_roads(
|
|||||||
let mut restrictions = Vec::new();
|
let mut restrictions = Vec::new();
|
||||||
for (restriction, from_osm, via_osm, to_osm) in input.simple_turn_restrictions {
|
for (restriction, from_osm, via_osm, to_osm) in input.simple_turn_restrictions {
|
||||||
let roads = map.roads_per_intersection(OriginalIntersection {
|
let roads = map.roads_per_intersection(OriginalIntersection {
|
||||||
osm_node_id: via_osm.0,
|
osm_node_id: via_osm,
|
||||||
});
|
});
|
||||||
// If some of the roads are missing, they were likely filtered out -- usually service
|
// If some of the roads are missing, they were likely filtered out -- usually service
|
||||||
// roads.
|
// roads.
|
||||||
if let (Some(from), Some(to)) = (
|
if let (Some(from), Some(to)) = (
|
||||||
roads.iter().find(|r| r.osm_way_id == from_osm.0),
|
roads.iter().find(|r| r.osm_way_id == from_osm),
|
||||||
roads.iter().find(|r| r.osm_way_id == to_osm.0),
|
roads.iter().find(|r| r.osm_way_id == to_osm),
|
||||||
) {
|
) {
|
||||||
restrictions.push((*from, restriction, *to));
|
restrictions.push((*from, restriction, *to));
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ pub fn split_up_roads(
|
|||||||
let via_candidates: Vec<OriginalRoad> = map
|
let via_candidates: Vec<OriginalRoad> = map
|
||||||
.roads
|
.roads
|
||||||
.keys()
|
.keys()
|
||||||
.filter(|r| r.osm_way_id == via_osm.0)
|
.filter(|r| r.osm_way_id == via_osm)
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
if via_candidates.len() != 1 {
|
if via_candidates.len() != 1 {
|
||||||
@ -138,12 +138,12 @@ pub fn split_up_roads(
|
|||||||
.roads_per_intersection(via.i1)
|
.roads_per_intersection(via.i1)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(map.roads_per_intersection(via.i2).into_iter())
|
.chain(map.roads_per_intersection(via.i2).into_iter())
|
||||||
.find(|r| r.osm_way_id == from_osm.0);
|
.find(|r| r.osm_way_id == from_osm);
|
||||||
let maybe_to = map
|
let maybe_to = map
|
||||||
.roads_per_intersection(via.i1)
|
.roads_per_intersection(via.i1)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(map.roads_per_intersection(via.i2).into_iter())
|
.chain(map.roads_per_intersection(via.i2).into_iter())
|
||||||
.find(|r| r.osm_way_id == to_osm.0);
|
.find(|r| r.osm_way_id == to_osm);
|
||||||
match (maybe_from, maybe_to) {
|
match (maybe_from, maybe_to) {
|
||||||
(Some(from), Some(to)) => {
|
(Some(from), Some(to)) => {
|
||||||
complicated_restrictions.push((from, via, to));
|
complicated_restrictions.push((from, via, to));
|
||||||
|
@ -9,16 +9,16 @@ data/input/krakow/footways.bin,017e85fd6da69b67a1a7a790506f52ff,https://www.drop
|
|||||||
data/input/krakow/osm/krakow_center.osm,b914bbcd42a7f769a40a90970cea35f2,https://www.dropbox.com/s/pf3avtszpw732jd/krakow_center.osm.zip?dl=0
|
data/input/krakow/osm/krakow_center.osm,b914bbcd42a7f769a40a90970cea35f2,https://www.dropbox.com/s/pf3avtszpw732jd/krakow_center.osm.zip?dl=0
|
||||||
data/input/krakow/osm/malopolskie-latest.osm.pbf,9505917bbacc478177e36605e89b6d77,https://www.dropbox.com/s/vehjfvwx25v1qnd/malopolskie-latest.osm.pbf.zip?dl=0
|
data/input/krakow/osm/malopolskie-latest.osm.pbf,9505917bbacc478177e36605e89b6d77,https://www.dropbox.com/s/vehjfvwx25v1qnd/malopolskie-latest.osm.pbf.zip?dl=0
|
||||||
data/input/krakow/service_roads.bin,a6a5d22bb3dba66b5a4cad72f6842eb9,https://www.dropbox.com/s/is31c2ejl8nun28/service_roads.bin.zip?dl=0
|
data/input/krakow/service_roads.bin,a6a5d22bb3dba66b5a4cad72f6842eb9,https://www.dropbox.com/s/is31c2ejl8nun28/service_roads.bin.zip?dl=0
|
||||||
data/input/raw_maps/ballard.bin,422675e5ae0054651a3dc1f307c8bfbb,https://www.dropbox.com/s/bhekalw3smrs88p/ballard.bin.zip?dl=0
|
data/input/raw_maps/ballard.bin,6fdacf6a9503a4bdbe71140688486e53,https://www.dropbox.com/s/2eouht2x3z6scl9/ballard.bin.zip?dl=0
|
||||||
data/input/raw_maps/berlin_center.bin,55f7855f1be26430a46c8bbed74a6789,https://www.dropbox.com/s/g09clxwc5o8bqfk/berlin_center.bin.zip?dl=0
|
data/input/raw_maps/berlin_center.bin,9ccc8a91ebe62b0645c93cc681cffb79,https://www.dropbox.com/s/r9hc4uf3aerfnyb/berlin_center.bin.zip?dl=0
|
||||||
data/input/raw_maps/downtown.bin,2c84ccaa228df16ddef50e5c67d22c82,https://www.dropbox.com/s/jya9xkj38cshwj9/downtown.bin.zip?dl=0
|
data/input/raw_maps/downtown.bin,65d8baaaafb6ab00fb8ca034ff1d8402,https://www.dropbox.com/s/vlg509s9y3d321x/downtown.bin.zip?dl=0
|
||||||
data/input/raw_maps/huge_seattle.bin,e0b63d95fae06b9c6c9a9afc587270a6,https://www.dropbox.com/s/r7l2y22iyvla5b8/huge_seattle.bin.zip?dl=0
|
data/input/raw_maps/huge_seattle.bin,e73b9293a95f359173e3e81cd232e8e1,https://www.dropbox.com/s/6vhu9jziquel7ha/huge_seattle.bin.zip?dl=0
|
||||||
data/input/raw_maps/krakow_center.bin,a6c557888cf3211fce8f025150c49734,https://www.dropbox.com/s/y7hwvd547soiwan/krakow_center.bin.zip?dl=0
|
data/input/raw_maps/krakow_center.bin,4cd3c941b7d8704edb116ae2f8d1ed92,https://www.dropbox.com/s/qd5tm0xm9nqr0hs/krakow_center.bin.zip?dl=0
|
||||||
data/input/raw_maps/lakeslice.bin,b71cf35251603a6a787a065b8a37f6f3,https://www.dropbox.com/s/3ko1beo4uv2j49p/lakeslice.bin.zip?dl=0
|
data/input/raw_maps/lakeslice.bin,d221270f016a4324b871c38d1e395519,https://www.dropbox.com/s/xvp1a1nn6ck6vxz/lakeslice.bin.zip?dl=0
|
||||||
data/input/raw_maps/montlake.bin,11e3f20b67fb76359dc69737a039e8d1,https://www.dropbox.com/s/h9mymsai9ia9yde/montlake.bin.zip?dl=0
|
data/input/raw_maps/montlake.bin,4af4c6b0e4babb872670017be935ba56,https://www.dropbox.com/s/r9887v30x9k0su9/montlake.bin.zip?dl=0
|
||||||
data/input/raw_maps/south_seattle.bin,c1a531ccb0874a3fafaa48952ec58d29,https://www.dropbox.com/s/y7d3mcnqp4u50b6/south_seattle.bin.zip?dl=0
|
data/input/raw_maps/south_seattle.bin,8d5cedc6103459e4f84363904af239cc,https://www.dropbox.com/s/r39yyvy2u3e39fs/south_seattle.bin.zip?dl=0
|
||||||
data/input/raw_maps/udistrict.bin,5f1c93a1d7939af3995359c074b11bbc,https://www.dropbox.com/s/7doajjusb5if43q/udistrict.bin.zip?dl=0
|
data/input/raw_maps/udistrict.bin,7d16bcb9e17de9d3ad5ae694fd3cc5d8,https://www.dropbox.com/s/7zbpiyu0x1rfgag/udistrict.bin.zip?dl=0
|
||||||
data/input/raw_maps/west_seattle.bin,b6c92b97d266d644368c9f6e5f9ce812,https://www.dropbox.com/s/oa5gpkut51mc6vj/west_seattle.bin.zip?dl=0
|
data/input/raw_maps/west_seattle.bin,a20d2aaedf550cc0e6e1d58cf5b8f5da,https://www.dropbox.com/s/0mktaqiu8hq4rlu/west_seattle.bin.zip?dl=0
|
||||||
data/input/screenshots/downtown.zip,8759a23f7729e51f0a27ca781a1b5cbb,https://www.dropbox.com/s/qawd35wz62m2acl/downtown.zip.zip?dl=0
|
data/input/screenshots/downtown.zip,8759a23f7729e51f0a27ca781a1b5cbb,https://www.dropbox.com/s/qawd35wz62m2acl/downtown.zip.zip?dl=0
|
||||||
data/input/screenshots/krakow_center.zip,44b8e8301931e97fb87f928676723a6d,https://www.dropbox.com/s/azea6v6mnxbe0vc/krakow_center.zip.zip?dl=0
|
data/input/screenshots/krakow_center.zip,44b8e8301931e97fb87f928676723a6d,https://www.dropbox.com/s/azea6v6mnxbe0vc/krakow_center.zip.zip?dl=0
|
||||||
data/input/screenshots/lakeslice.zip,b36f19b5c44b51def26c2056f03bc5a1,https://www.dropbox.com/s/z0z96lsn7bunqfy/lakeslice.zip.zip?dl=0
|
data/input/screenshots/lakeslice.zip,b36f19b5c44b51def26c2056f03bc5a1,https://www.dropbox.com/s/z0z96lsn7bunqfy/lakeslice.zip.zip?dl=0
|
||||||
@ -51,30 +51,30 @@ data/input/seattle/osm/south_seattle.osm,f1243c78fe237bb55cc7b8c38904df0e,https:
|
|||||||
data/input/seattle/osm/udistrict.osm,05d718bca1305fbcedffb0c9d3c808d8,https://www.dropbox.com/s/yy1j6b6b8bj7wn1/udistrict.osm.zip?dl=0
|
data/input/seattle/osm/udistrict.osm,05d718bca1305fbcedffb0c9d3c808d8,https://www.dropbox.com/s/yy1j6b6b8bj7wn1/udistrict.osm.zip?dl=0
|
||||||
data/input/seattle/osm/washington-latest.osm.pbf,676dbdf08ebd8303f85eda7cb7de5833,https://www.dropbox.com/s/2ogkqpqnq8zjr1t/washington-latest.osm.pbf.zip?dl=0
|
data/input/seattle/osm/washington-latest.osm.pbf,676dbdf08ebd8303f85eda7cb7de5833,https://www.dropbox.com/s/2ogkqpqnq8zjr1t/washington-latest.osm.pbf.zip?dl=0
|
||||||
data/input/seattle/osm/west_seattle.osm,abee01cc1d034a9b12a984d219393dcc,https://www.dropbox.com/s/wwt9h4kqvx4vg4y/west_seattle.osm.zip?dl=0
|
data/input/seattle/osm/west_seattle.osm,abee01cc1d034a9b12a984d219393dcc,https://www.dropbox.com/s/wwt9h4kqvx4vg4y/west_seattle.osm.zip?dl=0
|
||||||
data/input/seattle/parcels.bin,32d515292c9298358eda739e715f609f,https://www.dropbox.com/s/3fz3eb9xlxu3xbm/parcels.bin.zip?dl=0
|
data/input/seattle/parcels.bin,4f21c1af49fbbcb35c2750c7dbb1ba55,https://www.dropbox.com/s/ef5yi74n0350i3l/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,ba74425bdd7e0435d16714342ddc1f7f,https://www.dropbox.com/s/o731ipwxu91ef0b/popdat.bin.zip?dl=0
|
data/input/seattle/popdat.bin,113028930e3dada483651a8d3fe169ec,https://www.dropbox.com/s/eddccrdrhz10qo3/popdat.bin.zip?dl=0
|
||||||
data/input/seattle/service_roads.bin,771cffc34dfbca9f941a90adf553be5d,https://www.dropbox.com/s/61o9prqoa7f52q7/service_roads.bin.zip?dl=0
|
data/input/seattle/service_roads.bin,771cffc34dfbca9f941a90adf553be5d,https://www.dropbox.com/s/61o9prqoa7f52q7/service_roads.bin.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,4c23d8a7fbf0981a65c7e9499a1c7185,https://www.dropbox.com/s/1vg3138khp81kyi/seattle.bin.zip?dl=0
|
data/system/cities/seattle.bin,4c23d8a7fbf0981a65c7e9499a1c7185,https://www.dropbox.com/s/1vg3138khp81kyi/seattle.bin.zip?dl=0
|
||||||
data/system/maps/ballard.bin,79ee86eee63666b74c1a616e7f58db45,https://www.dropbox.com/s/98wdkhwohiv982c/ballard.bin.zip?dl=0
|
data/system/maps/ballard.bin,e9d27fd4414a89528fbbd716b3b4f70a,https://www.dropbox.com/s/v7a85gyyx6cfmay/ballard.bin.zip?dl=0
|
||||||
data/system/maps/berlin_center.bin,065b4979987b228e19fe63adb5ee3856,https://www.dropbox.com/s/kivu0qhpdl2dfo6/berlin_center.bin.zip?dl=0
|
data/system/maps/berlin_center.bin,b06939686bc5150b5782aad19cc77462,https://www.dropbox.com/s/25eqv5i9vbd0f4u/berlin_center.bin.zip?dl=0
|
||||||
data/system/maps/downtown.bin,b502ad91c4aa90368ed6b40545aa0118,https://www.dropbox.com/s/okqy9d2lvpclbzt/downtown.bin.zip?dl=0
|
data/system/maps/downtown.bin,7507f28a8007734815230cd6af6cf683,https://www.dropbox.com/s/u5l2ij8c16ngyml/downtown.bin.zip?dl=0
|
||||||
data/system/maps/huge_seattle.bin,37a3d1587ab66bececb95ad1002e28cf,https://www.dropbox.com/s/8u0mw81isncs2t8/huge_seattle.bin.zip?dl=0
|
data/system/maps/huge_seattle.bin,172b664b7a2dae82170223646f10faa8,https://www.dropbox.com/s/7o0ljq7fd1yb8ao/huge_seattle.bin.zip?dl=0
|
||||||
data/system/maps/krakow_center.bin,ae135fdfc30743833c71d9c2b6ecf3e3,https://www.dropbox.com/s/5o2u3bt4d58qdi7/krakow_center.bin.zip?dl=0
|
data/system/maps/krakow_center.bin,43101257967295302234a3b0f52f0bc6,https://www.dropbox.com/s/sg4ibnev7pejfch/krakow_center.bin.zip?dl=0
|
||||||
data/system/maps/lakeslice.bin,6476b23467e7433ffb46e93ba61331a9,https://www.dropbox.com/s/f3nlxvinuo03gzt/lakeslice.bin.zip?dl=0
|
data/system/maps/lakeslice.bin,49d875187fc14ef2fc23576efdb66aca,https://www.dropbox.com/s/liwg9nsdxpnrsl8/lakeslice.bin.zip?dl=0
|
||||||
data/system/maps/montlake.bin,75d2fa79912db2d287b7bb3e68904f1e,https://www.dropbox.com/s/sfrnr6gajffvaxa/montlake.bin.zip?dl=0
|
data/system/maps/montlake.bin,fd25c4be0064852b1592057f707ce6c5,https://www.dropbox.com/s/z8e9906huko9ly7/montlake.bin.zip?dl=0
|
||||||
data/system/maps/south_seattle.bin,da9e3dc5019108e21f77eb40509ec155,https://www.dropbox.com/s/srlxi4hme132aec/south_seattle.bin.zip?dl=0
|
data/system/maps/south_seattle.bin,6166c1aa5878f3b40de329bb3807390d,https://www.dropbox.com/s/tz24rci6jwz14lz/south_seattle.bin.zip?dl=0
|
||||||
data/system/maps/udistrict.bin,10e8534ddca4a422d929a0cbb0b97368,https://www.dropbox.com/s/tefrx95x051eoir/udistrict.bin.zip?dl=0
|
data/system/maps/udistrict.bin,4bb601a033e307b65f205aea53af7aaf,https://www.dropbox.com/s/46siyvcd91lssnp/udistrict.bin.zip?dl=0
|
||||||
data/system/maps/west_seattle.bin,8413879e624c19d52a8437439f4aa444,https://www.dropbox.com/s/aqul2662x8xzdnm/west_seattle.bin.zip?dl=0
|
data/system/maps/west_seattle.bin,071fdeb39c1be10ebb676b6bdaba7fd8,https://www.dropbox.com/s/mz5jkqsaztl2ik6/west_seattle.bin.zip?dl=0
|
||||||
data/system/prebaked_results/lakeslice/weekday.bin,0e60d59420a34f648f17799895c4aa78,https://www.dropbox.com/s/eeeo9pl8aq38aw5/weekday.bin.zip?dl=0
|
data/system/prebaked_results/lakeslice/weekday.bin,3f4647f2d0f1e76d1b8dbdaaa6d737a6,https://www.dropbox.com/s/oacu1ou8yh0zhe0/weekday.bin.zip?dl=0
|
||||||
data/system/prebaked_results/montlake/car vs bike contention.bin,faa041af70a41bb8fcacd3dfd7a7d467,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.bin.zip?dl=0
|
data/system/prebaked_results/montlake/car vs bike contention.bin,faa041af70a41bb8fcacd3dfd7a7d467,https://www.dropbox.com/s/jefg0ikjy9dsrdd/car%20vs%20bike%20contention.bin.zip?dl=0
|
||||||
data/system/prebaked_results/montlake/weekday.bin,06746b72ec456e69c4500edf0b06d82f,https://www.dropbox.com/s/bcuc4gnmq3sxefo/weekday.bin.zip?dl=0
|
data/system/prebaked_results/montlake/weekday.bin,30c99765b3c9199172dcf9b0a3643c7a,https://www.dropbox.com/s/v8jborb259zj5x6/weekday.bin.zip?dl=0
|
||||||
data/system/scenarios/ballard/weekday.bin,8a2165ab31b5a9c3912362f08e0dc2b9,https://www.dropbox.com/s/w9g4tanopzyaza4/weekday.bin.zip?dl=0
|
data/system/scenarios/ballard/weekday.bin,af52fa3a40c4594b262e5e0e898c6091,https://www.dropbox.com/s/xfs8n9s7wkuzms1/weekday.bin.zip?dl=0
|
||||||
data/system/scenarios/downtown/weekday.bin,b38bb955b90a6356a3033ba1e0cec942,https://www.dropbox.com/s/8cmr13ll9bcekmd/weekday.bin.zip?dl=0
|
data/system/scenarios/downtown/weekday.bin,6ff9f0fdd2a940624b5c3ff43f17cdcd,https://www.dropbox.com/s/1ilmwyojskakdsq/weekday.bin.zip?dl=0
|
||||||
data/system/scenarios/huge_seattle/weekday.bin,64f059dc127da745673a72c6b3b9583a,https://www.dropbox.com/s/3xzp1wxq6shgabg/weekday.bin.zip?dl=0
|
data/system/scenarios/huge_seattle/weekday.bin,7ad74a845affe1f1fcae00364ddeed9c,https://www.dropbox.com/s/m55682sqttuasdz/weekday.bin.zip?dl=0
|
||||||
data/system/scenarios/lakeslice/weekday.bin,d6e6e790b477655b6edd82524d679064,https://www.dropbox.com/s/7653v8k8bzm49bp/weekday.bin.zip?dl=0
|
data/system/scenarios/lakeslice/weekday.bin,57966c48908ef1d482d15ba68a41e0ed,https://www.dropbox.com/s/4gx5sjob61b5lgd/weekday.bin.zip?dl=0
|
||||||
data/system/scenarios/montlake/weekday.bin,888c0f0009cf6867939c410b798563e1,https://www.dropbox.com/s/7qgfn453ad149cz/weekday.bin.zip?dl=0
|
data/system/scenarios/montlake/weekday.bin,db3293db2a7f88c82604a1f8e648077c,https://www.dropbox.com/s/drm388cogdd0348/weekday.bin.zip?dl=0
|
||||||
data/system/scenarios/south_seattle/weekday.bin,de52bd964f6e3f48ff86ebf2a664d195,https://www.dropbox.com/s/covz7zncujqmmzh/weekday.bin.zip?dl=0
|
data/system/scenarios/south_seattle/weekday.bin,9ea93086ada998426c11027cd0ea125b,https://www.dropbox.com/s/z8e3a4qo2fv1itd/weekday.bin.zip?dl=0
|
||||||
data/system/scenarios/udistrict/weekday.bin,1c5c80e1abe4b16db4be497915921820,https://www.dropbox.com/s/4zshiz2lqinw2df/weekday.bin.zip?dl=0
|
data/system/scenarios/udistrict/weekday.bin,001a34c107c980fdba6139d5e2557cc5,https://www.dropbox.com/s/bhjb7r5fs2ll53a/weekday.bin.zip?dl=0
|
||||||
data/system/scenarios/west_seattle/weekday.bin,fad7c87544e370120758a391a55f9ac6,https://www.dropbox.com/s/fpf9kml3uanyejl/weekday.bin.zip?dl=0
|
data/system/scenarios/west_seattle/weekday.bin,e3fda5838068120ebe819b214edd1773,https://www.dropbox.com/s/2ykr20egt4ufqi2/weekday.bin.zip?dl=0
|
||||||
|
@ -56,7 +56,7 @@ impl ViewKML {
|
|||||||
.map
|
.map
|
||||||
.all_buildings()
|
.all_buildings()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|b| (b.osm_way_id.to_string(), b.id))
|
.map(|b| (b.orig_id.osm_id.inner().to_string(), b.id))
|
||||||
.collect();
|
.collect();
|
||||||
let cs = &app.cs;
|
let cs = &app.cs;
|
||||||
let objects: Vec<Object> = timer
|
let objects: Vec<Object> = timer
|
||||||
|
@ -9,6 +9,7 @@ use ezgui::{
|
|||||||
};
|
};
|
||||||
use geom::{Distance, FindClosest, PolyLine, Polygon};
|
use geom::{Distance, FindClosest, PolyLine, Polygon};
|
||||||
use map_model::{osm, RoadID};
|
use map_model::{osm, RoadID};
|
||||||
|
use osm::WayID;
|
||||||
use sim::DontDrawAgents;
|
use sim::DontDrawAgents;
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
@ -21,7 +22,7 @@ pub struct ParkingMapper {
|
|||||||
show: Show,
|
show: Show,
|
||||||
selected: Option<(HashSet<RoadID>, Drawable)>,
|
selected: Option<(HashSet<RoadID>, Drawable)>,
|
||||||
|
|
||||||
data: BTreeMap<i64, Value>,
|
data: BTreeMap<WayID, Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
@ -51,7 +52,7 @@ impl ParkingMapper {
|
|||||||
ctx: &mut EventCtx,
|
ctx: &mut EventCtx,
|
||||||
app: &mut App,
|
app: &mut App,
|
||||||
show: Show,
|
show: Show,
|
||||||
data: BTreeMap<i64, Value>,
|
data: BTreeMap<WayID, Value>,
|
||||||
) -> Box<dyn State> {
|
) -> Box<dyn State> {
|
||||||
app.opts.min_zoom_for_detail = 2.0;
|
app.opts.min_zoom_for_detail = 2.0;
|
||||||
|
|
||||||
@ -304,7 +305,7 @@ impl State for ParkingMapper {
|
|||||||
if let Some((ref roads, _)) = self.selected {
|
if let Some((ref roads, _)) = self.selected {
|
||||||
if ctx.input.key_pressed(Key::O) {
|
if ctx.input.key_pressed(Key::O) {
|
||||||
open_browser(format!(
|
open_browser(format!(
|
||||||
"https://www.openstreetmap.org/way/{}",
|
"{}",
|
||||||
app.primary
|
app.primary
|
||||||
.map
|
.map
|
||||||
.get_r(*roads.iter().next().unwrap())
|
.get_r(*roads.iter().next().unwrap())
|
||||||
@ -389,8 +390,8 @@ impl State for ParkingMapper {
|
|||||||
struct ChangeWay {
|
struct ChangeWay {
|
||||||
composite: Composite,
|
composite: Composite,
|
||||||
draw: Drawable,
|
draw: Drawable,
|
||||||
osm_way_id: i64,
|
osm_way_id: WayID,
|
||||||
data: BTreeMap<i64, Value>,
|
data: BTreeMap<WayID, Value>,
|
||||||
show: Show,
|
show: Show,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,7 +401,7 @@ impl ChangeWay {
|
|||||||
app: &App,
|
app: &App,
|
||||||
selected: &HashSet<RoadID>,
|
selected: &HashSet<RoadID>,
|
||||||
show: Show,
|
show: Show,
|
||||||
data: BTreeMap<i64, Value>,
|
data: BTreeMap<WayID, Value>,
|
||||||
) -> Box<dyn State> {
|
) -> Box<dyn State> {
|
||||||
let map = &app.primary.map;
|
let map = &app.primary.map;
|
||||||
let osm_way_id = map
|
let osm_way_id = map
|
||||||
@ -507,7 +508,7 @@ impl State for ChangeWay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
fn generate_osmc(_: &BTreeMap<i64, Value>, _: bool, _: &mut Timer) -> Result<(), Box<dyn Error>> {
|
fn generate_osmc(_: &BTreeMap<WayID, Value>, _: bool, _: &mut Timer) -> Result<(), Box<dyn Error>> {
|
||||||
Err("Woops, mapping mode isn't supported on the web yet"
|
Err("Woops, mapping mode isn't supported on the web yet"
|
||||||
.to_string()
|
.to_string()
|
||||||
.into())
|
.into())
|
||||||
@ -515,7 +516,7 @@ fn generate_osmc(_: &BTreeMap<i64, Value>, _: bool, _: &mut Timer) -> Result<(),
|
|||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
fn generate_osmc(
|
fn generate_osmc(
|
||||||
data: &BTreeMap<i64, Value>,
|
data: &BTreeMap<WayID, Value>,
|
||||||
in_seattle: bool,
|
in_seattle: bool,
|
||||||
timer: &mut Timer,
|
timer: &mut Timer,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
@ -527,7 +528,7 @@ fn generate_osmc(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = format!("https://api.openstreetmap.org/api/0.6/way/{}", way);
|
let url = format!("https://api.openstreetmap.org/api/0.6/way/{}", way.0);
|
||||||
timer.note(format!("Fetching {}", url));
|
timer.note(format!("Fetching {}", url));
|
||||||
let resp = reqwest::blocking::get(&url)?.text()?;
|
let resp = reqwest::blocking::get(&url)?.text()?;
|
||||||
let mut tree = xmltree::Element::parse(resp.as_bytes())?
|
let mut tree = xmltree::Element::parse(resp.as_bytes())?
|
||||||
|
@ -18,7 +18,7 @@ pub fn info(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BuildingID
|
|||||||
kv.push(("Name", name.clone()));
|
kv.push(("Name", name.clone()));
|
||||||
}
|
}
|
||||||
if app.opts.dev {
|
if app.opts.dev {
|
||||||
kv.push(("OSM ID", format!("{}", b.osm_way_id)));
|
kv.push(("OSM ID", format!("{}", b.orig_id.osm_id.inner())));
|
||||||
}
|
}
|
||||||
|
|
||||||
let num_spots = b.num_parking_spots();
|
let num_spots = b.num_parking_spots();
|
||||||
|
@ -175,10 +175,7 @@ pub fn route(ctx: &mut EventCtx, app: &App, details: &mut Details, id: BusRouteI
|
|||||||
if app.opts.dev {
|
if app.opts.dev {
|
||||||
rows.push(Btn::text_bg1("Open OSM relation").build(
|
rows.push(Btn::text_bg1("Open OSM relation").build(
|
||||||
ctx,
|
ctx,
|
||||||
format!(
|
format!("open {}", route.osm_rel_id),
|
||||||
"open https://www.openstreetmap.org/relation/{}",
|
|
||||||
route.osm_rel_id
|
|
||||||
),
|
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -27,16 +27,11 @@ pub fn info(ctx: &EventCtx, app: &App, details: &mut Details, id: IntersectionID
|
|||||||
rows.push(txt.draw(ctx));
|
rows.push(txt.draw(ctx));
|
||||||
|
|
||||||
if app.opts.dev {
|
if app.opts.dev {
|
||||||
rows.push(
|
rows.push(Btn::text_bg1("Open OSM node").build(
|
||||||
Btn::text_bg1(format!("Open OSM node {}", i.orig_id.osm_node_id)).build(
|
|
||||||
ctx,
|
ctx,
|
||||||
format!(
|
format!("open {}", i.orig_id.osm_node_id),
|
||||||
"open https://www.openstreetmap.org/node/{}",
|
|
||||||
i.orig_id.osm_node_id
|
|
||||||
),
|
|
||||||
None,
|
None,
|
||||||
),
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rows
|
rows
|
||||||
|
@ -131,15 +131,17 @@ pub fn debug(ctx: &EventCtx, app: &App, details: &mut Details, id: LaneID) -> Ve
|
|||||||
l.length()
|
l.length()
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
let pair = r.dir_and_offset(l.id);
|
||||||
|
kv.push((
|
||||||
|
"Dir and offset".to_string(),
|
||||||
|
format!("fwd={}, {}", pair.0, pair.1),
|
||||||
|
));
|
||||||
|
|
||||||
rows.extend(make_table(ctx, kv.into_iter()));
|
rows.extend(make_table(ctx, kv.into_iter()));
|
||||||
|
|
||||||
rows.push(Btn::text_bg1("Open OSM way").build(
|
rows.push(Btn::text_bg1("Open OSM way").build(
|
||||||
ctx,
|
ctx,
|
||||||
format!(
|
format!("open {}", r.orig_id.osm_way_id),
|
||||||
"open https://www.openstreetmap.org/way/{}",
|
|
||||||
r.orig_id.osm_way_id
|
|
||||||
),
|
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -353,8 +353,8 @@ pub fn make_crosswalk(batch: &mut GeomBatch, turn: &Turn, map: &Map, cs: &ColorS
|
|||||||
|
|
||||||
fn make_rainbow_crosswalk(batch: &mut GeomBatch, turn: &Turn, map: &Map) -> bool {
|
fn make_rainbow_crosswalk(batch: &mut GeomBatch, turn: &Turn, map: &Map) -> bool {
|
||||||
// TODO The crosswalks aren't tagged in OSM yet. Manually hardcoding some now.
|
// TODO The crosswalks aren't tagged in OSM yet. Manually hardcoding some now.
|
||||||
let node = map.get_i(turn.id.parent).orig_id.osm_node_id;
|
let node = map.get_i(turn.id.parent).orig_id.osm_node_id.0;
|
||||||
let way = map.get_parent(turn.id.src).orig_id.osm_way_id;
|
let way = map.get_parent(turn.id.src).orig_id.osm_way_id.0;
|
||||||
match (node, way) {
|
match (node, way) {
|
||||||
// Broadway and Pine
|
// Broadway and Pine
|
||||||
(53073255, 428246441) |
|
(53073255, 428246441) |
|
||||||
|
@ -111,7 +111,9 @@ impl TransitRoutes {
|
|||||||
|
|
||||||
let col = vec![
|
let col = vec![
|
||||||
DashTab::TransitRoutes.picker(ctx, app),
|
DashTab::TransitRoutes.picker(ctx, app),
|
||||||
Line("Transit routes").small_heading().draw(ctx),
|
Line(format!("{} Transit routes", routes.len()))
|
||||||
|
.small_heading()
|
||||||
|
.draw(ctx),
|
||||||
Widget::row(vec![
|
Widget::row(vec![
|
||||||
Widget::draw_svg(ctx, "system/assets/tools/search.svg"),
|
Widget::draw_svg(ctx, "system/assets/tools/search.svg"),
|
||||||
Autocomplete::new(
|
Autocomplete::new(
|
||||||
|
@ -16,8 +16,8 @@ use ezgui::{
|
|||||||
VerticalAlignment, Widget,
|
VerticalAlignment, Widget,
|
||||||
};
|
};
|
||||||
use geom::{ArrowCap, Distance, Duration, PolyLine, Polygon, Pt2D, Time};
|
use geom::{ArrowCap, Distance, Duration, PolyLine, Polygon, Pt2D, Time};
|
||||||
use map_model::raw::{OriginalIntersection, OriginalRoad};
|
use map_model::raw::{OriginalBuilding, OriginalIntersection, OriginalRoad};
|
||||||
use map_model::{BuildingID, Map, OriginalLane, Position};
|
use map_model::{osm, BuildingID, Map, OriginalLane, Position};
|
||||||
use sim::{
|
use sim::{
|
||||||
AgentID, Analytics, BorderSpawnOverTime, CarID, DrivingGoal, IndividTrip, OriginDestination,
|
AgentID, Analytics, BorderSpawnOverTime, CarID, DrivingGoal, IndividTrip, OriginDestination,
|
||||||
PersonID, PersonSpec, Scenario, ScenarioGenerator, SpawnOverTime, SpawnTrip, VehicleType,
|
PersonID, PersonSpec, Scenario, ScenarioGenerator, SpawnOverTime, SpawnTrip, VehicleType,
|
||||||
@ -646,10 +646,10 @@ fn make_bike_lane_scenario(map: &Map) -> ScenarioGenerator {
|
|||||||
start_time: Time::START_OF_DAY,
|
start_time: Time::START_OF_DAY,
|
||||||
stop_time: Time::START_OF_DAY + Duration::seconds(10.0),
|
stop_time: Time::START_OF_DAY + Duration::seconds(10.0),
|
||||||
start_from_border: map
|
start_from_border: map
|
||||||
.find_r_by_osm_id(263665925, (2499826475, 53096959))
|
.find_r_by_osm_id(OriginalRoad::new(263665925, (2499826475, 53096959)))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.backwards(),
|
.backwards(),
|
||||||
goal: OriginDestination::GotoBldg(map.find_b_by_osm_id(217699501).unwrap()),
|
goal: OriginDestination::GotoBldg(map.find_b_by_osm_id(bldg(217699501)).unwrap()),
|
||||||
});
|
});
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
@ -895,7 +895,7 @@ impl TutorialState {
|
|||||||
parking_found: false,
|
parking_found: false,
|
||||||
score_delivered: false,
|
score_delivered: false,
|
||||||
|
|
||||||
fire_station: app.primary.map.find_b_by_osm_id(731238736).unwrap(),
|
fire_station: app.primary.map.find_b_by_osm_id(bldg(731238736)).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let tool_panel = tool_panel(ctx);
|
let tool_panel = tool_panel(ctx);
|
||||||
@ -913,7 +913,10 @@ impl TutorialState {
|
|||||||
state.stages.push(
|
state.stages.push(
|
||||||
Stage::new(Task::Camera)
|
Stage::new(Task::Camera)
|
||||||
.warp_to(
|
.warp_to(
|
||||||
ID::Intersection(map.find_i_by_osm_id(53096945).unwrap()),
|
ID::Intersection(
|
||||||
|
map.find_i_by_osm_id(OriginalIntersection::new(53096945))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.msg(
|
.msg(
|
||||||
@ -971,7 +974,10 @@ impl TutorialState {
|
|||||||
state.stages.push(
|
state.stages.push(
|
||||||
Stage::new(Task::TimeControls)
|
Stage::new(Task::TimeControls)
|
||||||
.warp_to(
|
.warp_to(
|
||||||
ID::Intersection(map.find_i_by_osm_id(53096945).unwrap()),
|
ID::Intersection(
|
||||||
|
map.find_i_by_osm_id(OriginalIntersection::new(53096945))
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
Some(6.5),
|
Some(6.5),
|
||||||
)
|
)
|
||||||
.msg(
|
.msg(
|
||||||
@ -1031,24 +1037,16 @@ impl TutorialState {
|
|||||||
Stage::new(Task::Escort)
|
Stage::new(Task::Escort)
|
||||||
// Don't center on where the agents are, be a little offset
|
// Don't center on where the agents are, be a little offset
|
||||||
.warp_to(
|
.warp_to(
|
||||||
ID::Building(map.find_b_by_osm_id(217699780).unwrap()),
|
ID::Building(map.find_b_by_osm_id(bldg(217699780)).unwrap()),
|
||||||
Some(10.0),
|
Some(10.0),
|
||||||
)
|
)
|
||||||
.spawn(Box::new(move |app| {
|
.spawn(Box::new(move |app| {
|
||||||
// Seed a specific target car, and fill up the target building's private
|
// Seed a specific target car, and fill up the target building's private
|
||||||
// parking to force the target to park on-street.
|
// parking to force the target to park on-street.
|
||||||
let map = &app.primary.map;
|
let map = &app.primary.map;
|
||||||
let goal_bldg = map.find_b_by_osm_id(217701875).unwrap();
|
let goal_bldg = map.find_b_by_osm_id(bldg(217701875)).unwrap();
|
||||||
let start_lane = OriginalLane {
|
let start_lane = OriginalLane {
|
||||||
parent: OriginalRoad {
|
parent: OriginalRoad::new(158782224, (1709145066, 53128052)),
|
||||||
osm_way_id: 158782224,
|
|
||||||
i1: OriginalIntersection {
|
|
||||||
osm_node_id: 1709145066,
|
|
||||||
},
|
|
||||||
i2: OriginalIntersection {
|
|
||||||
osm_node_id: 53128052,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
num_fwd: 3,
|
num_fwd: 3,
|
||||||
num_back: 3,
|
num_back: 3,
|
||||||
fwd: false,
|
fwd: false,
|
||||||
@ -1057,15 +1055,7 @@ impl TutorialState {
|
|||||||
.from_permanent(map)
|
.from_permanent(map)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let lane_near_bldg = OriginalLane {
|
let lane_near_bldg = OriginalLane {
|
||||||
parent: OriginalRoad {
|
parent: OriginalRoad::new(6484869, (53163501, 53069236)),
|
||||||
osm_way_id: 6484869,
|
|
||||||
i1: OriginalIntersection {
|
|
||||||
osm_node_id: 53163501,
|
|
||||||
},
|
|
||||||
i2: OriginalIntersection {
|
|
||||||
osm_node_id: 53069236,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
num_fwd: 3,
|
num_fwd: 3,
|
||||||
num_back: 3,
|
num_back: 3,
|
||||||
fwd: true,
|
fwd: true,
|
||||||
@ -1118,7 +1108,13 @@ impl TutorialState {
|
|||||||
app.primary.sim.tiny_step(map, &mut app.primary.sim_cb);
|
app.primary.sim.tiny_step(map, &mut app.primary.sim_cb);
|
||||||
|
|
||||||
// And add some noise
|
// And add some noise
|
||||||
spawn_agents_around(app.primary.map.find_i_by_osm_id(1709145066).unwrap(), app);
|
spawn_agents_around(
|
||||||
|
app.primary
|
||||||
|
.map
|
||||||
|
.find_i_by_osm_id(OriginalIntersection::new(1709145066))
|
||||||
|
.unwrap(),
|
||||||
|
app,
|
||||||
|
);
|
||||||
}))
|
}))
|
||||||
.msg(
|
.msg(
|
||||||
vec!["Alright alright, no need to wear out your spacebar."],
|
vec!["Alright alright, no need to wear out your spacebar."],
|
||||||
@ -1222,7 +1218,7 @@ impl TutorialState {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let bike_lane_scenario = make_bike_lane_scenario(map);
|
let bike_lane_scenario = make_bike_lane_scenario(map);
|
||||||
let bike_lane_focus_pt = map.find_b_by_osm_id(217699496).unwrap();
|
let bike_lane_focus_pt = map.find_b_by_osm_id(bldg(217699496)).unwrap();
|
||||||
|
|
||||||
state.stages.push(
|
state.stages.push(
|
||||||
Stage::new(Task::WatchBikes)
|
Stage::new(Task::WatchBikes)
|
||||||
@ -1456,3 +1452,10 @@ fn intro_story(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assumes ways
|
||||||
|
fn bldg(id: i64) -> OriginalBuilding {
|
||||||
|
OriginalBuilding {
|
||||||
|
osm_id: osm::OsmID::Way(osm::WayID(id)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use abstutil::{prettyprint_usize, Counter, FileWithProgress, Timer};
|
use abstutil::{prettyprint_usize, Counter, FileWithProgress, Timer};
|
||||||
use geom::{Distance, Duration, FindClosest, LonLat, Pt2D, Time};
|
use geom::{Distance, Duration, FindClosest, LonLat, Pt2D, Time};
|
||||||
use kml::{ExtraShape, ExtraShapes};
|
use kml::{ExtraShape, ExtraShapes};
|
||||||
use map_model::Map;
|
use map_model::{osm, Map};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sim::{OrigPersonID, TripMode};
|
use sim::{OrigPersonID, TripMode};
|
||||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
@ -116,9 +116,9 @@ fn import_parcels(
|
|||||||
) -> (HashMap<usize, Endpoint>, BTreeMap<usize, ExtraShape>) {
|
) -> (HashMap<usize, Endpoint>, BTreeMap<usize, ExtraShape>) {
|
||||||
// TODO I really just want to do polygon containment with a quadtree. FindClosest only does
|
// TODO I really just want to do polygon containment with a quadtree. FindClosest only does
|
||||||
// line-string stuff right now, which'll be weird for the last->first pt line and stuff.
|
// line-string stuff right now, which'll be weird for the last->first pt line and stuff.
|
||||||
let mut closest_bldg: FindClosest<i64> = FindClosest::new(huge_map.get_bounds());
|
let mut closest_bldg: FindClosest<osm::OsmID> = FindClosest::new(huge_map.get_bounds());
|
||||||
for b in huge_map.all_buildings() {
|
for b in huge_map.all_buildings() {
|
||||||
closest_bldg.add(b.osm_way_id, b.polygon.points());
|
closest_bldg.add(b.orig_id.osm_id, b.polygon.points());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut x_coords: Vec<f64> = Vec::new();
|
let mut x_coords: Vec<f64> = Vec::new();
|
||||||
@ -201,7 +201,7 @@ fn import_parcels(
|
|||||||
attributes.insert("parking".to_string(), offstreet_parking_spaces.to_string());
|
attributes.insert("parking".to_string(), offstreet_parking_spaces.to_string());
|
||||||
}
|
}
|
||||||
if let Some(b) = osm_building {
|
if let Some(b) = osm_building {
|
||||||
attributes.insert("osm_bldg".to_string(), b.to_string());
|
attributes.insert("osm_bldg".to_string(), b.inner().to_string());
|
||||||
}
|
}
|
||||||
shapes.insert(
|
shapes.insert(
|
||||||
id,
|
id,
|
||||||
@ -298,7 +298,7 @@ pub struct OrigTrip {
|
|||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Endpoint {
|
pub struct Endpoint {
|
||||||
pub pos: LonLat,
|
pub pos: LonLat,
|
||||||
pub osm_building: Option<i64>,
|
pub osm_building: Option<osm::OsmID>,
|
||||||
pub parcel_id: usize,
|
pub parcel_id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::soundcast::popdat::{Endpoint, OrigTrip, PopDat};
|
use crate::soundcast::popdat::{Endpoint, OrigTrip, PopDat};
|
||||||
use abstutil::{prettyprint_usize, MultiMap, Parallelism, Timer};
|
use abstutil::{prettyprint_usize, MultiMap, Parallelism, Timer};
|
||||||
use geom::LonLat;
|
use geom::LonLat;
|
||||||
use map_model::{BuildingID, IntersectionID, Map, PathConstraints, PathRequest, PathStep};
|
use map_model::{osm, BuildingID, IntersectionID, Map, PathConstraints, PathRequest, PathStep};
|
||||||
use sim::{
|
use sim::{
|
||||||
IndividTrip, OffMapLocation, OrigPersonID, PersonID, PersonSpec, Scenario, SpawnTrip,
|
IndividTrip, OffMapLocation, OrigPersonID, PersonID, PersonSpec, Scenario, SpawnTrip,
|
||||||
TripEndpoint, TripMode,
|
TripEndpoint, TripMode,
|
||||||
@ -20,13 +20,13 @@ fn endpoints(
|
|||||||
from: &Endpoint,
|
from: &Endpoint,
|
||||||
to: &Endpoint,
|
to: &Endpoint,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
osm_id_to_bldg: &HashMap<i64, BuildingID>,
|
osm_id_to_bldg: &HashMap<osm::OsmID, BuildingID>,
|
||||||
(in_borders, out_borders): (
|
(in_borders, out_borders): (
|
||||||
&Vec<(IntersectionID, LonLat)>,
|
&Vec<(IntersectionID, LonLat)>,
|
||||||
&Vec<(IntersectionID, LonLat)>,
|
&Vec<(IntersectionID, LonLat)>,
|
||||||
),
|
),
|
||||||
constraints: PathConstraints,
|
constraints: PathConstraints,
|
||||||
maybe_huge_map: Option<&(&Map, HashMap<i64, BuildingID>)>,
|
maybe_huge_map: Option<&(&Map, HashMap<osm::OsmID, BuildingID>)>,
|
||||||
) -> Option<(TripEndpoint, TripEndpoint)> {
|
) -> Option<(TripEndpoint, TripEndpoint)> {
|
||||||
let from_bldg = from
|
let from_bldg = from
|
||||||
.osm_building
|
.osm_building
|
||||||
@ -147,14 +147,14 @@ fn clip_trips(map: &Map, popdat: &PopDat, huge_map: &Map, timer: &mut Timer) ->
|
|||||||
} else {
|
} else {
|
||||||
let mut huge_osm_id_to_bldg = HashMap::new();
|
let mut huge_osm_id_to_bldg = HashMap::new();
|
||||||
for b in huge_map.all_buildings() {
|
for b in huge_map.all_buildings() {
|
||||||
huge_osm_id_to_bldg.insert(b.osm_way_id, b.id);
|
huge_osm_id_to_bldg.insert(b.orig_id.osm_id, b.id);
|
||||||
}
|
}
|
||||||
Some((huge_map, huge_osm_id_to_bldg))
|
Some((huge_map, huge_osm_id_to_bldg))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut osm_id_to_bldg = HashMap::new();
|
let mut osm_id_to_bldg = HashMap::new();
|
||||||
for b in map.all_buildings() {
|
for b in map.all_buildings() {
|
||||||
osm_id_to_bldg.insert(b.osm_way_id, b.id);
|
osm_id_to_bldg.insert(b.orig_id.osm_id, b.id);
|
||||||
}
|
}
|
||||||
let bounds = map.get_gps_bounds();
|
let bounds = map.get_gps_bounds();
|
||||||
let incoming_borders_walking: Vec<(IntersectionID, LonLat)> = map
|
let incoming_borders_walking: Vec<(IntersectionID, LonLat)> = map
|
||||||
|
@ -449,7 +449,7 @@ impl Model {
|
|||||||
|
|
||||||
pub fn create_b(&mut self, center: Pt2D, ctx: &EventCtx) -> ID {
|
pub fn create_b(&mut self, center: Pt2D, ctx: &EventCtx) -> ID {
|
||||||
let id = OriginalBuilding {
|
let id = OriginalBuilding {
|
||||||
osm_way_id: self.map.new_osm_way_id(time_to_id()),
|
osm_id: osm::OsmID::Way(self.map.new_osm_way_id(time_to_id())),
|
||||||
};
|
};
|
||||||
self.map.buildings.insert(
|
self.map.buildings.insert(
|
||||||
id,
|
id,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::raw::{OriginalIntersection, OriginalRoad};
|
use crate::raw::{OriginalIntersection, OriginalRoad};
|
||||||
use crate::{
|
use crate::{
|
||||||
connectivity, BusRouteID, ControlStopSign, ControlTrafficSignal, IntersectionID,
|
connectivity, osm, BusRouteID, ControlStopSign, ControlTrafficSignal, IntersectionID,
|
||||||
IntersectionType, LaneID, LaneType, Map, PathConstraints, RoadID, TurnID, Zone,
|
IntersectionType, LaneID, LaneType, Map, PathConstraints, RoadID, TurnID, Zone,
|
||||||
};
|
};
|
||||||
use abstutil::{deserialize_btreemap, retain_btreemap, retain_btreeset, serialize_btreemap, Timer};
|
use abstutil::{deserialize_btreemap, retain_btreemap, retain_btreeset, serialize_btreemap, Timer};
|
||||||
@ -310,7 +310,7 @@ enum PermanentEditCmd {
|
|||||||
old_allow_through_traffic: EnumSet<PathConstraints>,
|
old_allow_through_traffic: EnumSet<PathConstraints>,
|
||||||
},
|
},
|
||||||
ChangeRouteSchedule {
|
ChangeRouteSchedule {
|
||||||
osm_rel_id: i64,
|
osm_rel_id: osm::RelationID,
|
||||||
old: Vec<Time>,
|
old: Vec<Time>,
|
||||||
new: Vec<Time>,
|
new: Vec<Time>,
|
||||||
},
|
},
|
||||||
@ -397,18 +397,15 @@ impl PermanentMapEdits {
|
|||||||
}
|
}
|
||||||
PermanentEditCmd::ReverseLane { l, dst_i } => {
|
PermanentEditCmd::ReverseLane { l, dst_i } => {
|
||||||
let l = l.from_permanent(map)?;
|
let l = l.from_permanent(map)?;
|
||||||
let dst_i = map.find_i_by_osm_id(dst_i.osm_node_id)?;
|
let dst_i = map.find_i_by_osm_id(dst_i)?;
|
||||||
Ok(EditCmd::ReverseLane { l, dst_i })
|
Ok(EditCmd::ReverseLane { l, dst_i })
|
||||||
}
|
}
|
||||||
PermanentEditCmd::ChangeSpeedLimit { id, new, old } => {
|
PermanentEditCmd::ChangeSpeedLimit { id, new, old } => {
|
||||||
let id = map.find_r_by_osm_id(
|
let id = map.find_r_by_osm_id(id)?;
|
||||||
id.osm_way_id,
|
|
||||||
(id.i1.osm_node_id, id.i2.osm_node_id),
|
|
||||||
)?;
|
|
||||||
Ok(EditCmd::ChangeSpeedLimit { id, new, old })
|
Ok(EditCmd::ChangeSpeedLimit { id, new, old })
|
||||||
}
|
}
|
||||||
PermanentEditCmd::ChangeIntersection { i, new, old } => {
|
PermanentEditCmd::ChangeIntersection { i, new, old } => {
|
||||||
let id = map.find_i_by_osm_id(i.osm_node_id)?;
|
let id = map.find_i_by_osm_id(i)?;
|
||||||
Ok(EditCmd::ChangeIntersection {
|
Ok(EditCmd::ChangeIntersection {
|
||||||
i: id,
|
i: id,
|
||||||
new: new
|
new: new
|
||||||
@ -424,10 +421,7 @@ impl PermanentMapEdits {
|
|||||||
new_allow_through_traffic,
|
new_allow_through_traffic,
|
||||||
old_allow_through_traffic,
|
old_allow_through_traffic,
|
||||||
} => {
|
} => {
|
||||||
let id = map.find_r_by_osm_id(
|
let id = map.find_r_by_osm_id(id)?;
|
||||||
id.osm_way_id,
|
|
||||||
(id.i1.osm_node_id, id.i2.osm_node_id),
|
|
||||||
)?;
|
|
||||||
Ok(EditCmd::ChangeAccessRestrictions {
|
Ok(EditCmd::ChangeAccessRestrictions {
|
||||||
id,
|
id,
|
||||||
new_allow_through_traffic,
|
new_allow_through_traffic,
|
||||||
@ -439,10 +433,9 @@ impl PermanentMapEdits {
|
|||||||
old,
|
old,
|
||||||
new,
|
new,
|
||||||
} => {
|
} => {
|
||||||
let id = map.find_br(osm_rel_id).ok_or(format!(
|
let id = map
|
||||||
"can't find https://www.openstreetmap.org/relation/{}",
|
.find_br(osm_rel_id)
|
||||||
osm_rel_id
|
.ok_or(format!("can't find {}", osm_rel_id))?;
|
||||||
))?;
|
|
||||||
Ok(EditCmd::ChangeRouteSchedule { id, old, new })
|
Ok(EditCmd::ChangeRouteSchedule { id, old, new })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -484,11 +477,7 @@ impl PermanentEditIntersection {
|
|||||||
PermanentEditIntersection::StopSign { must_stop } => {
|
PermanentEditIntersection::StopSign { must_stop } => {
|
||||||
let mut translated_must_stop = BTreeMap::new();
|
let mut translated_must_stop = BTreeMap::new();
|
||||||
for (r, stop) in must_stop {
|
for (r, stop) in must_stop {
|
||||||
translated_must_stop.insert(
|
translated_must_stop.insert(map.find_r_by_osm_id(r).ok()?, stop);
|
||||||
map.find_r_by_osm_id(r.osm_way_id, (r.i1.osm_node_id, r.i2.osm_node_id))
|
|
||||||
.ok()?,
|
|
||||||
stop,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the roads exactly match up
|
// Make sure the roads exactly match up
|
||||||
@ -529,10 +518,7 @@ impl OriginalLane {
|
|||||||
// - Some validation happens in the lane editor, not even here.
|
// - Some validation happens in the lane editor, not even here.
|
||||||
// - Is it inevitable? Maybe we need to apply edits as we convert.
|
// - Is it inevitable? Maybe we need to apply edits as we convert.
|
||||||
pub fn from_permanent(self, map: &Map) -> Result<LaneID, String> {
|
pub fn from_permanent(self, map: &Map) -> Result<LaneID, String> {
|
||||||
let r = map.get_r(map.find_r_by_osm_id(
|
let r = map.get_r(map.find_r_by_osm_id(self.parent)?);
|
||||||
self.parent.osm_way_id,
|
|
||||||
(self.parent.i1.osm_node_id, self.parent.i2.osm_node_id),
|
|
||||||
)?);
|
|
||||||
if r.children_forwards.len() != self.num_fwd || r.children_backwards.len() != self.num_back
|
if r.children_forwards.len() != self.num_fwd || r.children_backwards.len() != self.num_back
|
||||||
{
|
{
|
||||||
return Err(format!("number of lanes has changed in {:?}", self));
|
return Err(format!("number of lanes has changed in {:?}", self));
|
||||||
|
@ -55,13 +55,13 @@ pub fn make_all_buildings(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let id = BuildingID(results.len());
|
let id = BuildingID(results.len());
|
||||||
let mut rng = XorShiftRng::seed_from_u64(orig_id.osm_way_id as u64);
|
let mut rng = XorShiftRng::seed_from_u64(orig_id.osm_id.inner() as u64);
|
||||||
results.push(Building {
|
results.push(Building {
|
||||||
id,
|
id,
|
||||||
polygon: b.polygon.clone(),
|
polygon: b.polygon.clone(),
|
||||||
address: get_address(&b.osm_tags, sidewalk_pos.lane(), map),
|
address: get_address(&b.osm_tags, sidewalk_pos.lane(), map),
|
||||||
name: b.osm_tags.get(osm::NAME).cloned(),
|
name: b.osm_tags.get(osm::NAME).cloned(),
|
||||||
osm_way_id: orig_id.osm_way_id,
|
orig_id,
|
||||||
label_center: b.polygon.polylabel(),
|
label_center: b.polygon.polylabel(),
|
||||||
amenities: b.amenities.clone(),
|
amenities: b.amenities.clone(),
|
||||||
bldg_type: classify_bldg(&b.osm_tags, &b.amenities, b.polygon.area(), &mut rng),
|
bldg_type: classify_bldg(&b.osm_tags, &b.amenities, b.polygon.area(), &mut rng),
|
||||||
|
@ -115,7 +115,7 @@ impl InitialMap {
|
|||||||
m.roads[r2].trimmed_center_pts.reversed()
|
m.roads[r2].trimmed_center_pts.reversed()
|
||||||
};
|
};
|
||||||
if pl1 == pl2 {
|
if pl1 == pl2 {
|
||||||
problems.insert(format!("{} and {} overlap", r1.way_url(), r2.way_url()));
|
problems.insert(format!("{} and {} overlap", r1.osm_way_id, r2.osm_way_id));
|
||||||
bad_intersections.insert(i.id);
|
bad_intersections.insert(i.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,10 +88,8 @@ pub fn make_all_parking_lots(
|
|||||||
sidewalk_pos: *sidewalk_pos,
|
sidewalk_pos: *sidewalk_pos,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// TODO Plumb WayID forward
|
|
||||||
timer.warn(format!(
|
timer.warn(format!(
|
||||||
"Parking lot from https://www.openstreetmap.org/way/{}, near sidewalk {}, \
|
"Parking lot from {}, near sidewalk {}, can't have a driveway.",
|
||||||
can't have a driveway.",
|
|
||||||
orig.osm_id,
|
orig.osm_id,
|
||||||
sidewalk_pos.lane()
|
sidewalk_pos.lane()
|
||||||
));
|
));
|
||||||
|
@ -17,7 +17,7 @@ pub fn get_possible_policies(
|
|||||||
// independently.
|
// independently.
|
||||||
if let Some(raw) = seattle_traffic_signals::load_all_data()
|
if let Some(raw) = seattle_traffic_signals::load_all_data()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.remove(&map.get_i(id).orig_id.osm_node_id)
|
.remove(&map.get_i(id).orig_id.osm_node_id.0)
|
||||||
{
|
{
|
||||||
if let Ok(ts) = ControlTrafficSignal::import(raw, id, map) {
|
if let Ok(ts) = ControlTrafficSignal::import(raw, id, map) {
|
||||||
results.push(("hand-mapped current real settings".to_string(), ts));
|
results.push(("hand-mapped current real settings".to_string(), ts));
|
||||||
@ -557,7 +557,7 @@ pub fn synchronize(map: &mut Map) {
|
|||||||
for i in map.all_intersections() {
|
for i in map.all_intersections() {
|
||||||
if !i.is_traffic_signal()
|
if !i.is_traffic_signal()
|
||||||
|| seen.contains(&i.id)
|
|| seen.contains(&i.id)
|
||||||
|| handmapped.contains_key(&i.orig_id.osm_node_id)
|
|| handmapped.contains_key(&i.orig_id.osm_node_id.0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,7 @@ pub fn make_stops_and_routes(map: &mut Map, raw_routes: &Vec<RawBusRoute>, timer
|
|||||||
if let Err(err) = make_route(map, r, &mut pt_to_stop, &matcher) {
|
if let Err(err) = make_route(map, r, &mut pt_to_stop, &matcher) {
|
||||||
timer.warn(format!(
|
timer.warn(format!(
|
||||||
"Skipping route {} ({}): {}",
|
"Skipping route {} ({}): {}",
|
||||||
r.full_name,
|
r.full_name, r.osm_rel_id, err
|
||||||
rel_url(r.osm_rel_id),
|
|
||||||
err
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +87,7 @@ fn make_route(
|
|||||||
// Start or end at a border?
|
// Start or end at a border?
|
||||||
let mut end_border = None;
|
let mut end_border = None;
|
||||||
let start = if let Some(i) = r.border_start {
|
let start = if let Some(i) = r.border_start {
|
||||||
let i = map.get_i(map.find_i_by_osm_id(i.osm_node_id).unwrap());
|
let i = map.get_i(map.find_i_by_osm_id(i).unwrap());
|
||||||
if !i.is_border() {
|
if !i.is_border() {
|
||||||
panic!("Route starts at {}, but isn't a border?", i.orig_id);
|
panic!("Route starts at {}, but isn't a border?", i.orig_id);
|
||||||
}
|
}
|
||||||
@ -98,10 +96,7 @@ fn make_route(
|
|||||||
} else {
|
} else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Route {} starts at {} ({}), but no starting lane for a {:?}?",
|
"Route {} starts at {} ({}), but no starting lane for a {:?}?",
|
||||||
rel_url(r.osm_rel_id),
|
r.osm_rel_id, i.id, i.orig_id, route_type
|
||||||
i.id,
|
|
||||||
i.orig_id,
|
|
||||||
route_type
|
|
||||||
)
|
)
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
@ -110,7 +105,7 @@ fn make_route(
|
|||||||
pick_start_lane(map.get_bs(stops[0]).driving_pos, route_type, map)?
|
pick_start_lane(map.get_bs(stops[0]).driving_pos, route_type, map)?
|
||||||
};
|
};
|
||||||
if let Some(i) = r.border_end {
|
if let Some(i) = r.border_end {
|
||||||
let i = map.get_i(map.find_i_by_osm_id(i.osm_node_id).unwrap());
|
let i = map.get_i(map.find_i_by_osm_id(i).unwrap());
|
||||||
if !i.is_border() {
|
if !i.is_border() {
|
||||||
panic!("Route ends at {}, but isn't a border?", i.orig_id);
|
panic!("Route ends at {}, but isn't a border?", i.orig_id);
|
||||||
}
|
}
|
||||||
@ -125,10 +120,7 @@ fn make_route(
|
|||||||
// TODO Should panic
|
// TODO Should panic
|
||||||
println!(
|
println!(
|
||||||
"Route {} ends at {} ({}), but no ending lane for a {:?}?",
|
"Route {} ends at {} ({}), but no ending lane for a {:?}?",
|
||||||
rel_url(r.osm_rel_id),
|
r.osm_rel_id, i.id, i.orig_id, route_type
|
||||||
i.id,
|
|
||||||
i.orig_id,
|
|
||||||
route_type
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,10 +313,6 @@ impl Matcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rel_url(id: i64) -> String {
|
|
||||||
format!("https://www.openstreetmap.org/relation/{}", id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pick_start_lane(
|
fn pick_start_lane(
|
||||||
first_stop: Position,
|
first_stop: Position,
|
||||||
constraints: PathConstraints,
|
constraints: PathConstraints,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::raw::{DrivingSide, RawMap};
|
use crate::raw::{DrivingSide, OriginalBuilding, OriginalIntersection, OriginalRoad, RawMap};
|
||||||
use crate::{
|
use crate::{
|
||||||
Area, AreaID, Building, BuildingID, BuildingType, BusRoute, BusRouteID, BusStop, BusStopID,
|
osm, Area, AreaID, Building, BuildingID, BuildingType, BusRoute, BusRouteID, BusStop,
|
||||||
ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID, Lane, LaneID, LaneType,
|
BusStopID, ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID, Lane, LaneID,
|
||||||
Map, MapEdits, OffstreetParking, ParkingLot, ParkingLotID, Path, PathConstraints, PathRequest,
|
LaneType, Map, MapEdits, OffstreetParking, ParkingLot, ParkingLotID, Path, PathConstraints,
|
||||||
Position, Road, RoadID, Turn, TurnGroupID, TurnID, TurnType,
|
PathRequest, Position, Road, RoadID, Turn, TurnGroupID, TurnID, TurnType,
|
||||||
};
|
};
|
||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
use geom::{Angle, Bounds, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D, Ring, Time};
|
use geom::{Angle, Bounds, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D, Ring, Time};
|
||||||
@ -547,47 +547,36 @@ impl Map {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_r_by_osm_id(
|
pub fn find_r_by_osm_id(&self, id: OriginalRoad) -> Result<RoadID, String> {
|
||||||
&self,
|
|
||||||
osm_way_id: i64,
|
|
||||||
osm_node_ids: (i64, i64),
|
|
||||||
) -> Result<RoadID, String> {
|
|
||||||
for r in self.all_roads() {
|
for r in self.all_roads() {
|
||||||
if r.orig_id.osm_way_id == osm_way_id
|
if r.orig_id == id {
|
||||||
&& r.orig_id.i1.osm_node_id == osm_node_ids.0
|
|
||||||
&& r.orig_id.i2.osm_node_id == osm_node_ids.1
|
|
||||||
{
|
|
||||||
return Ok(r.id);
|
return Ok(r.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(format!(
|
Err(format!("Can't find {}", id))
|
||||||
"Can't find osm_way_id {} between nodes {} and {}",
|
|
||||||
osm_way_id, osm_node_ids.0, osm_node_ids.1
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Take OriginalIntersection
|
pub fn find_i_by_osm_id(&self, id: OriginalIntersection) -> Result<IntersectionID, String> {
|
||||||
pub fn find_i_by_osm_id(&self, osm_node_id: i64) -> Result<IntersectionID, String> {
|
|
||||||
for i in self.all_intersections() {
|
for i in self.all_intersections() {
|
||||||
if i.orig_id.osm_node_id == osm_node_id {
|
if i.orig_id == id {
|
||||||
return Ok(i.id);
|
return Ok(i.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(format!("Can't find osm_node_id {}", osm_node_id))
|
Err(format!("Can't find {}", id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_b_by_osm_id(&self, osm_way_id: i64) -> Option<BuildingID> {
|
pub fn find_b_by_osm_id(&self, id: OriginalBuilding) -> Option<BuildingID> {
|
||||||
for b in self.all_buildings() {
|
for b in self.all_buildings() {
|
||||||
if b.osm_way_id == osm_way_id {
|
if b.orig_id == id {
|
||||||
return Some(b.id);
|
return Some(b.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_br(&self, osm_rel_id: i64) -> Option<BusRouteID> {
|
pub fn find_br(&self, id: osm::RelationID) -> Option<BusRouteID> {
|
||||||
for br in self.all_bus_routes() {
|
for br in self.all_bus_routes() {
|
||||||
if br.osm_rel_id == osm_rel_id {
|
if br.osm_rel_id == id {
|
||||||
return Some(br.id);
|
return Some(br.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::osm;
|
||||||
use abstutil::{deserialize_usize, serialize_usize, Tags};
|
use abstutil::{deserialize_usize, serialize_usize, Tags};
|
||||||
use geom::Polygon;
|
use geom::Polygon;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -32,5 +33,5 @@ pub struct Area {
|
|||||||
pub area_type: AreaType,
|
pub area_type: AreaType,
|
||||||
pub polygon: Polygon,
|
pub polygon: Polygon,
|
||||||
pub osm_tags: Tags,
|
pub osm_tags: Tags,
|
||||||
pub osm_id: i64,
|
pub osm_id: osm::OsmID,
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::raw::OriginalBuilding;
|
||||||
use crate::{LaneID, Map, PathConstraints, Position};
|
use crate::{LaneID, Map, PathConstraints, Position};
|
||||||
use abstutil::{deserialize_usize, serialize_usize};
|
use abstutil::{deserialize_usize, serialize_usize};
|
||||||
use geom::{Distance, PolyLine, Polygon, Pt2D};
|
use geom::{Distance, PolyLine, Polygon, Pt2D};
|
||||||
@ -26,7 +27,7 @@ pub struct Building {
|
|||||||
pub polygon: Polygon,
|
pub polygon: Polygon,
|
||||||
pub address: String,
|
pub address: String,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub osm_way_id: i64,
|
pub orig_id: OriginalBuilding,
|
||||||
// Where a text label should be centered to have the best chances of being contained within the
|
// Where a text label should be centered to have the best chances of being contained within the
|
||||||
// polygon.
|
// polygon.
|
||||||
pub label_center: Pt2D,
|
pub label_center: Pt2D,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{LaneID, Map, PathConstraints, PathRequest, Position};
|
use crate::{osm, LaneID, Map, PathConstraints, PathRequest, Position};
|
||||||
use abstutil::{deserialize_usize, serialize_usize};
|
use abstutil::{deserialize_usize, serialize_usize};
|
||||||
use geom::Time;
|
use geom::Time;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -50,7 +50,7 @@ pub struct BusRoute {
|
|||||||
pub full_name: String,
|
pub full_name: String,
|
||||||
pub short_name: String,
|
pub short_name: String,
|
||||||
pub gtfs_trip_marker: Option<String>,
|
pub gtfs_trip_marker: Option<String>,
|
||||||
pub osm_rel_id: i64,
|
pub osm_rel_id: osm::RelationID,
|
||||||
pub stops: Vec<BusStopID>,
|
pub stops: Vec<BusStopID>,
|
||||||
// May be a border or not. If not, is long enough for buses to spawn fully.
|
// May be a border or not. If not, is long enough for buses to spawn fully.
|
||||||
pub start: LaneID,
|
pub start: LaneID,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::Position;
|
use crate::{osm, Position};
|
||||||
use abstutil::{deserialize_usize, serialize_usize};
|
use abstutil::{deserialize_usize, serialize_usize};
|
||||||
use geom::{Angle, Line, PolyLine, Polygon, Pt2D};
|
use geom::{Angle, Line, PolyLine, Polygon, Pt2D};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -33,7 +33,7 @@ pub struct ParkingLot {
|
|||||||
pub id: ParkingLotID,
|
pub id: ParkingLotID,
|
||||||
pub polygon: Polygon,
|
pub polygon: Polygon,
|
||||||
pub aisles: Vec<Vec<Pt2D>>,
|
pub aisles: Vec<Vec<Pt2D>>,
|
||||||
pub osm_id: i64,
|
pub osm_id: osm::OsmID,
|
||||||
// The middle of the "T", pointing towards the parking aisle
|
// The middle of the "T", pointing towards the parking aisle
|
||||||
pub spots: Vec<(Pt2D, Angle)>,
|
pub spots: Vec<(Pt2D, Angle)>,
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use crate::make::traffic_signals::{brute_force, get_possible_policies};
|
use crate::make::traffic_signals::{brute_force, get_possible_policies};
|
||||||
|
use crate::raw::{OriginalIntersection, OriginalRoad};
|
||||||
use crate::{
|
use crate::{
|
||||||
DirectedRoadID, IntersectionID, Map, TurnGroup, TurnGroupID, TurnID, TurnPriority, TurnType,
|
osm, DirectedRoadID, IntersectionID, Map, TurnGroup, TurnGroupID, TurnID, TurnPriority,
|
||||||
|
TurnType,
|
||||||
};
|
};
|
||||||
use abstutil::{deserialize_btreemap, retain_btreeset, serialize_btreemap, Timer};
|
use abstutil::{deserialize_btreemap, retain_btreeset, serialize_btreemap, Timer};
|
||||||
use geom::Duration;
|
use geom::Duration;
|
||||||
@ -230,7 +232,7 @@ impl Phase {
|
|||||||
impl ControlTrafficSignal {
|
impl ControlTrafficSignal {
|
||||||
pub fn export(&self, map: &Map) -> seattle_traffic_signals::TrafficSignal {
|
pub fn export(&self, map: &Map) -> seattle_traffic_signals::TrafficSignal {
|
||||||
seattle_traffic_signals::TrafficSignal {
|
seattle_traffic_signals::TrafficSignal {
|
||||||
intersection_osm_node_id: map.get_i(self.id).orig_id.osm_node_id,
|
intersection_osm_node_id: map.get_i(self.id).orig_id.osm_node_id.0,
|
||||||
phases: self
|
phases: self
|
||||||
.phases
|
.phases
|
||||||
.iter()
|
.iter()
|
||||||
@ -314,18 +316,18 @@ fn export_turn_group(id: &TurnGroupID, map: &Map) -> seattle_traffic_signals::Tu
|
|||||||
|
|
||||||
seattle_traffic_signals::Turn {
|
seattle_traffic_signals::Turn {
|
||||||
from: seattle_traffic_signals::DirectedRoad {
|
from: seattle_traffic_signals::DirectedRoad {
|
||||||
osm_way_id: from.osm_way_id,
|
osm_way_id: from.osm_way_id.0,
|
||||||
osm_node1: from.i1.osm_node_id,
|
osm_node1: from.i1.osm_node_id.0,
|
||||||
osm_node2: from.i2.osm_node_id,
|
osm_node2: from.i2.osm_node_id.0,
|
||||||
is_forwards: id.from.forwards,
|
is_forwards: id.from.forwards,
|
||||||
},
|
},
|
||||||
to: seattle_traffic_signals::DirectedRoad {
|
to: seattle_traffic_signals::DirectedRoad {
|
||||||
osm_way_id: to.osm_way_id,
|
osm_way_id: to.osm_way_id.0,
|
||||||
osm_node1: to.i1.osm_node_id,
|
osm_node1: to.i1.osm_node_id.0,
|
||||||
osm_node2: to.i2.osm_node_id,
|
osm_node2: to.i2.osm_node_id.0,
|
||||||
is_forwards: id.to.forwards,
|
is_forwards: id.to.forwards,
|
||||||
},
|
},
|
||||||
intersection_osm_node_id: map.get_i(id.parent).orig_id.osm_node_id,
|
intersection_osm_node_id: map.get_i(id.parent).orig_id.osm_node_id.0,
|
||||||
is_crosswalk: id.crosswalk,
|
is_crosswalk: id.crosswalk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +336,11 @@ fn import_turn_group(id: seattle_traffic_signals::Turn, map: &Map) -> Option<Tur
|
|||||||
Some(TurnGroupID {
|
Some(TurnGroupID {
|
||||||
from: find_r(id.from, map)?,
|
from: find_r(id.from, map)?,
|
||||||
to: find_r(id.to, map)?,
|
to: find_r(id.to, map)?,
|
||||||
parent: map.find_i_by_osm_id(id.intersection_osm_node_id).ok()?,
|
parent: map
|
||||||
|
.find_i_by_osm_id(OriginalIntersection {
|
||||||
|
osm_node_id: osm::NodeID(id.intersection_osm_node_id),
|
||||||
|
})
|
||||||
|
.ok()?,
|
||||||
crosswalk: id.is_crosswalk,
|
crosswalk: id.is_crosswalk,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -342,7 +348,10 @@ fn import_turn_group(id: seattle_traffic_signals::Turn, map: &Map) -> Option<Tur
|
|||||||
fn find_r(id: seattle_traffic_signals::DirectedRoad, map: &Map) -> Option<DirectedRoadID> {
|
fn find_r(id: seattle_traffic_signals::DirectedRoad, map: &Map) -> Option<DirectedRoadID> {
|
||||||
Some(DirectedRoadID {
|
Some(DirectedRoadID {
|
||||||
id: map
|
id: map
|
||||||
.find_r_by_osm_id(id.osm_way_id, (id.osm_node1, id.osm_node2))
|
.find_r_by_osm_id(OriginalRoad::new(
|
||||||
|
id.osm_way_id,
|
||||||
|
(id.osm_node1, id.osm_node2),
|
||||||
|
))
|
||||||
.ok()?,
|
.ok()?,
|
||||||
forwards: id.is_forwards,
|
forwards: id.is_forwards,
|
||||||
})
|
})
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
// These are common OSM keys. Keys used in just one or two places don't really need to be defined
|
// These are common OSM keys. Keys used in just one or two places don't really need to be defined
|
||||||
// here.
|
// here.
|
||||||
|
|
||||||
@ -44,3 +47,51 @@ impl RoadRank {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub struct NodeID(pub i64);
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub struct WayID(pub i64);
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub struct RelationID(pub i64);
|
||||||
|
|
||||||
|
impl fmt::Display for NodeID {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "https://www.openstreetmap.org/node/{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl fmt::Display for WayID {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "https://www.openstreetmap.org/way/{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl fmt::Display for RelationID {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "https://www.openstreetmap.org/relation/{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
pub enum OsmID {
|
||||||
|
Node(NodeID),
|
||||||
|
Way(WayID),
|
||||||
|
Relation(RelationID),
|
||||||
|
}
|
||||||
|
impl fmt::Display for OsmID {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
OsmID::Node(n) => write!(f, "{}", n),
|
||||||
|
OsmID::Way(w) => write!(f, "{}", w),
|
||||||
|
OsmID::Relation(r) => write!(f, "{}", r),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl OsmID {
|
||||||
|
pub fn inner(self) -> i64 {
|
||||||
|
match self {
|
||||||
|
OsmID::Node(n) => n.0,
|
||||||
|
OsmID::Way(w) => w.0,
|
||||||
|
OsmID::Relation(r) => r.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -44,33 +44,28 @@ pub struct RawMap {
|
|||||||
// (https://github.com/opentraffic/architecture/issues/1).
|
// (https://github.com/opentraffic/architecture/issues/1).
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct OriginalRoad {
|
pub struct OriginalRoad {
|
||||||
pub osm_way_id: i64,
|
pub osm_way_id: osm::WayID,
|
||||||
pub i1: OriginalIntersection,
|
pub i1: OriginalIntersection,
|
||||||
pub i2: OriginalIntersection,
|
pub i2: OriginalIntersection,
|
||||||
}
|
}
|
||||||
impl OriginalRoad {
|
|
||||||
pub fn way_url(self) -> String {
|
|
||||||
format!("https://www.openstreetmap.org/way/{}", self.osm_way_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A way to refer to intersections across many maps.
|
// A way to refer to intersections across many maps.
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct OriginalIntersection {
|
pub struct OriginalIntersection {
|
||||||
pub osm_node_id: i64,
|
pub osm_node_id: osm::NodeID,
|
||||||
}
|
}
|
||||||
|
|
||||||
// A way to refer to buildings across many maps.
|
// A way to refer to buildings across many maps.
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct OriginalBuilding {
|
pub struct OriginalBuilding {
|
||||||
pub osm_way_id: i64,
|
pub osm_id: osm::OsmID,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for OriginalRoad {
|
impl fmt::Display for OriginalRoad {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"OriginalRoad(https://www.openstreetmap.org/way/{} from https://www.openstreetmap.org/node/{} to https://www.openstreetmap.org/node/{})",
|
"OriginalRoad({} from {} to {}",
|
||||||
self.osm_way_id, self.i1.osm_node_id, self.i2.osm_node_id
|
self.osm_way_id, self.i1.osm_node_id, self.i2.osm_node_id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -83,11 +78,7 @@ impl fmt::Debug for OriginalRoad {
|
|||||||
|
|
||||||
impl fmt::Display for OriginalIntersection {
|
impl fmt::Display for OriginalIntersection {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(f, "OriginalIntersection({})", self.osm_node_id)
|
||||||
f,
|
|
||||||
"OriginalIntersection(https://www.openstreetmap.org/node/{})",
|
|
||||||
self.osm_node_id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl fmt::Debug for OriginalIntersection {
|
impl fmt::Debug for OriginalIntersection {
|
||||||
@ -98,11 +89,7 @@ impl fmt::Debug for OriginalIntersection {
|
|||||||
|
|
||||||
impl fmt::Display for OriginalBuilding {
|
impl fmt::Display for OriginalBuilding {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(f, "OriginalBuilding({}", self.osm_id)
|
||||||
f,
|
|
||||||
"OriginalBuilding(https://www.openstreetmap.org/way/{})",
|
|
||||||
self.osm_way_id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl fmt::Debug for OriginalBuilding {
|
impl fmt::Debug for OriginalBuilding {
|
||||||
@ -111,6 +98,23 @@ impl fmt::Debug for OriginalBuilding {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl OriginalIntersection {
|
||||||
|
pub fn new(id: i64) -> OriginalIntersection {
|
||||||
|
OriginalIntersection {
|
||||||
|
osm_node_id: osm::NodeID(id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl OriginalRoad {
|
||||||
|
pub fn new(way: i64, (i1, i2): (i64, i64)) -> OriginalRoad {
|
||||||
|
OriginalRoad {
|
||||||
|
osm_way_id: osm::WayID(way),
|
||||||
|
i1: OriginalIntersection::new(i1),
|
||||||
|
i2: OriginalIntersection::new(i2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RawMap {
|
impl RawMap {
|
||||||
pub fn blank(city_name: &str, name: &str) -> RawMap {
|
pub fn blank(city_name: &str, name: &str) -> RawMap {
|
||||||
RawMap {
|
RawMap {
|
||||||
@ -144,7 +148,7 @@ impl RawMap {
|
|||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_osm_node_id(&self, start: i64) -> i64 {
|
pub fn new_osm_node_id(&self, start: i64) -> osm::NodeID {
|
||||||
assert!(start < 0);
|
assert!(start < 0);
|
||||||
// Slow, but deterministic.
|
// Slow, but deterministic.
|
||||||
let mut osm_node_id = start;
|
let mut osm_node_id = start;
|
||||||
@ -152,29 +156,27 @@ impl RawMap {
|
|||||||
if self
|
if self
|
||||||
.intersections
|
.intersections
|
||||||
.keys()
|
.keys()
|
||||||
.any(|i| i.osm_node_id == osm_node_id)
|
.any(|i| i.osm_node_id.0 == osm_node_id)
|
||||||
{
|
{
|
||||||
osm_node_id -= 1;
|
osm_node_id -= 1;
|
||||||
} else {
|
} else {
|
||||||
return osm_node_id;
|
return osm::NodeID(osm_node_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Almost gone...
|
// TODO Almost gone...
|
||||||
pub fn new_osm_way_id(&self, start: i64) -> i64 {
|
pub fn new_osm_way_id(&self, start: i64) -> osm::WayID {
|
||||||
assert!(start < 0);
|
assert!(start < 0);
|
||||||
// Slow, but deterministic.
|
// Slow, but deterministic.
|
||||||
let mut osm_way_id = start;
|
let mut osm_way_id = start;
|
||||||
loop {
|
loop {
|
||||||
if self.roads.keys().any(|r| r.osm_way_id == osm_way_id)
|
// TODO Only checks roads, doesn't handle collisions with buildings, areas, parking
|
||||||
|| self.buildings.keys().any(|b| b.osm_way_id == osm_way_id)
|
// lots
|
||||||
|| self.areas.iter().any(|a| a.osm_id == osm_way_id)
|
if self.roads.keys().any(|r| r.osm_way_id.0 == osm_way_id) {
|
||||||
|| self.parking_lots.iter().any(|a| a.osm_id == osm_way_id)
|
|
||||||
{
|
|
||||||
osm_way_id -= 1;
|
osm_way_id -= 1;
|
||||||
} else {
|
} else {
|
||||||
return osm_way_id;
|
return osm::WayID(osm_way_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,13 +368,13 @@ pub struct RawArea {
|
|||||||
pub area_type: AreaType,
|
pub area_type: AreaType,
|
||||||
pub polygon: Polygon,
|
pub polygon: Polygon,
|
||||||
pub osm_tags: Tags,
|
pub osm_tags: Tags,
|
||||||
pub osm_id: i64,
|
pub osm_id: osm::OsmID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct RawParkingLot {
|
pub struct RawParkingLot {
|
||||||
pub polygon: Polygon,
|
pub polygon: Polygon,
|
||||||
pub osm_id: i64,
|
pub osm_id: osm::OsmID,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
@ -454,7 +456,7 @@ impl DrivingSide {
|
|||||||
pub struct RawBusRoute {
|
pub struct RawBusRoute {
|
||||||
pub full_name: String,
|
pub full_name: String,
|
||||||
pub short_name: String,
|
pub short_name: String,
|
||||||
pub osm_rel_id: i64,
|
pub osm_rel_id: osm::RelationID,
|
||||||
pub gtfs_trip_marker: Option<String>,
|
pub gtfs_trip_marker: Option<String>,
|
||||||
// If not, light rail
|
// If not, light rail
|
||||||
pub is_bus: bool,
|
pub is_bus: bool,
|
||||||
|
@ -355,7 +355,7 @@ impl IntersectionSimState {
|
|||||||
if !queue.try_to_reserve_entry(
|
if !queue.try_to_reserve_entry(
|
||||||
car,
|
car,
|
||||||
!self.dont_block_the_box
|
!self.dont_block_the_box
|
||||||
|| allow_block_the_box(map.get_i(turn.parent).orig_id.osm_node_id)
|
|| allow_block_the_box(map.get_i(turn.parent).orig_id.osm_node_id.0)
|
||||||
|| inside_ut,
|
|| inside_ut,
|
||||||
) {
|
) {
|
||||||
if self.break_turn_conflict_cycles {
|
if self.break_turn_conflict_cycles {
|
||||||
|
Loading…
Reference in New Issue
Block a user