Constrain visible roof grouping to compact clusters
This commit is contained in:
@@ -91,7 +91,7 @@ def _polygonal(geometry: Any) -> Any | None:
|
||||
|
||||
|
||||
def merge_touching_roof_instances(features: list[dict[str, Any]], source_name: str) -> list[dict[str, Any]]:
|
||||
"""Dissolve only touching/overlapping footprints into imagery-visible roof instances."""
|
||||
"""Dissolve only compact touching groups into imagery-visible roof instances."""
|
||||
if not features:
|
||||
return []
|
||||
source_geometries = [(feature, shape(feature["geometry"])) for feature in features]
|
||||
@@ -105,6 +105,17 @@ def merge_touching_roof_instances(features: list[dict[str, Any]], source_name: s
|
||||
if geometry.intersects(component)
|
||||
]
|
||||
source_ids = sorted(str(feature["properties"]["source_feature_id"]) for feature in contributors)
|
||||
envelope_area = component.envelope.area
|
||||
fill_ratio = component.area / envelope_area if envelope_area else 0.0
|
||||
# Large connected blocks and irregular chains are administratively
|
||||
# adjacent but not one reliably box-shaped roof target. Preserve their
|
||||
# native instances instead of creating a giant ambiguous detector box.
|
||||
if len(contributors) > 12 or fill_ratio < 0.55:
|
||||
for feature in contributors:
|
||||
retained = json.loads(json.dumps(feature))
|
||||
retained["properties"]["label_semantics"] = "native_instance_complex_touch_group"
|
||||
merged.append(retained)
|
||||
continue
|
||||
properties = dict(contributors[0]["properties"])
|
||||
properties.update(
|
||||
{
|
||||
@@ -112,6 +123,7 @@ def merge_touching_roof_instances(features: list[dict[str, Any]], source_name: s
|
||||
"source_feature_ids": source_ids,
|
||||
"source_feature_count": len(source_ids),
|
||||
"source_feature_id": source_ids[0],
|
||||
"roof_group_fill_ratio": fill_ratio,
|
||||
}
|
||||
)
|
||||
digest = hashlib.sha256(component.normalize().wkb).hexdigest()[:24]
|
||||
|
||||
Reference in New Issue
Block a user