Skip to content

Commit

Permalink
tweaks default cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
songololo committed Nov 25, 2024
1 parent ef0de3a commit 2544b8c
Show file tree
Hide file tree
Showing 21 changed files with 74 additions and 49 deletions.
23 changes: 3 additions & 20 deletions docs/plots/plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
buffer = 1250
poly_wgs, _ = io.buffered_point_poly(lng, lat, buffer)
graph_raw = io.osm_graph_from_poly(poly_wgs, simplify=False)
graph_utm = io.osm_graph_from_poly(poly_wgs, simplify=True, iron_edges=True)
graph_utm = io.osm_graph_from_poly(poly_wgs, simplify=True)
# plot buffer
buffered_point, _ = io.buffered_point_poly(lng, lat, 750, projected=True)
min_x, min_y, max_x, max_y = buffered_point.bounds
Expand All @@ -116,25 +116,8 @@ def simple_plot(_G, _path, plot_geoms=True):
)


simple_plot(graph_raw, f"{IMAGES_PATH}/graph_cleaning_1.{FORMAT}", plot_geoms=False)
simple_plot(graph_utm, f"{IMAGES_PATH}/graph_cleaning_1b.{FORMAT}")

graph_utm = graphs.nx_simple_geoms(graph_raw)
graph_utm = graphs.nx_remove_filler_nodes(graph_utm)
graph_utm = graphs.nx_remove_dangling_nodes(graph_utm, despine=15, remove_disconnected=10)
simple_plot(graph_utm, f"{IMAGES_PATH}/graph_cleaning_2.{FORMAT}")
# first pass of consolidation
graph_utm = graphs.nx_consolidate_nodes(graph_utm, buffer_dist=15, crawl=True)
simple_plot(graph_utm, f"{IMAGES_PATH}/graph_cleaning_3.{FORMAT}")
# split opposing line geoms to facilitate parallel merging
graph_utm = graphs.nx_split_opposing_geoms(graph_utm, buffer_dist=15)
simple_plot(graph_utm, f"{IMAGES_PATH}/graph_cleaning_4.{FORMAT}")
# second pass of consolidation
graph_utm = graphs.nx_consolidate_nodes(graph_utm, buffer_dist=15, crawl=False, neighbour_policy="indirect")
simple_plot(graph_utm, f"{IMAGES_PATH}/graph_cleaning_5.{FORMAT}")
# iron edges
graph_utm = graphs.nx_iron_edges(graph_utm)
simple_plot(graph_utm, f"{IMAGES_PATH}/graph_cleaning_6.{FORMAT}")
simple_plot(graph_raw, f"{IMAGES_PATH}/graph_raw.{FORMAT}")
simple_plot(graph_utm, f"{IMAGES_PATH}/graph_clean.{FORMAT}")
# LAYERS MODULE
# show assignment to network
# random seed 25
Expand Down
Binary file modified docs/public/images/assignment.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/assignment_decomposed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/assignment_plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/betas.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/images/graph_clean.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/graph_colour.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/graph_decomposed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/graph_dual.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/graph_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/images/graph_raw.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/graph_simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/intro_mixed_uses.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/public/images/intro_segment_harmonic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 9 additions & 13 deletions docs/src/pages/rustalgos/rustalgos.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ Overriding the default $w_{min}$ will adjust the $d_{max}$ accordingly, for exam
</div>
<span class="pt">)-&gt;[</span>
<span class="pr">list[int]</span>
<span class="pr">list[float</span>
<span class="pr">list[float]</span>
<span class="pt">]</span>
</div>
</div>
Expand Down Expand Up @@ -1903,7 +1903,7 @@ datapoints are not located with high spatial precision.
</div>
<span class="pt">)-&gt;[</span>
<span class="pr">list[int]</span>
<span class="pr">NodeVisit</span>
<span class="pr">NodeVisit]</span>
<span class="pt">]</span>
</div>
</div>
Expand Down Expand Up @@ -1940,7 +1940,7 @@ datapoints are not located with high spatial precision.
</div>
<span class="pt">)-&gt;[</span>
<span class="pr">list[int]</span>
<span class="pr">NodeVisit</span>
<span class="pr">NodeVisit]</span>
<span class="pt">]</span>
</div>
</div>
Expand Down Expand Up @@ -1979,7 +1979,7 @@ datapoints are not located with high spatial precision.
<span class="pr">list[int]</span>
<span class="pr">list[int]</span>
<span class="pr">NodeVisit]</span>
<span class="pr">EdgeVisit</span>
<span class="pr">EdgeVisit]</span>
<span class="pt">]</span>
</div>
</div>
Expand Down Expand Up @@ -2807,22 +2807,22 @@ datapoints are not located with high spatial precision.



<span class="name">node_xys</span><span class="annotation">: list[tuple[float, float]]</span>
<span class="name">node_ys</span><span class="annotation">: list[float]</span>




<span class="name">node_xs</span><span class="annotation">: list[float]</span>
<span class="name">node_lives</span><span class="annotation">: list[bool]</span>




<span class="name">node_ys</span><span class="annotation">: list[float]</span>
<span class="name">node_xs</span><span class="annotation">: list[float]</span>




<span class="name">node_lives</span><span class="annotation">: list[bool]</span>
<span class="name">node_xys</span><span class="annotation">: list[tuple[float, float]]</span>



Expand Down Expand Up @@ -2999,7 +2999,6 @@ datapoints are not located with high spatial precision.
<span class="pa"> bool = False</span>
</div>
<span class="pt">)-&gt;[</span>
<span class="pr">Union[Buffer</span>
<span class="pr">Any]]</span>
<span class="pr">Any]]]</span>
<span class="pr">bool</span>
Expand All @@ -3009,7 +3008,6 @@ datapoints are not located with high spatial precision.
<span class="pr">str</span>
<span class="pr">bytes</span>
<span class="pr">_NestedSequence[bool | int | float | complex | str | bytes]]</span>
<span class="pr">Union[Buffer</span>
<span class="pr">Any]]</span>
<span class="pr">Any]]]</span>
<span class="pr">bool</span>
Expand All @@ -3019,7 +3017,6 @@ datapoints are not located with high spatial precision.
<span class="pr">str</span>
<span class="pr">bytes</span>
<span class="pr">_NestedSequence[bool | int | float | complex | str | bytes]]</span>
<span class="pr">Union[Buffer</span>
<span class="pr">Any]]</span>
<span class="pr">Any]]]</span>
<span class="pr">bool</span>
Expand All @@ -3028,7 +3025,7 @@ datapoints are not located with high spatial precision.
<span class="pr">complex</span>
<span class="pr">str</span>
<span class="pr">bytes</span>
<span class="pr">_NestedSequence[bool | int | float | complex | str | bytes</span>
<span class="pr">_NestedSequence[bool | int | float | complex | str | bytes]]</span>
<span class="pt">]</span>
</div>
</div>
Expand Down Expand Up @@ -3072,7 +3069,6 @@ datapoints are not located with high spatial precision.
<span class="pa"> bool = False</span>
</div>
<span class="pt">)-&gt;[</span>
<span class="pr">Union[Buffer</span>
<span class="pr">dtype[Any]]</span>
<span class="pr">dtype[Any]]]</span>
<span class="pr">bool</span>
Expand Down
36 changes: 33 additions & 3 deletions docs/src/pages/tools/graphs.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,21 @@ side-effects as a function of varied node intensities when computing network cen


<div class="content">
<span class="name">nx_iron_edges</span><div class="signature">
<span class="name">nx_iron_edges</span><div class="signature multiline">
<span class="pt">(</span>
<div class="param">
<span class="pn">nx_multigraph</span>
</div>
<div class="param">
<span class="pn">simplify_by_angle</span>
<span class="pc">:</span>
<span class="pa"> int = 100</span>
</div>
<div class="param">
<span class="pn">min_self_loop_length</span>
<span class="pc">:</span>
<span class="pa"> int = 100</span>
</div>
<span class="pt">)</span>
</div>
</div>
Expand All @@ -353,6 +363,26 @@ side-effects as a function of varied node intensities when computing network cen
A `networkX` `MultiGraph` in a projected coordinate system, containing `x` and `y` node attributes, and `geom` edge attributes containing `LineString` geoms.</div>
</div>

<div class="param-set">
<div class="def">
<div class="name">simplify_by_angle</div>
<div class="type">int</div>
</div>
<div class="desc">

The maximum angle to permit for a given edge. Angles greater than this will be reduced.</div>
</div>

<div class="param-set">
<div class="def">
<div class="name">min_self_loop_length</div>
<div class="type">int</div>
</div>
<div class="desc">

Maximum self loop length to permit for a given edge.</div>
</div>

### Returns
<div class="param-set">
<div class="def">
Expand Down Expand Up @@ -578,9 +608,9 @@ side-effects as a function of varied node intensities when computing network cen

See the guide on [graph cleaning](/guide#graph-cleaning) for more information.

![Example raw graph from OSM](/images/graph_cleaning_1.png) _The pre-consolidation OSM street network for Soho, London. © OpenStreetMap contributors._
![Example raw graph from OSM](/images/graph_raw.png) _The pre-consolidation OSM street network for Soho, London. © OpenStreetMap contributors._

![Example cleaned graph](/images/graph_cleaning_5.png) _The consolidated OSM street network for Soho, London. © OpenStreetMap contributors._
![Example cleaned graph](/images/graph_clean.png) _The consolidated OSM street network for Soho, London. © OpenStreetMap contributors._

</div>

Expand Down
2 changes: 2 additions & 0 deletions docs/src/pages/tools/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@ layout: ../../layouts/PageLayout.astro
<span class="pt">)-&gt;[</span>
<span class="pr">STRtree</span>
<span class="pr">list[dict[str</span>
<span class="pr">Any]]</span>
<span class="pt">]</span>
</div>
</div>
Expand All @@ -688,6 +689,7 @@ layout: ../../layouts/PageLayout.astro
<span class="pt">)-&gt;[</span>
<span class="pr">STRtree</span>
<span class="pr">list[dict[str</span>
<span class="pr">Any]]</span>
<span class="pt">]</span>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "cityseer"
version = '4.16.4'
version = '4.16.5'
description = "Computational tools for network-based pedestrian-scale urban analysis"
readme = "README.md"
requires-python = ">=3.10, <3.14"
Expand Down
20 changes: 14 additions & 6 deletions pysrc/cityseer/tools/graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ def nx_snap_endpoints(nx_multigraph: MultiGraph) -> MultiGraph:


def nx_iron_edges(
nx_multigraph: MultiGraph,
nx_multigraph: MultiGraph, simplify_by_angle: int = 100, min_self_loop_length: int = 100
) -> MultiGraph:
"""
Simplifies edges.
Expand All @@ -525,6 +525,10 @@ def nx_iron_edges(
nx_multigraph: MultiGraph
A `networkX` `MultiGraph` in a projected coordinate system, containing `x` and `y` node attributes, and `geom`
edge attributes containing `LineString` geoms.
simplify_by_angle: int
The maximum angle to permit for a given edge. Angles greater than this will be reduced.
min_self_loop_length: int
Maximum self loop length to permit for a given edge.
Returns
-------
Expand All @@ -542,15 +546,16 @@ def nx_iron_edges(
for start_nd_key, end_nd_key, edge_idx, edge_data in tqdm(
g_multi_copy.edges(keys=True, data=True), disable=config.QUIET_MODE
):
edge_geom: geometry.LineString = edge_data["geom"]
# only apply to non looping geoms otherwise issues occur
if start_nd_key == end_nd_key:
if start_nd_key == end_nd_key and edge_geom.length < min_self_loop_length:
remove_edges.append((start_nd_key, end_nd_key, edge_idx))
continue
edge_geom: geometry.LineString = edge_data["geom"]
hits = edges_tree.query(edge_geom, predicate="crosses")
if len(hits):
remove_edges.append((start_nd_key, end_nd_key, edge_idx))
continue
line_coords = simplify_line_by_angle(edge_geom.coords, 100)
line_coords = simplify_line_by_angle(edge_geom.coords, simplify_by_angle)
g_multi_copy[start_nd_key][end_nd_key][edge_idx]["geom"] = geometry.LineString(line_coords)
g_multi_copy.remove_edges_from(remove_edges)
# straightening parallel edges can create duplicates
Expand Down Expand Up @@ -746,6 +751,9 @@ def _squash_adjacent(
new_edge_geom = geometry.LineString(line_coords)
if new_edge_geom.length == 0:
continue
# bail if short self loop
if new_nd_name == target_nd_key and new_edge_geom.length < 100:
continue
# check that a duplicate is not being added
dupe = False
if nx_multigraph.has_edge(new_nd_name, target_nd_key):
Expand Down Expand Up @@ -856,10 +864,10 @@ def nx_consolidate_nodes(
--------
See the guide on [graph cleaning](/guide#graph-cleaning) for more information.
![Example raw graph from OSM](/images/graph_cleaning_1.png)
![Example raw graph from OSM](/images/graph_raw.png)
_The pre-consolidation OSM street network for Soho, London. © OpenStreetMap contributors._
![Example cleaned graph](/images/graph_cleaning_5.png)
![Example cleaned graph](/images/graph_clean.png)
_The consolidated OSM street network for Soho, London. © OpenStreetMap contributors._
"""
Expand Down
18 changes: 12 additions & 6 deletions pysrc/cityseer/tools/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,8 @@ def osm_graph_from_poly(
graph_crs = graphs.nx_remove_dangling_nodes(graph_crs, despine=0, remove_disconnected=remove_disconnected)
# clean by highway types - leave motorway and trunk as is
for dist, tags, simplify_line_angles in (
(20, ["primary"], 45), # , "primary_link"
(18, ["primary", "secondary"], 45), # , "secondary_link"
(24, ["primary"], 45), # , "primary_link"
(20, ["primary", "secondary"], 45), # , "secondary_link"
(16, ["primary", "secondary", "tertiary"], 45), # , "tertiary_link"
):
graph_crs = graphs.nx_split_opposing_geoms(
Expand All @@ -453,20 +453,22 @@ def osm_graph_from_poly(
osm_hwy_target_tags=tags,
prioritise_by_hwy_tag=True,
simplify_line_angles=simplify_line_angles,
contains_buffer_dist=50,
)
for dist, tags, simplify_line_angles in (
(20, ["primary"], 95), # , "primary_link"
(18, ["primary", "secondary"], 95), # , "secondary_link"
(24, ["primary"], 95), # , "primary_link"
(20, ["primary", "secondary"], 95), # , "secondary_link"
(16, ["primary", "secondary", "tertiary"], 95), # , "tertiary_link"
):
graph_crs = graphs.nx_consolidate_nodes(
graph_crs,
buffer_dist=dist,
crawl=True,
crawl=False,
centroid_by_itx=True,
osm_hwy_target_tags=tags,
prioritise_by_hwy_tag=True,
simplify_line_angles=simplify_line_angles,
contains_buffer_dist=50,
)
graph_crs = graphs.nx_remove_filler_nodes(graph_crs)
# do smaller scale cleaning
Expand All @@ -479,6 +481,7 @@ def osm_graph_from_poly(
"cycleway",
"bridleway",
"footway",
"footway_pedestrian", # plazas
"path",
"living_street",
"unclassified",
Expand All @@ -495,6 +498,7 @@ def osm_graph_from_poly(
osm_hwy_target_tags=tags,
prioritise_by_hwy_tag=True,
simplify_line_angles=simplify_angles,
contains_buffer_dist=50,
)
graph_crs = graphs.nx_consolidate_nodes(
graph_crs,
Expand All @@ -504,6 +508,7 @@ def osm_graph_from_poly(
osm_hwy_target_tags=tags,
prioritise_by_hwy_tag=True,
simplify_line_angles=simplify_angles,
contains_buffer_dist=50,
)
graph_crs = graphs.nx_remove_filler_nodes(graph_crs)
# snap gapped endings - don't clean danglers before this
Expand All @@ -517,6 +522,7 @@ def osm_graph_from_poly(
"cycleway",
"bridleway",
"footway",
"footway_pedestrian", # plazas
"path",
"living_street",
"unclassified",
Expand All @@ -532,7 +538,7 @@ def osm_graph_from_poly(
squash_nodes=False,
)
# remove longer danglers
graph_crs = graphs.nx_remove_dangling_nodes(graph_crs, despine=20)
graph_crs = graphs.nx_remove_dangling_nodes(graph_crs, despine=50)

return graph_crs

Expand Down

0 comments on commit 2544b8c

Please sign in to comment.