fix(p3-batch): восстановление 13 Fable 5 P3-fixes из lost branches #1301
1 changed files with 49 additions and 26 deletions
|
|
@ -126,6 +126,11 @@ def _way_to_polygon_wkt(nodes: list[dict]) -> str | None:
|
||||||
|
|
||||||
Используется для natural=water (озёра, пруды). Если кольцо не замкнуто
|
Используется для natural=water (озёра, пруды). Если кольцо не замкнуто
|
||||||
автоматически — добавляем первую точку в конец.
|
автоматически — добавляем первую точку в конец.
|
||||||
|
|
||||||
|
PostGIS отвергает linear ring < 4 точек. Замкнутый way из 3 точек
|
||||||
|
[A, B, A] (points[0]==points[-1]) даёт POLYGON((A,B,A)) — "geometry
|
||||||
|
requires more points". Возвращаем None, чтобы caller сделал fallback
|
||||||
|
на LineString или пропустил элемент.
|
||||||
"""
|
"""
|
||||||
points = [f"{n['lon']} {n['lat']}" for n in nodes if "lon" in n and "lat" in n]
|
points = [f"{n['lon']} {n['lat']}" for n in nodes if "lon" in n and "lat" in n]
|
||||||
if len(points) < 3:
|
if len(points) < 3:
|
||||||
|
|
@ -133,6 +138,9 @@ def _way_to_polygon_wkt(nodes: list[dict]) -> str | None:
|
||||||
# Замкнуть кольцо если нужно
|
# Замкнуть кольцо если нужно
|
||||||
if points[0] != points[-1]:
|
if points[0] != points[-1]:
|
||||||
points.append(points[0])
|
points.append(points[0])
|
||||||
|
# Итоговое кольцо должно содержать ≥4 точек (PostGIS требование).
|
||||||
|
if len(points) < 4:
|
||||||
|
return None
|
||||||
return f"POLYGON(({', '.join(points)}))"
|
return f"POLYGON(({', '.join(points)}))"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -203,10 +211,13 @@ def sync_noise_sources_to_db() -> dict[str, int]:
|
||||||
**geom_params,
|
**geom_params,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with db.begin_nested(): # SAVEPOINT — откат только этой записи
|
||||||
result = db.execute(
|
result = db.execute(
|
||||||
text(f"""
|
text(f"""
|
||||||
INSERT INTO osm_noise_sources_ekb
|
INSERT INTO osm_noise_sources_ekb
|
||||||
(osm_type, osm_id, source_type, road_class, name, geom, tags, fetched_at)
|
(osm_type, osm_id, source_type, road_class, name, geom, tags,
|
||||||
|
fetched_at)
|
||||||
VALUES (
|
VALUES (
|
||||||
:osm_type, :osm_id, :source_type, :road_class, :name,
|
:osm_type, :osm_id, :source_type, :road_class, :name,
|
||||||
{geom_sql},
|
{geom_sql},
|
||||||
|
|
@ -223,15 +234,27 @@ def sync_noise_sources_to_db() -> dict[str, int]:
|
||||||
"""),
|
"""),
|
||||||
params,
|
params,
|
||||||
).scalar()
|
).scalar()
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
inserted += 1
|
inserted += 1
|
||||||
else:
|
else:
|
||||||
updated += 1
|
updated += 1
|
||||||
|
except Exception as e:
|
||||||
|
# Дефектный way (например, 3-точечное замкнутое кольцо POLYGON((A,B,A))
|
||||||
|
# отвергается PostGIS) не должен валить весь weekly-sync. SAVEPOINT
|
||||||
|
# откатывает только эту строку, продолжаем с остальными.
|
||||||
|
logger.warning(
|
||||||
|
"noise_sync insert failed for %s/%s (source_type=%s): %s",
|
||||||
|
osm_type,
|
||||||
|
osm_id,
|
||||||
|
source_type,
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
skipped += 1
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
except Exception:
|
except Exception as e:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
|
logger.exception("noise_sync: unexpected error, outer tx rolled back: %s", e)
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue