feat(site-finder): utilities (power/pipeline) + fix Внешние факторы layout
This commit is contained in:
parent
2855a01ca7
commit
6ce634a9b9
3 changed files with 73 additions and 7 deletions
|
|
@ -628,6 +628,60 @@ def analyze_parcel(
|
|||
logger.warning("hydrology query failed for %s: %s", cad_num, e)
|
||||
hydrology = None
|
||||
|
||||
# 9d) Utilities — power lines + pipelines из OSM (магистральные сети)
|
||||
utilities: dict[str, Any] | None = None
|
||||
try:
|
||||
util_rows = (
|
||||
db.execute(
|
||||
text("""
|
||||
SELECT road_class, name,
|
||||
ST_Distance(
|
||||
n.geom::geography,
|
||||
ST_Centroid(ST_GeomFromText(:wkt, 4326))::geography
|
||||
) AS distance_m
|
||||
FROM osm_noise_sources_ekb n
|
||||
WHERE source_type = 'utility'
|
||||
AND ST_DWithin(
|
||||
n.geom::geography,
|
||||
ST_Centroid(ST_GeomFromText(:wkt, 4326))::geography,
|
||||
2000
|
||||
)
|
||||
ORDER BY distance_m ASC
|
||||
LIMIT 10
|
||||
"""),
|
||||
{"wkt": geom_wkt},
|
||||
)
|
||||
.mappings()
|
||||
.all()
|
||||
)
|
||||
# Группировка по типу для compactness
|
||||
by_subtype: dict[str, dict[str, Any]] = {}
|
||||
for r in util_rows:
|
||||
sub = r["road_class"] or "other"
|
||||
if sub not in by_subtype:
|
||||
by_subtype[sub] = {
|
||||
"subtype": sub,
|
||||
"nearest_m": round(float(r["distance_m"])),
|
||||
"name": r["name"],
|
||||
"count_within_2km": 0,
|
||||
}
|
||||
by_subtype[sub]["count_within_2km"] += 1
|
||||
utilities = {
|
||||
"summary": list(by_subtype.values()),
|
||||
"power_line_охранная_зона_flag": any(
|
||||
float(r["distance_m"]) < 25 and r["road_class"] == "power_line" for r in util_rows
|
||||
),
|
||||
"note": (
|
||||
"Охранная зона ЛЭП ≥35 кВ — 15-40м по обе стороны (СП 36.13330). "
|
||||
"В зоне ОЗ нельзя строить капитальные объекты. "
|
||||
"Точная классификация напряжения / магистральности — ЗОУИТ "
|
||||
"5 (ОЗ ЛЭП) и 9 (ОЗ газопровода) через ФГИС ТП."
|
||||
),
|
||||
}
|
||||
except Exception as e:
|
||||
logger.warning("utilities query failed for %s: %s", cad_num, e)
|
||||
utilities = None
|
||||
|
||||
# 10) Market trend — динамика цен ДДУ в радиусе 3 км за 6 vs предыдущие 6 месяцев
|
||||
market_trend: dict[str, Any] | None = None
|
||||
try:
|
||||
|
|
@ -748,6 +802,7 @@ def analyze_parcel(
|
|||
"wind": (weather or {}).get("wind") if weather else None, # backward compat
|
||||
"geology": geology,
|
||||
"hydrology": hydrology,
|
||||
"utilities": utilities,
|
||||
"geotech_risk": _geotech_risk(66, db, geom_wkt),
|
||||
"market_trend": market_trend,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ _NOISE_QUERIES: list[tuple[str, str, str, str | None]] = [
|
|||
("waterway", "stream", "water", "stream"),
|
||||
("waterway", "canal", "water", "canal"),
|
||||
("natural", "water", "water", "lake_or_pond"),
|
||||
# Инженерные сети — магистральные линии (для proximity-проверки доступности
|
||||
# подключения / распознавания ЛЭП-охранных зон через ЗОУИТ типа 5/9)
|
||||
("power", "line", "utility", "power_line"),
|
||||
("power", "minor_line", "utility", "power_line"),
|
||||
("man_made", "pipeline", "utility", "pipeline"),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -460,12 +460,18 @@ function WeatherBlock({
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Source + note */}
|
||||
<div style={{ fontSize: 11, color: "#9ca3af" }} title={weather.note}>
|
||||
{weather.source} ·{" "}
|
||||
{weather.note.length > 60
|
||||
? weather.note.slice(0, 60) + "…"
|
||||
: weather.note}
|
||||
{/* Source — note shown only on hover */}
|
||||
<div
|
||||
style={{
|
||||
fontSize: 11,
|
||||
color: "#9ca3af",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
}}
|
||||
title={weather.note}
|
||||
>
|
||||
{weather.source} · 7 дн.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -667,7 +673,7 @@ export function ScoreCard({ data }: Props) {
|
|||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(3, 1fr)",
|
||||
gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
|
||||
gap: 10,
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue