fix(zoning): NSPD blocks bot access — fallback to deep-links (PKK6 API closed 2024)

This commit is contained in:
lekss361 2026-05-11 22:56:50 +03:00
parent 49eadeb9ce
commit 2cbcea9e73

View file

@ -779,8 +779,31 @@ def analyze_parcel(
logger.warning("market_trend query failed for %s: %s", cad_num, e)
market_trend = None
# 10b) Zoning — территориальная зона ПЗЗ из Росреестр PKK6
zoning: dict[str, Any] | None = None
# 10b) Zoning — территориальная зона ПЗЗ.
# NB: Росреестр PKK6 API закрыт в 2024 → редирект на NSPD (anti-bot WAF).
# Open-data shapefile ПЗЗ ЕКБ публично не выкладывается (data.midural.ru
# содержит только metadata). Реальный per-parcel zoning требует либо
# ручного импорта shapefile из ГИС ЕКБ (с авторизацией) либо платный
# API (egrn.reestr.net). Здесь — fallback на pzz_zones_ekb (если есть)
# + deep-links на публичные геопорталы для drill-down.
zoning: dict[str, Any] = {
"zone_code": None,
"zone_name": None,
"description": None,
"data_available": False,
"note": (
"Автоматический per-parcel zoning недоступен: Росреестр PKK6 API "
"закрыт (2024), NSPD блокирует bot-доступ. Используй внешние "
"геопорталы для определения зоны вручную."
),
"links": {
"nspd_portal": f"https://nspd.gov.ru/map?lat={centroid_lat}&lng={centroid_lon}&z=17",
"ekb_geoportal": "https://xn--80acgfbsl1azdqr.xn--p1ai/",
"midural_data": "https://data.midural.ru/",
},
"lat": centroid_lat,
"lon": centroid_lon,
}
try:
zoning_row = (
db.execute(
@ -799,20 +822,18 @@ def analyze_parcel(
.first()
)
if zoning_row:
zoning = {
"zone_code": zoning_row["zone_code"],
"zone_name": zoning_row["zone_name"],
"description": zoning_row["description"],
"rosreestr_id": zoning_row["rosreestr_id"],
"source": "rosreestr-pkk6",
"note": (
"Зона из ЕГРН (Росреестр). Регламенты (макс. высота, КЗ, ВРИ) "
"не хранятся в ЕГРН — для них нужен текст ПЗЗ муниципалитета."
),
}
zoning.update(
{
"zone_code": zoning_row["zone_code"],
"zone_name": zoning_row["zone_name"],
"description": zoning_row["description"],
"rosreestr_id": zoning_row["rosreestr_id"],
"data_available": True,
"source": "rosreestr-pkk6-cached",
}
)
except Exception as e:
logger.warning("zoning query failed for %s: %s", cad_num, e)
zoning = None
# 10c) Success recommendation — топ квартирография по district из v_bucket_success_score
success_recommendation: dict[str, Any] | None = None