gendesign/frontend/src/hooks/useUtilityInfrastructure.ts
Light1YT 1bbc032316
All checks were successful
CI / changes (pull_request) Successful in 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 1m3s
CI / openapi-codegen-check (pull_request) Successful in 1m54s
fix(site-finder): show networks & connection points on Раздел 3 map (#1961)
The "Сети" section table summarised engineering networks and distances, but
users could not see those points on the map. Three root causes:

- Connection-points layer was always empty: NSPD engineering_structures
  (cat 36328) arrive as Polygon/MultiPolygon in EPSG:3857 (prod: 587 Polygon
  + 298 MultiPolygon, zero Point), but extractLatLon only handled Point in
  EPSG:4326. Extend it to compute the outer-ring centroid for
  Polygon/MultiPolygon and reproject 3857→4326 (frontend math, no backend
  change), so the 10+ connection points render as markers with popups.
- Map vs table coverage mismatch: the table counts "В 2 км" while the OSM
  utility-infrastructure layer fetched only 500 m (1 object inside 500 m vs
  153 within 2 km). Raise the hook default to a shared
  UTILITY_COVERAGE_RADIUS_M = 2000 so the map matches the table column.
- Coherence microcopy: clarify that the map shows the same networks as the
  table (2 km), plus NSPD connection points and protection zones.

Adds unit tests for extractLatLon polygon-centroid + 3857→4326 reprojection.

Refs #1961
2026-06-27 17:52:51 +05:00

49 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useQuery } from "@tanstack/react-query";
import { apiFetch } from "@/lib/api";
import type { components } from "@/lib/api-types";
// Reuse generated OpenAPI types (api-types.ts) — НЕ дублировать руками.
export type UtilityInfrastructureResponse =
components["schemas"]["UtilityInfrastructureResponse"];
export type UtilityInfrastructureFeature =
components["schemas"]["UtilityInfrastructureFeature"];
export type UtilityInfrastructureSummary =
components["schemas"]["UtilityInfrastructureSummary"];
/**
* #1961 — единый радиус «зоны охвата» для раздела «Сети». Таблица utilities
* (osm_noise_sources_ekb) считает «В 2 км», а карта-слой раньше тянула только
* 500 м → внутри 500 м был 1 объект, а в 2 км — 153, и пользователь не видел
* на карте то, что показывала таблица. Делаем радиус карты = радиус таблицы.
* Бэкенд допускает 50..2000 м (ST_DWithin geography по ЕКБ на 2 км ок по перф).
*/
export const UTILITY_COVERAGE_RADIUS_M = 2000;
/**
* Слой инженерной инфраструктуры из OSM (#1746). Источник — open-data таблица
* osm_utility_infrastructure_ekb (weekly-sync). Большинство объектов — ЛЭП
* (power=line, LineString) и подстанции; точечных узлов (towers) меньше.
*
* Зеркалит useConnectionPoints, но с параметром radius_m (бэкенд: 50..2000).
* #1961 — дефолт повышен до UTILITY_COVERAGE_RADIUS_M (2 км), чтобы охват карты
* совпадал с таблицей «В 2 км». Сервер — единственный источник истины по форме
* ответа (см. UtilityInfrastructureResponse в api-types.ts).
*/
export function useUtilityInfrastructure(
cadNum: string | null | undefined,
radiusM: number = UTILITY_COVERAGE_RADIUS_M,
enabled = true,
) {
return useQuery<UtilityInfrastructureResponse>({
queryKey: ["utility-infrastructure", cadNum, radiusM],
queryFn: () =>
apiFetch<UtilityInfrastructureResponse>(
`/api/v1/parcels/${encodeURIComponent(cadNum!)}/utility-infrastructure?radius_m=${radiusM}`,
),
enabled: !!cadNum && enabled,
staleTime: 5 * 60 * 1000,
});
}