(mut graph: GeometryGraph<D>, tolerance: f64)
| 328 | } |
| 329 | |
| 330 | fn snap_graph_grid<D>(mut graph: GeometryGraph<D>, tolerance: f64) -> GeometryGraph<D> |
| 331 | where |
| 332 | D: EdgeType, |
| 333 | { |
| 334 | let mut index = GraphKdTree::new(2); |
| 335 | let mut nodes_to_remove = Vec::new(); |
| 336 | for node_idx in graph.node_indices() { |
| 337 | let snapped_coord = snap_coord_grid(graph[node_idx].0, tolerance); |
| 338 | |
| 339 | // Check if there's already a node that has been snapped to that point, if so, snap the two |
| 340 | // together in a way that properly adjusts their adjacencies. |
| 341 | let mut already_snapped = None; |
| 342 | let snapped_coords = [snapped_coord.x, snapped_coord.y]; |
| 343 | let nearest = index |
| 344 | .within(&snapped_coords, tolerance / 2.0, &squared_euclidean) |
| 345 | .unwrap(); |
| 346 | for (_distance, node_idx) in nearest { |
| 347 | if graph[*node_idx].0 == snapped_coord { |
| 348 | already_snapped = Some(node_idx); |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | if let Some(already_snapped) = already_snapped { |
| 353 | nodes_to_remove.push(node_idx); |
| 354 | snap_graph_nodes(&mut graph, node_idx, *already_snapped); |
| 355 | } else { |
| 356 | index.add(snapped_coords, node_idx).unwrap(); |
| 357 | graph[node_idx].0 = snapped_coord; |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | // Removing nodes invalidates any existing indices >= the removed index, so remove nodes from |
| 362 | // greater to smaller, so that smaller indices aren't invalidated by the removal |
| 363 | nodes_to_remove.sort_unstable(); |
| 364 | for node_idx in nodes_to_remove.into_iter().rev() { |
| 365 | graph.remove_node(node_idx); |
| 366 | } |
| 367 | graph |
| 368 | } |
| 369 | |
| 370 | #[cfg(test)] |
| 371 | mod tests { |
no test coverage detected