Skip to content

Commit e830230

Browse files
Merge pull request #7 from NREL/rjf/cleanup
Rjf/cleanup
2 parents 9c005cb + 98e645d commit e830230

39 files changed

+790
-1121
lines changed

rust/bambam-osm/src/algorithm/buffer.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
use std::borrow::Cow;
2-
3-
use geo::line_measures::LengthMeasurable;
41
use geo::{
5-
line_string, Centroid, Convert, Coord, CoordFloat, Destination, Distance, GeoFloat, Geometry,
6-
Haversine, KNearestConcaveHull, Length, LineString, Point, Polygon, Scale, TryConvert,
2+
line_string, Centroid, Coord, CoordFloat, Destination, GeoFloat, Geometry, Haversine,
3+
KNearestConcaveHull, Length, LineString, Point, Polygon, Scale,
74
};
85
use itertools::Itertools;
96
use num_traits::FromPrimitive;
10-
use routee_compass_core::model::unit;
11-
use routee_compass_core::model::unit::AsF64;
127

138
pub trait Buffer<F: CoordFloat + FromPrimitive> {
149
/// buffer a geometry up to some distance. GEOS uses a fancier method to determine

rust/bambam-osm/src/algorithm/clustering/clustering_rtree.rs

Lines changed: 4 additions & 206 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
use super::ClusteredGeometry;
2-
use crate::algorithm::bfs_undirected;
3-
use crate::model::osm::graph::OsmGraph;
41
use crate::model::osm::graph::OsmNodeId;
5-
use crate::model::osm::OsmError;
6-
use geo::{BooleanOps, BoundingRect, Geometry, Intersects, Polygon, RemoveRepeatedPoints};
7-
use geo::{Coord, MultiPolygon};
2+
3+
use super::ClusteredGeometry;
4+
use geo::{BoundingRect, Coord, Polygon};
85
use itertools::Itertools;
9-
use kdam::{tqdm, Bar, BarExt};
10-
use rayon::prelude::*;
11-
use routee_compass_core::model::unit::AsF64;
12-
use routee_compass_core::model::unit::DistanceUnit;
6+
use kdam::tqdm;
137
use rstar::primitives::{GeomWithData, Rectangle};
148
use rstar::{RTree, RTreeObject};
15-
use std::collections::HashSet;
16-
use std::collections::{BinaryHeap, HashMap};
17-
use std::sync::Arc;
18-
use std::sync::Mutex;
199
use wkt::ToWkt;
2010

21-
pub type ClusterLabel = usize;
2211
pub type ClusteredIntersections = GeomWithData<Rectangle<(f32, f32)>, ClusteredGeometry>;
2312

2413
/// build an undirected graph of node geometries that intersect spatially.
@@ -75,197 +64,6 @@ pub fn build(
7564
Ok(rtree)
7665
}
7766

78-
// /// merges two geometries by Union that should be either Polygon or MultiPolygon geometries.
79-
// fn merge_areal_geometries(a: &Geometry, b: &Geometry) -> Result<Geometry, String> {
80-
// let unioned: MultiPolygon = match (a, b) {
81-
// (Geometry::Polygon(a), Geometry::Polygon(b)) => Ok(a.union(b)),
82-
// (Geometry::Polygon(p), Geometry::MultiPolygon(mp)) => Ok(p.union(mp)),
83-
// (Geometry::MultiPolygon(mp), Geometry::Polygon(p)) => Ok(mp.union(p)),
84-
// (Geometry::MultiPolygon(a), Geometry::MultiPolygon(b)) => Ok(a.union(b)),
85-
// _ => Err(format!(
86-
// "invalid geometry types \n{} \n{}",
87-
// a.to_wkt(),
88-
// b.to_wkt()
89-
// )),
90-
// }?;
91-
// // Ok(geo::Geometry::MultiPolygon(unioned))
92-
// // let cleaned = unioned.union(&geo::MultiPolygon::new(vec![]));
93-
94-
// let exteriors = unioned
95-
// .remove_repeated_points()
96-
// .iter()
97-
// .map(|p| Polygon::new(p.exterior().clone(), vec![]))
98-
// .collect_vec();
99-
// let no_holes = MultiPolygon::new(exteriors);
100-
// Ok(geo::Geometry::MultiPolygon(no_holes))
101-
// }
102-
103-
// /// in order to simplify the graph, we have to identify nodes that are within
104-
// /// some distance threshold of each other and then also confirm that they are
105-
// /// connected in the graph space (for example, a bridge may not be connected to
106-
// /// the roads beneath it).
107-
// ///
108-
// /// # Arguments
109-
// /// * `indices` - a collection of entity indices that should correspond to
110-
// /// the indices of the undirected graph. can be the complete
111-
// /// collection of indices to find all components, or a subset
112-
// /// in order to identify the disjoint union of sub-subsets that
113-
// /// are connected through the undirected graph.
114-
// /// * `undirected_graph` - all valid indices and their connections. in the
115-
// /// context of OSM import, this may be the graph of
116-
// /// spatial intersections or the graph of network
117-
// /// connections.
118-
// ///
119-
// /// # Returns
120-
// ///
121-
// /// A vector of components, each represented as a set of indices.
122-
// pub fn connected_components_clustering(
123-
// indices: &[OsmNodeId],
124-
// undirected_graph: &[Vec<OsmNodeId>],
125-
// ) -> Result<Vec<HashSet<OsmNodeId>>, OsmError> {
126-
// // handle base cases
127-
// match *indices {
128-
// [] => return Ok(vec![]),
129-
// [singleton] => return Ok(vec![HashSet::from([singleton])]),
130-
// _ => {}
131-
// };
132-
// // connected components (undirected graph)
133-
// // run breadth-first searches from indices that have not yet been assigned a label.
134-
// // labels found in the search become part of the next cluster.
135-
// let mut clusters: Vec<HashSet<OsmNodeId>> = vec![];
136-
// let mut unassigned = indices
137-
// .iter()
138-
// .map(|idx| (*idx, true))
139-
// .collect::<HashMap<_, _>>();
140-
141-
// let valid_set = indices.iter().collect::<HashSet<_>>();
142-
143-
// let cc_iter = tqdm!(
144-
// indices.iter(),
145-
// total = unassigned.len(),
146-
// desc = "connected components"
147-
// );
148-
// for label in cc_iter {
149-
// if unassigned[label] {
150-
// // found a label that is unassigned. begin the next cluster.
151-
// let next_cluster: HashSet<usize> =
152-
// bfs_undirected(*label, undirected_graph, &Some(valid_set)).map_err(|e| {
153-
// OsmError::GraphConsolidationError(format!(
154-
// "failure executing graph search for connected components: {}",
155-
// e
156-
// ))
157-
// })?;
158-
159-
// // for each clustered geometry index, label it assigned and add it to this cluster
160-
// for index in next_cluster.iter() {
161-
// unassigned.entry(*index).and_modify(|val| {
162-
// *val = false;
163-
// });
164-
// }
165-
166-
// clusters.push(next_cluster);
167-
// }
168-
// }
169-
// eprintln!();
170-
// Ok(clusters)
171-
// }
172-
173-
// /// a succession of intersection tests, in increasing order of computational complexity,
174-
// /// for finding geometric intersections.
175-
// fn geometries_intersect(
176-
// a: (usize, &Geometry),
177-
// b: (usize, &Geometry),
178-
// // ns: &Vec<HashSet<usize>>, // todo!: reintroduce this argument, respecting Arc<Mutex<T>>
179-
// ) -> bool {
180-
// let (a_label, a_geom) = a;
181-
// let (b_label, b_geom) = b;
182-
183-
// // simple identifier test. dismiss when row == column on the matrix.
184-
// if a_label == b_label {
185-
// log::debug!(
186-
// "geometries {},{} intersect? TRUE - matching label",
187-
// a_label,
188-
// b_label
189-
// );
190-
// return false;
191-
// }
192-
193-
// // // did we already find a from b?
194-
// // let a_has_already_found_b = ns
195-
// // .get(a_label)
196-
// // .ok_or_else(|| out_of_index_err(b_label, ns))?
197-
// // .contains(&b_label);
198-
// // if a_has_already_found_b {
199-
// // return false;
200-
// // }
201-
202-
// // first geometric test, only using bounding boxes.
203-
// if bbox_intersects(a_geom, b_geom) {
204-
// log::debug!(
205-
// "geometries {},{} intersect? TRUE - bboxes intersect",
206-
// a_label,
207-
// b_label
208-
// );
209-
// return true;
210-
// }
211-
212-
// // final test is a true geometric intersection test (expensive).
213-
// let geometries_intersect = a_geom.intersects(b_geom);
214-
// if geometries_intersect {
215-
// log::debug!(
216-
// "geometries {},{} intersect? TRUE - matching label",
217-
// a_label,
218-
// b_label
219-
// );
220-
// return true;
221-
// } else {
222-
// log::debug!("geometries {},{} intersect? FALSE", a_label, b_label);
223-
// return false;
224-
// }
225-
// }
226-
227-
// fn bbox_intersects(a: &Geometry, b: &Geometry) -> bool {
228-
// let a_box = match a.bounding_rect() {
229-
// Some(bbox) => bbox,
230-
// None => return false,
231-
// };
232-
// let b_box = match b.bounding_rect() {
233-
// Some(bbox) => bbox,
234-
// None => return false,
235-
// };
236-
// a_box.intersects(&b_box)
237-
// }
238-
239-
// fn out_of_index_err(label: usize, ns: &[Vec<usize>]) -> String {
240-
// format!(
241-
// "neighbors expected to have index {} but only has {} elements",
242-
// label,
243-
// ns.len()
244-
// )
245-
// }
246-
247-
// /// finds the set of indices that are part of the same geometry cluster
248-
// /// using a breadth-first search over an undirected graph of geometry
249-
// /// intersection relations.
250-
// fn bfs(src: usize, ns: &[Vec<usize>]) -> Result<HashSet<usize>, String> {
251-
// let mut visited: HashSet<usize> = HashSet::new();
252-
// visited.insert(src);
253-
// let mut frontier: BinaryHeap<(usize, i32)> = BinaryHeap::new();
254-
// frontier.push((src, 0));
255-
// while let Some((next_id, next_depth)) = frontier.pop() {
256-
// visited.insert(next_id);
257-
// let next_neighbors = ns
258-
// .get(next_id)
259-
// .ok_or_else(|| out_of_index_err(next_id, ns))?;
260-
// for neighbor in next_neighbors.iter() {
261-
// if !visited.contains(neighbor) {
262-
// frontier.push((*neighbor, next_depth - 1)); // max heap
263-
// }
264-
// }
265-
// }
266-
// Ok(visited)
267-
// }
268-
26967
/// helper function to create a rectangular rtree envelope for a given geometry
27068
fn rect_from_geometries(ps: &[&Polygon<f32>]) -> Result<Rectangle<(f32, f32)>, String> {
27169
if ps.is_empty() {

rust/bambam-osm/src/algorithm/clustering/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ mod clustered_geometry;
22
mod clustering_rtree;
33

44
pub use clustered_geometry::ClusteredGeometry;
5-
pub use clustering_rtree::{build, ClusterLabel, ClusteredIntersections};
5+
pub use clustering_rtree::{build, ClusteredIntersections};

rust/bambam-osm/src/algorithm/connected_components.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
use crate::model::osm::{
2-
graph::{
3-
AdjacencyDirection, AdjacencyList, AdjacencyListDeprecated, OsmGraph, OsmNodeId, OsmNodes,
4-
},
2+
graph::{OsmGraph, OsmNodeId},
53
OsmError,
64
};
75
use itertools::Itertools;
86
use kdam::{tqdm, Bar, BarExt};
9-
use std::{
10-
collections::{HashMap, HashSet, VecDeque},
11-
io::Write,
12-
time::Duration,
13-
};
7+
use std::collections::{HashMap, HashSet, VecDeque};
148

15-
const PROGRESS_BAR_MIN_SIZE: usize = 1000;
169
pub type UndirectedAdjacencyList = HashMap<OsmNodeId, HashSet<OsmNodeId>>;
1710

1811
pub fn to_undirected(graph: &OsmGraph) -> UndirectedAdjacencyList {
@@ -83,7 +76,7 @@ pub fn weakly_connected_components(
8376
}
8477
solution.push(cluster);
8578
}
86-
bar.update(1);
79+
let _ = bar.update(1);
8780
}
8881
eprintln!();
8982
log::info!("found {} weakly-connected components", solution.len());
@@ -133,11 +126,7 @@ pub fn bfs_undirected(
133126

134127
#[cfg(test)]
135128
mod tests {
136-
use crate::model::osm::graph::{
137-
osm_segment::OsmSegment, AdjacencyDirection, AdjacencyList, AdjacencyList3,
138-
AdjacencyListDeprecated, OsmGraph, OsmNodeData, OsmNodeId, OsmWayData, OsmWayId,
139-
OsmWaysByOd,
140-
};
129+
use crate::model::osm::graph::{OsmGraph, OsmNodeData, OsmNodeId, OsmWayData, OsmWayId};
141130
use std::collections::HashMap;
142131

143132
#[test]
@@ -182,7 +171,7 @@ mod tests {
182171
fn test_bfs_complete_graph_5() {
183172
let source = OsmNodeId(0);
184173
let n_connected_nodes: usize = 5;
185-
let mut nodes = create_nodes_in_circle(n_connected_nodes);
174+
let nodes = create_nodes_in_circle(n_connected_nodes);
186175
let mut ways: HashMap<OsmWayId, OsmWayData> = HashMap::new();
187176

188177
let n_iters = n_connected_nodes as i64;

rust/bambam-osm/src/algorithm/consolidation/consolidation_ops.rs

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,20 @@ use crate::algorithm::*;
33
use crate::model::osm::graph::AdjacencyDirection;
44
use crate::model::osm::graph::OsmNodeData;
55
use crate::model::osm::graph::OsmWayData;
6-
use crate::model::osm::graph::{fill_value_lookup::FillValueLookup, OsmGraph, OsmNodeId};
7-
use crate::model::osm::graph::{AdjacencyListDeprecated, OsmWayId};
6+
use crate::model::osm::graph::OsmWayId;
7+
use crate::model::osm::graph::{OsmGraph, OsmNodeId};
88
use crate::model::osm::OsmError;
99
use clustering::ClusteredIntersections;
10-
use geo::{BooleanOps, BoundingRect, Intersects, Polygon, RemoveRepeatedPoints};
11-
use geo::{Coord, Geometry, Haversine, Length, LineString, MultiPolygon};
10+
use geo::Polygon;
11+
use geo::{Coord, Geometry};
1212
use itertools::Itertools;
1313
use kdam::{term, tqdm, Bar, BarExt};
1414
use rayon::prelude::*;
15-
use routee_compass_core::model::{
16-
network::{Edge, Vertex},
17-
unit::{AsF64, DistanceUnit, SpeedUnit},
18-
};
19-
use rstar::primitives::{GeomWithData, Rectangle};
20-
use rstar::{RTree, RTreeObject};
15+
use rstar::RTree;
16+
use std::collections::HashMap;
2117
use std::collections::HashSet;
22-
use std::collections::LinkedList;
23-
use std::collections::{BinaryHeap, HashMap};
24-
use std::fs::File;
2518
use std::sync::Arc;
2619
use std::sync::Mutex;
27-
use wkt::ToWkt;
2820

2921
/// implements osmnx.simplification.consolidate_intersections with dead_ends=False, rebuild_graph=True,
3022
/// reconnect_edges=True for the given distance tolerance.
@@ -41,7 +33,6 @@ use wkt::ToWkt;
4133
pub fn consolidate_graph(
4234
graph: &mut OsmGraph,
4335
tolerance: uom::si::f64::Length,
44-
ignore_osm_parsing_errors: bool,
4536
) -> Result<(), OsmError> {
4637
// STEP 1
4738
// buffer nodes to passed-in distance and merge overlaps. turn merged nodes
@@ -171,17 +162,17 @@ pub fn buffer_nodes(
171162
result
172163
}
173164

174-
fn get_fill_value(
175-
way: &OsmWayData,
176-
maxspeeds_fill_lookup: &FillValueLookup,
177-
) -> Result<uom::si::f64::Velocity, OsmError> {
178-
let highway_class = way
179-
.get_string_at_field("highway")
180-
.map_err(OsmError::GraphConsolidationError)?;
181-
let avg_speed = maxspeeds_fill_lookup.get(&highway_class);
182-
let result = uom::si::f64::Velocity::new::<uom::si::velocity::kilometer_per_hour>(avg_speed);
183-
Ok(result)
184-
}
165+
// fn get_fill_value(
166+
// way: &OsmWayData,
167+
// maxspeeds_fill_lookup: &FillValueLookup,
168+
// ) -> Result<uom::si::f64::Velocity, OsmError> {
169+
// let highway_class = way
170+
// .get_string_at_field("highway")
171+
// .map_err(OsmError::GraphConsolidationError)?;
172+
// let avg_speed = maxspeeds_fill_lookup.get(&highway_class);
173+
// let result = uom::si::f64::Velocity::new::<uom::si::velocity::kilometer_per_hour>(avg_speed);
174+
// Ok(result)
175+
// }
185176

186177
/// with knowledge of which geometry indices contain spatially-similar nodes,
187178
/// constructs new merged node data for the connected sub-clusters, assigning

rust/bambam-osm/src/algorithm/consolidation/way_consolidation.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
use crate::model::osm::{
2-
graph::{AdjacencyDirection, OsmGraph, OsmNodeId, OsmWayData},
3-
OsmError,
4-
};
5-
use itertools::Itertools;
6-
use serde_json::value::Index;
7-
use std::collections::HashSet;
1+
use crate::model::osm::graph::{AdjacencyDirection, OsmNodeId, OsmWayData};
82

93
/// tracks a way that will be impacted by node consolidation along with the
104
/// source or destination node attached to it.

rust/bambam-osm/src/algorithm/search.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::model::osm::{
2-
graph::{AdjacencyDirection, OsmGraph, OsmNodeId},
2+
graph::{OsmGraph, OsmNodeId},
33
OsmError,
44
};
55
use itertools::Itertools;

0 commit comments

Comments
 (0)