"use client"; import { useQuery } from "@tanstack/react-query"; import type { FeatureCollection, MultiPolygon, Polygon } from "geojson"; import { apiFetch } from "@/lib/api"; /** * Радиус поиска соседних зданий вокруг участка для 3D-сцены / 2D-плана §7 * («Размещение застройки»). Дефолт 300 м — согласован с бэком * (GET /neighbor-buildings?radius_m=…, диапазон 50–1000). Держим отдельной * константой, чтобы подпись и запрос не расходились. */ export const NEIGHBOR_BUILDINGS_RADIUS_M = 300; /** * properties одной соседней постройки. Форма — единственный источник истины * бэкенд (parcels.py::get_parcel_neighbor_buildings): endpoint отдаёт plain * GeoJSON FeatureCollection (handler-return `dict[str, Any]`, НЕ Pydantic-модель), * поэтому в api-types.ts codegen'ом он не попадает — типизуем вручную, как и * соседний `NeighborBuilding` в types/site-finder.ts. */ export interface NeighborBuildingProps { cad_num: string | null; /** Этажность НСПД (int) либо null, если не заполнена в кадастре. */ floors: number | null; /** Высота = floors × 3 м (бэк), либо null при неизвестной этажности. */ height_m: number | null; building_name: string | null; year_built: number | null; is_neighbor: true; } export interface NeighborBuildingsResponse extends FeatureCollection< Polygon | MultiPolygon, NeighborBuildingProps > { /** Число возвращённых фич (после cap на бэке). */ count: number; /** Радиус, по которому реально искали (echo query-параметра). */ radius_m: number; /** true, если в радиусе зданий было больше лимита (300) и выборку обрезали. */ truncated: boolean; } /** * Соседние здания (footprint'ы) вокруг участка для сцены «Размещение застройки» * (§7 отчёта ПТИЦА, Forgejo #2180): существующая застройка контекста, чтобы * концепция читалась в окружении квартала. * * Зеркалит useConnectionCapacity: apiFetch, queryKey-массив, staleTime 5 мин, * enabled по cadNum. Пустой / отсутствующий cadNum (например standalone-страница * /concept без кадастра) → запрос не идёт (enabled=false), сцена работает как * раньше без соседей. */ export function useNeighborBuildings( cadNum: string | null | undefined, radiusM: number = NEIGHBOR_BUILDINGS_RADIUS_M, enabled = true, ) { return useQuery({ queryKey: ["neighbor-buildings", cadNum, radiusM], queryFn: () => apiFetch( `/api/v1/parcels/${encodeURIComponent(cadNum!)}/neighbor-buildings?radius_m=${radiusM}`, ), enabled: !!cadNum && enabled, staleTime: 5 * 60 * 1000, }); }