style(sn): format integrated map modules

This commit is contained in:
2026-10-01 15:54:43 +09:00
parent f71fa7d97a
commit c8b30810f6
8 changed files with 249 additions and 55 deletions
@@ -1,24 +1,35 @@
/** 노후관로의 지도와 목록이 사용하는 DB 레이어 설정 계약이다. */
import { getRawJson } from "@/shared/api/sewerage-api";
import { buildAgedPipeCqlFilters, isAgedPipeLayerNode, type AgedPipeFilters } from "@/entities/facility/lib/aged-pipe-utils";
import {
buildAgedPipeCqlFilters,
isAgedPipeLayerNode,
type AgedPipeFilters,
} from "@/entities/facility/lib/aged-pipe-utils";
/** DB 응답을 그대로 보존하며 최초 표출 전에 필터만 해석한다. */
export const prepareAgedPipeLayerRows = (rows: any[], filters: AgedPipeFilters): any[] =>
export const prepareAgedPipeLayerRows = (
rows: any[],
filters: AgedPipeFilters,
): any[] =>
rows.map((row) => {
const next = { ...row };
if (isAgedPipeLayerNode(row)) {
next.agedPipeFilterTemplate = row.flterSql;
try {
validateAgedPipeLayer(row);
next.flterSql = buildAgedPipeCqlFilters(filters, row.flterSql).join(" AND ");
next.flterSql = buildAgedPipeCqlFilters(filters, row.flterSql).join(
" AND ",
);
} catch (error) {
// 노후관로 DB 미전환이 다른 시설물 레이어까지 중단시키지 않도록 이 행만 차단한다.
next.agedPipeConfigError = error instanceof Error ? error.message : "노후관로 레이어 설정 오류";
next.agedPipeConfigError =
error instanceof Error ? error.message : "노후관로 레이어 설정 오류";
next.actlLyrYn = "N";
next.flterSql = "EXCLUDE";
}
}
if (Array.isArray(row.children)) next.children = prepareAgedPipeLayerRows(row.children, filters);
if (Array.isArray(row.children))
next.children = prepareAgedPipeLayerRows(row.children, filters);
return next;
});
@@ -26,7 +37,9 @@ export const prepareAgedPipeLayerRows = (rows: any[], filters: AgedPipeFilters):
export const findAgedPipeLayer = (rows: any[]): any | undefined => {
for (const row of rows) {
if (isAgedPipeLayerNode(row)) return row;
const child = Array.isArray(row.children) ? findAgedPipeLayer(row.children) : undefined;
const child = Array.isArray(row.children)
? findAgedPipeLayer(row.children)
: undefined;
if (child) return child;
}
};
@@ -34,14 +47,24 @@ export const findAgedPipeLayer = (rows: any[]): any | undefined => {
/** 예전 제어용 행을 실제 WFS 레이어처럼 요청하지 않도록 전환 상태를 확인한다. */
export const validateAgedPipeLayer = (row: any) => {
if (row?.agedPipeConfigError) throw new Error(row.agedPipeConfigError);
if (!row || row.actlLyrYn !== "Y" || row.srvcNm !== "wfs" || !row.lyrTyNm || row.lyrTyNm === "tb_old_pipe") {
throw new Error("노후관로 DB 레이어 설정을 실제 WFS 레이어와 sql_filt 템플릿으로 갱신해 주세요.");
if (
!row ||
row.actlLyrYn !== "Y" ||
row.srvcNm !== "wfs" ||
!row.lyrTyNm ||
row.lyrTyNm === "tb_old_pipe"
) {
throw new Error(
"노후관로 DB 레이어 설정을 실제 WFS 레이어와 sql_filt 템플릿으로 갱신해 주세요.",
);
}
};
/** 독립 목록 팝업도 부모창의 하드코딩 없이 동일 설정 API를 조회한다. */
export const fetchAgedPipeLayer = async () => {
const rows = await getRawJson("/sewerage-service/api/v1/map/lyrStngs/SN_NETWORK");
const rows = await getRawJson(
"/sewerage-service/api/v1/map/lyrStngs/SN_NETWORK",
);
const row = findAgedPipeLayer(Array.isArray(rows) ? rows : []);
validateAgedPipeLayer(row);
return row;
@@ -150,7 +150,11 @@ export default function AgedPipePopupPage() {
setAppliedFilters(normalizeAgedPipeFilters(nextFilters));
} catch (error) {
console.error("노후관로 목록 조회 중 오류:", error);
alert(error instanceof Error ? error.message : "노후관로 목록 조회 중 오류가 발생했습니다.");
alert(
error instanceof Error
? error.message
: "노후관로 목록 조회 중 오류가 발생했습니다.",
);
setRows([]);
setTotal(0);
} finally {
@@ -1,4 +1,3 @@
import { SINKHOLE_TREE_ICON_NAME } from "../model/map-constants";
export const normalizeTreeRowSpacing = (data: any[]) => {
@@ -16,4 +15,8 @@ export const normalizeTreeRowSpacing = (data: any[]) => {
};
});
};
export { extractUsageCodesFromLayerInfo, isLayerVisibleAtZoom, extractCheckedPipeUsageStyles } from "@/features/map-layers/lib/flow-direction-selection";
export {
extractUsageCodesFromLayerInfo,
isLayerVisibleAtZoom,
extractCheckedPipeUsageStyles,
} from "@/features/map-layers/lib/flow-direction-selection";
@@ -1,6 +1,11 @@
"use client";
import type { useFloodPredictionMap } from "@/features/fldng-predc-prst/lib/use-flood-prediction-map";
import { useEffect, type MutableRefObject, type Dispatch, type SetStateAction } from "react";
import {
useEffect,
type MutableRefObject,
type Dispatch,
type SetStateAction,
} from "react";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
import { WINDOW_POPUP_MESSAGE_TYPE } from "@/features/window-popup/model/types";
@@ -8,7 +13,9 @@ type MapRuntimeBridgeOptions = {
/** 공통 Gis가 생성한 지도 참조. 생성/파괴 소유권은 Gis에 유지한다. */
gisMaps: MutableRefObject<any>;
setMapReady: Dispatch<SetStateAction<boolean>>;
handleFloodPredictionPopupSelection: ReturnType<typeof useFloodPredictionMap>["handleFloodPredictionPopupSelection"];
handleFloodPredictionPopupSelection: ReturnType<
typeof useFloodPredictionMap
>["handleFloodPredictionPopupSelection"];
};
/** 지도 준비 감지와 정보검색/GIS 업로드 메시지 연결을 소유한다.
@@ -81,10 +88,15 @@ export function useMapRuntimeBridge({
return;
}
if (data?.type === WINDOW_POPUP_MESSAGE_TYPE.MAP_SEARCH_SHOW_FLOOD_GROUP) {
await handleFloodPredictionPopupSelection(data.payload, { source: event.source as Window | null, origin: event.origin });
return;
}
if (
data?.type === WINDOW_POPUP_MESSAGE_TYPE.MAP_SEARCH_SHOW_FLOOD_GROUP
) {
await handleFloodPredictionPopupSelection(data.payload, {
source: event.source as Window | null,
origin: event.origin,
});
return;
}
if (data?.type === WINDOW_POPUP_MESSAGE_TYPE.GIS_UPLOAD_COMPLETED) {
const rawLayerTypeNames = data.payload?.refreshLayerTypeNames;
@@ -17,8 +17,15 @@
"use client";
import { useFloodPredictionMap } from "@/features/fldng-predc-prst/lib/use-flood-prediction-map";
import { FLOOD_DNGR_MAP_LAYER_NAME, FLOOD_DNGR_MAP_LAYER_TYPE } from "../components/flood-dngr-map/flood-dngr-map-types";
import { findAgedPipeLayer, prepareAgedPipeLayerRows, validateAgedPipeLayer } from "../components/aged-pipe/aged-pipe-layer";
import {
FLOOD_DNGR_MAP_LAYER_NAME,
FLOOD_DNGR_MAP_LAYER_TYPE,
} from "../components/flood-dngr-map/flood-dngr-map-types";
import {
findAgedPipeLayer,
prepareAgedPipeLayerRows,
validateAgedPipeLayer,
} from "../components/aged-pipe/aged-pipe-layer";
import { useFloodHistoryClick } from "../lib/use-flood-history-click";
import { useFacilityCodeCatalog } from "@/entities/facility/lib/use-facility-code-catalog";
import { useFloodHistoryVisibility } from "../lib/use-flood-history-visibility";
@@ -35,14 +42,40 @@ import { useWaterRiskLayer } from "../lib/use-water-risk-layer";
import { useFlowDirectionLayer } from "@/features/map-layers/lib/use-flow-direction-layer";
import dynamic from "next/dynamic";
import { type VertexHandleMeta } from "@/features/gis-edit/model/vertex-handles";
import { type RightPanelTab, findRightPanelTabOverflowCandidate, removeRightPanelTabGroup, RightPanelBookmarkTabs } from "../components/right-panel/right-panel-bookmark-tabs";
import { FLOW_DIRECTION_DEFAULT_MIN_ZOOM, getFlowDirectionModeByPathname, SWAGE_PRCS_FCLT_LAYER_TYPE, type SwagePrcsFcltLayerMode, getSwagePrcsFcltLayerMode, normalizeFlowDirectionLayerInfos, normalizeRainObservationLayerInteraction, getFlowDirectionMinZoom } from "@/features/map-layers";
import {
type RightPanelTab,
findRightPanelTabOverflowCandidate,
removeRightPanelTabGroup,
RightPanelBookmarkTabs,
} from "../components/right-panel/right-panel-bookmark-tabs";
import {
FLOW_DIRECTION_DEFAULT_MIN_ZOOM,
getFlowDirectionModeByPathname,
SWAGE_PRCS_FCLT_LAYER_TYPE,
type SwagePrcsFcltLayerMode,
getSwagePrcsFcltLayerMode,
normalizeFlowDirectionLayerInfos,
normalizeRainObservationLayerInteraction,
getFlowDirectionMinZoom,
} from "@/features/map-layers";
import { ListTree } from "lucide-react";
import { Fragment, useCallback, useEffect, useMemo, useRef, useState, type ReactNode, type UIEvent } from "react";
import {
Fragment,
useCallback,
useEffect,
useMemo,
useRef,
useState,
type ReactNode,
type UIEvent,
} from "react";
import { usePathname, useSearchParams } from "next/navigation";
import GeoJSON from "ol/format/GeoJSON.js";
import { openWindowPopup } from "@/features/window-popup/lib/open-window-popup";
import { isWindowPopupKey, type WindowPopupKey } from "@/features/window-popup/model/popup-definitions";
import {
isWindowPopupKey,
type WindowPopupKey,
} from "@/features/window-popup/model/popup-definitions";
import { WINDOW_POPUP_MESSAGE_TYPE } from "@/features/window-popup/model/types";
import Gis from "@common/business_components/ui/map/Gis";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
@@ -58,9 +91,27 @@ import GisEditSessionPanel from "../components/gis-edit/gis-edit-session-panel";
import GisEditToolbar from "../components/gis-edit/gis-edit-toolbar";
import GisEditPipeSessionPopup from "../components/gis-edit/gis-edit-pipe-session-popup";
import { useGisEdit } from "../components/gis-edit/use-gis-edit";
import type { GisEditPipeBasicInfo, GisEditSessionSnapshot } from "../components/gis-edit/gis-edit-types";
import { PIPE_ANALYSIS_DETAIL_ROW_SELECT_MESSAGE, type PipeAnalysisDetailRow } from "../components/pipe-analysis/pipe-analysis-utils";
import { AGED_PIPE_DEFAULT_FILTERS, AGED_PIPE_GUIDE_MIN_ZOOM, AGED_PIPE_LAYER_TYPE, AGED_PIPE_PAGE_SIZE, type AgedPipeFilters, type AgedPipeRow, buildAgedPipeCqlFilters, isAgedPipeLayerNode, normalizeAgedPipeFilters, toDisplayPipeRow, validateElapsedYears } from "@/entities/facility/lib/aged-pipe-utils";
import type {
GisEditPipeBasicInfo,
GisEditSessionSnapshot,
} from "../components/gis-edit/gis-edit-types";
import {
PIPE_ANALYSIS_DETAIL_ROW_SELECT_MESSAGE,
type PipeAnalysisDetailRow,
} from "../components/pipe-analysis/pipe-analysis-utils";
import {
AGED_PIPE_DEFAULT_FILTERS,
AGED_PIPE_GUIDE_MIN_ZOOM,
AGED_PIPE_LAYER_TYPE,
AGED_PIPE_PAGE_SIZE,
type AgedPipeFilters,
type AgedPipeRow,
buildAgedPipeCqlFilters,
isAgedPipeLayerNode,
normalizeAgedPipeFilters,
toDisplayPipeRow,
validateElapsedYears,
} from "@/entities/facility/lib/aged-pipe-utils";
import { downloadAgedPipeExcel } from "../components/aged-pipe/aged-pipe-export";
import { useInftwtResultMap } from "../components/inftwt-result/use-inftwt-result-map";
import { useRdiiResultMap } from "../components/rdii-result/use-rdii-result-map";
@@ -70,26 +121,104 @@ import FldngHstryDetailPanel from "../components/fldng-hstry/fldng-hstry-detail-
import FldngHstryLayerSettingPanel from "../components/fldng-hstry/fldng-hstry-layer-setting-panel";
import ExmnLayerSettingPanel from "../components/exmn/exmn-layer-setting-panel";
import LayerSettingCard from "../components/layer-setting/layer-setting-card";
import { EMPTY_EXMN_MAP_FILTERS, appendExmnResultControlNodes, buildExmnMapEntryContext, isExmnResultMnhlNode, isExmnResultPplNode, type ExmnMapFilters } from "../components/exmn/exmn-map-types";
import { buildSinkholeDefaultYearRange, buildSinkholeFiltersFromYearRange, buildSinkholeScope, isSinkholeLayerNode, isSinkholeRootNode, normalizeSinkholeFilters, normalizeSinkholeYearRange, SINKHOLE_DEFAULT_RADIUS, SINKHOLE_FILTER_SYNC_MESSAGE, SINKHOLE_LAYER_TYPE, SINKHOLE_POPUP_KEY, SINKHOLE_ROW_SELECT_MESSAGE, SINKHOLE_SYNC_COMPLETED_MESSAGE, type SinkholeDetail, type SinkholeFilters, type SinkholeListItem, type SinkholeNearbyPipe, type SinkholeSyncSummary, type SinkholeYearRange } from "../components/sinkhole/sinkhole-types";
import { FLDNG_HSTRY_LAYER_TYPE, FLDNG_HSTRY_POPUP_KEY, FLDNG_HSTRY_ROW_SELECT_MESSAGE, type FldngHstryYearRange, type FldngHstryItem } from "@/entities/flood-history/model/flood-history-types";
import { buildFldngHstryDefaultYearRange, isFldngHstryDepthNode, isFldngHstryWtlvNode, isFldngHstryRootNode } from "@/entities/flood-history/lib/flood-history-utils";
import { SBMRG_DNGR_MAP_POPUP_KEY, isSbmrgDngrMapRootNode } from "../components/sbmrg-dngr-map/sbmrg-dngr-map-types";
import { FLOOD_DNGR_MAP_POPUP_KEY, isFloodDngrMapRootNode } from "../components/flood-dngr-map/flood-dngr-map-types";
import {
EMPTY_EXMN_MAP_FILTERS,
appendExmnResultControlNodes,
buildExmnMapEntryContext,
isExmnResultMnhlNode,
isExmnResultPplNode,
type ExmnMapFilters,
} from "../components/exmn/exmn-map-types";
import {
buildSinkholeDefaultYearRange,
buildSinkholeFiltersFromYearRange,
buildSinkholeScope,
isSinkholeLayerNode,
isSinkholeRootNode,
normalizeSinkholeFilters,
normalizeSinkholeYearRange,
SINKHOLE_DEFAULT_RADIUS,
SINKHOLE_FILTER_SYNC_MESSAGE,
SINKHOLE_LAYER_TYPE,
SINKHOLE_POPUP_KEY,
SINKHOLE_ROW_SELECT_MESSAGE,
SINKHOLE_SYNC_COMPLETED_MESSAGE,
type SinkholeDetail,
type SinkholeFilters,
type SinkholeListItem,
type SinkholeNearbyPipe,
type SinkholeSyncSummary,
type SinkholeYearRange,
} from "../components/sinkhole/sinkhole-types";
import {
FLDNG_HSTRY_LAYER_TYPE,
FLDNG_HSTRY_POPUP_KEY,
FLDNG_HSTRY_ROW_SELECT_MESSAGE,
type FldngHstryYearRange,
type FldngHstryItem,
} from "@/entities/flood-history/model/flood-history-types";
import {
buildFldngHstryDefaultYearRange,
isFldngHstryDepthNode,
isFldngHstryWtlvNode,
isFldngHstryRootNode,
} from "@/entities/flood-history/lib/flood-history-utils";
import {
SBMRG_DNGR_MAP_POPUP_KEY,
isSbmrgDngrMapRootNode,
} from "../components/sbmrg-dngr-map/sbmrg-dngr-map-types";
import {
FLOOD_DNGR_MAP_POPUP_KEY,
isFloodDngrMapRootNode,
} from "../components/flood-dngr-map/flood-dngr-map-types";
import FeatureClickEventPopup from "@/features/facility-detail/ui/feature-click-event-popup";
import SearchModal from "../search-modal/search-modal";
import { WATER_DEPTH_LAYER_TYPES, extractWaterDepthLegendItems } from "../water-depth/water-depth";
import {
WATER_DEPTH_LAYER_TYPES,
extractWaterDepthLegendItems,
} from "../water-depth/water-depth";
import { buildWaterRiskStatusLabel } from "../components/water-risk/water-risk-types";
const AnalysisPopupMenu = dynamic(
() => import("../components/analysis-menu/analysis-popup-menu"),
{ ssr: false },
);
import { AGED_PIPE_ROW_SELECT_MESSAGE, AGED_PIPE_POPUP_MINIMIZE_MESSAGE, AGED_PIPE_FILTER_SYNC_MESSAGE, EXMN_PROC_SEARCH_EVENT, SOUTH_KOREA_VIEW_EXTENT, FLOW_DIRECTION_SRS, SHORT_TERM_FORECAST_GRID_LAYER_NAME, RIGHT_PANEL_TAB_LIMIT, RIGHT_PANEL_SINKHOLE_PIPE_TAB_ID, AGED_PIPE_FOCUS_PADDING, DEFAULT_FEATURE_FIT_PADDING } from "../model/map-constants";
import {
AGED_PIPE_ROW_SELECT_MESSAGE,
AGED_PIPE_POPUP_MINIMIZE_MESSAGE,
AGED_PIPE_FILTER_SYNC_MESSAGE,
EXMN_PROC_SEARCH_EVENT,
SOUTH_KOREA_VIEW_EXTENT,
FLOW_DIRECTION_SRS,
SHORT_TERM_FORECAST_GRID_LAYER_NAME,
RIGHT_PANEL_TAB_LIMIT,
RIGHT_PANEL_SINKHOLE_PIPE_TAB_ID,
AGED_PIPE_FOCUS_PADDING,
DEFAULT_FEATURE_FIT_PADDING,
} from "../model/map-constants";
import { getFeatureCollection } from "../lib/map-values";
import { getSinkholeAccidentId, getSinkholeFallbackDetailFromSelection, getSinkholePointFromSelection, createSinkholeFocusedPipeStyle, appendSinkholeControlNode } from "../lib/sinkhole-features";
import { getGisEditFeatureFid, isGisEditPreviewFeatureData, highlightGisEditSelectedFeature, isVisibleGisEditSessionChange, getLatestNumericEditSn, findInvalidPipeRequiredChange } from "../lib/gis-edit-features";
import { getSelectedFeatureLayerTypeName, getRightPanelFeatureIdentifier, getRightPanelFeatureProperty, getRightPanelTabCategory, getRightPanelFeatureDisplayLabel } from "../lib/right-panel-features";
import {
getSinkholeAccidentId,
getSinkholeFallbackDetailFromSelection,
getSinkholePointFromSelection,
createSinkholeFocusedPipeStyle,
appendSinkholeControlNode,
} from "../lib/sinkhole-features";
import {
getGisEditFeatureFid,
isGisEditPreviewFeatureData,
highlightGisEditSelectedFeature,
isVisibleGisEditSessionChange,
getLatestNumericEditSn,
findInvalidPipeRequiredChange,
} from "../lib/gis-edit-features";
import {
getSelectedFeatureLayerTypeName,
getRightPanelFeatureIdentifier,
getRightPanelFeatureProperty,
getRightPanelTabCategory,
getRightPanelFeatureDisplayLabel,
} from "../lib/right-panel-features";
import { normalizeTreeRowSpacing } from "../lib/layer-tree";
import { useMapRuntimeBridge } from "../lib/use-map-runtime-bridge";
import MapControlStyles from "./map-control-styles";
@@ -126,13 +255,13 @@ const MapPageClient = () => {
} | null>(null);
const [layerLoadError, setLayerLoadError] = useState<string | null>(null);
const gisMaps = useRef<any | null>(null);
const requestFloodPredictionLayer = useCallback(() => {
const requestFloodPredictionLayer = useCallback(() => {
setCheckedLayerRequest((current) => ({
requestKey: (current?.requestKey ?? 0) + 1,
layerNames: [FLOOD_DNGR_MAP_LAYER_NAME],
}));
}, []);
const { handleFloodPredictionPopupSelection } = useFloodPredictionMap({
const { handleFloodPredictionPopupSelection } = useFloodPredictionMap({
mapRef: gisMaps,
floodLayerType: FLOOD_DNGR_MAP_LAYER_TYPE,
onRequestFloodLayer: requestFloodPredictionLayer,
@@ -371,7 +500,6 @@ const { handleFloodPredictionPopupSelection } = useFloodPredictionMap({
useGisEditPipeSnap({ gisEdit, gisMaps, mapReady });
useGisEditOriginalMask({ gisMaps, gisEdit, mapReady });
const gisEditVisibleSessionChanges = useMemo(
() => gisEdit.changes.filter(isVisibleGisEditSessionChange),
@@ -631,7 +759,11 @@ const { handleFloodPredictionPopupSelection } = useFloodPredictionMap({
sinkholeYearRange,
]);
useMapRuntimeBridge({ gisMaps, setMapReady, handleFloodPredictionPopupSelection });
useMapRuntimeBridge({
gisMaps,
setMapReady,
handleFloodPredictionPopupSelection,
});
useEffect(() => {
if (shouldShowGisEditSession) return;
@@ -754,8 +886,12 @@ const { handleFloodPredictionPopupSelection } = useFloodPredictionMap({
"/sewerage-service/api/v1/map/lyrStngs/SN_NETWORK",
);
// DB 필터 치환 실패는 노후관로에만 한정하고 다른 시설물 레이어는 유지한다.
const preparedData = prepareAgedPipeLayerRows(data, appliedAgedPipeFilters);
const agedPipeConfigError = findAgedPipeLayer(preparedData)?.agedPipeConfigError;
const preparedData = prepareAgedPipeLayerRows(
data,
appliedAgedPipeFilters,
);
const agedPipeConfigError =
findAgedPipeLayer(preparedData)?.agedPipeConfigError;
if (agedPipeConfigError) alert(agedPipeConfigError);
setTreeData(
appendExmnResultControlNodes(
@@ -1039,7 +1175,10 @@ const { handleFloodPredictionPopupSelection } = useFloodPredictionMap({
sort: "string",
});
const cqlFilters = buildAgedPipeCqlFilters(normalized, layer.agedPipeFilterTemplate ?? layer.flterSql);
const cqlFilters = buildAgedPipeCqlFilters(
normalized,
layer.agedPipeFilterTemplate ?? layer.flterSql,
);
if (cqlFilters.length > 0) {
queryParams.append("cqlFiter", cqlFilters.join(" and "));
}
@@ -2554,7 +2693,8 @@ const { handleFloodPredictionPopupSelection } = useFloodPredictionMap({
try {
validateAgedPipeLayer(row);
const filter = buildAgedPipeCqlFilters(
appliedAgedPipeFilters, row.agedPipeFilterTemplate ?? row.flterSql,
appliedAgedPipeFilters,
row.agedPipeFilterTemplate ?? row.flterSql,
).join(" AND ");
layerCode.flterSql = filter;
const visible = isAgedPipeChecked && isAgedPipeSettingEnabled;
@@ -2573,8 +2713,14 @@ const { handleFloodPredictionPopupSelection } = useFloodPredictionMap({
core?.getLayerById?.(id)?.setVisible?.(false);
console.error("노후관로 DB 레이어 설정 오류:", error);
}
}, [appliedAgedPipeFilters, isAgedPipeChecked, isAgedPipeSettingEnabled,
mapReady, treeData, checkedLayerLegendVersion]);
}, [
appliedAgedPipeFilters,
isAgedPipeChecked,
isAgedPipeSettingEnabled,
mapReady,
treeData,
checkedLayerLegendVersion,
]);
useFloodHistoryVisibility({
mapReady,
gisMaps,
@@ -246,13 +246,20 @@ export const getElapsedYearsDisplayText = (value: unknown) => {
};
/** DB의 SQL 필터 템플릿을 해석한다. 누락/미지원 토큰은 전체 관로 조회로 대체하지 않는다. */
export const buildAgedPipeCqlFilters = (filters: AgedPipeFilters, filterTemplate: string) => {
export const buildAgedPipeCqlFilters = (
filters: AgedPipeFilters,
filterTemplate: string,
) => {
const normalized = normalizeAgedPipeFilters(filters);
const template = String(filterTemplate ?? "").trim();
if (!template.includes("${cutoffYmd}")) {
throw new Error("노후관로 DB sql_filt에 ${cutoffYmd} 조건을 등록해 주세요.");
throw new Error(
"노후관로 DB sql_filt에 ${cutoffYmd} 조건을 등록해 주세요.",
);
}
const filter = template.split("${cutoffYmd}").join(getCutoffYmd(normalized.elapsedYears));
const filter = template
.split("${cutoffYmd}")
.join(getCutoffYmd(normalized.elapsedYears));
if (/\$\{[^}]*\}/.test(filter)) {
throw new Error("노후관로 DB sql_filt에 지원하지 않는 치환값이 있습니다.");
}
@@ -60,9 +60,7 @@ type Filters = {
const PAGE_SIZE = 10;
const EXCEL_DOWNLOAD_PAGE_SIZE = 500;
const MAP_FREQUENCIES = new Set([30, 50, 80, 100]);
const FREQUENCY_OPTIONS = [
5, 10, 20, 30, 50, 80, 100
] as const;
const FREQUENCY_OPTIONS = [5, 10, 20, 30, 50, 80, 100] as const;
/** 도시침수지도 DB의 3자리 빈도 코드로 변환한다. 30년 이하는 030, 100년 초과는 100으로 제한한다. */
const toFloodMapFrequencyCode = (value: number) => {
@@ -55,7 +55,8 @@ export const extractCheckedPipeUsageStyles = (
checkedNodesData.forEach((node) => {
const data = node?.data ?? node;
if (!data || isFlowDirectionLayerInfo(data) || isAgedPipeLayerNode(data)) return;
if (!data || isFlowDirectionLayerInfo(data) || isAgedPipeLayerNode(data))
return;
if (getLayerTypeName(data) !== FLOW_DIRECTION_PIPE_LAYER_TYPE) return;
if (!isLayerVisibleAtZoom(data, zoom)) return;