@@ -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