Merge branch 'iipbs/wr/dev' of https://www.onasys.co.kr:3000/ONAANDALL/frontend into iipbs/wr/dev
This commit is contained in:
@@ -24,7 +24,7 @@ const Map = () => {
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await mapService.getLyrStngs();
|
||||
const response = await mapService.getLyrStngs('WR_NETWORK');
|
||||
setTreeData(response); // API 응답 저장
|
||||
} catch (error) {
|
||||
console.error("데이터 불러오기 실패:", error);
|
||||
|
||||
@@ -30,8 +30,8 @@ export type LyrStngProps = {
|
||||
|
||||
export const mapService = {
|
||||
//레이어 설정 조회
|
||||
getLyrStngs: async () => {
|
||||
const response = await fetch(`${API_URL}/lyrStngs/WR_NETWORK`, {
|
||||
getLyrStngs: async (lyrGrp : string) => {
|
||||
const response = await fetch(`${API_URL}/lyrStngs/${lyrGrp}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { Label } from "@common/components/ui/label";
|
||||
|
||||
export const DRGT_LAYER_TYPES: string[] = [
|
||||
// 수정 필요
|
||||
'drought1',
|
||||
'drought2',
|
||||
'drought3',
|
||||
'drought4',
|
||||
'drought5',
|
||||
'drought6',
|
||||
];
|
||||
// 지정된 순서에 따른 lyr_sn 배열
|
||||
export const EXPRS_ORDERED_LAYERS: string[] = [
|
||||
// 수정 필요
|
||||
'106', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 30년 빈도
|
||||
'107', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 50년 빈도
|
||||
'108', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 80년 빈도
|
||||
'109', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 100년 빈도
|
||||
'110', // 도시침수지도(tb_ms_flood_dngr_map) - 30년 빈도
|
||||
'111', // 도시침수지도(tb_ms_flood_dngr_map) - 50년 빈도
|
||||
];
|
||||
|
||||
export function DrgtLegend() {
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-white rounded-lg shadow-lg border border-gray-200 w-[160px] px-4 py-3">
|
||||
<div className="flex items-center justify-between mx-2 my-4">
|
||||
<Label className="text-3xl text-gray-900 font-bold">가뭄정보 범례</Label>
|
||||
</div>
|
||||
<div className="mb-3">
|
||||
<div className="w-full bg-gray-200 rounded-full h-1">
|
||||
<div className="bg-blue-900 h-1 rounded-full transition-all duration-300 ease-in-out" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-[140px] mx-auto flex flex-col items-center">
|
||||
<div className="bg-blue-900 text-white text-2xl text-center py-1 mb-2 rounded w-full">가 뭄 정 보</div>
|
||||
<div className="space-y-1 w-full">
|
||||
<Label className="text-xl text-gray-900 font-bold">관심</Label>
|
||||
<LegendItem color="rgba(222,235,247, 1)" label="1회 미만" /> {/* 관심 - 1회 미만 */}
|
||||
<LegendItem color="rgba(46, 117, 182, 1)" label="1회 이상" /> {/* 관심 - 1회 이상 */}
|
||||
<Label className="text-xl text-gray-900 font-bold">주의</Label>
|
||||
<LegendItem color="rgba(255, 242, 204, 1)" label="1회 미만" /> {/* 주의 - 1회 미만 */}
|
||||
<LegendItem color="rgba(255, 217, 102, 1)" label="1회 이상" /> {/* 주의 - 1회 이상 */}
|
||||
<Label className="text-xl text-gray-900 font-bold">관심 + 주의</Label>
|
||||
<LegendItem color="rgba(251, 229, 214, 1)" label="1회 미만" /> {/* 관심+주의 - 1회 미만 */}
|
||||
<LegendItem color="rgba(237, 125, 49, 1)" label="1회 이상" /> {/* 관심+주의 - 1회 이상 */}
|
||||
</div>
|
||||
<div className="border-t-2 border-blue-900 mt-1 mx-auto w-full" />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function LegendItem({ color, label }: { color: string; label: string }) {
|
||||
return (
|
||||
<div className="flex items-center gap-2 w-full">
|
||||
<span
|
||||
className="inline-block w-16 h-6"
|
||||
style={{ backgroundColor: color, border: "1px solid #ccc" }}
|
||||
/>
|
||||
<span className="text-xl text-gray-900 font-bold">{label}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { boundingExtent, getCenter } from 'ol/extent';
|
||||
import Feature from 'ol/Feature';
|
||||
import Geometry from 'ol/geom/Geometry';
|
||||
|
||||
export function medianCoordinate2D(feature: Feature<Geometry>) {
|
||||
// Feature를 입력 받아 중심 좌표를 계산하는 함수
|
||||
if (!feature) {
|
||||
console.warn("유효한 피처가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(feature)
|
||||
|
||||
const geometry = feature.getGeometry();
|
||||
if (!geometry) {
|
||||
console.warn("피처에 geometry가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
const extent = geometry.getExtent();
|
||||
const center = getCenter(extent);
|
||||
const centerExtent = boundingExtent([center]);
|
||||
return centerExtent;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
"use client";
|
||||
|
||||
import Gis from "@common/business_components/ui/map/Gis";
|
||||
import { useEffect, useRef, useState, useCallback } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { mapService } from "../../(map-layout)/service";
|
||||
import { DrgtLegend, DRGT_LAYER_TYPES, EXPRS_ORDERED_LAYERS } from "./drgtLegend";
|
||||
import { SearchBar } from "./searchBar";
|
||||
|
||||
|
||||
export default function MapDrgtPopUp() {
|
||||
const searchParams = useSearchParams();
|
||||
const ctpvCd = searchParams.get('ctpvCd') || '';
|
||||
const sggCd = searchParams.get('sggCd') || '';
|
||||
const fromDate = searchParams.get('fromDate') || '';
|
||||
const toDate = searchParams.get('toDate') || '';
|
||||
|
||||
const gisMaps = useRef<any | null>(null);
|
||||
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
|
||||
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
|
||||
const [showDrgtLegend, setShowDrgtLegend] = useState(false); // DrgtLegend 표시 여부
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
|
||||
// 컴포넌트 마운트 시 1회 실행
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
function fetchData() {
|
||||
(async () => {
|
||||
try {
|
||||
const response = await mapService.getLyrStngs('WR_DROUGHT');
|
||||
setTreeData(response); // API 응답 저장
|
||||
console.log("Drought layers fetched:", response);
|
||||
} catch (error) {
|
||||
console.error("데이터 불러오기 실패:", error);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
// WaterDepth 표시 여부를 결정하는 함수
|
||||
const handleDrgtLegndVisibility = useCallback((checkedIds: string[], checkedNodesData: any[]) => {
|
||||
const drgtLegndLayers = checkedNodesData.filter(node =>
|
||||
DRGT_LAYER_TYPES.includes(node.data?.lyrTyNm)
|
||||
);
|
||||
|
||||
const hasDrgtLegndLayer = drgtLegndLayers.length > 0;
|
||||
setShowDrgtLegend(hasDrgtLegndLayer);
|
||||
}, []);
|
||||
|
||||
// 체크된 레이어 변경 처리 함수
|
||||
const handleCheckedLayersChange = useCallback((checkedIds: string[], checkedNodesData: any[]) => {
|
||||
handleDrgtLegndVisibility(checkedIds, checkedNodesData);
|
||||
}, [handleDrgtLegndVisibility]);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="bg-container">
|
||||
<Gis
|
||||
treeData={treeData}
|
||||
isSearch={false}
|
||||
gisMaps={gisMaps}
|
||||
isMiniMap={false}
|
||||
searchView={undefined}
|
||||
detailView={undefined}
|
||||
onFeatureSelect={undefined}
|
||||
setIsOpen={setIsOpen}
|
||||
setFeatureData={undefined}
|
||||
featureData={undefined}
|
||||
setIsSearchModalOpen={undefined}
|
||||
isOpen={isOpen}
|
||||
isSearchModalOpen={undefined}
|
||||
onCheckedLayersChange={handleCheckedLayersChange}
|
||||
imgVisble={true}
|
||||
searchBar={<SearchBar gisMaps={gisMaps} ctpvCode={ctpvCd} sggCode={sggCd} fromDate={fromDate} toDate={toDate} />}
|
||||
waterDepth={showDrgtLegend ? DrgtLegend : undefined}
|
||||
isPlaying={isPlaying}
|
||||
setIsPlaying={setIsPlaying as any}
|
||||
targetLayerTypes={DRGT_LAYER_TYPES as any}
|
||||
orderedLayers={EXPRS_ORDERED_LAYERS as any}
|
||||
checkInterval={2500}
|
||||
height={`h-[100vh]`}
|
||||
droughtDates={{ startYmd: fromDate, endYmd: toDate }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { SelectBox } from '@common/business_components/ui'
|
||||
import { Label, Button } from '@common/components';
|
||||
import { type SelectDataType } from "@common/business_components/ui";
|
||||
import GisApp from "@common/business_components/ui/map/lib/gis.core";
|
||||
import GeoJSON from "ol/format/GeoJSON";
|
||||
import Feature from "ol/Feature";
|
||||
import Geometry from "ol/geom/Geometry";
|
||||
import { medianCoordinate2D } from "./median";
|
||||
|
||||
interface CtpvSggPrcsFcltSelectBoxProps {
|
||||
gisMaps: React.RefObject<any>;
|
||||
ctpvCode: string;
|
||||
sggCode: string;
|
||||
fromDate: string;
|
||||
toDate: string;
|
||||
}
|
||||
|
||||
const DEFAULT_OPTION: SelectDataType = { val: '0', text: '전체' };
|
||||
|
||||
export function SearchBar({ gisMaps, ctpvCode, sggCode }: CtpvSggPrcsFcltSelectBoxProps) {
|
||||
const [ctpvCd, setCtpvCd] = useState<string>(ctpvCode);
|
||||
const [sggCd, setSggCd] = useState<string>(sggCode);
|
||||
const [ctpv, setCtpv] = useState<SelectDataType[]>([]);
|
||||
const [sgg, setSgg] = useState<SelectDataType[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
await fetchSido();
|
||||
await fetchSigungu();
|
||||
setCtpvCd(ctpvCode);
|
||||
setSggCd(sggCode);
|
||||
})();
|
||||
}, []);
|
||||
|
||||
function onViewMapClick() {
|
||||
if (sggCd && sggCd !== '0') {
|
||||
fetchSggData();
|
||||
return;
|
||||
}
|
||||
if (ctpvCd && ctpvCd !== '0') fetchCtpvData();
|
||||
}
|
||||
|
||||
async function fetchCtpvData() {
|
||||
try {
|
||||
const ctpvData = await fetch(`/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo%3Atb_ms_ctpv&outputFormat=application%2Fjson&cql_filter=mctpv_cd=%27${ctpvCd.trim()}%27&srsName=EPSG:5179`)
|
||||
.then(res => res.json());
|
||||
console.log('시도 데이터', ctpvData.features[0]);
|
||||
|
||||
const format = new GeoJSON();
|
||||
const feature: Feature<Geometry> = format.readFeature(ctpvData.features[0], {
|
||||
dataProjection: "EPSG:5179", // GeoJSON 좌표계
|
||||
featureProjection: GisApp.TO_PROJ // 지도 좌표계
|
||||
});
|
||||
|
||||
console.log('feature', feature);
|
||||
|
||||
const extent = medianCoordinate2D(feature);
|
||||
console.log('GisApp.TO_PROJ', GisApp.TO_PROJ);
|
||||
console.log('extent', extent)
|
||||
|
||||
handleFeatureFocus(extent);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("시도 data fetching Error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchSggData() {
|
||||
try {
|
||||
const sggData = await fetch(`/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo%3Atb_ms_sgg&outputFormat=application%2Fjson&cql_filter=sgg_cd=%27${sggCd}%27&srsName=EPSG:5179`)
|
||||
.then(res => res.json());
|
||||
console.log('시군구 데이터', sggData.features[0]);
|
||||
|
||||
|
||||
const format = new GeoJSON();
|
||||
const feature: Feature<Geometry> = format.readFeature(sggData.features[0], {
|
||||
dataProjection: "EPSG:5179", // GeoJSON 좌표계
|
||||
featureProjection: GisApp.TO_PROJ // 지도 좌표계
|
||||
});
|
||||
|
||||
const extent = medianCoordinate2D(feature);
|
||||
|
||||
handleFeatureFocus(extent);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("시군구 data fetching Error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function handleFeatureFocus(extent: any) {
|
||||
console.log('ctpv', ctpv);
|
||||
console.log('sgg', sgg);
|
||||
const map = gisMaps.current;
|
||||
if (!map) {
|
||||
console.warn("지도가 초기화되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
map.getView().fit(extent, {
|
||||
duration: 300,
|
||||
padding: [50, 50, 50, 50],
|
||||
maxZoom: 11
|
||||
});
|
||||
};
|
||||
|
||||
const fetchSido = async () => {
|
||||
const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_ms_ctpv&outputFormat=application/json&propertyName=mctpv_korn_nm,mctpv_cd`;
|
||||
const res = await fetch(url).then(res => res.json());
|
||||
|
||||
const list = res.features.map((f: any) => ({
|
||||
text: f.properties.mctpv_korn_nm,
|
||||
val: f.properties.mctpv_cd,
|
||||
}));
|
||||
|
||||
console.log('시도 데이터', list);
|
||||
setCtpv(list);
|
||||
};
|
||||
|
||||
const fetchSigungu = async () => {
|
||||
const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_ms_sgg&outputFormat=application/json&propertyName=sgg_cd,sgg_korn_nm`;
|
||||
const res = await fetch(url).then(res => res.json());
|
||||
|
||||
const list = res.features.map((f: any) => ({
|
||||
text: f.properties.sgg_korn_nm,
|
||||
val: f.properties.sgg_cd,
|
||||
}));
|
||||
|
||||
console.log('시군구 데이터', list);
|
||||
setSgg(list);
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-4 bg-white min-h-[48px] min-w-[430px] px-5 py-3 rounded-lg shadow">
|
||||
<div className={`flex items-center justify-center mr-8`}>
|
||||
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시도</Label>
|
||||
<SelectBox
|
||||
className="w-60 mr-8"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label=""
|
||||
selectArray={[DEFAULT_OPTION, ...ctpv]}
|
||||
value={ctpvCd}
|
||||
onSelectValue={val => {
|
||||
setCtpvCd(String(val));
|
||||
setSggCd(String(0));
|
||||
}}
|
||||
selectContentClass="z-[101]"
|
||||
/>
|
||||
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시군구</Label>
|
||||
<SelectBox
|
||||
className="w-48"
|
||||
selectClass="w-48 rounded-lg bg-white truncate"
|
||||
label=""
|
||||
selectArray={
|
||||
[DEFAULT_OPTION,
|
||||
...sgg.filter(opt => String(opt.val).slice(0, 2) === String(ctpvCd).trim())
|
||||
]
|
||||
}
|
||||
value={sggCd}
|
||||
onSelectValue={val => { setSggCd(String(val)) }}
|
||||
selectContentClass="z-[101]"
|
||||
/>
|
||||
</div>
|
||||
<div className='flex flex-1 justify-end '>
|
||||
<Button size="sm" onClick={() => onViewMapClick()}>조회</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/b
|
||||
import { ContentsDiv, DateMonthPicker, downloadExcel, SearchDiv, SearchFormLeft, SearchFormRight, SelectBox, Title, UiModal, UiTable, type SelectDataType } from "@common/business_components/ui";
|
||||
import ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Button, Label, ScrollArea } from "@common/components/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useState, useRef } from "react";
|
||||
import { toast, Toaster } from "react-hot-toast";
|
||||
|
||||
export default function DrgtSttn() {
|
||||
@@ -26,6 +26,7 @@ export default function DrgtSttn() {
|
||||
isOpen: boolean;
|
||||
data: customDrgt[] | undefined;
|
||||
}>({ data: undefined, isOpen: false });
|
||||
const popupRef = useRef<Window | null>(null);
|
||||
|
||||
const cellClick = (index: number) => {
|
||||
if (fromDate && toDate && drgtRes[index]) {
|
||||
@@ -121,6 +122,19 @@ export default function DrgtSttn() {
|
||||
setToDate(formatted);
|
||||
}
|
||||
}, [fromDate, toDate])
|
||||
|
||||
function onViewMapClick() {
|
||||
const params = new URLSearchParams({
|
||||
ctpvCd: String(objSearch.city),
|
||||
sggCd: String(objSearch.sgg),
|
||||
fromDate: fromDate || '',
|
||||
toDate: toDate || ''
|
||||
});
|
||||
const popupOptions = `width=${window.screen.availWidth},height=${window.screen.availHeight},left=0,top=0,resizable=yes,scrollbars=yes`;
|
||||
popupRef.current = window.open(`/mapDrgtPopUp?${params.toString()}`, "가뭄 지도 보기 팝업", popupOptions);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContentsDiv>
|
||||
@@ -136,7 +150,7 @@ export default function DrgtSttn() {
|
||||
selectClass={""}
|
||||
selectArray={code.cityCd || []}
|
||||
onSelectValue={getSelCity}
|
||||
value={objSearch?.city ||code.cityCd[0]?.val ||""}
|
||||
value={objSearch?.city || code.cityCd[0]?.val || ""}
|
||||
/>
|
||||
<SelectBox
|
||||
className="col-span-2 w-1/6 h-full text-2xl ml-8"
|
||||
@@ -144,7 +158,7 @@ export default function DrgtSttn() {
|
||||
selectClass={""}
|
||||
selectArray={selectSgg || [{ val: '0', text: '전체' }]}
|
||||
onSelectValue={getSgg}
|
||||
value={selectedSgg ||'0'}
|
||||
value={selectedSgg || '0'}
|
||||
/>
|
||||
<div className="col-span-5 w-auto">
|
||||
<div className="flex flex-row items-center">
|
||||
@@ -156,7 +170,7 @@ export default function DrgtSttn() {
|
||||
onChange: (date: string | undefined) => {
|
||||
const year = date ? date.slice(0, 4) : '';
|
||||
let month = date?.slice(4);
|
||||
if (month&&month?.length < 2) {
|
||||
if (month && month?.length < 2) {
|
||||
month = month?.padStart(2, "0");
|
||||
}
|
||||
const formatted = `${year}${month}`;
|
||||
@@ -172,7 +186,7 @@ export default function DrgtSttn() {
|
||||
onChange: (date: string | undefined) => {
|
||||
const year = date ? date.slice(0, 4) : '';
|
||||
let month = date?.slice(4);
|
||||
if (month&&month.length < 2) {
|
||||
if (month && month.length < 2) {
|
||||
month = month?.padStart(2, "0");
|
||||
}
|
||||
const formatted = `${year}${month}`;
|
||||
@@ -211,7 +225,7 @@ export default function DrgtSttn() {
|
||||
sggText = sidoText;
|
||||
}
|
||||
|
||||
const searchArr:string[] = [];
|
||||
const searchArr: string[] = [];
|
||||
if (sidoText) searchArr.push(sidoText);
|
||||
if (Array.isArray(sggText)) {
|
||||
searchArr.push(...sggText);
|
||||
@@ -234,7 +248,7 @@ export default function DrgtSttn() {
|
||||
<Button
|
||||
size={"sm"}
|
||||
className={btnClass}
|
||||
onClick={() => { }}
|
||||
onClick={onViewMapClick}
|
||||
>
|
||||
지도보기
|
||||
</Button>
|
||||
|
||||
@@ -91,6 +91,8 @@ export function middleware(req: NextRequest) {
|
||||
let queryParams = searchParams.toString();
|
||||
const typename = searchParams.get("TYPENAME");
|
||||
console.log("typename ", typename);
|
||||
const startYmd = searchParams.get("START_YMD") ?? null;
|
||||
const endYmd = searchParams.get("END_YMD") ?? null;
|
||||
|
||||
let newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`;
|
||||
|
||||
@@ -116,10 +118,13 @@ export function middleware(req: NextRequest) {
|
||||
typename == "hasudo:tb_wr_rswtr_fclt" || //중수도시설
|
||||
typename == "hasudo:tb_wr_htdfl_fclt" || //온배수시설
|
||||
typename == "hasudo:tb_wr_ruse_fclt_dmd_co" || //수요처
|
||||
typename == "hasudo:tb_wr_tmpr_dmd_co" //잠재수요처
|
||||
typename == "hasudo:tb_wr_tmpr_dmd_co" || //잠재수요처
|
||||
typename?.startsWith("hasudo:drought") //가뭄 지도
|
||||
) {
|
||||
const url = req.nextUrl.clone();
|
||||
url.searchParams.set("TYPENAME", typename.replace("hasudo:", ""));
|
||||
if (startYmd) url.searchParams.set("startYmd", startYmd);
|
||||
if (endYmd) url.searchParams.set("endYmd", endYmd);
|
||||
queryParams = url.searchParams.toString();
|
||||
newUrl = `${SEWERAGE_API_URL}/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
"lucide-react": "^0.474.0",
|
||||
"moment": "^2.30.1",
|
||||
"next": "15.1.7",
|
||||
"ol": "^7.3.0",
|
||||
"ol-ext": "^4.0.11",
|
||||
"react-hook-form": "^7.54.2",
|
||||
"react-hot-toast": "^2.5.2",
|
||||
"react-i18next": "^15.6.0",
|
||||
|
||||
@@ -123,8 +123,8 @@ function Gis({
|
||||
orderedLayers = [],
|
||||
checkInterval = 3000,
|
||||
height: height = "h-[calc(100vh-5rem)]",
|
||||
onOpenPopup=(data)=>{}
|
||||
|
||||
onOpenPopup = (data) => { },
|
||||
droughtDates = { startYmd: '', endYmd: '' }
|
||||
}) {
|
||||
const mapRef = useRef();
|
||||
const [mapObject, setMapObject] = useState({});
|
||||
@@ -283,6 +283,17 @@ function Gis({
|
||||
GisApp.layerCode = layerCode; // 전역 레이어 코드 설정
|
||||
}, [treeData]);
|
||||
|
||||
// droughtDates를 전역(GisApp)에 반영
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined") return;
|
||||
if (droughtDates?.startYmd && droughtDates?.endYmd) {
|
||||
GisApp.DROUGHT_DATES = {
|
||||
startYmd: String(droughtDates.startYmd),
|
||||
endYmd: String(droughtDates.endYmd),
|
||||
};
|
||||
}
|
||||
}, [droughtDates?.startYmd, droughtDates?.endYmd]);
|
||||
|
||||
const getLayerItems = (layerCode) => {
|
||||
const layerItems = Object.entries(layerCode)
|
||||
.filter(([key, obj], idx) => obj?.updtPsblYn === "Y")
|
||||
|
||||
@@ -27,6 +27,8 @@ const GisApp = {};
|
||||
*/
|
||||
//레이어 정보
|
||||
GisApp.layerInfos = [];
|
||||
// 가뭄 레이어 날짜 전역 보관소 추가
|
||||
GisApp.DROUGHT_DATES = { startYmd: '', endYmd: '' };
|
||||
//기본정보
|
||||
GisApp.GEOSERVER_URL = '/geoserver/hasudo/ows';
|
||||
GisApp.GEOSERVER_WMS_URL = '/geoserver/hasudo/wms';
|
||||
|
||||
@@ -112,7 +112,7 @@ GisOlLayer.prototype = {
|
||||
let toProj = GisApp.TO_PROJ;
|
||||
let lyrTyNm = options.lyrTyNm;
|
||||
let typename = this.storageNm + lyrTyNm;
|
||||
let filter = options?.flterSql && options.flterSql && options.flterSql.trim() !== ''
|
||||
let filter = options?.flterSql && options.flterSql && options.flterSql.trim() !== '';
|
||||
|
||||
let params = {};
|
||||
params['TYPENAME'] = typename;
|
||||
@@ -122,6 +122,10 @@ GisOlLayer.prototype = {
|
||||
params['SRS'] = toProj;
|
||||
params['OUTPUTFORMAT'] = 'application/json';
|
||||
if (filter) params['CQL_FILTER'] = filter;
|
||||
else if (GisApp.DROUGHT_DATES) {
|
||||
params['START_YMD'] = GisApp.DROUGHT_DATES.startYmd;
|
||||
params['END_YMD'] = GisApp.DROUGHT_DATES.endYmd;
|
||||
}
|
||||
let strParams = new URLSearchParams(params).toString();
|
||||
|
||||
let source = new VectorSource({
|
||||
|
||||
@@ -54,30 +54,25 @@ export const ComboSearchBar = ({
|
||||
|
||||
//시도, 시군구 조회
|
||||
const fetchSido = async () => {
|
||||
const url = `/cms-service/api/v1/code/cache/ADSTDSTRCD/Y`;
|
||||
const res = await fetch(url);
|
||||
const json = await res.json();
|
||||
const sidoList = json
|
||||
.filter(
|
||||
(item: any) =>
|
||||
typeof item.lwpoCd === "string" && item.lwpoCd.length === 2,
|
||||
)
|
||||
.map((feature: any) => ({
|
||||
val: feature.lwpoCd,
|
||||
text: feature.lwpoCdNm,
|
||||
}));
|
||||
setSidoData([{ text: "선택", val: "0" }, ...sidoList]);
|
||||
const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_ms_ctpv&outputFormat=application/json&propertyName=mctpv_korn_nm,mctpv_cd`;
|
||||
const res = await fetch(url).then(res => res.json());
|
||||
|
||||
const sigunList = json
|
||||
.filter(
|
||||
(item: any) =>
|
||||
typeof item.lwpoCd === "string" && item.lwpoCd.length !== 2,
|
||||
)
|
||||
.map((feature: any) => ({
|
||||
val: feature.lwpoCd,
|
||||
text: feature.lwpoCdNm,
|
||||
}));
|
||||
setSigunData(sigunList);
|
||||
const list = res.features.map((f: any) => ({
|
||||
text: f.properties.mctpv_korn_nm,
|
||||
val: f.properties.mctpv_cd,
|
||||
}));
|
||||
setSidoData([{ text: "선택", val: "0" }, ...list]);
|
||||
};
|
||||
|
||||
const fetchSigungu = async () => {
|
||||
const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_ms_sgg&outputFormat=application/json&propertyName=sgg_cd,sgg_korn_nm`;
|
||||
const res = await fetch(url).then(res => res.json());
|
||||
|
||||
const list = res.features.map((f: any) => ({
|
||||
text: f.properties.sgg_korn_nm,
|
||||
val: f.properties.sgg_cd,
|
||||
}));
|
||||
setSigunData(list);
|
||||
};
|
||||
|
||||
//시설명 콤보박스 조회
|
||||
@@ -170,6 +165,7 @@ export const ComboSearchBar = ({
|
||||
//시도, 시군구 초기 데이터 조회
|
||||
useEffect(() => {
|
||||
fetchSido();
|
||||
fetchSigungu();
|
||||
}, []);
|
||||
|
||||
//시군구 데이터 초기화
|
||||
|
||||
@@ -39,32 +39,26 @@ export const ProcSearchBar = ({ gisMaps, facilityTypes }: SearchBarProps) => {
|
||||
: "0",
|
||||
);
|
||||
|
||||
//시도, 시군구 조회
|
||||
const fetchSido = async () => {
|
||||
const url = `/cms-service/api/v1/code/cache/ADSTDSTRCD/Y`;
|
||||
const res = await fetch(url);
|
||||
const json = await res.json();
|
||||
const sidoList = json
|
||||
.filter(
|
||||
(item: any) =>
|
||||
typeof item.lwpoCd === "string" && item.lwpoCd.length === 2,
|
||||
)
|
||||
.map((feature: any) => ({
|
||||
val: feature.lwpoCd,
|
||||
text: feature.lwpoCdNm,
|
||||
}));
|
||||
setSidoData([{ text: "시도", val: "0" }, ...sidoList]);
|
||||
const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_ms_ctpv&outputFormat=application/json&propertyName=mctpv_korn_nm,mctpv_cd`;
|
||||
const res = await fetch(url).then(res => res.json());
|
||||
|
||||
const sigunList = json
|
||||
.filter(
|
||||
(item: any) =>
|
||||
typeof item.lwpoCd === "string" && item.lwpoCd.length !== 2,
|
||||
)
|
||||
.map((feature: any) => ({
|
||||
val: feature.lwpoCd,
|
||||
text: feature.lwpoCdNm,
|
||||
}));
|
||||
setSigunData(sigunList);
|
||||
const list = res.features.map((f: any) => ({
|
||||
text: f.properties.mctpv_korn_nm,
|
||||
val: f.properties.mctpv_cd,
|
||||
}));
|
||||
setSidoData([{ text: "선택", val: "0" }, ...list]);
|
||||
};
|
||||
|
||||
const fetchSigungu = async () => {
|
||||
const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_ms_sgg&outputFormat=application/json&propertyName=sgg_cd,sgg_korn_nm`;
|
||||
const res = await fetch(url).then(res => res.json());
|
||||
|
||||
const list = res.features.map((f: any) => ({
|
||||
text: f.properties.sgg_korn_nm,
|
||||
val: f.properties.sgg_cd,
|
||||
}));
|
||||
setSigunData(list);
|
||||
};
|
||||
|
||||
//시설명 콤보박스 조회
|
||||
@@ -157,6 +151,7 @@ export const ProcSearchBar = ({ gisMaps, facilityTypes }: SearchBarProps) => {
|
||||
//시도, 시군구 초기 데이터 조회
|
||||
useEffect(() => {
|
||||
fetchSido();
|
||||
fetchSigungu();
|
||||
}, []);
|
||||
|
||||
//시군구 데이터 초기화
|
||||
|
||||
Reference in New Issue
Block a user