@@ -116,12 +146,15 @@ export default function AnalysisPopupMenu({
}, 300);
}}
>
-
-
{item.label}
+ {item.renderIcon ? item.renderIcon({ isActive }) : null}
+ {Icon ? (
+
+ ) : null}
+
{item.label}
);
})}
@@ -141,4 +174,4 @@ export default function AnalysisPopupMenu({
);
-}
\ No newline at end of file
+}
diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts
index aba8d2eed..eab5b6e9d 100644
--- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts
+++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts
@@ -1,9 +1,9 @@
-import {useState, useEffect} from 'react';
-import { getData } from '@/components/lib/api';
+import { useState, useEffect } from "react";
import moment from "moment";
+import { getData } from "@/components/lib/api";
export type TInftwtAnls = {
- inftwtAnlsSn:number;
+ inftwtAnlsSn: number;
aplcnYm: string;
ctpvCd: string;
sggCd: string;
@@ -15,18 +15,20 @@ export type TInftwtAnls = {
atflMpngNm: string;
atflOilqNm: string;
atflNm: string;
- drtwSwtcRt:number;
+ drtwSwtcRt: number;
anlsInfo: string;
scsYn: string;
};
+
export type TInftwtAnlsRslt = {
inftwtAnlsSn: number;
pplMngNo: string;
anlsTm: string;
- predcOilq:number;
-}
+ predcOilq: number;
+};
+
export type TRdiiAnls = {
- rainInfwtAnlsSn:number;
+ rainInfwtAnlsSn: number;
aplcnYm: string;
ctpvCd: string;
sggCd: string;
@@ -38,234 +40,259 @@ export type TRdiiAnls = {
atflMpngNm: string;
atflRainNm: string;
atflNm: string;
- drtwSwtcRt:number;
+ drtwSwtcRt: number;
anlsInfo: string;
scsYn: string;
- srcNm: string; // 출처이름
+ srcNm: string;
};
+
export type TRdiiAnlsRslt = {
rainInfwtAnlsSn: number;
pplMngNo: string;
anlsTm: string;
- predcOilq:number;
- minq:number;
-}
+ predcOilq: number;
+ minq: number;
+};
+
export type TOilqData = {
- inftwtAnlsSn: number; // 침입수분석 일련번호
- pplMngNo: string; // 관로관리번호
- mtrngDt: string; // 계측일시
- oilq: number; // 유량
-}
+ inftwtAnlsSn: number;
+ pplMngNo: string;
+ mtrngDt: string;
+ oilq: number;
+};
+
export type TRainData = {
rainInfwtAnlsSn: number;
mtrngDt: string;
- amrf: number; // 강우량
-}
+ amrf: number;
+};
function roundTo(n: number, digits: number): number {
const factor = Math.pow(10, digits);
return Math.round(n * factor) / factor;
}
-const getOptionsAplcnYm = (yyyymms: string[]): { text: string; val: string, hidden?: boolean }[] => {
- const yyyymms1 : { text: string; val: string; hidden?: boolean }[] = yyyymms.map(dateStr => {
- const year = dateStr.slice(0, 4);
- const month = dateStr.slice(4, 6);
- return {
- text: `${year}-${month}`,
- val: dateStr
- };
- });
- yyyymms1.unshift({ val: '0', text: '선택', hidden: true });
- return yyyymms1;
-};
-const selectAplcnYms = async(gubun:string) => { // 상수사용월
- try {
- const queryString = '';
- const result = await getData(`v1/${gubun}/aplcnYm${queryString ? `?${queryString}` : ''}`);
- if (result && result.length > 0) {
- return getOptionsAplcnYm(result);
- }
- } catch (error) {
- console.error(error);
- }
+const getOptionsAplcnYm = (yyyymms: string[]): { text: string; val: string; hidden?: boolean }[] => {
+ const mapped: { text: string; val: string; hidden?: boolean }[] = yyyymms.map((dateStr) => ({
+ text: `${dateStr.slice(0, 4)}-${dateStr.slice(4, 6)}`,
+ val: dateStr,
+ }));
+ mapped.unshift({ val: "0", text: "선택", hidden: true });
+ return mapped;
};
-export const useAplcnYms = (gubun:string) => {
- const [data, setData] = useState<{ text: string; val: string }[]>([]);
+const selectAplcnYms = async (gubun: string) => {
+ if (!gubun) return [];
+
+ try {
+ const result = await getData(`v1/${gubun}/aplcnYm`);
+ if (Array.isArray(result) && result.length > 0) {
+ return getOptionsAplcnYm(result);
+ }
+ } catch {
+ return [];
+ }
+
+ return [];
+};
+
+export const useAplcnYms = (gubun: string) => {
+ const [data, setData] = useState<{ text: string; val: string; hidden?: boolean }[]>([]);
useEffect(() => {
- const fetch = async (gubun:string) => {
+ if (!gubun) {
+ setData([]);
+ return;
+ }
+
+ const fetch = async () => {
const result = await selectAplcnYms(gubun);
- if (result) setData(result);
+ setData(result ?? []);
};
- fetch(gubun);
+
+ void fetch();
}, [gubun]);
return data;
};
-export const getOptionsInftwtAnlsInfo = (anlsArr: TInftwtAnls[]): { text: string; val: number, hidden?: boolean }[] => {
- const options : { text: string; val: number; hidden?: boolean }[] = anlsArr.map(anls => ({
+
+export const getOptionsInftwtAnlsInfo = (anlsArr: TInftwtAnls[]): { text: string; val: number; hidden?: boolean }[] => {
+ const options: { text: string; val: number; hidden?: boolean }[] = anlsArr.map((anls) => ({
text: anls.anlsInfo,
val: anls.inftwtAnlsSn,
}));
- options.unshift({ val: 0, text: '선택', hidden: true });
+ options.unshift({ val: 0, text: "선택", hidden: true });
return options;
};
-export const selectInftwtAnls = async(aplcnYm:string) => { // 침입수분석
+export const selectInftwtAnls = async (aplcnYm: string) => {
try {
- const queryString = aplcnYm ? `aplcnYmFrom=${aplcnYm}&aplcnYmTo=${aplcnYm}` : '';
- const result = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`);
+ const queryString = aplcnYm ? `aplcnYmFrom=${aplcnYm}&aplcnYmTo=${aplcnYm}` : "";
+ const result = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ""}`);
if (result && result.numberOfElements > 0) {
- return result.content;
- }
- } catch (error) {
- console.error(error);
+ return result.content;
+ }
+ } catch {
+ return [];
}
+
+ return [];
};
-export const getChartDataInftwtAnlsRslt = (arr: TInftwtAnlsRslt[]): { label: string; val: number }[] => {
- const options = arr.map(anlsRslt => ({
+
+export const getChartDataInftwtAnlsRslt = (arr: TInftwtAnlsRslt[]) => {
+ return arr.map((anlsRslt) => ({
label: moment(anlsRslt.anlsTm, "YYYYMMDDHHmmss").format("HH시"),
val: roundTo(anlsRslt.predcOilq, 2),
}));
- return options;
};
-export const selectInftwtAnlsRslt = async(inftwtAnlsSn:number, pplMngNo:string) => { // 침입수분석 결과
+
+export const selectInftwtAnlsRslt = async (inftwtAnlsSn: number, pplMngNo: string) => {
try {
- if ((inftwtAnlsSn === undefined || inftwtAnlsSn === 0) || !pplMngNo) {
- console.warn("inftwtAnlsSn or pplMngNo is not provided");
- return [];
- }
+ if (!inftwtAnlsSn || !pplMngNo) return [];
const result = await getData(`v1/inftwtAnlsRslt/ppl/${inftwtAnlsSn}/${pplMngNo}`);
if (result && result.numberOfElements > 0) {
- return result.content;
- }
- } catch (error) {
- console.error(error);
+ return result.content;
+ }
+ } catch {
+ return [];
}
+
+ return [];
};
-export const getChartDataOilq = (arr: TOilqData[]): { label: string; val: number }[] => {
- const options = arr.map(anlsRslt => ({
+
+export const getChartDataOilq = (arr: TOilqData[]) => {
+ return arr.map((anlsRslt) => ({
label: anlsRslt.mtrngDt,
val: roundTo(anlsRslt.oilq, 2),
}));
- return options;
-};
-export const selectOilq = async(inftwtAnlsSn:number, pplMngNo:string) => { // 유량
- try {
- if ((inftwtAnlsSn === undefined || inftwtAnlsSn === 0) || !pplMngNo) {
- console.warn("inftwtAnlsSn or pplMngNo is not provided");
- return [];
- }
- const result = await getData(`v1/inftwtAnlsRslt/oilqPpl/${inftwtAnlsSn}/${pplMngNo}`);
- if (result && result.numberOfElements > 0) {
- return result.content;
- }
- } catch (error) {
- console.error(error);
- }
-};
-export const selectPplInftwtQty = async(inftwtAnlsSn:number, pplMngNo:string) => { // 침입수량
- try {
- if ((inftwtAnlsSn === undefined || inftwtAnlsSn === 0) || !pplMngNo) {
- console.warn("inftwtAnlsSn or pplMngNo is not provided");
- return [];
- }
- const result = await getData(`v1/inftwtAnlsRslt/pplInftwtQty/${inftwtAnlsSn}/${pplMngNo}`);
- if (result.length > 0) {
- return result[0].avg_day_flow;
- } else {
- return 0; // 데이터가 없을 경우 0 반환
- }
- } catch (error) {
- console.error(error);
- }
-};
-//----------
-export const selectPplRdiiQty = async(rainInfwtAnlsSn:number, pplMngNo:string) => { // rdii값
- try {
- if ((rainInfwtAnlsSn === undefined || rainInfwtAnlsSn === 0) || !pplMngNo) {
- console.warn("rainInfwtAnlsSn or pplMngNo is not provided");
- return [];
- }
- const result = await getData(`v1/rdiiAnlsRslt/pplRdiiQty/${rainInfwtAnlsSn}/${pplMngNo}`);
- if (result?.sustaintime > 0) {
- return result;
- }
- } catch (error) {
- console.error(error);
- }
};
-export const getOptionsRdiiAnlsInfo = (anlsArr: TRdiiAnls[]): { text: string; val: number, hidden?: boolean }[] => {
- const options : { text: string; val: number; hidden?: boolean }[] = anlsArr.map(anls => ({
+export const selectOilq = async (inftwtAnlsSn: number, pplMngNo: string) => {
+ try {
+ if (!inftwtAnlsSn || !pplMngNo) return [];
+ const result = await getData(`v1/inftwtAnlsRslt/oilqPpl/${inftwtAnlsSn}/${pplMngNo}`);
+ if (result && result.numberOfElements > 0) {
+ return result.content;
+ }
+ } catch {
+ return [];
+ }
+
+ return [];
+};
+
+export const selectPplInftwtQty = async (inftwtAnlsSn: number, pplMngNo: string) => {
+ try {
+ if (!inftwtAnlsSn || !pplMngNo) return 0;
+ const result = await getData(`v1/inftwtAnlsRslt/pplInftwtQty/${inftwtAnlsSn}/${pplMngNo}`);
+ if (Array.isArray(result) && result.length > 0) {
+ return result[0].avg_day_flow;
+ }
+ } catch {
+ return 0;
+ }
+
+ return 0;
+};
+
+const buildPplMngNoCandidates = (pplMngNo: string) => {
+ const normalized = String(pplMngNo ?? "").trim();
+ if (!normalized) return [];
+ const withoutPrefix = normalized.replace(/^L/, "");
+ const withPrefix = withoutPrefix ? `L${withoutPrefix}` : "";
+ return Array.from(new Set([normalized, withPrefix, withoutPrefix].filter(Boolean)));
+};
+
+export const selectPplRdiiQty = async (rainInfwtAnlsSn: number, pplMngNo: string) => {
+ if (!rainInfwtAnlsSn || !pplMngNo) return null;
+
+ for (const candidate of buildPplMngNoCandidates(pplMngNo)) {
+ try {
+ const result = await getData(`v1/rdiiAnlsRslt/pplRdiiQty/${rainInfwtAnlsSn}/${candidate}`);
+ if (result) {
+ return result;
+ }
+ } catch {
+ // resultOnly mode fallback candidates should not raise console noise
+ }
+ }
+
+ return null;
+};
+
+export const getOptionsRdiiAnlsInfo = (anlsArr: TRdiiAnls[]): { text: string; val: number; hidden?: boolean }[] => {
+ const options: { text: string; val: number; hidden?: boolean }[] = anlsArr.map((anls) => ({
text: anls.anlsInfo,
val: anls.rainInfwtAnlsSn,
}));
- options.unshift({ val: 0, text: '선택', hidden: true });
+ options.unshift({ val: 0, text: "선택", hidden: true });
return options;
};
-export const selectRdiiAnls = async(aplcnYm:string) => { // 침입수분석
+export const selectRdiiAnls = async (aplcnYm: string) => {
try {
- const queryString = aplcnYm ? `aplcnYmFrom=${aplcnYm}&aplcnYmTo=${aplcnYm}` : '';
- const result = await getData(`v1/rdiiAnls${queryString ? `?${queryString}` : ''}`);
+ const queryString = aplcnYm ? `aplcnYmFrom=${aplcnYm}&aplcnYmTo=${aplcnYm}` : "";
+ const result = await getData(`v1/rdiiAnls${queryString ? `?${queryString}` : ""}`);
if (result && result.numberOfElements > 0) {
- return result.content;
- }
- } catch (error) {
- console.error(error);
+ return result.content;
+ }
+ } catch {
+ return [];
}
+
+ return [];
};
-export const getChartDataRdiiAnlsRslt = (arr: TRdiiAnlsRslt[]): { label: string; lineVal0: number, barVal0:number }[] => {
- const options = arr.map(anlsRslt => ({
+
+export const getChartDataRdiiAnlsRslt = (arr: TRdiiAnlsRslt[]) => {
+ return arr.map((anlsRslt) => ({
label: moment(anlsRslt.anlsTm, "YYYYMMDDHHmmss").format("MM-DD HH시"),
lineVal0: roundTo(anlsRslt.predcOilq, 2),
- barVal0: 0
+ barVal0: 0,
}));
- return options;
};
-export const getChartDataRdiiAnlsRsltMinq = (arr: TRdiiAnlsRslt[]): { label: string; val: number }[] => {
- const options = arr.map(anlsRslt => ({
+
+export const getChartDataRdiiAnlsRsltMinq = (arr: TRdiiAnlsRslt[]) => {
+ return arr.map((anlsRslt) => ({
label: moment(anlsRslt.anlsTm, "YYYYMMDDHHmmss").format("MM-DD HH시"),
val: roundTo(anlsRslt.minq, 2),
}));
- return options;
};
-export const selectRdiiAnlsRslt = async(rainInfwtAnlsSn:number, pplMngNo:string) => { // RDII분석 결과
- try {
- if ((rainInfwtAnlsSn === undefined || rainInfwtAnlsSn === 0) || !pplMngNo) {
- console.warn("RdiiAnlsSn or pplMngNo is not provided");
- return [];
- }
- const result = await getData(`v1/rdiiAnlsRslt/ppl/${rainInfwtAnlsSn}/${pplMngNo}`);
- if (result && result.numberOfElements > 0) {
+
+export const selectRdiiAnlsRslt = async (rainInfwtAnlsSn: number, pplMngNo: string) => {
+ if (!rainInfwtAnlsSn || !pplMngNo) return [];
+
+ for (const candidate of buildPplMngNoCandidates(pplMngNo)) {
+ try {
+ const result = await getData(`v1/rdiiAnlsRslt/ppl/${rainInfwtAnlsSn}/${candidate}`);
+ if (result && result.numberOfElements > 0) {
return result.content;
- }
- } catch (error) {
- console.error(error);
- }
-};
-export const selectRainData = async(rainInfwtAnlsSn:number) => { // 강우데이터
- try {
- if ((rainInfwtAnlsSn === undefined || rainInfwtAnlsSn === 0)) {
- console.warn("RdiiAnlsSn or pplMngNo is not provided");
- return [];
+ }
+ } catch {
+ // resultOnly mode fallback candidates should not raise console noise
}
+ }
+
+ return [];
+};
+
+export const selectRainData = async (rainInfwtAnlsSn: number) => {
+ try {
+ if (!rainInfwtAnlsSn) return [];
const result = await getData(`v1/rdiiAnlsRslt/rainData/${rainInfwtAnlsSn}`);
if (result && result.numberOfElements > 0) {
- return result.content;
- }
- } catch (error) {
- console.error(error);
+ return result.content;
+ }
+ } catch {
+ return [];
}
+
+ return [];
};
-export const getChartDataRainData = (arr: TRainData[]): { label: string; lineVal0: number, barVal0: number }[] => {
- const options = arr.map(data => ({
+
+export const getChartDataRainData = (arr: TRainData[]) => {
+ return arr.map((data) => ({
label: moment(data.mtrngDt, "YYYY-MM-DD HH:mm:ss").format("MM-DD HH시"),
lineVal0: 0,
- barVal0: roundTo(data.amrf,2),
+ barVal0: roundTo(data.amrf, 2),
}));
- return options;
};
\ No newline at end of file
diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/rdiiChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/rdiiChart.tsx
index ec1cec8b1..3b9d412d1 100644
--- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/rdiiChart.tsx
+++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/rdiiChart.tsx
@@ -1,21 +1,25 @@
-'use client'
+"use client";
-import React, { useEffect, useMemo, useState } from 'react';
-import moment from 'moment';
+import React, { useEffect, useMemo, useState } from "react";
+import moment from "moment";
import {
CHART_FORM,
type ChartConfig,
MainChart,
-} from '@common/business_components';
-import { SelectBox } from '@common/business_components/ui';
-import { Button, Input, Label } from '@common/components';
+} from "@common/business_components";
+import { SelectBox } from "@common/business_components/ui";
+import { Button, Input, Label } from "@common/components";
-import type { TRdiiAnls } from './aplcnYms';
-import * as fn from './aplcnYms';
+import type { TRdiiAnls } from "./aplcnYms";
+import * as fn from "./aplcnYms";
type ModalOpenProp = {
- pplMngNo?: string; // 관로관리번호
+ pplMngNo?: string;
+ rainInfwtAnlsSn?: number;
+ aplcnYm?: string;
+ analysisInfo?: string;
+ resultOnly?: boolean;
};
type LineBarChartData = {
@@ -24,112 +28,77 @@ type LineBarChartData = {
barVal0: number;
};
-const INITIAL_ANALYSIS_OPTIONS = [{ val: 0, text: '선택' }];
+const INITIAL_ANALYSIS_OPTIONS = [{ val: 0, text: "선택" }];
-const RdiiChart = ({ pplMngNo = '' }: ModalOpenProp) => {
+const normalizePplMngNo = (value: string) => {
+ const trimmed = String(value ?? "").trim();
+ if (!trimmed) return "";
+ return trimmed.startsWith("L") ? trimmed : `L${trimmed}`;
+};
- const [aplcnYm, setAplcnYm] = useState('');
+const RdiiChart = ({
+ pplMngNo = "",
+ rainInfwtAnlsSn = 0,
+ aplcnYm = "",
+ analysisInfo = "",
+ resultOnly = false,
+}: ModalOpenProp) => {
+ const [selectedAplcnYm, setSelectedAplcnYm] = useState("");
const [rdiiAnlss, setRdiiAnlss] = useState
([]);
const [rdiiAnlsInfos, setRdiiAnlsInfos] = useState<{ text: string; val: number; hidden?: boolean }[]>(
INITIAL_ANALYSIS_OPTIONS,
);
- const [rdiiAnls, setRdiiAnls] = useState(null); // 강우유입수분석정보
- const [rainInfwtAnlsSn, setRainInfwtAnlsSn] = useState(0);// 강우유입수분석 정보 선택시 사용
+ const [rdiiAnls, setRdiiAnls] = useState(null);
+ const [selectedRainInfwtAnlsSn, setSelectedRainInfwtAnlsSn] = useState(0);
const [chartData, setChartData] = useState([]);
- const [rdiiQty, setRdiiQty] = useState('0'); // 강우유입수량
- const [rainTotal, setRainTotal] = useState('0'); // 적용강우량
- const [totalVolume, setTotalVolume] = useState('0');// 총체적 m³/mm
+ const [rdiiQty, setRdiiQty] = useState("0");
+ const [rainTotal, setRainTotal] = useState("0");
+ const [totalVolume, setTotalVolume] = useState("0");
- const aplcnYms = fn.useAplcnYms('rdiiAnlsRslt'); // 상수사용월 데이터 가져오기
- const normalizedPplMngNo = pplMngNo ? `L${pplMngNo}` : '';
+ const normalizedPplMngNo = normalizePplMngNo(pplMngNo);
+ const isResultOnlyMode = resultOnly && rainInfwtAnlsSn > 0 && Boolean(normalizedPplMngNo);
+ const aplcnYms = fn.useAplcnYms(isResultOnlyMode ? "" : "rdiiAnlsRslt");
const chartForm = CHART_FORM.LINEBAR2;
const chartConfig = {
barVal0: {
- label: '강수량',
- color: '#33AAFF',
+ label: "강수량",
+ color: "#33AAFF",
},
lineVal0: {
- label: 'RDII',
- color: '#FF0000',
+ label: "RDII",
+ color: "#FF0000",
},
} as ChartConfig;
const hasChartData = useMemo(() => chartData.length > 0, [chartData]);
const resetState = () => {
- setAplcnYm(''); // 상수사용월 초기화
- setRdiiAnlss([]); // 강우유입수분석 초기화
- setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS); // 강우유입수분석정보 초기화
- setRdiiAnls(null); // 강우유입수분석정보 초기화
- setRainInfwtAnlsSn(0); // 강우유입수분석 일련번호 초기화
- setChartData([]);
- setRdiiQty('0'); // 강우유입수량 초기화
- setRainTotal('0');// 적용강우량 초기화
- setTotalVolume('0');// 총체적 m³/mm 초기화
- };
-
- const handleAplcnYmChange = async (val: string | number) => {
- const selectedValue = String(val);
-
- setAplcnYm(selectedValue);
+ setSelectedAplcnYm("");
setRdiiAnlss([]);
+ setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS);
setRdiiAnls(null);
- setRainInfwtAnlsSn(0);
+ setSelectedRainInfwtAnlsSn(0);
setChartData([]);
- setRdiiQty('0');
- setRainTotal('0');
- setTotalVolume('0');
-
- if (!selectedValue || selectedValue === '0') {
- setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS);
- return;
- }
-
- try {
- const data = await fn.selectRdiiAnls(selectedValue); // 상수사용월 변경시 분석 정보 리스트 가져오기
- const list = data ?? [];
- setRdiiAnlss(list);
- setRdiiAnlsInfos(fn.getOptionsRdiiAnlsInfo(list));
- } catch (error) {
- console.error('selectRdiiAnls 에러:', error);
- setRdiiAnlss([]);
- setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS);
- }
+ setRdiiQty("0");
+ setRainTotal("0");
+ setTotalVolume("0");
};
- const handleRdiiAnlsSnChange = (val: string | number) => {
- const selectedValue = Number(val);
-
- setRainInfwtAnlsSn(selectedValue);
- setChartData([]);
- setRdiiQty('0');
- setRainTotal('0');
- setTotalVolume('0');
-
- if (selectedValue === 0) {
- setRdiiAnls(null);
- return;
- }
-
- const selectedAnls = rdiiAnlss.find((anls) => anls.rainInfwtAnlsSn === selectedValue) ?? null;
- setRdiiAnls(selectedAnls);
- };
-
- const fetchFilteredData = async () => {
- if (!rainInfwtAnlsSn || !normalizedPplMngNo) {
+ const loadResultChart = async (targetRainInfwtAnlsSn: number) => {
+ if (!targetRainInfwtAnlsSn || !normalizedPplMngNo) {
setChartData([]);
- setRdiiQty('0');
- setRainTotal('0');
- setTotalVolume('0');
+ setRdiiQty("0");
+ setRainTotal("0");
+ setTotalVolume("0");
return;
}
try {
const [rsltData, rainData, qtyData] = await Promise.all([
- fn.selectRdiiAnlsRslt(rainInfwtAnlsSn, normalizedPplMngNo),
- fn.selectRainData(rainInfwtAnlsSn),
- fn.selectPplRdiiQty(rainInfwtAnlsSn, normalizedPplMngNo),
+ fn.selectRdiiAnlsRslt(targetRainInfwtAnlsSn, normalizedPplMngNo),
+ fn.selectRainData(targetRainInfwtAnlsSn),
+ fn.selectPplRdiiQty(targetRainInfwtAnlsSn, normalizedPplMngNo),
]);
const rsltDataFormatted = fn.getChartDataRdiiAnlsRslt(rsltData ?? []);
@@ -143,7 +112,7 @@ const RdiiChart = ({ pplMngNo = '' }: ModalOpenProp) => {
}
});
- setChartData(rsltDataFormatted);// 차트 데이터 설정
+ setChartData(rsltDataFormatted);
const avgRdii = Number(qtyData?.rdiih ?? 0);
const appliedRainfall = Number(qtyData?.raintotal ?? 0);
@@ -152,18 +121,80 @@ const RdiiChart = ({ pplMngNo = '' }: ModalOpenProp) => {
? Math.round(avgRdii * Number(qtyData?.sustaintime ?? 0) / qtyData.raintotal)
: 0;
- setRdiiQty(Math.round(avgRdii * 24).toLocaleString('ko-KR'));
- setRainTotal(appliedRainfall.toLocaleString('ko-KR'));
- setTotalVolume(rdiiPerRainfall.toLocaleString('ko-KR'));
+ setRdiiQty(Math.round(avgRdii * 24).toLocaleString("ko-KR"));
+ setRainTotal(appliedRainfall.toLocaleString("ko-KR"));
+ setTotalVolume(rdiiPerRainfall.toLocaleString("ko-KR"));
} catch (error) {
- console.error('rdiiRsltChart 에러:', error);
+ console.error("RDII 분석결과 차트 조회 중 오류:", error);
setChartData([]);
- setRdiiQty('0');
- setRainTotal('0');
- setTotalVolume('0');
+ setRdiiQty("0");
+ setRainTotal("0");
+ setTotalVolume("0");
}
};
+ useEffect(() => {
+ if (!isResultOnlyMode) return;
+
+ setSelectedAplcnYm(aplcnYm);
+ setSelectedRainInfwtAnlsSn(rainInfwtAnlsSn);
+ setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS);
+ void loadResultChart(rainInfwtAnlsSn);
+ }, [aplcnYm, isResultOnlyMode, normalizedPplMngNo, rainInfwtAnlsSn]);
+
+ const handleAplcnYmChange = async (val: string | number) => {
+ const selectedValue = String(val);
+
+ setSelectedAplcnYm(selectedValue);
+ setRdiiAnlss([]);
+ setRdiiAnls(null);
+ setSelectedRainInfwtAnlsSn(0);
+ setChartData([]);
+ setRdiiQty("0");
+ setRainTotal("0");
+ setTotalVolume("0");
+
+ if (!selectedValue || selectedValue === "0") {
+ setRdiiAnlsInfos(INITIAL_ANALYSIS_OPTIONS);
+ return;
+ }
+
+ const data = await fn.selectRdiiAnls(selectedValue);
+ const list = data ?? [];
+ setRdiiAnlss(list);
+ setRdiiAnlsInfos(fn.getOptionsRdiiAnlsInfo(list));
+ };
+
+ const handleRdiiAnlsSnChange = (val: string | number) => {
+ const selectedValue = Number(val);
+
+ setSelectedRainInfwtAnlsSn(selectedValue);
+ setChartData([]);
+ setRdiiQty("0");
+ setRainTotal("0");
+ setTotalVolume("0");
+
+ if (selectedValue === 0) {
+ setRdiiAnls(null);
+ return;
+ }
+
+ const selectedAnls = rdiiAnlss.find((anls) => anls.rainInfwtAnlsSn === selectedValue) ?? null;
+ setRdiiAnls(selectedAnls);
+ };
+
+ const fetchFilteredData = async () => {
+ if (!selectedRainInfwtAnlsSn || !normalizedPplMngNo) {
+ setChartData([]);
+ setRdiiQty("0");
+ setRainTotal("0");
+ setTotalVolume("0");
+ return;
+ }
+
+ await loadResultChart(selectedRainInfwtAnlsSn);
+ };
+
const renderInfoInput = (label: string, value?: string | number | null) => (
);
- const renderBody = () => (
-
-
-
+ const renderResultPanel = () => (
+
+ RDII 분석 결과
+
+
+
+ 상수사용 적용연월
+
+
+ {selectedAplcnYm ? moment(selectedAplcnYm, "YYYYMM").format("YYYY-MM") : "-"}
+
+
+
+
+
+ 강우유입수량 분석결과
+
+
+
+
평균RDII
+
{rdiiQty}
+
m³/d
+
+
+
적용 강우량
+
{rainTotal}
+
mm
+
+
+
강우량 대비 RDII
+
{totalVolume}
+
m³/mm
+
+
+
+
+ {hasChartData ? (
+
+ ) : (
+
데이터가 없습니다.
+ )}
+
+
+ );
+
+ const renderDefaultBody = () => (
+
-
- 강우유입수분석 선택 조건
-
+ 강우유입수량 선택 조건
-
+
-
+
- {renderInfoInput('오수전환율:', rdiiAnls?.drtwSwtcRt ?? '')}
- {renderInfoInput('수용가-맨홀 매칭:', rdiiAnls?.atflMpngNm ?? '')}
- {renderInfoInput('관망도 파일명:', rdiiAnls?.atflInpNm ?? '')}
- {renderInfoInput('강우 파일명:', rdiiAnls?.atflRainNm ?? '')}
- {renderInfoInput('RTK계수 출처:', rdiiAnls?.srcNm ?? '')}
+ {renderInfoInput("오수전환율", rdiiAnls?.drtwSwtcRt ?? "")}
+ {renderInfoInput("수용가-맨홀 매칭:", rdiiAnls?.atflMpngNm ?? "")}
+ {renderInfoInput("관망도 파일명", rdiiAnls?.atflInpNm ?? "")}
+ {renderInfoInput("강우 파일명", rdiiAnls?.atflRainNm ?? "")}
+ {renderInfoInput("RTK계수 출처:", rdiiAnls?.srcNm ?? "")}
-
+
-
+
-
-
- 강우유입수분석 결과
-
-
-
- {/* 좌측 카드 */}
-
-
- 상수사용량 적용연월
-
-
- {aplcnYm ? moment(aplcnYm, 'YYYYMM').format('YYYY-MM') : '-'}
-
-
-
- {/* 우측 카드 */}
-
- {/* 좌측: 제목 (세로 가운데 정렬) */}
-
-
- {/* 우측: 지표 영역 */}
-
-
-
- 평균RDII
-
-
- {rdiiQty}
-
-
- m³/d
-
-
-
-
-
- 적용 강우량
-
-
- {rainTotal}
-
-
- mm
-
-
-
-
-
- 강우량 대비 RDII
-
-
- {totalVolume}
-
-
- m³/mm
-
-
-
-
-
-
-
- {hasChartData ? (
-
- ) : (
-
- 데이터가 없습니다.
-
- )}
-
-
+ {renderResultPanel()}
);
+ if (isResultOnlyMode) {
+ return
{renderResultPanel()}
;
+ }
+
return (
RDII 분석
- {renderBody()}
+ {renderDefaultBody()}
);
};
-export default React.memo(RdiiChart);
+export default React.memo(RdiiChart);
\ No newline at end of file
diff --git a/apps/sn/app/(map-layout)/map/components/rdiiResult/RdiiResultPopupPage.tsx b/apps/sn/app/(map-layout)/map/components/rdiiResult/RdiiResultPopupPage.tsx
new file mode 100644
index 000000000..bcda216de
--- /dev/null
+++ b/apps/sn/app/(map-layout)/map/components/rdiiResult/RdiiResultPopupPage.tsx
@@ -0,0 +1,327 @@
+"use client";
+
+import { useCallback, useEffect, useState } from "react";
+import { DateMonthPicker, UiTable, downloadExcelWithKoreanHeaders } from "@common/business_components/ui";
+import { Button } from "@common/components";
+
+import { getData } from "@/components/lib/api";
+import LoadingOverlay from "@/components/ui/LoadingBar";
+import { CtpvSggPrcsFcltSelectBox } from "@/components/ui/ctpvSggPrcsFcltSelectBox";
+import { formatDisplayData } from "@/components/lib/utils/formatDisplayValue";
+import useStore from "@/store/useStore";
+
+import {
+ RDII_RESULT_ROW_SELECT_MESSAGE,
+ type RdiiResultRow,
+} from "./rdiiResultTypes";
+
+const RDII_RESULT_PAGE_SIZE = 10;
+
+const RDII_RESULT_HEADLIST = [
+ { id: "rowNumber", title: "일련번호" },
+ { id: "ctpvNm", title: "시도" },
+ { id: "sggNm", title: "시군구" },
+ { id: "swtrmtFcltNm", title: "하수처리시설" },
+ { id: "aplcnYm", title: "상수사용연월" },
+ { id: "drtwSwtcRt", title: "오수 전환율" },
+ { id: "srcNm", title: "RTK 계수 출처" },
+ { id: "cntbArea", title: "RDII 기여면적" },
+ { id: "anlsInfo", title: "RDII 분석정보" },
+ { id: "regDt", title: "분석일자" },
+ { id: "rgtrNm", title: "분석자" },
+ { id: "scsYn", title: "분석성공여부" },
+] as const;
+
+type RdiiResultFilters = {
+ ctpvCd: string;
+ sggCd: string;
+ sggName: string;
+ swtrmtFcltNm: string;
+ aplcnYmFrom: string;
+ aplcnYmTo: string;
+};
+
+const createDefaultAplcnYm = () => {
+ const now = new Date();
+ const year = now.getFullYear();
+ const month = String(now.getMonth() + 1).padStart(2, "0");
+ return `${year}${month}`;
+};
+
+const DEFAULT_FILTERS: RdiiResultFilters = {
+ ctpvCd: "0",
+ sggCd: "0",
+ sggName: "",
+ swtrmtFcltNm: "",
+ aplcnYmFrom: `${new Date().getFullYear()}01`,
+ aplcnYmTo: createDefaultAplcnYm(),
+};
+
+const postRowSelectMessage = (row: RdiiResultRow) => {
+ if (typeof window === "undefined" || !window.opener) return;
+ window.opener.postMessage(
+ {
+ type: RDII_RESULT_ROW_SELECT_MESSAGE,
+ row,
+ },
+ window.location.origin,
+ );
+};
+
+export default function RdiiResultPopupPage() {
+ const { ctpv, sgg, fetchCtpv, fetchSgg } = useStore();
+ const [filters, setFilters] = useState
(DEFAULT_FILTERS);
+ const [selectedSwagePrcsFclt, setSelectedSwagePrcsFclt] = useState("0");
+ const [selectedRow, setSelectedRow] = useState(null);
+ const [rows, setRows] = useState([]);
+ const [total, setTotal] = useState(0);
+ const [currentPage, setCurrentPage] = useState(1);
+ const [selectedIndex, setSelectedIndex] = useState(-1);
+ const [isLoading, setIsLoading] = useState(false);
+
+ useEffect(() => {
+ if (ctpv.length === 0) void fetchCtpv();
+ if (sgg.length === 0) void fetchSgg();
+ }, [ctpv.length, fetchCtpv, fetchSgg, sgg.length]);
+
+ const fetchRows = useCallback(
+ async (page: number, nextFilters: RdiiResultFilters) => {
+ const queryParams = new URLSearchParams({
+ page: String(page - 1),
+ size: String(RDII_RESULT_PAGE_SIZE),
+ sort: "rainInfwtAnlsSn,desc",
+ });
+
+ if (nextFilters.aplcnYmFrom) queryParams.set("aplcnYmFrom", nextFilters.aplcnYmFrom);
+ if (nextFilters.aplcnYmTo) queryParams.set("aplcnYmTo", nextFilters.aplcnYmTo);
+ if (nextFilters.ctpvCd !== "0") queryParams.set("ctpvCd", nextFilters.ctpvCd);
+ if (nextFilters.sggCd !== "0") queryParams.set("sggCd", nextFilters.sggCd);
+ if (nextFilters.swtrmtFcltNm.trim()) queryParams.set("swtrmtFcltNm", nextFilters.swtrmtFcltNm.trim());
+
+ const response = await getData(`v1/rdiiAnls?${queryParams.toString()}`);
+ const content = Array.isArray(response?.content) ? response.content : [];
+
+ const nextRows = content
+ .map((item: Record, index: number) => {
+ const formattedItem = formatDisplayData(item);
+ const ctpvOption = ctpv.find((code) => code.val.trim() === String(item?.ctpvCd ?? "").trim());
+ const sggOption = sgg.find((code) => code.val === item?.sggCd);
+
+ return {
+ ...(formattedItem as Record),
+ rowNumber: (page - 1) * RDII_RESULT_PAGE_SIZE + index + 1,
+ ctpvNm: ctpvOption ? ctpvOption.text : String(item?.ctpvCd ?? "-"),
+ sggNm: sggOption ? sggOption.text : String(item?.sggCd ?? "-"),
+ scsYn: String(item?.scsYn ?? "N"),
+ } as RdiiResultRow;
+ })
+ .filter((item: RdiiResultRow) => item.scsYn === "Y");
+
+ setRows(nextRows);
+ setTotal(Number(response?.totalElements ?? nextRows.length));
+ setCurrentPage(page);
+ },
+ [ctpv, sgg],
+ );
+
+ const loadRows = useCallback(
+ async (page = 1, nextFilters = filters) => {
+ setIsLoading(true);
+ try {
+ await fetchRows(page, nextFilters);
+ } catch (error) {
+ console.error("RDII 분석결과 목록 조회 중 오류:", error);
+ alert("RDII 분석결과 목록을 불러오지 못했습니다.");
+ setRows([]);
+ setTotal(0);
+ } finally {
+ setIsLoading(false);
+ }
+ },
+ [fetchRows, filters],
+ );
+
+ useEffect(() => {
+ void loadRows(1, DEFAULT_FILTERS);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ const handleSearch = async (page = 1) => {
+ setSelectedIndex(-1);
+ setSelectedRow(null);
+ await loadRows(page, filters);
+ };
+
+ const handleRowClick = (index?: number) => {
+ if (typeof index !== "number") return;
+ const row = rows[index];
+ if (!row) return;
+
+ setSelectedIndex(index);
+ setSelectedRow(row);
+ postRowSelectMessage(row);
+ };
+
+ const handleDownload = async () => {
+ if (!selectedRow?.rainInfwtAnlsSn) {
+ alert("다운로드할 분석결과를 먼저 선택해주세요.");
+ return;
+ }
+
+ try {
+ setIsLoading(true);
+ const response = await getData(`v1/rdiiAnlsRslt/ppl/${selectedRow.rainInfwtAnlsSn}`);
+ const excelRows = Array.isArray(response?.content) ? response.content : [];
+
+ await downloadExcelWithKoreanHeaders({
+ data: excelRows as JSON[],
+ fileName: `RDII분석결과_${selectedRow.swtrmtFcltNm}_${selectedRow.aplcnYm}_${selectedRow.rainInfwtAnlsSn}`,
+ sheetNameArray: ["RDII 분석결과"],
+ headerRange: "A1:D1",
+ headerMapping: {
+ rainInfwtAnlsSn: "RDII분석\n일련번호",
+ pplMngNo: "관로\n관리번호",
+ anlsTm: "분석시각",
+ predcOilq: "예측유량\n(m³/h)",
+ },
+ });
+ } catch (error) {
+ console.error("RDII 분석결과 다운로드 중 오류:", error);
+ alert("RDII 분석결과 다운로드 중 오류가 발생했습니다.");
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+ 상수사용기간
+ {
+ setFilters((current) => ({
+ ...current,
+ aplcnYmFrom: value,
+ }));
+ },
+ }}
+ selectClass="w-[145px]"
+ startYear={1900}
+ />
+ ~
+ {
+ setFilters((current) => ({
+ ...current,
+ aplcnYmTo: value,
+ }));
+ },
+ }}
+ selectClass="w-[145px]"
+ startYear={1900}
+ />
+
+
+
+ {
+ setSelectedSwagePrcsFclt("0");
+ setFilters((current) => ({
+ ...current,
+ ctpvCd: value,
+ sggCd: "0",
+ sggName: "",
+ swtrmtFcltNm: "",
+ }));
+ }}
+ onSigunguChange={(value) => {
+ setSelectedSwagePrcsFclt("0");
+ setFilters((current) => ({
+ ...current,
+ sggCd: value,
+ swtrmtFcltNm: "",
+ }));
+ }}
+ setSggName={(value) => {
+ setSelectedSwagePrcsFclt("0");
+ setFilters((current) => ({
+ ...current,
+ sggName: value ?? "",
+ swtrmtFcltNm: "",
+ }));
+ }}
+ selectedSwagePrcsFclt={selectedSwagePrcsFclt}
+ onSwagePrcsFcltChange={setSelectedSwagePrcsFclt}
+ setSwtrmtFcltNm={(value) =>
+ setFilters((current) => ({
+ ...current,
+ swtrmtFcltNm: value ?? "",
+ }))
+ }
+ setIsLoading={setIsLoading}
+ />
+
+
+
+
+
+
+
+
+
+
+
+ headName={<>{`분석이력 총 ${total.toLocaleString()}건`}>}
+ tableData={rows}
+ headlist={RDII_RESULT_HEADLIST as unknown as { id: string; title: string }[]}
+ pageSize={RDII_RESULT_PAGE_SIZE}
+ total={total}
+ cellClick={(index) => handleRowClick(index)}
+ onPageChange={(page) => void handleSearch(page)}
+ curPage={currentPage}
+ index={selectedIndex}
+ widthFixed={true}
+ />
+
+
+ {selectedRow ? (
+
+ {"선택 분석: "}
+ {selectedRow.anlsInfo}
+
+ ) : null}
+
+
+ );
+}
\ No newline at end of file
diff --git a/apps/sn/app/(map-layout)/map/components/rdiiResult/rdiiResultTypes.ts b/apps/sn/app/(map-layout)/map/components/rdiiResult/rdiiResultTypes.ts
new file mode 100644
index 000000000..30604e653
--- /dev/null
+++ b/apps/sn/app/(map-layout)/map/components/rdiiResult/rdiiResultTypes.ts
@@ -0,0 +1,46 @@
+"use client";
+
+export const RDII_RESULT_ROW_SELECT_MESSAGE = "SN_RDII_RESULT_ROW_SELECT";
+export const RDII_RESULT_OVERLAY_TYPE = "RDII_RESULT";
+
+export type RdiiResultRow = {
+ rowNumber: number;
+ rainInfwtAnlsSn: number;
+ ctpvCd?: string;
+ ctpvNm: string;
+ sggCd?: string;
+ sggNm: string;
+ swtrmtFcltNm: string;
+ aplcnYm: string;
+ drtwSwtcRt?: number | string;
+ srcNm?: string;
+ cntbArea?: number | string;
+ anlsInfo: string;
+ regDt?: string;
+ rgtrNm?: string;
+ scsYn?: string;
+};
+
+export type RdiiResultMapViewPipe = {
+ pplMngNo: string;
+ fcltMngNo: string;
+};
+
+export type RdiiResultMapViewResponse = {
+ analysis: {
+ rainInfwtAnlsSn: number;
+ aplcnYm: string;
+ ctpvCd?: string;
+ sggCd?: string;
+ swtrmtFcltNm?: string;
+ anlsInfo?: string;
+ };
+ focusTargetType: "PIPE_EXTENT";
+ focusTargetName: string;
+ focusLayerType?: "tb_ms_swage_ppl";
+ focusFid?: string;
+ focusFallbackApplied?: boolean;
+ pipeGeometry: Record;
+ pipes: RdiiResultMapViewPipe[];
+ pipeCount: number;
+};
\ No newline at end of file
diff --git a/apps/sn/app/(map-layout)/map/components/rdiiResult/useRdiiResultMap.ts b/apps/sn/app/(map-layout)/map/components/rdiiResult/useRdiiResultMap.ts
new file mode 100644
index 000000000..bca19cc0b
--- /dev/null
+++ b/apps/sn/app/(map-layout)/map/components/rdiiResult/useRdiiResultMap.ts
@@ -0,0 +1,349 @@
+"use client";
+
+import { useCallback, useEffect, useRef, useState, type MutableRefObject } from "react";
+import GeoJSON from "ol/format/GeoJSON.js";
+import VectorLayer from "ol/layer/Vector.js";
+import VectorSource from "ol/source/Vector.js";
+import Stroke from "ol/style/Stroke.js";
+import Style from "ol/style/Style.js";
+
+import { getRawJson } from "@/components/lib/api";
+import { openWindowPopup } from "@/features/windowPopup/lib/openWindowPopup";
+
+import GisApp from "@common/business_components/ui/map/lib/gis.core";
+import { getSigunguCenter, moveMapToCenter, sidoCenter } from "@common/business_components/ui/map/searchBar/utils";
+
+import {
+ RDII_RESULT_OVERLAY_TYPE,
+ RDII_RESULT_ROW_SELECT_MESSAGE,
+ type RdiiResultMapViewResponse,
+ type RdiiResultRow,
+} from "./rdiiResultTypes";
+
+type UseRdiiResultMapParams = {
+ gisMaps: MutableRefObject;
+ setFeatureData: (value: any) => void;
+ setIsOpen: (value: boolean) => void;
+ setIsSearchModalOpen: (value: boolean) => void;
+};
+
+const RDII_PIPE_LAYER_ID = "SN_RDII_RESULT_PIPE_LAYER";
+const DEFAULT_RESULT_FIT_PADDING: [number, number, number, number] = [120, 120, 120, 120];
+const PROC_SEARCH_EVENT = "SN_INFTWT_PROC_SEARCH";
+
+const pipeStyle = [
+ new Style({
+ stroke: new Stroke({
+ color: "rgba(15, 23, 42, 0.56)",
+ width: 9,
+ lineCap: "round",
+ lineJoin: "round",
+ }),
+ zIndex: 20020,
+ }),
+ new Style({
+ stroke: new Stroke({
+ color: "rgba(255, 255, 255, 0.98)",
+ width: 5,
+ lineCap: "round",
+ lineJoin: "round",
+ }),
+ zIndex: 20021,
+ }),
+ new Style({
+ stroke: new Stroke({
+ color: "rgba(59, 130, 246, 0.98)",
+ width: 2.5,
+ lineCap: "round",
+ lineJoin: "round",
+ }),
+ zIndex: 20022,
+ }),
+];
+
+const getFeatureCollection = (payload: any) => {
+ if (payload?.type === "FeatureCollection") return payload;
+ if (payload?.data?.type === "FeatureCollection") return payload.data;
+ return { type: "FeatureCollection", features: [] };
+};
+
+const normalizeProjectionName = (value: string) => {
+ const trimmed = String(value ?? "").trim();
+ if (!trimmed) return "EPSG:4326";
+ if (trimmed.startsWith("EPSG:")) return trimmed;
+ const match = trimmed.match(/EPSG[:/]{1,2}(\d{4,5})/i) || trimmed.match(/(\d{4,5})$/);
+ return match?.[1] ? `EPSG:${match[1]}` : trimmed;
+};
+
+const resolveFeatureCollectionProjection = (payload: any) => {
+ const featureCollection = getFeatureCollection(payload);
+ const crsName = String(featureCollection?.crs?.properties?.name ?? "").trim();
+ return normalizeProjectionName(crsName || GisApp.TO_PROJ);
+};
+
+const getOverlayFlag = (data: any) =>
+ String(
+ data?.get?.("analysisOverlayType") ??
+ data?.values_?.analysisOverlayType ??
+ data?.analysisOverlayType ??
+ "",
+ ).trim();
+
+const getOverlayBasePplMngNo = (data: any) =>
+ String(
+ data?.get?.("fcltMngNo") ??
+ data?.values_?.fcltMngNo ??
+ data?.values_?.fclt_mng_no ??
+ data?.fcltMngNo ??
+ data?.fclt_mng_no ??
+ "",
+ ).trim();
+
+const getOverlayAnalysisPplMngNo = (data: any) =>
+ String(
+ data?.get?.("pplMngNo") ??
+ data?.values_?.pplMngNo ??
+ data?.pplMngNo ??
+ "",
+ ).trim();
+
+const getOverlayAnalysisSn = (data: any) =>
+ Number(
+ data?.get?.("rainInfwtAnlsSn") ??
+ data?.values_?.rainInfwtAnlsSn ??
+ data?.rainInfwtAnlsSn ??
+ 0,
+ );
+
+const getOverlayAplcnYm = (data: any) =>
+ String(
+ data?.get?.("aplcnYm") ??
+ data?.values_?.aplcnYm ??
+ data?.aplcnYm ??
+ "",
+ ).trim();
+
+const getOverlayAnalysisInfo = (data: any) =>
+ String(
+ data?.get?.("analysisInfo") ??
+ data?.values_?.analysisInfo ??
+ data?.analysisInfo ??
+ "",
+ ).trim();
+
+export const useRdiiResultMap = ({
+ gisMaps,
+ setFeatureData,
+ setIsOpen,
+ setIsSearchModalOpen,
+}: UseRdiiResultMapParams) => {
+ const activeResultRowRef = useRef(null);
+ const pipeLayerRef = useRef | null>(null);
+ const pipeSourceRef = useRef(null);
+ const mapViewCacheRef = useRef