From 0320cad063c51764ca230f4fffe87b8d998cee37 Mon Sep 17 00:00:00 2001 From: Viktor Antropov Date: Wed, 9 Sep 2026 14:14:44 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20GeoJSON=20MultiPolygon=20=E2=80=94=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BB=D1=8C=D1=86=D0=B0=20=D0=BE=D0=B1=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=D1=87=D0=B8=D0=B2=D0=B0=D1=82=D1=8C=20=D0=B2=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=B8=D0=B3=D0=BE=D0=BD=D1=8B=20([[ring]])?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Баг: для relation с 2+ внешними кольцами coordinates отдавался [ring0, ring1] (глубина 3) при type=MultiPolygon — невалидный GeoJSON, Leaflet падал ('latlngs[0] undefined') → белый экран страницы анализа на кейсах с мультиполигонами (РАС-кейс Минск: Камсамольскае возера из 2 колец). Фронт: toLatLngs различает Polygon/MultiPolygon по глубине coords[0][0][0]. --- backend/routers/water.py | 3 ++- frontend/src/components/SearchMap.jsx | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/routers/water.py b/backend/routers/water.py index c895937..3b4fe5e 100644 --- a/backend/routers/water.py +++ b/backend/routers/water.py @@ -173,7 +173,8 @@ def _water_geoms(elements: list[dict]) -> list[dict]: if not polygons: continue geom = ( - {'type': 'MultiPolygon', 'coordinates': polygons} + # GeoJSON MultiPolygon: [[ring0], [ring1]] — каждый полигон = список колец. + {'type': 'MultiPolygon', 'coordinates': [[p] for p in polygons]} if len(polygons) > 1 else {'type': 'Polygon', 'coordinates': polygons[0]} ) diff --git a/frontend/src/components/SearchMap.jsx b/frontend/src/components/SearchMap.jsx index 99a358e..ccc96c1 100644 --- a/frontend/src/components/SearchMap.jsx +++ b/frontend/src/components/SearchMap.jsx @@ -129,9 +129,9 @@ const SearchMap = ({ tnpLat, tnpLon, maxDistance, zones, waterFeatures }) => { // Слой георекомендаций: водоёмы/болота (полигоны) + ж/д (линии) из /api/v1/water/{case_id}. // Рисуется ПОД зонами, поверх тайлов OSM. - const toLatLngs = (coords) => Array.isArray(coords[0][0]) - ? coords.map((poly) => poly[0].map((c) => [c[1], c[0]])) // MultiPolygon - : coords[0].map((c) => [c[1], c[0]]); // Polygon + const toLatLngs = (coords) => Array.isArray(coords[0][0][0]) + ? coords.map((poly) => poly[0].map((c) => [c[1], c[0]])) // MultiPolygon: poly → внешнее кольцо + : coords[0].map((c) => [c[1], c[0]]); // Polygon: одно кольцо const waterGeoJSON = (waterFeatures || []) .filter((f) => f.layer !== 'railway') .map((f) => ({ feature: f, positions: toLatLngs(f.geom.coordinates) }));