Skip to content

Commit

Permalink
docstring & typehints in simplify.network_simplify(), etc. (#107)
Browse files Browse the repository at this point in the history
* docstring from simplify.network_simplify() + others

* return type hint in simplify_network()

* forgot consolidation_tolerance keyword explanation

* martin comments & clarifications
  • Loading branch information
jGaboardi authored Nov 26, 2024
1 parent 0a948d0 commit 05ab52c
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 49 deletions.
28 changes: 14 additions & 14 deletions sgeop/artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@

def get_artifacts(
roads: gpd.GeoDataFrame,
threshold: None | float = None,
threshold_fallback: None | float = None,
area_threshold_blocks: float = 1e5,
isoareal_threshold_blocks: float = 0.5,
area_threshold_circles: float = 5e4,
isoareal_threshold_circles_enclosed: float = 0.75,
isoperimetric_threshold_circles_touching: float = 0.9,
threshold: None | float | int = None,
threshold_fallback: None | float | int = None,
area_threshold_blocks: float | int = 1e5,
isoareal_threshold_blocks: float | int = 0.5,
area_threshold_circles: float | int = 5e4,
isoareal_threshold_circles_enclosed: float | int = 0.75,
isoperimetric_threshold_circles_touching: float | int = 0.9,
exclusion_mask: None | gpd.GeoSeries = None,
predicate: str = "intersects",
) -> tuple[gpd.GeoDataFrame, float]:
Expand All @@ -40,24 +40,24 @@ def get_artifacts(
----------
roads : geopandas.GeoDataFrame
Input roads that have been preprocessed.
threshold : None | float = None
threshold : None | float | int = None
First option threshold used to determine face artifacts. See the
``artifact_threshold`` keyword argument in ``simplify.simplify_network()``.
threshold_fallback : None | float = None
threshold_fallback : None | float | int = None
Second option threshold used to determine face artifacts. See the
``artifact_threshold_fallback`` keyword argument in
``simplify.simplify_network()``.
area_threshold_blocks : float = 1e5
area_threshold_blocks : float | int = 1e5
Areal theshold for block detection.
isoareal_threshold_blocks : float = 0.5
isoareal_threshold_blocks : float | int = 0.5
Isoareal theshold for block detection.
See ``esda.shape.isoareal_quotient``.
area_threshold_circles : float = 5e4
area_threshold_circles : float | int = 5e4
Areal theshold for circle detection.
isoareal_threshold_circles_enclosed : float = 0.75
isoareal_threshold_circles_enclosed : float | int = 0.75
Isoareal theshold for enclosed circle detection.
See ``esda.shape.isoareal_quotient``.
isoperimetric_threshold_circles_touching : float = 0.9
isoperimetric_threshold_circles_touching : float | int = 0.9
Isoperimetric theshold for enclosed circle touching.
See ``esda.shape.isoperimetric_quotient``.
exclusion_mask : None | gpd.GeoSeries = None
Expand Down
4 changes: 2 additions & 2 deletions sgeop/continuity.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ def get_stroke_info(
Parameters
----------
artifacts : GeoSeries | GeoDataFrame
artifacts : geopandas.GeoSeries | geopandas.GeoDataFrame
Polygons representing the artifacts.
roads : GeoSeries | GeoDataFrame
roads : geopandas.GeoSeries | geopandas.GeoDataFrame
LineStrings representing the road network.
Returns
Expand Down
14 changes: 7 additions & 7 deletions sgeop/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ def voronoi_skeleton(
lines: list | np.ndarray | gpd.GeoSeries,
poly: None | shapely.Polygon = None,
snap_to: None | gpd.GeoSeries = None,
max_segment_length: int = 1,
max_segment_length: float | int = 1,
buffer: None | float | int = None,
secondary_snap_to: None | gpd.GeoSeries = None,
clip_limit: None | int = 2,
consolidation_tolerance: None | float = None,
clip_limit: None | float | int = 2,
consolidation_tolerance: None | float | int = None,
) -> tuple[np.ndarray]:
"""
Returns average geometry.
Expand All @@ -117,20 +117,20 @@ def voronoi_skeleton(
Polygon enclosed by ``lines``.
snap_to : None | gpd.GeoSeries = None
Series of geometries that shall be connected to the skeleton.
max_segment_length: int = 1
max_segment_length: float | int = 1
Additional vertices will be added so that all line segments
are no longer than this value. Must be greater than 0.
buffer : None | float | int = None
Optional custom buffer distance for dealing with Voronoi infinity issues.
secondary_snap_to : None | gpd.GeoSeries = None
Fall-back series of geometries that shall be connected to the skeleton.
clip_limit : None | int = 2
clip_limit : None | float | int = 2
Following generation of the Voronoi linework, we clip to fit inside the polygon.
To ensure we get a space to make proper topological connections from the
linework to the actual points on the edge of the polygon, we clip using a
polygon with a negative buffer of ``clip_limit`` or the radius of
maximum inscribed circle, whichever is smaller.
consolidation_tolerance : None | float = None
consolidation_tolerance : None | float | int = None
Tolerance passed to node consolidation within the resulting skeleton.
If ``None``, no consolidation happens.
Expand Down Expand Up @@ -291,7 +291,7 @@ def _as_parts(edgelines: np.ndarray) -> np.ndarray:


def _consolidate(
edgelines: np.ndarray, consolidation_tolerance: float | int
edgelines: np.ndarray, consolidation_tolerance: None | float | int
) -> np.ndarray:
"""Return ``edgelines`` from consolidated nodes, if criteria met."""
if consolidation_tolerance and edgelines.shape[0] > 0:
Expand Down
96 changes: 70 additions & 26 deletions sgeop/simplify.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,39 +469,83 @@ def get_solution(group, roads):


def simplify_network(
roads,
roads: gpd.GeoDataFrame,
*,
max_segment_length=1,
min_dangle_length=20,
clip_limit: int = 2,
simplification_factor=2,
consolidation_tolerance=10,
artifact_threshold=None,
artifact_threshold_fallback=None,
area_threshold_blocks=1e5,
isoareal_threshold_blocks=0.5,
area_threshold_circles=5e4,
isoareal_threshold_circles_enclosed=0.75,
isoperimetric_threshold_circles_touching=0.9,
eps=1e-4,
exclusion_mask=None,
predicate="intersects",
):
"""
max_segment_length: float | int = 1,
min_dangle_length: float | int = 20,
clip_limit: float | int = 2,
simplification_factor: float | int = 2,
consolidation_tolerance: float | int = 10,
artifact_threshold: None | float | int = None,
artifact_threshold_fallback: None | float | int = None,
area_threshold_blocks: float | int = 1e5,
isoareal_threshold_blocks: float | int = 0.5,
area_threshold_circles: float | int = 5e4,
isoareal_threshold_circles_enclosed: float | int = 0.75,
isoperimetric_threshold_circles_touching: float | int = 0.9,
eps: float = 1e-4,
exclusion_mask: None | gpd.GeoSeries = None,
predicate: str = "intersects",
) -> gpd.GeoDataFrame:
"""Top-level workflow for simplifying networks. The input raw road network data is
first preprocessed (topological corrections & node consolidation) before two
iterations of artifact detection and simplification. For further information on
face artifact detection and extraction see :cite:`fleischmann2023`.
Parameters
----------
clip_limit : int = 2
Following generation of the Voronoi linework in ``geometry.voronoi_skeleton()``,
we clip to fit inside the polygon. To ensure we get a space to make proper
topological connections from the linework to the actual points on the edge of
the polygon, we clip using a polygon with a negative buffer of ``clip_limit``
or the radius of maximum inscribed circle, whichever is smaller.
roads : geopandas.GeoDataFrame
Raw road network data.
max_segment_length : float | int = 1
Additional vertices will be added so that all line segments
are no longer than this value. Must be greater than 0.
Used in multiple internal geometric operations.
min_dangle_length : float | int
The threshold for determining if linestrings are dangling slivers to be
removed or not.
clip_limit : float | int = 2
Following generation of the Voronoi linework, we clip to fit inside the
polygon. To ensure we get a space to make proper topological connections
from the linework to the actual points on the edge of the polygon, we clip
using a polygon with a negative buffer of ``clip_limit`` or the radius of
maximum inscribed circle, whichever is smaller.
simplification_factor : float | int = 2
The factor by which singles, pairs, and clusters are simplified. The
``max_segment_length`` is multiplied by this factor to get the
simplification epsilon.
consolidation_tolerance : float | int = 10
Tolerance passed to node consolidation when generating Voronoi skeletons.
artifact_threshold : None | float | int = None
When ``artifact_threshold`` is passed, the computed value from
``momepy.FaceArtifacts.threshold`` is not used in favor of the
given value. This is useful for small networks where artifact
detection may fail or become unreliable.
artifact_threshold_fallback : None | float | int = None
If artifact threshold detection fails, this value is used as a fallback.
area_threshold_blocks : float | int = 1e5
Areal theshold for block detection.
isoareal_threshold_blocks : float | int = 0.5
Isoareal theshold for block detection.
See ``esda.shape.isoareal_quotient``.
area_threshold_circles : float | int = 5e4
Areal theshold for circle detection.
isoareal_threshold_circles_enclosed : float | int = 0.75
Isoareal theshold for enclosed circle detection.
See ``esda.shape.isoareal_quotient``.
isoperimetric_threshold_circles_touching : float | int = 0.9
Isoperimetric theshold for enclosed circle touching.
See ``esda.shape.isoperimetric_quotient``.
eps : float = 1e-4
Tolerance epsilon used in multiple internal geometric operations.
exclusion_mask : None | geopandas.GeoSeries = None
Polygons used to determine face artifacts to exclude from returned output.
predicate : str = 'intersects'
The spatial predicate used to exclude face artifacts from returned output.
Returns
-------
geopandas.GeoDataFrame
The final, simplified road network line data.
"""

roads = fix_topology(roads, eps=eps)
Expand Down

0 comments on commit 05ab52c

Please sign in to comment.