Skip to content

Commit

Permalink
Store movements in Intersections and add a debug layer showing them
Browse files Browse the repository at this point in the history
  • Loading branch information
BudgieInWA committed Oct 20, 2022
1 parent 6b6fb7a commit 0dc5a0b
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 11 deletions.
7 changes: 7 additions & 0 deletions osm2streets-js/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ impl JsStreetNetwork {
.debug_clockwise_ordering_geojson(&mut Timer::throwaway())
.unwrap()
}

#[wasm_bindgen(js_name = debugMovementsGeojson)]
pub fn debug_movements_geojson(&self) -> String {
self.inner
.debug_movements_geojson(&mut Timer::throwaway())
.unwrap()
}
}

#[wasm_bindgen]
Expand Down
5 changes: 4 additions & 1 deletion osm2streets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ pub use self::lanes::{
};
pub use self::transform::Transformation;
pub use self::types::{
ConflictType, ControlType, DrivingSide, IntersectionComplexity, MapConfig, NamePerLanguage,
ConflictType, ControlType, DrivingSide, IndexedMovement, IntersectionComplexity, MapConfig,
NamePerLanguage,
};

mod edit;
Expand Down Expand Up @@ -623,6 +624,7 @@ pub struct Intersection {
/// All roads connected to this intersection. They may be incoming or outgoing relative to this
/// intersection. They're ordered clockwise aroundd the intersection.
pub roads: Vec<OriginalRoad>,
pub movements: Vec<IndexedMovement>,

// true if src_i matches this intersection (or the deleted/consolidated one, whatever)
pub trim_roads_for_merging: BTreeMap<(osm::WayID, bool), Pt2D>,
Expand All @@ -642,6 +644,7 @@ impl Intersection {
control,
// Filled out later
roads: Vec::new(),
movements: Vec::new(),
elevation: Distance::ZERO,
trim_roads_for_merging: BTreeMap::new(),
}
Expand Down
39 changes: 39 additions & 0 deletions osm2streets/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,45 @@ impl StreetNetwork {
let output = serde_json::to_string_pretty(&obj)?;
Ok(output)
}

/// For an intersection, show all the movements.
pub fn debug_movements_geojson(&self, timer: &mut Timer) -> Result<String> {
let initial_map = crate::initial::InitialMap::new(self, timer);

let mut pairs = Vec::new();

for (i, intersection) in &self.intersections {
// Find the endpoints
let road_points: Vec<_> = intersection
.roads
.iter()
.map(|r| {
let pl = &initial_map.roads[r].trimmed_center_pts;
let pt = if r.i1 == *i {
pl.first_pt()
} else {
pl.last_pt()
};
pt
})
.collect();
for (a, b) in intersection.movements.iter() {
if *a != *b {
pairs.push((
Line::must_new(road_points[*a], road_points[*b])
.to_polyline()
.make_arrow(Distance::meters(0.3), ArrowCap::Triangle)
.to_geojson(Some(&self.gps_bounds)),
make_props(&[]),
))
}
}
}

let obj = geom::geometries_with_properties_to_geojson(pairs);
let output = serde_json::to_string_pretty(&obj)?;
Ok(output)
}
}

impl DebugStreets {
Expand Down
21 changes: 12 additions & 9 deletions osm2streets/src/transform/classify_intersections.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::osm::NodeID;
use crate::types::IndexedMovement;
use crate::IntersectionComplexity::*;
use crate::{
ConflictType, IntersectionComplexity, OriginalRoad, RestrictionType, Road, StreetNetwork,
Expand All @@ -9,17 +10,18 @@ use std::collections::BTreeMap;
/// Determines the initial complexity of all intersections. Intersections marked "Crossing" are
/// considered "unclassified" and will be updated with a guess, others will be left unchanged.
pub fn classify_intersections(streets: &mut StreetNetwork) {
let mut changes: Vec<(NodeID, (IntersectionComplexity, ConflictType))> = Vec::new();
let mut changes: Vec<_> = Vec::new();
for (id, inter) in &streets.intersections {
if let Crossing = inter.complexity {
changes.push((*id, guess_complexity(streets, id)));
}
}

for (id, complexity) in changes.into_iter() {
for (id, (complexity, conflict_level, movements)) in changes.into_iter() {
let intersection = streets.intersections.get_mut(&id).unwrap();
intersection.complexity = complexity.0;
intersection.conflict_level = complexity.1;
intersection.complexity = complexity;
intersection.conflict_level = conflict_level;
intersection.movements = movements;
}
}

Expand All @@ -29,7 +31,7 @@ pub fn classify_intersections(streets: &mut StreetNetwork) {
fn guess_complexity(
streets: &StreetNetwork,
intersection_id: &NodeID,
) -> (IntersectionComplexity, ConflictType) {
) -> (IntersectionComplexity, ConflictType, Vec<IndexedMovement>) {
use ConflictType::*;
let road_ids = streets.roads_per_intersection(*intersection_id);
let roads: Vec<&Road> = road_ids
Expand All @@ -39,12 +41,13 @@ fn guess_complexity(

// A terminus is characterised by a single connected road.
if road_ids.len() == 1 {
return (Terminus, Uncontested);
return (Terminus, Uncontested, vec![(0, 0)]);
}

// A Connection is characterised by exactly two connected roads.
if road_ids.len() == 2 {
return (Connection, Uncontested);
// TODO check directions of roads and determine movements and if it is well formed etc.
return (Connection, Uncontested, vec![(0, 1), (1, 0)]);
}

// Calculate all the possible movements, except (U-turns).
Expand Down Expand Up @@ -79,8 +82,8 @@ fn guess_complexity(
}

match worst_conflict {
Cross => (Crossing, Cross),
c => (MultiConnection, c),
Cross => (Crossing, Cross, connections),
c => (MultiConnection, c, connections),
}
}

Expand Down
4 changes: 4 additions & 0 deletions osm2streets/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,7 @@ pub enum ControlType {
Border, //TODO move to using IntersectionComplexity::MapEdge
Construction, // Are these treated as "closed"?
}

/// The path that some lanes of traffic can take through an intersection.
/// This representation is the (from, to) roads, identified by their index in the Intersection.
pub type IndexedMovement = (usize, usize);
4 changes: 3 additions & 1 deletion street-explorer/www/js/layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ export const makeDotLayer = async (text, { bounds }) => {
export const makeDebugLayer = (text) => {
return new L.geoJSON(JSON.parse(text), {
onEachFeature: function (feature, layer) {
layer.bindTooltip(feature.properties.label, { permanent: true });
if (feature.properties.label) {
layer.bindTooltip(feature.properties.label, { permanent: true });
}
},
});
};
Expand Down
3 changes: 3 additions & 0 deletions street-explorer/www/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ function importOSM(groupName, app, osmXML, drivingSide, addOSMLayer) {
group.addLazyLayer("Debug road ordering", () =>
makeDebugLayer(network.debugClockwiseOrderingGeojson())
);
group.addLazyLayer("Debug movements", () =>
makeDebugLayer(network.debugMovementsGeojson())
);
// TODO Graphviz hits `ReferenceError: can't access lexical declaration 'graph' before initialization`

const numDebugSteps = network.getDebugSteps().length;
Expand Down

0 comments on commit 0dc5a0b

Please sign in to comment.