sn: 침수흔적깊이 정보 추가
This commit is contained in:
@@ -52,8 +52,7 @@ const resolveFldngHstryMapFeatureFid = (row: FldngHstryTableRow) => {
|
|||||||
if (fid.startsWith(`${FLOOD_HISTORY_LAYER_TYPE}.`)) return fid;
|
if (fid.startsWith(`${FLOOD_HISTORY_LAYER_TYPE}.`)) return fid;
|
||||||
if (fid) return `${FLOOD_HISTORY_LAYER_TYPE}.${fid}`;
|
if (fid) return `${FLOOD_HISTORY_LAYER_TYPE}.${fid}`;
|
||||||
|
|
||||||
const mapFid = String(row.fldngMapFid ?? "").trim();
|
return "";
|
||||||
return mapFid || "";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildDownloadRows = (rows: FldngHstryTableRow[]) =>
|
const buildDownloadRows = (rows: FldngHstryTableRow[]) =>
|
||||||
@@ -123,6 +122,7 @@ export default function FldngHstryPopupPage() {
|
|||||||
|
|
||||||
const fldngYearOptions = useMemo(() => buildFldngHstryYearOptions(), []);
|
const fldngYearOptions = useMemo(() => buildFldngHstryYearOptions(), []);
|
||||||
|
|
||||||
|
|
||||||
const sggOptions = useMemo(
|
const sggOptions = useMemo(
|
||||||
() =>
|
() =>
|
||||||
filters.ctpvCd === "0"
|
filters.ctpvCd === "0"
|
||||||
@@ -295,7 +295,7 @@ export default function FldngHstryPopupPage() {
|
|||||||
시도
|
시도
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
className="h-[3.2rem] w-[16rem] rounded-md border border-input bg-field px-3 text-[1.3rem]"
|
className="h-[3.2rem] w-[12rem] rounded-md border border-input bg-field px-3 text-[1.3rem]"
|
||||||
value={filters.ctpvCd}
|
value={filters.ctpvCd}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setFilters((current) => ({
|
setFilters((current) => ({
|
||||||
@@ -342,7 +342,7 @@ export default function FldngHstryPopupPage() {
|
|||||||
침수발생년도
|
침수발생년도
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
className="h-[3.2rem] w-[14rem] rounded-md border border-input bg-field px-3 text-[1.3rem]"
|
className="h-[3.2rem] w-[8rem] rounded-md border border-input bg-field px-3 text-[1.3rem]"
|
||||||
value={filters.floodYear}
|
value={filters.floodYear}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
setFilters((current) => ({
|
setFilters((current) => ({
|
||||||
@@ -360,6 +360,24 @@ export default function FldngHstryPopupPage() {
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label className="flex items-center gap-2">
|
||||||
|
<span className="whitespace-nowrap text-[1.3rem] text-label">강우시작일</span>
|
||||||
|
<Input
|
||||||
|
className="w-[11rem]"
|
||||||
|
type="date"
|
||||||
|
value={filters.rainStartDate}
|
||||||
|
min={filters.floodYear ? `${filters.floodYear}-01-01` : undefined}
|
||||||
|
max={filters.floodYear ? `${filters.floodYear}-12-31` : undefined}
|
||||||
|
disabled={!filters.floodYear}
|
||||||
|
onChange={(event) => setFilters((current) => ({ ...current, rainStartDate: event.target.value }))}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label className="flex items-center gap-2">
|
||||||
|
<span className="whitespace-nowrap text-[1.3rem] text-label">침수지구명</span>
|
||||||
|
<Input type="text" value={filters.districtName} onChange={(event) => setFilters((current) => ({ ...current, districtName: event.target.value }))} onKeyDown={(event) => { if (event.key === "Enter") void handleSearch(1); }} />
|
||||||
|
</label>
|
||||||
|
|
||||||
<label className="flex items-center gap-2">
|
<label className="flex items-center gap-2">
|
||||||
<span className="whitespace-nowrap text-[1.3rem] text-label">
|
<span className="whitespace-nowrap text-[1.3rem] text-label">
|
||||||
침수재해명
|
침수재해명
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ export type FldngHstryFilters = {
|
|||||||
sggCd: string;
|
sggCd: string;
|
||||||
floodYear: string;
|
floodYear: string;
|
||||||
disasterName: string;
|
disasterName: string;
|
||||||
|
rainStartDate: string;
|
||||||
|
districtName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FldngHstryDepthZone = {
|
export type FldngHstryDepthZone = {
|
||||||
@@ -108,6 +110,8 @@ export const FLDNG_HSTRY_DEFAULT_FILTERS: FldngHstryFilters = {
|
|||||||
sggCd: "0",
|
sggCd: "0",
|
||||||
floodYear: "",
|
floodYear: "",
|
||||||
disasterName: "",
|
disasterName: "",
|
||||||
|
rainStartDate: "",
|
||||||
|
districtName: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FLDNG_HSTRY_DEPTH_LEGEND_ITEMS = [
|
export const FLDNG_HSTRY_DEPTH_LEGEND_ITEMS = [
|
||||||
@@ -350,6 +354,8 @@ export const normalizeFldngHstryFilters = (
|
|||||||
.replace(/[^0-9]/g, "")
|
.replace(/[^0-9]/g, "")
|
||||||
.slice(0, 4),
|
.slice(0, 4),
|
||||||
disasterName: String(filters.disasterName ?? "").trim(),
|
disasterName: String(filters.disasterName ?? "").trim(),
|
||||||
|
rainStartDate: String(filters.rainStartDate ?? "").trim(),
|
||||||
|
districtName: String(filters.districtName ?? "").trim(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const buildFldngHstryYearOptions = () => {
|
export const buildFldngHstryYearOptions = () => {
|
||||||
@@ -375,6 +381,8 @@ export const buildFldngHstryListQueryString = (
|
|||||||
if (normalized.floodYear) params.set("fldngYr", normalized.floodYear);
|
if (normalized.floodYear) params.set("fldngYr", normalized.floodYear);
|
||||||
if (normalized.disasterName)
|
if (normalized.disasterName)
|
||||||
params.set("fldngDstrNm", normalized.disasterName);
|
params.set("fldngDstrNm", normalized.disasterName);
|
||||||
|
if (normalized.rainStartDate) params.set("rainBgngTm", normalized.rainStartDate);
|
||||||
|
if (normalized.districtName) params.set("fldngDstrctNm", normalized.districtName);
|
||||||
return params.toString();
|
return params.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ import {
|
|||||||
isInvalidInstallYmd,
|
isInvalidInstallYmd,
|
||||||
} from "../agedPipe/agedPipeUtils";
|
} from "../agedPipe/agedPipeUtils";
|
||||||
import { openWindowPopup } from "@/features/windowPopup/lib/openWindowPopup";
|
import { openWindowPopup } from "@/features/windowPopup/lib/openWindowPopup";
|
||||||
|
import { WINDOW_POPUP_MESSAGE_TYPE } from "@/features/windowPopup/model/types";
|
||||||
import { useAlertStore } from "@/shared/lib";
|
import { useAlertStore } from "@/shared/lib";
|
||||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||||
import useStore from "@/store/useStore";
|
import useStore from "@/store/useStore";
|
||||||
@@ -777,6 +778,9 @@ const FeatureClickEventPopup = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (selectedLayerName === "침수흔적수위" && featureId) {
|
if (selectedLayerName === "침수흔적수위" && featureId) {
|
||||||
|
const depthLookupKey = normalizeFldngWtlvMapApiFid(featureId);
|
||||||
|
setFloodDepthRows([]);
|
||||||
|
setSelectedFloodDepthYear(null);
|
||||||
try {
|
try {
|
||||||
const normalizedFloodMapFid =
|
const normalizedFloodMapFid =
|
||||||
normalizeFldngWtlvMapApiFid(featureId);
|
normalizeFldngWtlvMapApiFid(featureId);
|
||||||
@@ -794,27 +798,27 @@ const FeatureClickEventPopup = ({
|
|||||||
setFetchData(mergedData);
|
setFetchData(mergedData);
|
||||||
setTableData(mergedData);
|
setTableData(mergedData);
|
||||||
}
|
}
|
||||||
const depthDataSn = Number(
|
} catch (rainError) {
|
||||||
data?.data_sn ?? data?.dataSn ?? formattedData?.data_sn ?? formattedData?.dataSn,
|
console.warn("침수강우분석 조회 실패:", rainError);
|
||||||
);
|
}
|
||||||
if (Number.isFinite(depthDataSn)) {
|
try {
|
||||||
|
if (depthLookupKey) {
|
||||||
const depthRows = await getData(
|
const depthRows = await getData(
|
||||||
`v1/fldng/hstry/depth-map/${encodeURIComponent(String(depthDataSn))}`,
|
`v1/fldng/hstry/depth-map/${encodeURIComponent(depthLookupKey)}`,
|
||||||
);
|
);
|
||||||
const normalizedDepthRows = Array.isArray(depthRows)
|
const depthPayload = depthRows?.data ?? depthRows;
|
||||||
? depthRows.filter((row) => row && typeof row === "object")
|
const normalizedDepthRows = Array.isArray(depthPayload)
|
||||||
|
? depthPayload.filter((row) => row && typeof row === "object")
|
||||||
: [];
|
: [];
|
||||||
setFloodDepthRows(normalizedDepthRows);
|
setFloodDepthRows(normalizedDepthRows);
|
||||||
const years = normalizedDepthRows
|
const years = normalizedDepthRows
|
||||||
.map((row) => String(row.fldng_yr ?? row.fldngYr ?? row.yr ?? "").trim())
|
.map((row) => String(row.fldng_yr ?? row.fldngYr ?? row.yr ?? "").trim())
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
setSelectedFloodDepthYear(years[0] ?? null);
|
// 최초에는 연도를 선택하지 않고 목록만 표시한다.
|
||||||
} else {
|
|
||||||
setFloodDepthRows([]);
|
|
||||||
setSelectedFloodDepthYear(null);
|
setSelectedFloodDepthYear(null);
|
||||||
}
|
}
|
||||||
} catch (rainError) {
|
} catch (depthError) {
|
||||||
console.warn("침수강우분석 조회 실패:", rainError);
|
console.warn("침수깊이지도 조회 실패:", depthError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1066,7 +1070,27 @@ const FeatureClickEventPopup = ({
|
|||||||
<button
|
<button
|
||||||
key={year}
|
key={year}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setSelectedFloodDepthYear(year)}
|
onClick={() => {
|
||||||
|
setSelectedFloodDepthYear(year);
|
||||||
|
const selectedDepthRow = floodDepthRows.find(
|
||||||
|
(row) => String(row.fldng_yr ?? row.fldngYr ?? row.yr ?? "").trim() === year,
|
||||||
|
);
|
||||||
|
const depthFid = String(
|
||||||
|
selectedDepthRow?.fldng_dpth_map_sn ?? selectedDepthRow?.fid ?? "",
|
||||||
|
).trim();
|
||||||
|
if (depthFid) {
|
||||||
|
window.opener?.postMessage(
|
||||||
|
{
|
||||||
|
type: WINDOW_POPUP_MESSAGE_TYPE.MAP_SEARCH_SELECT_FEATURE,
|
||||||
|
payload: {
|
||||||
|
layerNm: "tb_ms_fldng_dpth_map",
|
||||||
|
fid: `tb_ms_fldng_dpth_map.${depthFid.replace(/^tb_ms_fldng_dpth_map\./, "")}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
window.location.origin,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
className={`rounded-full border px-3 py-1 text-sm ${selectedFloodDepthYear === year ? "border-blue-600 bg-blue-600 text-white" : "border-blue-400 bg-transparent text-blue-600"}`}
|
className={`rounded-full border px-3 py-1 text-sm ${selectedFloodDepthYear === year ? "border-blue-600 bg-blue-600 text-white" : "border-blue-400 bg-transparent text-blue-600"}`}
|
||||||
>
|
>
|
||||||
{year}
|
{year}
|
||||||
@@ -1075,6 +1099,19 @@ const FeatureClickEventPopup = ({
|
|||||||
</div>
|
</div>
|
||||||
<button type="button" aria-label="다음 연도" className="shrink-0 px-1 text-blue-600" onClick={() => floodDepthYearListRef.current?.scrollBy({ left: 120, behavior: "smooth" })}>›</button>
|
<button type="button" aria-label="다음 연도" className="shrink-0 px-1 text-blue-600" onClick={() => floodDepthYearListRef.current?.scrollBy({ left: 120, behavior: "smooth" })}>›</button>
|
||||||
</div>
|
</div>
|
||||||
|
{selectedFloodDepthYear && (
|
||||||
|
<>
|
||||||
|
<div className="mb-2 flex items-center justify-between border-b border-border pb-2">
|
||||||
|
<span className="text-sm font-semibold text-label">침수흔적깊이 정보</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label="침수흔적깊이 정보 닫기"
|
||||||
|
className="rounded px-2 text-lg leading-none text-muted-foreground hover:bg-accent"
|
||||||
|
onClick={() => setSelectedFloodDepthYear(null)}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div className="max-h-64 overflow-auto">
|
<div className="max-h-64 overflow-auto">
|
||||||
<table className="w-full border-collapse text-sm">
|
<table className="w-full border-collapse text-sm">
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -1091,6 +1128,8 @@ const FeatureClickEventPopup = ({
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{ContentComponent && (
|
{ContentComponent && (
|
||||||
|
|||||||
Reference in New Issue
Block a user