From 2ae460fc4a4c2419cf44329783d49a739e2a04ea Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Wed, 19 Aug 2026 16:58:50 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/geoai/geoai-workbench
---
capabilities/00-change-detection/rectangularize_vectors.py | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/capabilities/00-change-detection/rectangularize_vectors.py b/capabilities/00-change-detection/rectangularize_vectors.py
new file mode 100644
index 0000000..959ec41
--- /dev/null
+++ b/capabilities/00-change-detection/rectangularize_vectors.py
@@ -0,0 +1,45 @@
+"""Convert irregular change polygons into product-friendly rectangles."""
+
+from __future__ import annotations
+
+import json
+from pathlib import Path
+
+from shapely.geometry import box, mapping, shape
+
+
+def rectangularize_vector(source: Path, destination: Path, wgs84_destination: Path | None = None) -> int:
+ # geoai.masks_to_vector may omit the file when a threshold produces no
+ # features. Keep the artifact contract stable by materializing an empty
+ # GeoJSON collection so downstream promotion and downloads still work.
+ if source.is_file():
+ payload = json.loads(source.read_text(encoding="utf-8"))
+ else:
+ payload = {"type": "FeatureCollection", "features": []}
+ source.parent.mkdir(parents=True, exist_ok=True)
+ source.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
+ rectangles = []
+ for feature in payload.get("features", []):
+ geometry = feature.get("geometry")
+ if not geometry:
+ continue
+ source_shape = shape(geometry)
+ if source_shape.is_empty:
+ continue
+ rectangle = box(*source_shape.bounds)
+ properties = dict(feature.get("properties") or {})
+ properties["geometry_mode"] = "axis_aligned_rectangle"
+ properties["source_geometry_type"] = source_shape.geom_type
+ rectangles.append({"type": "Feature", "properties": properties, "geometry": mapping(rectangle)})
+ output = {"type": "FeatureCollection", "features": rectangles}
+ if payload.get("crs"):
+ output["crs"] = payload["crs"]
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ destination.write_text(json.dumps(output, ensure_ascii=False, indent=2), encoding="utf-8")
+ if wgs84_destination is not None and payload.get("crs") and rectangles:
+ import geopandas as gpd
+
+ frame = gpd.GeoDataFrame.from_features(output["features"], crs=payload["crs"].get("properties", {}).get("name"))
+ if frame.crs:
+ frame.to_crs("EPSG:4326").to_file(wgs84_destination, driver="GeoJSON")
+ return len(rectangles)
--
Gitblit v1.9.3