style(sn): format integrated map modules
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user