"use client"; /** * GasOutletPointsLayer — точки выхода газосети (форма 6 АО «Екатеринбурггаз», * ФАС №960) в радиусе от участка для §3 «Сети» (#2119 B2 PR-4). Отдельный слой * поверх карты: CircleMarker per gas_outlet_point, цвет по ЗНАКУ свободной * мощности (профицит → --success, дефицит → --danger, needs_calc → --warn). * * Меньший радиус (7) чем у центров питания Россетей (9) — точки выхода это * низовой слой газосети, визуально второстепенный относительно ЦП. Свободная * мощность здесь в млн м³/МЕС (НЕ тыс. м³/ч как у ГРС) — единица зашита в * formatMlnM3Month, чтобы не перепутать. * * Только ~19% строк источника геокодированы → список часто пуст (это норма, * слой не рисуется). Цвета/подписи/приведение чисел — из общего модуля * connection-capacity.ts. Inline token-hex в popup — документированное * исключение raw-Leaflet попапов (ui-tokens.md). */ import { CircleMarker, LayerGroup, Popup } from "react-leaflet"; import type { GasOutletPoint } from "@/hooks/useConnectionCapacity"; import { classifyGasOutlet, formatMeters, formatMlnM3Month, gasOutletColor, toFiniteNumber, } from "@/components/site-finder/connection-capacity"; // ── Point coordinate guard ───────────────────────────────────────────────────── // lat/lon могут прийти строкой (Decimal→str) — приводим через toFiniteNumber, а // не typeof-гвардом (иначе валидная точка молча не рисуется). function pointLatLon(p: GasOutletPoint): [number, number] | null { const lat = toFiniteNumber(p.lat); const lon = toFiniteNumber(p.lon); if (lat === null || lon === null) return null; return [lat, lon]; } // ── Popup ────────────────────────────────────────────────────────────────────── function GasOutletPopup({ point }: { point: GasOutletPoint }) { const state = classifyGasOutlet(point); const color = gasOutletColor(point); const consumer = point.consumer_type?.trim() || null; const free = formatMlnM3Month(point.free_capacity_mln_m3); const isDeficit = state === "deficit"; const distance = formatMeters(point.distance_m); return (
Точка выхода газосети
{point.outlet_name}
{consumer && (
Тип потребителя: {consumer}
)} {state === "calc" ? (
Свободная мощность: требует гидравлического расчёта
) : ( free && (
{isDeficit ? "Дефицит" : "Свободная мощность"}:{" "} {free}
) )} {distance && (
До участка: {distance}
)}
Форма 6 АО «Екатеринбурггаз» · млн м³/мес
); } // ── Layer ────────────────────────────────────────────────────────────────────── interface Props { points: GasOutletPoint[]; } export function GasOutletPointsLayer({ points }: Props) { return ( {points.map((point, idx) => { const latLon = pointLatLon(point); if (!latLon) return null; const color = gasOutletColor(point); return ( ); })} ); } // Число рисуемых точек (с валидными координатами) — для легенды/чекбокса. export function countMappableGasOutlets( points: GasOutletPoint[] | undefined, ): number { if (!points) return 0; return points.filter((p) => pointLatLon(p) !== null).length; }