Skip to content

Commit 554326a

Browse files
committed
Fix the tessellation retry
1 parent b52cba2 commit 554326a

4 files changed

Lines changed: 649 additions & 101 deletions

File tree

city2graph/morphology.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,7 @@ def _create_and_filter_tessellation(
17511751
context,
17521752
distance,
17531753
segments_filtered,
1754+
reason="could not be created (barriers enclose no area)",
17541755
)
17551756

17561757
tessellation = tessellation.rename(columns={"tess_id": _PLACE_ID_COL})
@@ -1818,6 +1819,7 @@ def _create_and_filter_tessellation(
18181819
context,
18191820
distance,
18201821
segments_filtered,
1822+
reason="retained no cells after filtering",
18211823
)
18221824

18231825
return tessellation
@@ -1851,6 +1853,12 @@ def _include_unenclosed_building_tessellation(
18511853
if missing_buildings.empty:
18521854
return tessellation
18531855

1856+
logger.warning(
1857+
"Enclosed tessellation covers no cell for %d of %d eligible buildings; "
1858+
"adding building-footprint fallback cells.",
1859+
len(missing_buildings),
1860+
len(buildings_gdf),
1861+
)
18541862
tessellation = tessellation.copy()
18551863
if "enclosure_index" in tessellation.columns:
18561864
tessellation["enclosure_index"] = tessellation["enclosure_index"].astype(str)
@@ -1987,6 +1995,7 @@ def _fallback_tessellation_without_enclosures(
19871995
context: _MorphologyContext,
19881996
distance: float | None,
19891997
segments_filtered: gpd.GeoDataFrame,
1998+
reason: str = "produced no usable cells",
19901999
) -> gpd.GeoDataFrame:
19912000
"""
19922001
Build place cells from building footprints when enclosed tessellation fails.
@@ -2005,6 +2014,9 @@ def _fallback_tessellation_without_enclosures(
20052014
Maximum network distance for a cell to be retained.
20062015
segments_filtered : geopandas.GeoDataFrame
20072016
Reachable movement segments used for the network-distance filters.
2017+
reason : str, optional
2018+
Why the enclosed tessellation is unavailable, used in the warning log
2019+
so operators can tell the failure paths apart.
20082020
20092021
Returns
20102022
-------
@@ -2034,6 +2046,11 @@ def _fallback_tessellation_without_enclosures(
20342046
context.extent_buffer,
20352047
field=context.field,
20362048
)
2049+
logger.warning(
2050+
"Enclosed tessellation %s; using %d building-footprint fallback cells.",
2051+
reason,
2052+
len(tessellation),
2053+
)
20372054
if context.keep_buildings:
20382055
tessellation = _add_building_info(tessellation, buildings)
20392056
else:
@@ -2245,9 +2262,18 @@ def _prepare_barriers(
22452262
if geom_col and geom_col in segments.columns and geom_col != "geometry":
22462263
# The alternative column may be object-dtype (e.g. after assigning
22472264
# None values or a parquet round trip), so coerce it to a GeoSeries.
2265+
barrier_series = gpd.GeoSeries(segments[geom_col], index=segments.index)
2266+
if segments.crs is not None:
2267+
if barrier_series.crs is None:
2268+
barrier_series = barrier_series.set_crs(segments.crs)
2269+
elif barrier_series.crs != segments.crs:
2270+
# to_crs() on a GeoDataFrame only reprojects the active
2271+
# geometry column, so a barrier column created before the
2272+
# reprojection keeps its original CRS.
2273+
barrier_series = barrier_series.to_crs(segments.crs)
22482274
barriers = gpd.GeoDataFrame(
22492275
segments.drop(columns=["geometry"]),
2250-
geometry=gpd.GeoSeries(segments[geom_col], index=segments.index, crs=segments.crs),
2276+
geometry=barrier_series,
22512277
crs=segments.crs,
22522278
)
22532279
else:

0 commit comments

Comments
 (0)