From 3ba11b55083cc19f64db6bb4594d3561177ba5e8 Mon Sep 17 00:00:00 2001 From: leedj312 Date: Tue, 29 Jul 2025 20:11:51 +0900 Subject: [PATCH 1/9] =?UTF-8?q?=EB=B9=97=EB=AC=BC=20=EC=97=91=EC=85=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=ED=95=AD=EB=AA=A9=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=A0=90=EA=B2=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prfmncReg/chkgdnReg/rainChkgdn/excel.tsx | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx index 6d6ef18a6..a484f87c2 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx @@ -6,6 +6,7 @@ import { isInvalidNumber, parseRawValue, } from "@/components/lib/func/excelFunc"; +import toast from "react-hot-toast"; export const useTypes = [ "조경용수", "청소화장실용수", @@ -16,6 +17,18 @@ export const useTypes = [ "기타", ]; + +export const chkMngType =[ + '위탁', + '자체' +] +export const chkSpwtPositnType = [ + '유량계', + '수위계', + '펌프적산전력계', + '기타' +] + export type Buildingtype = { bdstInfoSn: number; ctpvCd: 1; @@ -143,43 +156,56 @@ export const excelToRainChkData = (excelData: any, year: string) => { }) .filter((el: any) => el !== undefined); +console.log("rainChkgdData", rainChkgdData); if (rainChkgdData.length > 0) { rainChkgdData.forEach((rain: any) => { const defaultMessage = `[시설명: ${rain.bdstNm}, 점검일: ${rain.chckYmd}, 이용용도: ${rain.guideDetails[0]?.utztnUsgCd}] 항목에서 `; if (rain.chckYmd && isInvalidDate(rain.chckYmd)) { issues.push( - defaultMessage + `점검일: 날짜 형식 아님 (${rain.chckYmd})` + defaultMessage + `점검일: 날짜 형식 아님 입력값 : (${rain.chckYmd})` ); } if (rain.anlOperCst.length > 2 && isInvalidNumber(rain.anlOperCst)) { issues.push( defaultMessage + - ` 연간운영비(원/년): 숫자 형식 아님 (${rain.anlOperCst})` + ` 연간운영비(원/년): 숫자 형식 아님 /입력값:${rain.anlOperCst}` ); } + if (rain.oilqMeasMthd.length > 1 && !chkMngType.includes(rain.oilqMeasMthd)) { + issues.push( + defaultMessage + `유량측정방법: 위탁 혹은 자체 만 허용) /입력값:${rain.oilqMeasMthd}` + ); + } + if (rain.spwtPositn.length > 1 && !chkSpwtPositnType.includes(rain.spwtPositn)) { + issues.push( + defaultMessage + `측정위치: 유량계, 수위계, 펌프적산전력계, 기타 중 하나만 허용) /입력값:${rain.spwtPositn}` + ); + } + + rain.rainyDetails?.forEach((key) => { if (key.ph?.length > 1 && isInvalidNumber(key.ph)) { - issues.push(defaultMessage + `PH: 숫자 형식 아님 (${key.ph})`); + issues.push(defaultMessage + `PH: 숫자 형식 아님 /입력값:${key.ph}`); } if (key.trbt?.length > 1 && isInvalidNumber(key.trbt)) { - issues.push(defaultMessage + `탁도: 숫자 형식 아님 (${key.trbt})`); + issues.push(defaultMessage + `탁도: 숫자 형식 아님 /입력값:${key.trbt}`); } if (key.grssClfg?.length > 1 && isInvalidNumber(key.grssClfg)) { issues.push( - defaultMessage + `총대장균군수: 숫자 형식 아님 (${key.grssClfg})` + defaultMessage + `총대장균군수: 숫자 형식 아님 /입력값:${key.grssClfg}` ); } if (key.levyAmt?.length > 1 && isInvalidNumber(key.levyAmt)) { issues.push( defaultMessage + - `과태료부과금액(천원): 숫자 형식 아님 (${key.levyAmt})` + `과태료부과금액(천원): 숫자 형식 아님 /입력값:${key.levyAmt}` ); } if (key.vltnDt?.length > 2 && isInvalidDate(key.vltnDt)) { issues.push( defaultMessage + - `과태료 부과일(위반일): 날짜 형식 아님 (${key.vltnDt})` + `과태료 부과일(위반일): 날짜 형식 아님 /입력값:${key.vltnDt}` ); } }); @@ -188,17 +214,19 @@ export const excelToRainChkData = (excelData: any, year: string) => { if (isInvalidNumber(guide.splyUswtrUtztnQnt)) { issues.push( defaultMessage + - `대체_${mm}: 숫자 형식 아님 (${guide.splyUswtrUtztnQnt})` + `대체_${mm}: 숫자 형식 아님 /입력값:${guide.splyUswtrUtztnQnt}` ); } if (isInvalidNumber(guide.ruseFcltUtztnQnt)) { issues.push( defaultMessage + - `빗물_${mm}: 숫자 형식 아님 (${guide.ruseFcltUtztnQnt})` + `빗물_${mm}: 숫자 형식 아님 /입력값:${guide.ruseFcltUtztnQnt}` ); } }); }); + }else{ + toast.error("데이터가 없습니다. 점검 데이터를 확인해주세요."); } if (issues.length > 0) { From e5f2cb2182f407a78d25edc05f81e5cc6f49deaf Mon Sep 17 00:00:00 2001 From: jyha00 Date: Tue, 29 Jul 2025 20:40:05 +0900 Subject: [PATCH 2/9] =?UTF-8?q?=EB=AC=BC=EC=9E=AC=EC=9D=B4=EC=9A=A9?= =?UTF-8?q?=EC=82=AC=EB=A1=80=EA=B4=80=EB=A6=AC=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx | 238 ++++++++++-------- .../app/store/matDmd/ruseCaseMng/headList.tsx | 2 +- .../wr/app/store/matDmd/ruseCaseMng/index.tsx | 154 +++++++----- .../ruseCaseMng/ruseCaseMngExcelModal.tsx | 38 ++- apps/wr/public/sample_ruseCaseMng.xlsx | Bin 20324 -> 20272 bytes 5 files changed, 245 insertions(+), 187 deletions(-) diff --git a/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx index e45a0a0f2..813b4e23f 100644 --- a/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx +++ b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx @@ -17,35 +17,45 @@ import { UiModal, UiTable, type SelectDataType, + type SheetParameter, } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button } from "@common/components/ui"; +import { Button, Label } from "@common/components/ui"; import { useEffect, useState } from "react"; -import { Toaster } from "react-hot-toast"; +import toast, { Toaster } from "react-hot-toast"; +import { useTranslation } from "react-i18next"; export default function RuseCaseMng() { - const { code, ruseCaseMng, selectRuseCaseMng } = useWrStore((state) => state); - const { ruseCaseMngList, status, count } = ruseCaseMng; + const { code, ruseCaseMng, selectRuseCaseMng, ruseCaseMngInit } = useWrStore((state) => state); + const { ruseCaseMngList, status, count, excelList } = ruseCaseMng; const [selectSgg, setSelectSgg] = useState([]); const [objSearch, setObjSearch] = useState({ sgg: "", city: "" }); - + const [sidoCd, setSidoCd] = useState(""); const [sigunguCd, setSigunguCd] = useState(""); - const [selectUtz, setSelectUtz] = useState(["조경용수"]); + // const [selectUtz, setSelectUtz] = useState(["조경용수"]); + const [selectUtz, setSelectUtz] = useState(""); const [name, setName] = useState(""); + const [resetPage, isResetPage] = useState(false); + const { t } = useTranslation('base'); // 물재이용사례 조회 - const searchRuseCaseMng = async (pageNo: number, pageSize: number) => { + const searchRuseCaseMng = async (isExcel: boolean, pageNo: number, pageSize: number) => { await selectRuseCaseMng( + isExcel, pageNo, pageSize, - sidoCd ?? "", - sigunguCd ?? "", - selectUtz[0] ?? "", + sidoCd ?? "", + sigunguCd ?? "", + selectUtz ?? "", name ?? "" ); } + useEffect(() => { + ruseCaseMngInit(); + }, []) + // 시도 선택 const getSelCity = (val: string | number) => { const cityValue = String(val); @@ -69,91 +79,97 @@ export default function RuseCaseMng() { isModal: boolean; }>({ isModal: false }); - // 다운로드 - const download = () => { - searchRuseCaseMng(1, 10000);; - + + useEffect(() => { + + if (excelList !== undefined && excelList.length === 0) { + toast.error(t('excelDownErrMsg')); + return; + } fetch(`/sample_ruseCaseMng.xlsx`, {}).then(async (response) => { - if (!response.ok) { - throw Error(response.statusText); - } - // 받은 파일 바인너리 처리 - const blobRet = await response.arrayBuffer(); - - const excelData1 = ruseCaseMngList.map((item) => { - return [ - item.ruseBizNm, - item.bizBgngDate, - item.bizEndDate, - item.splyFcltKnd, - item.splyFcltNm, - item.splyFcltCpct, - item.dmdFcltNm, - item.dmdFcltAddr, - item.ruseFcltCpct, - item.ruseFcltPplLen, - item.ruseFcltUsg, - item.ruseFcltSplyCpct, - item.ruseFcltPrcsMsrc, - item.grnteWqUsg, - item.grnteWqGrssClfg, - item.grnteWqCombResdch, - item.grnteWqTrbt, - item.grnteWqBod, - item.grnteWqSmll, - item.grnteWqCrmty, - item.grnteWqTn, - item.grnteWqTp, - item.grnteWqPh, - item.grnteWqClIonQnt, - item.grnteWqCndctStat, - item.grnteWqRmrk, - item.reqBizGrssCst, - item.reqBizReuseFcltCst, - item.reqBizPplCst, - item.reqBizArchCst, - item.reqBizMchnCst, - item.reqBizMtrngCst, - item.reqBizGisCst, - item.reqBizCctvCst, - item.reqBizCmcnCst, - item.reqBizWstCst, - item.reqBizDesignCst, - item.reqBizSpvsCst, - item.reqBizSbsdCst, - item.reqBizEtc, - item.prcmPlanGrssCst, - item.prcmPlanNlep, - item.prcmPlanLcep, - item.prcmPlanBrdnCst, - item.prcmPlanEcqrRt, - item.clclnGrssCst, - item.clclnNlep, - item.clclnLcep, - item.clclnBrdnCst, - item.clclnEcqrRt, - ]; - }); - - const sheetParameter = [ - { - data: excelData1, - headerNum: 2, - headerRange: 'A1:AX1', - sheetName: '물재이용사례', - startCol: 'A' + if (!response.ok) { + throw Error(response.statusText); + } + // 받은 파일 바인너리 처리 + const blobRet = await response.arrayBuffer(); + if(excelList){ + const excelData1 = excelList.map((item) => { + return [ + item.ruseBizNm, + item.bizBgngDate, + item.bizEndDate, + item.splyFcltKnd, + item.splyFcltNm, + item.splyFcltCpct, + item.dmdFcltNm, + item.dmdFcltAddr, + item.ruseFcltCpct, + item.ruseFcltPplLen, + item.ruseFcltUsg, + item.ruseFcltSplyCpct, + item.ruseFcltPrcsMsrc, + item.grnteWqUsg, + item.grnteWqGrssClfg, + item.grnteWqCombResdch, + item.grnteWqTrbt, + item.grnteWqBod, + item.grnteWqSmll, + item.grnteWqCrmty, + item.grnteWqTn, + item.grnteWqTp, + item.grnteWqPh, + item.grnteWqClIonQnt, + item.grnteWqCndctStat, + item.grnteWqRmrk, + item.reqBizGrssCst, + item.reqBizReuseFcltCst, + item.reqBizPplCst, + item.reqBizArchCst, + item.reqBizMchnCst, + item.reqBizMtrngCst, + item.reqBizGisCst, + item.reqBizCctvCst, + item.reqBizCmcnCst, + item.reqBizWstCst, + item.reqBizDesignCst, + item.reqBizSpvsCst, + item.reqBizSbsdCst, + item.reqBizEtc, + item.prcmPlanGrssCst, + item.prcmPlanNlep, + item.prcmPlanLcep, + item.prcmPlanBrdnCst, + item.prcmPlanEcqrRt, + item.clclnGrssCst, + item.clclnNlep, + item.clclnLcep, + item.clclnBrdnCst, + item.clclnEcqrRt, + ]; + }); + + const sheetParameter: SheetParameter[] = [ + { + data: excelData1, + headerNum: 2, + headerRange: 'A1:AX1', + sheetName: '물재이용사례', + startCol: 'A' + } + ]; + // 버퍼에 있는 엑셀데이터 전달 후 json으로 변환 + await filePickedBlobArray(blobRet, '물재이용사례현황', sheetParameter); } - ]; - // 버퍼에 있는 엑셀데이터 전달 후 json으로 변환 - await filePickedBlobArray(blobRet, '물재이용사례현황', sheetParameter); }); - } + + + }, [excelList]) // 양식받기 const sampleDownLoad = () => { excelDownload( [[]], - "물재이용사례 관리", + "물재이용사례 관리 등록양식", "sample_ruseCaseMng.xlsx", "A1:AX1", 2 @@ -161,7 +177,7 @@ export default function RuseCaseMng() { } useEffect(() => { - if(status === 200){ + if (status === 200) { setIsExcelOpen({ isModal: false }); } }, [status]); @@ -174,7 +190,7 @@ export default function RuseCaseMng() { <SearchDiv> <SearchFormLeft> - <div className="col-span-8 flex flex-row"> + <div className="col-span-8 flex flex-row items-center"> <SelectBox className="col-span-2 w-1/3 h-full text-2xl" label="시도" @@ -183,24 +199,28 @@ export default function RuseCaseMng() { onSelectValue={getSelCity} /> <SelectBox - className="col-span-2 w-1/3 h-full text-2xl" + className="col-span-2 w-1/3 h-full text-2xl ml-4" label="시군구" selectClass={""} selectArray={selectSgg || []} onSelectValue={getSgg} /> <SelectBox - className="col-span-2 w-1/3 h-full text-2xl" + className="col-span-2 w-1/3 h-full text-2xl ml-4" label="용도" selectClass={""} selectArray={ruseUtzType} onSelectValue={(val) => { - if (val) setSelectUtz([String(val)]); + if (val) setSelectUtz(String(val)); }} + value={selectUtz || ruseUtzType[0]?.val} /> + <Label className="w-28 text-xl ml-4 mr-6"> + {"수요처명"} + </Label> <SearchInput - className={"text-2xl"} - label="수요처명" + className={"col-span-2 w-1/3 text-2xl"} + label="" textValue={name} setText={(e) => { setName(e); @@ -211,13 +231,29 @@ export default function RuseCaseMng() { <SearchFormRight className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2"> <div className="space-y"> <div className="flex flex-row space-x-2"> - <Button size={"sm"} onClick={() => { searchRuseCaseMng(1, 20) }}> + <Button size={"sm"} onClick={() => { + searchRuseCaseMng(false, 1, 10); + isResetPage(true); + }}> 조회 </Button> <Button size={"sm"} onClick={() => { setIsExcelOpen({ isModal: true }); }}> 엑셀등록 </Button> - <Button size={"sm"} onClick={() => { download() }}> + <Button size={"sm"} onClick={() => { + selectRuseCaseMng( + true, + 1, + count, + sidoCd ?? "", + sigunguCd ?? "", + selectUtz ?? "", + name ?? "" + ); + // download() + + + }} className={"green"}> 다운로드 </Button> <Button size={"sm"} onClick={() => { sampleDownLoad() }}> @@ -239,10 +275,12 @@ export default function RuseCaseMng() { headlist={ruseCaseMng.ruseHeadList} pageSize={20} total={count} - cellClick={() => {}} + cellClick={undefined} onPageChange={(pageNo: number) => { - searchRuseCaseMng(pageNo, 10); + searchRuseCaseMng(false, pageNo, 10); + isResetPage(false) }} + resetPageNo={resetPage} /> </div> </ListDiv> @@ -254,9 +292,9 @@ export default function RuseCaseMng() { <UiModal open={isExcelOpen.isModal} onOpenChange={() => { - setIsExcelOpen({ isModal: !isExcelOpen.isModal }) + setIsExcelOpen({ isModal: !isExcelOpen.isModal }) }} - bodyClass={"w-[40vw] max-w-none"} + bodyClass={"w-[35vw] max-w-none"} body={<RuseCaseMngExcel />} /> </> diff --git a/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx b/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx index 8c3a232e7..bc71fbf81 100644 --- a/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx +++ b/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx @@ -1,7 +1,6 @@ import type { SelectDataType } from "@common/business_components/ui"; import type { TableUpperProps } from "../../common/type/header"; -//★☆★☆ 여기서부터 수정하기 ★☆★☆ export const ruseCaseHeadListExport: TableUpperProps[] = [ { id: "ruseBizNm", @@ -358,6 +357,7 @@ export const ruseCaseHeadListExport: TableUpperProps[] = [ ]; export const ruseUtzType: SelectDataType[] = [ + { text: "전체", val: "0" }, { text: "조경용수", val: "조경용수" }, { text: "청소화장실용수", val: "청소화장실용수" }, { text: "세척살수용수", val: "세척살수용수" }, diff --git a/apps/wr/app/store/matDmd/ruseCaseMng/index.tsx b/apps/wr/app/store/matDmd/ruseCaseMng/index.tsx index 5ae2e67b4..160e1f7f3 100644 --- a/apps/wr/app/store/matDmd/ruseCaseMng/index.tsx +++ b/apps/wr/app/store/matDmd/ruseCaseMng/index.tsx @@ -4,90 +4,93 @@ import type { TableUpperProps } from "../../common/type/header"; import { ruseCaseHeadListExport } from "./headList"; export type ruseCaseState = { ruseCaseMng: { - ruseHeadList:TableUpperProps[]; - ruseCaseMngList:ruseCaseMngExcelProps[]; + ruseHeadList: TableUpperProps[]; + ruseCaseMngList: ruseCaseMngExcelProps[]; status: number; count: number; + excelList?: ruseCaseMngExcelProps[]; }; }; export interface ruseCaseMngExcelProps { - ruseBizNm: string, - bizBgngDate: string, - bizEndDate: string, - splyFcltKnd: string, - splyFcltNm: string, - splyFcltCpct: number | 0 |'', - dmdFcltNm: string, - dmdFcltAddr: string, - ruseFcltCpct: number | 0 |'', - ruseFcltPplLen: string, - ruseFcltUsg: string, - ruseFcltSplyCpct: number | 0 |'', - ruseFcltPrcsMsrc: string, - grnteWqUsg: string, - grnteWqGrssClfg: number | 0 |'', - grnteWqCombResdch: number | 0 |'', - grnteWqTrbt: string, - grnteWqBod: string, - grnteWqSmll: string, - grnteWqCrmty: string, - grnteWqTn: string, - grnteWqTp: string, - grnteWqPh: string, - grnteWqClIonQnt: string, - grnteWqCndctStat: string, - grnteWqRmrk: string, - reqBizReuseFcltCst: number | 0 |'', - reqBizPplCst: number | 0 |'', - reqBizArchCst: number | 0 |'', - reqBizMchnCst: number | 0 |'', - reqBizMtrngCst: number | 0 |'', - reqBizGisCst: number | 0 |'', - reqBizCctvCst: number | 0 |'', - reqBizCmcnCst: number | 0 |'', - reqBizWstCst: number | 0 |'', - reqBizDesignCst: number | 0 |'', - reqBizSpvsCst: number | 0 |'', - reqBizSbsdCst: number | 0 |'', - reqBizEtc: string, - reqBizGrssCst: number | 0 |'', - prcmPlanNlep: number | 0 |'', - prcmPlanLcep: number | 0 |'', - prcmPlanBrdnCst: number | 0 |'', - prcmPlanEcqrRt: number | 0 |'', - prcmPlanGrssCst: number | 0 |'', - clclnNlep: number | 0 |'', - clclnLcep: number | 0 |'', - clclnBrdnCst: number | 0 |'', - clclnEcqrRt: number | 0 |'', - clclnGrssCst: number | 0 |'', + ruseBizNm: string, + bizBgngDate: string, + bizEndDate: string, + splyFcltKnd: string, + splyFcltNm: string, + splyFcltCpct: number | 0 | '', + dmdFcltNm: string, + dmdFcltAddr: string, + ruseFcltCpct: number | 0 | '', + ruseFcltPplLen: string, + ruseFcltUsg: string, + ruseFcltSplyCpct: number | 0 | '', + ruseFcltPrcsMsrc: string, + grnteWqUsg: string, + grnteWqGrssClfg: number | 0 | '', + grnteWqCombResdch: number | 0 | '', + grnteWqTrbt: string, + grnteWqBod: string, + grnteWqSmll: string, + grnteWqCrmty: string, + grnteWqTn: string, + grnteWqTp: string, + grnteWqPh: string, + grnteWqClIonQnt: string, + grnteWqCndctStat: string, + grnteWqRmrk: string, + reqBizReuseFcltCst: number | 0 | '', + reqBizPplCst: number | 0 | '', + reqBizArchCst: number | 0 | '', + reqBizMchnCst: number | 0 | '', + reqBizMtrngCst: number | 0 | '', + reqBizGisCst: number | 0 | '', + reqBizCctvCst: number | 0 | '', + reqBizCmcnCst: number | 0 | '', + reqBizWstCst: number | 0 | '', + reqBizDesignCst: number | 0 | '', + reqBizSpvsCst: number | 0 | '', + reqBizSbsdCst: number | 0 | '', + reqBizEtc: string, + reqBizGrssCst: number | 0 | '', + prcmPlanNlep: number | 0 | '', + prcmPlanLcep: number | 0 | '', + prcmPlanBrdnCst: number | 0 | '', + prcmPlanEcqrRt: number | 0 | '', + prcmPlanGrssCst: number | 0 | '', + clclnNlep: number | 0 | '', + clclnLcep: number | 0 | '', + clclnBrdnCst: number | 0 | '', + clclnEcqrRt: number | 0 | '', + clclnGrssCst: number | 0 | '', } type ruseCaseActions = { - selectRuseCaseMng: (pageNo: number, pageSize: number, sidoCd: string, sigunguCd: string, usageCd : string, name: string) => Promise<void>; + ruseCaseMngInit: () => void; + selectRuseCaseMng: (isExcel: boolean, pageNo: number, pageSize: number, sidoCd: string, sigunguCd: string, usageCd: string, name: string) => Promise<void>; insertRuseCaseMng: (data: any) => Promise<void>; }; -export const fetchSearchRuseCaseMng = async (pageNo: number, pageSize: number, sidoCd: string, sigunguCd: string, usageCd : string, name: string) => { - const tailUrl = '/'+pageNo+'/'+pageSize+ ((sigunguCd !== '전체' && sigunguCd !=='') ? `/${sigunguCd}` : (sidoCd != '전체' && sidoCd != '') ? `/${sidoCd}` : `/0`) + (usageCd? `/${usageCd}` : '/0') + (name? `/${name}` : ''); - const resp = await getFetchWithCount(fetchType.WR,`/reuseFc/pubFcRuseCase${tailUrl}`); - return {data:resp.data, count:resp.count}; +export const fetchSearchRuseCaseMng = async (pageNo: number, pageSize: number, sidoCd: string, sigunguCd: string, usageCd: string, name: string) => { + const tailUrl = '/' + pageNo + '/' + pageSize + ((sigunguCd !== '전체' && sigunguCd !== '') ? `/${sigunguCd}` : (sidoCd != '전체' && sidoCd != '') ? `/${sidoCd}` : `/0`) + (usageCd ? `/${usageCd}` : '/0') + (name ? `/${name}` : ''); + const resp = await getFetchWithCount(fetchType.WR, `/reuseFc/pubFcRuseCase${tailUrl}`); + return { data: resp.data, count: resp.count }; }; export const fetchInsertRuseCaseMng = async (data: any) => { const response = await postFectch('/reuseFc/pubFcRuseCase', data, fetchType.WR); - return {data:response.data, status:response.status}; + return { data: response.data, status: response.status }; }; export type ruseCaseType = ruseCaseState & ruseCaseActions; export const ruseCaseStateExport: ruseCaseState = { ruseCaseMng: { - ruseHeadList:ruseCaseHeadListExport, - ruseCaseMngList:[], + ruseHeadList: ruseCaseHeadListExport, + ruseCaseMngList: [], status: 0, count: 0, + excelList: undefined, }, }; @@ -95,8 +98,8 @@ export const ruseCaseActionsExport: (set: any) => ruseCaseActions = ( set: any ) => { return { - selectRuseCaseMng: async (pageNo: number, pageSize: number, sidoCd: string, sigunguCd: string, usageCd : string, name: string) => { - const res = await fetchSearchRuseCaseMng(pageNo, pageSize, sidoCd, sigunguCd, usageCd, name); + ruseCaseMngInit: async () => { + const res = await getFetchWithCount(fetchType.WR, `/reuseFc/pubFcRuseCase/1/10/0/0`); set((state: ruseCaseState) => ({ ruseCaseMng: { ...state.ruseCaseMng, @@ -105,12 +108,35 @@ export const ruseCaseActionsExport: (set: any) => ruseCaseActions = ( }, })); }, + selectRuseCaseMng: async (isExcel: boolean, pageNo: number, pageSize: number, sidoCd: string, sigunguCd: string, usageCd: string, name: string) => { + const res = await fetchSearchRuseCaseMng(pageNo, pageSize, sidoCd, sigunguCd, usageCd, name); + if (isExcel) { + set((state: ruseCaseState) => { + return { + ...state, + ruseCaseMng: { + ...state.ruseCaseMng, + count: res.count, + excelList: res.data + }, + }; + }); + } else { + set((state: ruseCaseState) => ({ + ruseCaseMng: { + ...state.ruseCaseMng, + ruseCaseMngList: res.data, + count: res.count, + }, + })); + } + }, insertRuseCaseMng: async (data: any) => { const response = await fetchInsertRuseCaseMng(data); - if(response.status === 200){ + if (response.status === 200) { toast.success("물재이용사례 등록이 완료되었습니다. "); - }else{ + } else { toast.error("물재이용사례 등록에 실패하였습니다. "); } set((state: ruseCaseState) => ({ diff --git a/apps/wr/components/ui/modal/coMat/ruseCaseMng/ruseCaseMngExcelModal.tsx b/apps/wr/components/ui/modal/coMat/ruseCaseMng/ruseCaseMngExcelModal.tsx index 57424996e..a809c88f6 100644 --- a/apps/wr/components/ui/modal/coMat/ruseCaseMng/ruseCaseMngExcelModal.tsx +++ b/apps/wr/components/ui/modal/coMat/ruseCaseMng/ruseCaseMngExcelModal.tsx @@ -1,14 +1,14 @@ +import { useWrStore } from "@/app/store"; import { coRegExcel } from "@/app/store/matDmd/coSttn/headList"; -import type { ruseCaseMngExcelProps } from "@/app/store/matDmd/ruseCaseMng/index"; import { reUseCaseNames } from "@/app/store/matDmd/ruseCaseMng/excel"; -import { filePicked, FileUpload, FormUi, Title } from "@common/business_components/ui"; -import { Form, FormField } from "@common/business_components/ui/form"; -import { Button } from "@common/components/ui"; +import type { ruseCaseMngExcelProps } from "@/app/store/matDmd/ruseCaseMng/index"; +import { filePicked, Title } from "@common/business_components/ui"; +import { Form } from "@common/business_components/ui/form"; +import { Button, Input } from "@common/components/ui"; import { zodResolver } from "@hookform/resolvers/zod"; import { useState } from "react"; import { useForm } from "react-hook-form"; import type { z } from "zod"; -import { useWrStore } from "@/app/store"; export default function RuseCaseMngExcel() { const { insertRuseCaseMng } = useWrStore((state) => state); @@ -79,6 +79,7 @@ export default function RuseCaseMngExcel() { }; Object.keys(reUseCaseNames).forEach((key: string) => { + console.log("reUseCaseNames", reUseCaseNames) if (item && reUseCaseNames[key] !== undefined) { const mappedKey = reUseCaseNames[key]; if (mappedKey && object.hasOwnProperty(mappedKey)) { @@ -146,23 +147,16 @@ export default function RuseCaseMngExcel() { </div> <div> - <FormField - control={form.control} - name="file" - render={() => ( - <FormUi label=""> - <FileUpload - files={file ? [file] : []} - setFiles={(files: File[] | null) => { - console.log("files", files) - if (files && files?.length === 1) setFiles(files[0]); - }} - fileTypes="" - maxFiles={1} - ></FileUpload> - </FormUi> - )} - /> + <div className="space-y-4 p-4"> + <Input + type="file" + onChange={(e) => { + const selectedFile = e.target.files?.[0]; + if (selectedFile) setFiles(selectedFile); + }} + accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" + /> + </div> </div> </form> </Form> diff --git a/apps/wr/public/sample_ruseCaseMng.xlsx b/apps/wr/public/sample_ruseCaseMng.xlsx index 96027d557fe2cfc60d3de10c313c49d78f984591..3676b4f71f972b6d877a9f03946a2c5af8cd5b0e 100644 GIT binary patch delta 9160 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 delta 9127 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 From 0c16b9d14df0f523bbdd6908536b40f9e88e6d56 Mon Sep 17 00:00:00 2001 From: leedj312 <dlehd467@gmail.com> Date: Thu, 31 Jul 2025 13:28:21 +0900 Subject: [PATCH 3/9] =?UTF-8?q?=EC=A4=91=EC=88=98=EB=8F=84=20=EC=A7=80?= =?UTF-8?q?=EB=8F=84=EC=A0=90=EA=B2=80=20=EC=97=91=EC=85=80=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EC=98=A4=EB=A5=98=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx | 56 +++++++++++++------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx index 262b1cb30..aa550dcd1 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx @@ -1,5 +1,10 @@ import type { SelectDataType } from "@common/business_components/ui"; -import { useTypes, type Buildingtype } from "../rainChkgdn/excel"; +import { + chkMngType, + chkSpwtPositnType, + useTypes, + type Buildingtype, +} from "../rainChkgdn/excel"; import { TEST_UUID } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import type { rswtChkZodType } from "."; import { @@ -171,14 +176,14 @@ export const excelToRswtGuideData = ( .filter((el: any) => el !== undefined); if (rswtChkgdData.length > 0) { - rswtExcelDataCheck(rswtChkgdData,issues) + rswtExcelDataCheck(rswtChkgdData, issues); } if (issues.length > 0) { return { data: [], issues }; } - return { data:rswtChkgdData, issues: [] }; + return { data: rswtChkgdData, issues: [] }; }; export const excelToRswtPolution = (excelData: any, issues: string[]) => { @@ -248,25 +253,25 @@ export const excelToRswtPolution = (excelData: any, issues: string[]) => { }) .filter((el: any) => el !== undefined); if (rswtChkgdData.length > 0) { - rswtExcelDataCheck(rswtChkgdData,issues) + rswtExcelDataCheck(rswtChkgdData, issues); } if (issues.length > 0) { return { data: [], issues }; } - return { data:rswtChkgdData, issues: [] }; + return { data: rswtChkgdData, issues: [] }; }; - -const rswtExcelDataCheck=(rswtChkgdData:rswtChkZodType[], issues:string[]) =>{ +const rswtExcelDataCheck = ( + rswtChkgdData: rswtChkZodType[], + issues: string[] +) => { rswtChkgdData.forEach((rswt: any) => { const defaultMessage = `*중수도 수질 [NO: ${rswt.bdstRuseFcltSn}, 점검일: ${rswt.chckYmd}, 이용용도: ${rswt.utztnUsgCd}] 항목에서 `; if (rswt.chckYmd && isInvalidDate(rswt.chckYmd)) { - issues.push( - defaultMessage + `점검일: 날짜 형식 아님 (${rswt.chckYmd})` - ); + issues.push(defaultMessage + `점검일: 날짜 형식 아님 (${rswt.chckYmd})`); } if (rswt.anlOperCst.length > 2 && isInvalidNumber(rswt.anlOperCst)) { issues.push( @@ -279,6 +284,25 @@ const rswtExcelDataCheck=(rswtChkgdData:rswtChkZodType[], issues:string[]) =>{ defaultMessage + ` 처리용량(m³): 숫자 형식 아님 (${rswt.prcsCpct})` ); } + if ( + rswt.oilqMeasMthd.length > 1 && + !chkMngType.includes(rswt.oilqMeasMthd) + ) { + issues.push( + defaultMessage + + `유량측정방법: 위탁 혹은 자체 만 허용) /입력값:${rswt.oilqMeasMthd}` + ); + } + if ( + rswt.spwtPositn.length > 1 && + !chkSpwtPositnType.includes(rswt.spwtPositn) + ) { + issues.push( + defaultMessage + + `측정위치: 유량계, 수위계, 펌프적산전력계, 기타 중 하나만 허용) /입력값:${rswt.spwtPositn}` + ); + } + if (rswt?.rswtrPollutions && rswt?.rswtrPollutions.length > 0) { rswt.rswtrPollutions.forEach((pol) => { if (isInvalidNumber(pol.grssClfgUswtr)) { @@ -301,8 +325,7 @@ const rswtExcelDataCheck=(rswtChkgdData:rswtChkZodType[], issues:string[]) =>{ } if (isInvalidNumber(pol.bod)) { issues.push( - defaultMessage + - `${pol.node}분기_BOD: 숫자 형식 아님 (${pol.bod})` + defaultMessage + `${pol.node}분기_BOD: 숫자 형식 아님 (${pol.bod})` ); } if (isInvalidNumber(pol.smll)) { @@ -319,8 +342,7 @@ const rswtExcelDataCheck=(rswtChkgdData:rswtChkZodType[], issues:string[]) =>{ } if (isInvalidNumber(pol.tph)) { issues.push( - defaultMessage + - `${pol.node}분기_T-P: 숫자 형식 아님 (${pol.tph})` + defaultMessage + `${pol.node}분기_T-P: 숫자 형식 아님 (${pol.tph})` ); } if (isInvalidNumber(pol.tn)) { @@ -358,7 +380,5 @@ const rswtExcelDataCheck=(rswtChkgdData:rswtChkZodType[], issues:string[]) =>{ } }); } - }) - - -} \ No newline at end of file + }); +}; From 8a2bbfe2202f5766de75756ccce86b8b5e0b3b88 Mon Sep 17 00:00:00 2001 From: Your Name <mind-003@mind-one.co.kr> Date: Thu, 31 Jul 2025 13:52:52 +0900 Subject: [PATCH 4/9] =?UTF-8?q?=EC=9B=90=EC=95=A4=EC=98=AC=20API=20URL=20?= =?UTF-8?q?=EC=9E=AC=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/.env.development | 3 ++- apps/fo/.env.local | 3 ++- apps/fo/.env.production | 3 ++- apps/fo/src/shared/config/env.ts | 3 +-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/fo/.env.development b/apps/fo/.env.development index 94488f0cd..de8976c69 100644 --- a/apps/fo/.env.development +++ b/apps/fo/.env.development @@ -1,7 +1,8 @@ NEXT_PUBLIC_SITE_ID = FO NEXT_PUBLIC_PORT = 11300 NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11300 -NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +#NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1 NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver diff --git a/apps/fo/.env.local b/apps/fo/.env.local index 76fb868cd..ac8a22c06 100644 --- a/apps/fo/.env.local +++ b/apps/fo/.env.local @@ -1,7 +1,8 @@ NEXT_PUBLIC_SITE_ID = FO NEXT_PUBLIC_PORT = 3000 NEXT_PUBLIC_PROXY_HOST = http://localhost:3000 -NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +#NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1 NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver diff --git a/apps/fo/.env.production b/apps/fo/.env.production index 16675eaec..5e11cef61 100644 --- a/apps/fo/.env.production +++ b/apps/fo/.env.production @@ -14,7 +14,8 @@ NEXT_PUBLIC_SITE_ID = FO NEXT_PUBLIC_PORT = 11300 NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11300 -NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +# NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1 NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver diff --git a/apps/fo/src/shared/config/env.ts b/apps/fo/src/shared/config/env.ts index cc516daf1..8baf1b0f0 100644 --- a/apps/fo/src/shared/config/env.ts +++ b/apps/fo/src/shared/config/env.ts @@ -2,8 +2,7 @@ export const SITE_ID = process.env.NEXT_PUBLIC_SITE_ID || "FO"; export const PORT = process.env.NEXT_PUBLIC_PORT || "3000"; export const PROXY_HOST = process.env.NEXT_PUBLIC_PROXY_HOST || `http://localhost:${PORT}`; export const SERVER_API_WR_URL = process.env.NEXT_PUBLIC_WR_SERVER_API_URL ||'http://con.mind-one.co.kr:11080/api/v1'; -//export const SERVER_API_URL = process.env.NEXT_PUBLIC_SERVER_API_URL||' http://con.mind-one.co.kr:11082/api/v1'; -export const SERVER_API_URL = process.env.NEXT_PUBLIC_CS_SERVER_API_URL||' http://con.mind-one.co.kr:11082/api/v1'; +export const SERVER_API_URL = process.env.NEXT_PUBLIC_SERVER_API_URL||' http://con.mind-one.co.kr:11082/api/v1'; export const SERVER_API_CS_URL = process.env.NEXT_PUBLIC_CS_SERVER_API_URL||'http://dev.onasys.co.kr:8000'; export const CLAIM_NAME = process.env.NEXT_PUBLIC_CLAIM_NAME || "Authorization"; export const ACCESS_TOKEN = process.env.NEXT_PUBLIC_ACCESS_TOKEN || "access-token"; From 4c66dacdb03187496e86b5f8d81ea89fe3308564 Mon Sep 17 00:00:00 2001 From: Your Name <mind-003@mind-one.co.kr> Date: Thu, 31 Jul 2025 14:31:59 +0900 Subject: [PATCH 5/9] =?UTF-8?q?=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/.env.development | 4 ++-- apps/fo/.env.local | 4 ++-- apps/fo/.env.production | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/fo/.env.development b/apps/fo/.env.development index de8976c69..44fe06736 100644 --- a/apps/fo/.env.development +++ b/apps/fo/.env.development @@ -1,8 +1,8 @@ NEXT_PUBLIC_SITE_ID = FO NEXT_PUBLIC_PORT = 11300 NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11300 -#NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 -NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 +NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1 NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver diff --git a/apps/fo/.env.local b/apps/fo/.env.local index ac8a22c06..e125bed3d 100644 --- a/apps/fo/.env.local +++ b/apps/fo/.env.local @@ -1,8 +1,8 @@ NEXT_PUBLIC_SITE_ID = FO NEXT_PUBLIC_PORT = 3000 NEXT_PUBLIC_PROXY_HOST = http://localhost:3000 -#NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 -NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 +NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1 NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver diff --git a/apps/fo/.env.production b/apps/fo/.env.production index 5e11cef61..52534bd8e 100644 --- a/apps/fo/.env.production +++ b/apps/fo/.env.production @@ -14,8 +14,8 @@ NEXT_PUBLIC_SITE_ID = FO NEXT_PUBLIC_PORT = 11300 NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11300 -# NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 -NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 +NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1 +#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1 NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver From d4c115d7ca22241e0654c8ed52c84c9c575777a1 Mon Sep 17 00:00:00 2001 From: yschoi <yschoi> Date: Fri, 1 Aug 2025 14:13:19 +0900 Subject: [PATCH 6/9] =?UTF-8?q?=EC=A7=80=EB=8F=84=20=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EC=A4=911?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dm/app/(popup-layout)/map/popup/page.tsx | 1 + .../components/ui/map/searchBar/searchBar.tsx | 125 ++-- .../images/map/layericon/BML_CBAS_PS.png | Bin 1547 -> 919 bytes .../images/map/layericon/BML_STMS_PS.png | Bin 1542 -> 810 bytes .../images/map/layericon/RDL_ETCT_PS.png | Bin 1016 -> 896 bytes .../images/map/layericon/RDL_OCUP_PS.png | Bin 1061 -> 837 bytes .../images/map/layericon/RDL_SEPC_PS.png | Bin 1068 -> 790 bytes .../images/map/layericon/RDL_STAT_PS.png | Bin 1075 -> 855 bytes .../images/map/layericon/RDL_TSCT_PS.png | Bin 1700 -> 923 bytes apps/fo/app/pages/map/page.tsx | 16 +- apps/fo/app/pages/map/searchBar/searchBar.tsx | 158 +++++ .../images/map/layericon/BML_CBAS_PS.png | Bin 1547 -> 919 bytes .../images/map/layericon/BML_STMS_PS.png | Bin 1542 -> 810 bytes .../images/map/layericon/RDL_ETCT_PS.png | Bin 1016 -> 896 bytes .../images/map/layericon/RDL_OCUP_PS.png | Bin 1061 -> 837 bytes .../images/map/layericon/RDL_SEPC_PS.png | Bin 1068 -> 790 bytes .../images/map/layericon/RDL_STAT_PS.png | Bin 1075 -> 855 bytes .../images/map/layericon/RDL_TSCT_PS.png | Bin 1700 -> 923 bytes .../images/map/layericon/BML_CBAS_PS copy.png | Bin 0 -> 919 bytes .../images/map/layericon/BML_STMS_PS copy.png | Bin 0 -> 810 bytes .../images/map/layericon/RDL_ETCT_PS copy.png | Bin 0 -> 896 bytes .../images/map/layericon/RDL_OCUP_PS copy.png | Bin 0 -> 837 bytes .../images/map/layericon/RDL_SEPC_PS copy.png | Bin 0 -> 790 bytes .../images/map/layericon/RDL_STAT_PS copy.png | Bin 0 -> 855 bytes .../images/map/layericon/RDL_TSCT_PS copy.png | Bin 0 -> 923 bytes .../images/map/layericon/BML_CBAS_PS.png | Bin 1547 -> 919 bytes .../images/map/layericon/BML_STMS_PS.png | Bin 1542 -> 810 bytes .../images/map/layericon/RDL_ETCT_PS.png | Bin 1016 -> 896 bytes .../images/map/layericon/RDL_OCUP_PS.png | Bin 1061 -> 837 bytes .../images/map/layericon/RDL_SEPC_PS.png | Bin 1068 -> 790 bytes .../images/map/layericon/RDL_STAT_PS.png | Bin 1075 -> 855 bytes .../images/map/layericon/RDL_TSCT_PS.png | Bin 1700 -> 923 bytes .../business_components/src/ui/map/Gis.js | 599 +++++++++--------- .../business_components/src/ui/map/GisTree.js | 2 +- 34 files changed, 533 insertions(+), 368 deletions(-) create mode 100644 apps/fo/app/pages/map/searchBar/searchBar.tsx create mode 100644 apps/sn/public/images/map/layericon/BML_CBAS_PS copy.png create mode 100644 apps/sn/public/images/map/layericon/BML_STMS_PS copy.png create mode 100644 apps/sn/public/images/map/layericon/RDL_ETCT_PS copy.png create mode 100644 apps/sn/public/images/map/layericon/RDL_OCUP_PS copy.png create mode 100644 apps/sn/public/images/map/layericon/RDL_SEPC_PS copy.png create mode 100644 apps/sn/public/images/map/layericon/RDL_STAT_PS copy.png create mode 100644 apps/sn/public/images/map/layericon/RDL_TSCT_PS copy.png diff --git a/apps/dm/app/(popup-layout)/map/popup/page.tsx b/apps/dm/app/(popup-layout)/map/popup/page.tsx index ea71862d8..c0d38a5c5 100644 --- a/apps/dm/app/(popup-layout)/map/popup/page.tsx +++ b/apps/dm/app/(popup-layout)/map/popup/page.tsx @@ -233,6 +233,7 @@ const Map = () => { <> <div className="bg-container"> <Gis + height='h-screen' treeData={treeData} isSearch={false} gisMaps={gisMaps} diff --git a/apps/dm/components/ui/map/searchBar/searchBar.tsx b/apps/dm/components/ui/map/searchBar/searchBar.tsx index f2beeff82..7ca64bbce 100644 --- a/apps/dm/components/ui/map/searchBar/searchBar.tsx +++ b/apps/dm/components/ui/map/searchBar/searchBar.tsx @@ -1,8 +1,6 @@ "use client"; import { useDmStore } from "@/app/store"; import { - SearchDiv, - SearchFormLeft, SelectBox, type SelectDataType, } from "@common/business_components/ui"; @@ -48,6 +46,7 @@ export function SearchBar({ }, [Common.selectSigunData] ); + const onSelectValue = useCallback( (val: string, type: string) => { switch (type) { @@ -62,78 +61,58 @@ export function SearchBar({ [initializeSigunData] ); - // useEffect(() => { - // console.log("map.ruseFcltList ", map.ruseFcltList); - // }, [map.ruseFcltList]); - return ( - <> - <div className="grid grid-cols-4 gap-4 "> - <div className="col-span-4"> - <SearchDiv> - <SearchFormLeft> - <div className="col-span-10 flex flex-row"> - <SelectBox - className="col-span-2 w-1/6 h-full text-2xl" - label="시도" - selectClass={""} - selectArray={Common.selectSidoData || []} - onSelectValue={(val) => - onSelectValue(val.toString(), "ctpvCd") - } - value={sidoValue || Common.selectSidoData[0]?.val || ""} - /> - <SelectBox - className="col-span-2 w-1/6 h-full text-2xl ml-10" - label="시군구" - selectClass={""} - selectArray={filteredSigunData || []} - onSelectValue={(val) => - onSelectValue(val.toString(), "sggCd") - } - value={sigunValue} - /> - <div className="col-span-6 flex flex-row items-center min-w-[27rem] ml-10"> - <Label className="text-xl justify-self-center mt-2 mx-3"> - 하수재이용시설 - </Label> - <SearchInputText - label={"시설명"} - initValue={undefined} - setValue={(searchNm?: string) => { - let sggOrCity = ""; - if (searchNm) { - if (sigunValue === "0" || sigunValue === "") { - sggOrCity = sidoValue; - } else { - sggOrCity = sigunValue; - } - findRuseFclt(sggOrCity, searchNm); - } - }} - setRtnData={(rtnData: any) => { - setHasuPk(rtnData); - }} - searchList={map.ruseFcltList || []} - /> - </div> - <div className="flex flex-row space-x-2"> - <Button - color="sky" - className="mt-2" - size={"sm"} - onClick={() => { - onApply(); - }} - > - 적용 - </Button> - </div> - </div> - </SearchFormLeft> - </SearchDiv> - </div> + <div className="flex justify-center w-full px-4 py-3"> + <div className="flex items-center w-full max-w-screen-lg rounded-xl bg-white shadow-md px-6 py-4 space-x-3"> + <SelectBox + labelClass="w-[40px]" + className="w-[200px]" + label="시도" + selectClass="rounded-lg bg-white" + selectArray={Common.selectSidoData || []} + onSelectValue={(val) => onSelectValue(val.toString(), "ctpvCd")} + value={sidoValue || Common.selectSidoData[0]?.val || ""} + /> + <SelectBox + labelClass="w-[65px]" + className="w-[200px]" + label="시군구" + selectClass="rounded-lg bg-white" + selectArray={filteredSigunData || []} + onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")} + value={sigunValue} + /> + <Label className="text-gray-600">하수재이용시설</Label> + <SearchInputText + label="시설명" + initValue={undefined} + setValue={(searchNm?: string) => { + let sggOrCity = ""; + if (searchNm) { + if (sigunValue === "0" || sigunValue === "") { + sggOrCity = sidoValue; + } else { + sggOrCity = sigunValue; + } + findRuseFclt(sggOrCity, searchNm); + } + }} + setRtnData={(rtnData: any) => { + setHasuPk(rtnData); + }} + searchList={map.ruseFcltList || []} + /> + <Button + color="sky" + className="ml-2 text-white" + size="sm" + onClick={() => { + onApply(); + }} + > + 적용 + </Button> </div> - </> + </div> ); } diff --git a/apps/dm/public/images/map/layericon/BML_CBAS_PS.png b/apps/dm/public/images/map/layericon/BML_CBAS_PS.png index 5ff4add3ef67899ca56ef065952b919b8426d086..0e70939baeed2a0221089ebdf2ed19921495c8e9 100644 GIT binary patch delta 897 zcmV-{1AhFA43`IxBYy*4Nkl<Zc${TZT}+#07(LJXeue(PMzF0Gl#aAibkPX~Gt`K4 zL@G!^veC@NWm!z-#iEIq3o1VsCd(F0%obo?Ng^0((6}Yj5Qqgqkrb^I$|$Tb3bYjJ zr0lEf&-Z#^F$<o{ljofC<m7n>SqLGBhyXxHk_xF*(hA@J0Dl?45)q{yniG3EdYI&# zLzd+;Q{z9LUkL`EeefW0AU8*S-)JhjeYnEjXEGIc5s}>1*2X$IIurnqgb>u;-cCXY z?)Q1GyLvxA=l6M$PG`V4M>>_#sU)c~7?`g-QeD%yu@OI2WXj*%3nd{0V~i<*g}F~| z4Gz3NKRc7kQGaXLOLY!b|9TUJ*Vn|gD<3QJZd@s~SXD3AzcD=R-E6*aq2)dRFd|YE zMLF`*@X&iR-rq8uOI(we&y}1U+S!f6Vk@VH<`!-=6-j}>LV9-k*W*=HC8x7J5CZ_O zXR2j+DZq)C01?w^b-3f3!GwDR08rP^1hqy>fS|x_zki5^Lnllolh)~Uk^}(JNVsBa zGXlmqoqgwBR6bvW-s@NK`{d8CmOY77GKrPo9l@AH+uPf;^Jna-nwnz<m#c480)SK| ztx3o-)Y?3lORazqIApP5@T)Hoy1R@gtTt4?T1V4kZt+)a8<})QmFA=d@b3m1tuB~R zGOxUNtbY!V7!2^w`S6XaAIBYyXlOo(rQi|{S<4_P0z=;o3a(OxCr8JU|8-y}E*UnL zmeIuMh=|8`5RPrZWH#gUx%05t%JEu#BWxBM0&_m0H$F;St@|Ysxf}24=^+wAP*+!9 zfw@>S@<sP&&lQ`^se^i>YI$KE<xf9@6K}qSv44>vY(=A)vEd(h%bB;M-;Yk5y>;Wp zL@XAIQ}!UJx8HS?CGPd#{JO6s6j~K(wORmB@(&i!dT5my^ag4=d1`k{PJPgN@#43& zwY3qq+x<5Iz`(!&cRHQ?^5svDmY0=$^vBd>?fTk^l#pd`&hfap6o)ISeE!Ad?hjjA zhkERGd&J}M>;Mq7_Y_%^900~km#(~EFcefvjOml<Ok!;<GJCcAnkTxk5whFu_x8lt z4<Q5r$OVuGKo6h@Krw*F02DeLj@<nk+D~MSn8)Mc<KyFOad8oag@u{U&d#(D{}25K XcgcgJw%X%T00000NkvXXu0mjfo@TMS literal 1547 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`<jAm(=3qqRfJl%=|nBkco*&`K2Yc zN<f!FypUS}H#V;r8ce_d)2~P@&^OdG0C@?f(AO8g(%f9Q>f(~1RD^r68eAMwS&*t9 zlv<o$T9gcoxHM&uRRvbgMX8A;`9&f5`8lvq49LhY$uG{xFHmp}HdD|D&&*57FE7>v ztM~P_^2{qPNz6-5^>ndS0-B(gnVDi`<Z5p0Xk_kaV&V)8bypKdGh;(%XE$dj6H6Bh zS7&3GUYGpj(%jU%5}4i;gkC3{dO=Acw*Y9fOKMSOS!#+~QGTuh*vnR#xZPrb(>$o& z6x?pH#Hm*w=oo!a#3DsBObD2IKumbD1#;jCKQ#}S+KYh6+H&5{UIqrHdQTU}kcwM# zCdYbA4wN|lzxuh^-KyftM`9}$b|eHj#ydx=Nojj7R_fibWOhtktBRwzr;AGL6JLcX zP9asojgm^Nvyv>YoZNEAS66w8U5Los;>%~ht$SX1yNy%n%YpY#=RBYD{eR7zVv*&a zHg7yw)KPTEN8<3l%tLM_g0*X7YcHPdDrJgV)VE?sNS)uzi4)u2J~Hz-$nY#Z{b5O+ zn|F2jglp2BSwbJzieC`a_ZJb3;`&^C;m;P%xwd6GyY5cNP>d5PEO@UsWuC6v_uqA2 ztlg|m)V8_oF?{%<)YbL4?(SgT9XV^8jz4d=GUMYsCQ?~=c0bqc2kI7fy9%~0;^Ao3 z`RnX=Zd=fT{>}|zGDZ)d-L3kexg^7*Ma_@fQ6Qz_jGbq|BgbUpPoIh+uUG9-IKJeJ zkN3)jv-tO9Wgb5Agg?Wzc8g<qUWk*ktB=p$NzV<nOl#ugr-?nAn0{}$#OxW9ESQU{ zvW%{psx03-^`qSJ4;-6}E>~tflT*nqwc24D_r^eK(M07myPQdht9O1E(DK!JCiZNB zzeiH|raMOx65h_&*cMm)<@t$<#hNS+^COS+R2N!$F45U>`_2aQz0QG*+fLXNDYaDy zde2LpcWy(^SyL;u`NavPsi);W%v-$krbKb?sgs)yJid0_cHw8$;{vP29>hoX<vp8q z-TnF23PV0|y=f0zqr*G?r!wkodiZv?V@RxKv%=bg&c~m`e{`IrA}P1oe|eYV+qJJV z@}GBiu<hzBQ`CvGHL$s7`0uUyyZigtKL4|wQ1{!={BLZVtG}4s!NtF#ZrEE~y!kqz z^_8!DaAsknk#V-VkkHqFRaZagRDOK=T4kP1^}d(MzurIp<KDo?pc>2aQPz!58&o`d My85}Sb4q9e0Czo2EdT%j diff --git a/apps/dm/public/images/map/layericon/BML_STMS_PS.png b/apps/dm/public/images/map/layericon/BML_STMS_PS.png index 423f2e8fcb87d6c1b9192d1547a4cf97c3bb7292..bf4357181e9891bf71753cc3cd75aff9262de4a2 100644 GIT binary patch delta 788 zcmV+v1MB>T45|i@BYy(%Nkl<Zc${^TO-N&R6vfZ|f8?3iTChpuMs(1P77NAf#6nO6 zp<Rr$6|(KLiw3)xaUU(Sp00&1hS^P+nN88f*dZ&oQc#p;p++&OJ|p49<o~{JH_0$q zde--M@45FL;GURS03aa*+U@oWW6aM0P^nbZ{o4Pi2ZNcl<9|3W_V@RBcXv1Neg7u_ zD3{BUndw7DeE>@$ikLaoY&Kus+}wP9d3hP0pPx%9<yN=b{VbJAJuQ_=f|)@?3;=Ww z&NQ3NSM_@RtLy9QFp45otJT=^ym)GAO6GF8XX$kMNf?I2%tS=7DwoTB_`%iH)$2y1 z@uh9sp=DVr2!8@FGbIuUaddPP20`$+Uax<e$z&c8QOL~HcksDw+kez*wFi#lgj#C_ z0Iuue;^G25%Wz#c92*-`xm@l|Hk&OFkw?t@MYUS3oSd8tM^O|KkpciBf-weXXJ=q$ z0Duqzp63PGY*x?D&%c|Tocu-sXb2(R-QM1QSF6=vS$`Io8A1qjIvpGzAHQz^AU4LR zxw*MGl}h~yAXG$TTbA|x>FMe3dwY97RIAl+U|>M@58QXd%(3gbVsUXXEEbDD647%2 zB$$~z&!f@N(MJml3%||G%qU|_{QgZuh@vR=eP1juFT2HJag~Uk_kzWWh?tpaV`D=M z4-Y?f9Dk=JgxEYdIA9{;APAU<#LCJ_yHF^6OGIxgm5R#e^C19;-V_FaQmLedhK7D! zT3Y&Lc6OGGF_cUu#p>#6qfjU;6VcnPtu39;=cE6Pvk;=6%!k|C+h%8H=Wk}7?5}fQ zR4SE(<2Y8U)%pm)$5P56t@S5|hlgf;ef^<r+kY43a`~@`i3#nxZVNygK>P0Q?rwT| z+M~6#HOu$?bQDD+%$(I)XW}?cODQw0R*SUODw#|MVHny{%9|*PY$CdnQvNeCGGbG2 zci}jW<v31KDV0nl5(B>PTUu)k0G&=J5JLDt5SYQi!EU$PHRI#s{^sUp{4d9PpR{5; S2Mx6V0000<MNUMnLSTa3;)7@a literal 1542 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`<jAm(=3qqRfJl%=|nBkco*&`K2Yc zN<f!FypUS}H#V;r8ce_d)2~P@&^OdG0C@?f(AO8g(%f9Q>f(~1RD^r68eAMwS&*t9 zlv<o$T9gcoxHM&uRRvbgMX8A;`9&f5`8lvq49LhY$uG{xFHmp}HdD|D&&*57FE7>v ztM~P_^2{qPNz6-5^>ndS0-B(gnVDkc?Br<f<mO^%V&Y_MXy|I<XyN4I>}X<S=w$9< zX=Y&w)9aF-T$-DjR|3<Ug3xP(Q!gkf<Q4#Jc1bPDEK5ysE6UGR0DIXg6Q^68-Ef)* z)tiFbEe1IC>H{644~kf%h=vIPQxAv<Pqsh~JmIJ20aJSsFj-$;(cR9#z*Obw;uunK zt0c(RUpP?2_Vdk!+ghhNaj#`{R_sz!IkwbLsHd$}+C}UiyZF(i(!#>!Z9mxW?6};@ zEo2|D%REmdk7w!IEnAsXx3Fee%g-}U<hb@J?cVOs@AeeG+xy(^WNGXd>76loozD!P z&)&Lq>vfBCkG(7`X&G_Lf*+s096UWhW9E%h;$|<RRWGLLH{NOgQfXzo&1P25;|Ci$ z7v4}Xnt3JmSNzx04(~eU7Vnhr<vmy^>vw%~()q&4|I^Q@J~*G4D0Fh-ibWa?D}1IL z51*v6Bq*7&YTk!CH|nJ>%zXC!xsRIdY>y*~lO3j=&^@SJFq1VhVC9tnohe>l^nO*X zP<L6){rU6en{P~fHotk;b~y3HEWXvZkH)QLJ-w~)>nWL4S3e!)m$$clI?+9yv+1q9 z*{4e3_h$DN<(4m4J!?M0E|$|ij}FdN)#zfs_*bZgY4=sDBp2q})uC5rm1=ByboJdl z4oOayi!VzOt?$;mghbZQ`F8Kc3kw;yU3SLpZofGuJ+6AWS}R$@h)0*f*HnPlo#mZa zVdSe1!6_edtg0)s3{(zoGqu^X_eG->i}{RD4GRY41&6okY|)*q%AvciH|O7ve@!<; z9XA-woavCdymN6H^VUyh{3qjfojsf!BVmxh!!o0{)g_C`O{3{bg_KIf2h)PO>--B| zvZ<+0iiof8uQ}MVj8kwWqkQ*7VP(TL&+-z!A2_srZf)b%KiyAuP3k&0q0y_9{rFox zrd@uHp_4S`nU?gb-qe_7I&I14c^MYBSwknL=H!MamP>c=x+`vEeq{D5w?u~hVSvEz zuU4gr?rloTWkpWE+rB>DZ+(f4+~>6Yfm-4_#s0os7x9nFfMHhRx5p)mI~zeIv!|<{ J%Q~loCIHG1Mo<6% diff --git a/apps/dm/public/images/map/layericon/RDL_ETCT_PS.png b/apps/dm/public/images/map/layericon/RDL_ETCT_PS.png index 29c0b77b4ee74276df8de9416fe284e4c8bc15ec..e5a83f998a8ea4f36918482e08ec93f13fb6c40e 100644 GIT binary patch delta 874 zcmV-w1C{*v2Y?5VBYy)&Nkl<Zc${sMQD{>K7=_P&?@ex!Cb6k8%U0JFmZ}x(=At;Z zhq(C?nHyowhz<*T2|_^_+mJG7Ko~`bLx!++WwL=VsAG&FExNT6+p^(I5v^veuB~ZJ zG+mS2rb+L;x%d8iSVh#G$HV`f!~bxARWUPxK>%P!9hf=98h^jSDsSRmwmo+Dq#l|Q zWN1e9(D~x$Bd4<ODaW(B`Be7Z<^F}P)Vz}Zh<n)u0Lf%hcnnT*QebB3YH8ri2_?!0 zW^Ek%3;gy?a4Zdu&wxKIY~!K)cf;ii8~{BkC1w@`lB|is=ojA_9UqQo#%o^5DTpKr z7Bd78ELc|AtbbZB1RHG!%#%Zlhu(<oyA-GZfIvi+r5P{%Sp4$H@YJ~J#adC*1+iGw zsHO{0R&=VWEPAZ9()H<k#zp>SSM%|^2Z@LQkOTmi^8@>GJS84&X*b&HH;YSp89&Yc zhN0XQ+V0<s{Y_E$oj#hYWa)>6Upeg@+q(yev+;9rO@9Ii_tfdF|5QqFdF#n<uSc`} zS*+g}gkcD1Z`q9vaucdpK}oGrd0C^pkZax8+_LUu{F6Be0APvE*<t~mnKRhx5Aps` zgm$dkgpSs|aEnfi7H;6&-<NSEKM7T+U|UeK73I8R^#z7(dS~1e*r}TZT+L=^Ja-m5 zf*bhbmw#i_GkFo`Xa9s@nQ)3S+%6YOs^|Xb<o7xvAOQeE>XxBqc?%UPD$DEv3<qDj zdz;cq78ho2p{9v&uop^2<AC!;@;!Lwk11R)_a5vefthKdZ*Fjx^POvJ+(Bt^d8K9= zcCxb@5^S(rE?9;GN~LC)k}U4Dy|pm%_3uCX;D4(n5(!fPfcL-JqqxRA9UlY_XMAfK zZTFQWE|xV*uhq;_MK^QG5=%~x)c$;8Ss%n_eS>|s+9GWl5m^KP{r&x7JRTQMA3gnQ zeXOBtxHJ-(R%azoorqFZN0V(mBHq_076<Y@o!y<kgu~$nsZ?qSz@uTThS(i&1iHJr zUt_Cl^=wx~!!K#PQc4$Z_MGTRWsJ;xI2<lLg#Uk3A;<vS0Q>-+1JDQ{2%sSvjml3l zPfzo|AR(1XiDUUO;m++lXlQFNkG*-!V1ByvU-_e+CpFW^EdT%j07*qoM6N<$f?+_V AZvX%Q literal 1016 zcmaJ=OK8+k6b&tw(vJ!*{1ogXU8vB>XPTs)II*3XOznWFWjfFSH)fL8PUs{rO<tX} zn--yn3!xS_T?m4pE=1_Um4buR-%fF(?(9ZzBO-1Di7(U6)P-Y6@;;n%?s@m#cYSK| zd~er@E{dXha}#QwjEAGIvxEHme}p<2j^k_*Por5})jde1OjLp(XX|q?4|Q{C;SEeu zR6A`Iinyp<kPT!rdW2yD+a+v@N{$AuZp=drN^s6{6#CnfXEd-(g`N>LPIEJ`Y)veC zaC&*NU@XrY36mZ@2a<tI1Z;?P5ZD#Rmji{a>&j#vZL>6}L-4#p@0u!VQy_yp2t;Nm zW^g<YB#Ge#QIhyU5a;+f%aK=#@q#Q$a(o!<Jv52tnX__U9p8&ZRtjCl*p*qfTCFnG zAqIJKET2duB8_-FMi4Q7$-#OMbNqpZf(m`Zvs`Q;2Skc`2`yrUCQf&cV7pCO$KOj6 zNf;aGF3U4qbfgAQ)BX>&?IzmCdARTQpTd4&$%Skl`e@NJNa1D&qEN1!@t}^8S3s!J z$l_EPVdR&Q3o_FZI6Y%ICaU^p>Ud3)bB>R7$ACFip@{-xS*ARm&19rhd{__#k>|5Q zN)$#$QrT=;Oi1Y=Dc#_z$XK+YgBx6PpF7f$8?}P%lE^CbtSitQ_mB<hN0zPDUWk)c zUUs==YcEnuE=$a?QDOfobYqKjPc&_|Em<@hA3CJlJ<`@6+h6XGD^ba*sY39nv^Bc@ zD}4Vr>=~;C%<tj$t=ea<uh`$c@nPle=0mlwcK=1^z0LLQV_WaWX84`;SKR90YNfVP z5#C-37hWIvav&+(e!6<?<j?1KzPEJ?r#5c&r8W;fIJB`AhT+AVN2#_RYP~~TJ9`6t PjqYMDJE=ZOU%vVWRx?RH diff --git a/apps/dm/public/images/map/layericon/RDL_OCUP_PS.png b/apps/dm/public/images/map/layericon/RDL_OCUP_PS.png index 8a1ac0074ec2fb6ede26d23e927b6fca22809356..aeae3e26680a9415a77f0d9b310eb18b3e5f6c58 100644 GIT binary patch delta 815 zcmV+~1JL}X2*n1FBYy)7Nkl<Zc${sLT}a(^7{@=)@BecCo^#xhEi1weE2P?(GLto8 z!*y{c>rH6t=wcT|8WdD?9q2*`293yzvFajvAvhRF7aLP*qs7|9(uF2la}H0j>B^&> z7d_|y@^rB|g#27Se7|3KzRv@9QB_e804$Fc)kh1eyKbvK)_<yMuh+2-SsRLoVmXvc zg(LRFP`CMWs*y@571>@<@2kHO>}>n$n=N%GUJ+Tnrw43R75e%_RZVd9;wSddd#`fk z5|mcaFvPf40@rP}Zd_`9x#^|n>QoPdEUtx!sv0p?<j;(MXrKA$-C%mm7bhjsp0b$p zCAwHrNl2uXLVsjGw9P5)f8$J3>OlJ+4O9S(h(wD~*eK@*-wrO1g#<O0v?grR;)&T; zg?Y*ol45C)wEdacAU<)r?X=8x-Ce;LfU3!#JFFX%R#b9ST3lmV6R@ICZDHCsVGgCh zi9`bruKuQ*ua9=o+H2F-rv|{xXLs?}0@TLDI#>;k5PuH;OL#U9jvx=aSe+>p%dn6W zZ}H|1+V-a8=+Qgp(IBj1xdPkcu-PX1sX#Ee1PO!Q4ls>XnB8&AFDo#dC-g%%Zs(j5 zhyf_O$?Moj)m#N42u>{%`H^Zl!XH|qGO&Q&3gCXD;AuHloh^O-S*3TagZYNWVd@(s zyzsZ`Tz`Oh!b2AW(Lx9@P+uVw{LviLZk4$$b?5kfxbVWslOn1rM{W@x82|QM&A_pi zVxr{7y0<wxvx1f*%!3Z39Q=u;z&o{M=U;pCX7_yM`3nQbr?c5?8Pz*QW~OI$7QZ-g zO%LwXd}F;9UfdBBp55-}pLsmUKmACg`<k`*@qY))pJoOR12vtUo$mTqHX;(e|NZ%< z*DJaHO+Wr{z`Hi<vQh*u#%kSG3a$G`zYgtV?{svWO{df4k&%(&y#RnrCS!GVbqS=B z$G`h>_a34>@knb6QCR%7?2o_I-#^CG)IaHT+FvvO4^@>X!2xU_26#XmNIU?Eo}M0O tLnz}$L8@v`W-@N3x7SrwgUE*3{{XBoeqw|U;4}aL002ovPDHLkV1mCili~mX literal 1061 zcmaJ=O=#0#7>-tp>_^m#%!?s|Img;0{mI&}x^+$K0(R84*dBH;O}?(#mV7b!y0*iE z8*?alQ&5?^$i#!92*ZQF8;I!1o2VDBDvTW_3R9S0y0-IR4N1Nqp67Yr?|q-|a$@9U zd&`j)f*{((VIhgf1NOJiiT_78wj?}splBAQU>=nu6A)nq<^U;b(ilhrNvWKB3;GGd zL8<91%EnLeGSu9Xjd7PX1G5RDf1qqg@&rI+4veXKh+2R8k|I?lL}mPOCT>JPK^>kp zL27y=El*F#L4_JPLH3t<ET91-k!5XCxA=01s_OE1Zg0~RS%sj95Vf6DHl83O&;+F4 z?RCiv%aR=DW_^B+V|z&t!+K~2znqKp@qUi?^pUlP!qH46&nJagEf!vdr~*O;Pt&DR z$zAfgp*cpg!C=tV@OWGp;j$_^lFBaK>Z~gWz>-bXKq}NpTT#lvA_`GB)9oW@MnhJ& zYGuL&qsx*(vu?&dQXLqN{~xMp4YY-lU?<;y3R~%l0q7*KV9}Iu<MN$$D1(ofKtj+= zLpWKlVxj;Mv<lE5BPovT&ZxQqOV;r!J|5>q-9nNs15pT3Si!BT3h$3{0UyhReSU9@ zWuv};j|mL<W1g_bi>vMp*SP|eiyF{TovZ9{hnjM2D`*CeEC5rT0!qw;8d*IuuQtym z&{VI+Rhs7#Y|5o^GPK>;zZzZN!tSxB4cp>H!}vhQZa1;54?CBG_)6Rqg>bt3Dc9T6 zv-xhY>&x02P<F9PckYPqe}Dg)V%oWtdyi%mNB-{8tlD+s!mIoHoj<;f-u}oCQ>%|R zoz92LEzabJwgk=0?mnH#TvzDP7w0<;UZN<f?bpxsV?1+lZZ7ehaEy<S@9}?rQf&3M z8R8+w{6gy>8$Q$ftg<mbb8DICBd&G7*?VPc>+0gdDnYIg;-c_cm>i7R7gvmq2oHwN G&i(<yMpM!N diff --git a/apps/dm/public/images/map/layericon/RDL_SEPC_PS.png b/apps/dm/public/images/map/layericon/RDL_SEPC_PS.png index 087b4e94149966fd4edc1dd5b27ac50e40a4641f..b3db8e0a41bfd9e32d796bfa4035bde320607b2f 100644 GIT binary patch delta 767 zcmV<b0s#H22$lwrBYy(jNkl<Zc${rfOK6-`7(L&2??0JInuN9)XDBXGQ)!J<5D6lJ z;zkg3(M1*ANvjJXU07Wy9irkw7lIoph?If_i?1SXtaU)~1rcLyiosH`t?fKwI{D}E z|MSni_qb?NlHl2%2j_5rO(3ZNB?3_MJl@LO3jk0ht!x(mzkeAZ8C~%_{+=h_s;vwX z=bi_E{iGqeA;+#W8xip&hcEc>(T_$Szu4@!#p|&NQSNB$c-xrB8$v2chzM^5tTPvv z0zUrM=tH&Dz8hAt!yvz@HT^*J^?&+<t#_y%mJo!bib$|0Z<&*wX9GU@UU6^Zdg=<+ z*fxLwkx`+3cYn3!k{zWN&n5lsyMTit;z)|zY;gDQz!z0wXQ!RHNYx5}ZkFNv^1mPe z1EB4_yQ@^P&u+<mI-N7mh)7>Z-gCO!ub%eUrfKF>#gc%Epp*5nSZ{y;K)?vlbzx90 zPDC$_=g&N_b?gZX;9AayGxc_||9qo?F;#fn2xzA%et-GvZ;%84C=i14_OU@4wiS1O z4Zv9uX^t3u^5=H%{dcu=VE$U&jT<!pHr!=^;C;}icTc$!Gkc#Ckz*i5NlMpwxo<ds z@YU_3?>ut*4%_lRC~h<t5g>%%2|ci9Dm^i?_bCxMR;gC)+La(FAXNc0((K49wH40% z`bW6`r+>2nAAauT<d;1B+fq#OQ2?k^s}`G4sZ{jgn?#ajvv1Z{c;^obEPVDAk1YOq zmE?l}aCCk?+B|OqM0KszzSl0-leaHiS|Yh?J-0z$sZ=zM<DpiowFSVaF=i}^3gb)X z7Lu0_9oo0tXk7l_)TxC%Q&UlzrY!(%0PRkv(|DPlp6<)+?CemMWfR`}GRaaDMa2-p zgt4~RT3waMT3g8H2hO>sF=p9&-xQI$F{V~7mz%P-KaS&}IF1X}+Cnau%V$|O6h%=4 x0NrkPpsLwmFi1v5MtZ$oFPWU2%;x6i!hdSPmcBW5^N0Wd002ovPDHLkV1lGLdV>G} literal 1068 zcmaJ=TSyd97#_94Y=wl1?4`4#fk8X7v%9mG$<1_UH<wzobwOVWXJ?K&=**dBj_xSE zBuI!o^bkG;N<BmrLI_0{$d^RBKJ-*jgb>t&Bt>Dcv7J#@duSVG=3Mx`@BhyK|7X0t z?L>9efhvlks*|l^nvA=huW|?ZAN*dB$WV*pUAP1F;GASas#!r<2$GuA3)4_ihR-j; zMvAJS)l3)eN}Up9q%o3%VQkGHY>H}ZvJFY@hZtmGuc}AsuaBP4Kvkl2C!g}Bj2P@w zTSrXTG18WiNBZT6LN^@)jkZ7pG>9c&YXiC^*im{-S0Hm|o29`T1oubjbyHobb`V1* z1U%#S$X<>E!63s0_+XGb0(@T1$9l;d^l$-z4+_2z*m!6X%~X1Xw3yh4MOIO|4`V}M z*<3Ei<opaWds!|Li8vZQpNAkk*07Ex+oM}`MFkOBvZ)$aMLKX4r7Rl6QJOeiKZ0g# z%Ielenn=P}TQXRV@j6E;0#m8~Lp5y^ZQ(TB^7~I=D>H0BHVrK_Xv(B;J#|hfLx`DB z!pO`ZG*HZ9dmqBc>O%&Ibp$~}r>ZL`XB}R{r&2;vx3HwkFeyf9qQI!CB8VZLWVyv3 z;Qb=U#RCyB;g5N}VQ)Ab3Uh&Ykt-s3P=h)ya+NJ^pd{C61<fFlMQEx+P)V3b18YYX z)Y4u^*-Lp@=PISW_)2nFVup1J`&XfhTcmrO>1NxK#b)C}opifN+B&OUY9Uu*Iw>}1 z?04CGq0m&}YB>6{E*zeF|9kB6!i9axtNW*4*S2nN*da#p@XF-m{H@h5Z*HzuQ)O<q z`<aU>tEs7R-3_4+-Tc+@i!F1bCztYXXN`Mz9yhjCtURQq64zaJe#QOk9GD-v#?0+q z5+8j0_UZYar{y<hW|$Y#1rS^~4qmoS?&{uIHFdk)^?7-DY<6N|qSjbE!yhW&wx8-h V%kh;z>g%2Rn~b-KGcDbte*gsmT|@u? diff --git a/apps/dm/public/images/map/layericon/RDL_STAT_PS.png b/apps/dm/public/images/map/layericon/RDL_STAT_PS.png index 13d8ea6899c02aa0d0917b630ca9f697783fd6ff..9a0b11673abfd8ad6b85c32dcae55f5e3f7664b4 100644 GIT binary patch delta 833 zcmV-H1HSyT2-gOXBYy)PNkl<Zc${rhU1%I-6g}TJGrP01*-abMRBHUgpb3-|yA(?i zqaqTpDup(JBGi|K(wAT#N_}v_A1XzJA{tF44}I`q1s_UfEmngug>>mcY)EUft!dh{ z={BZjXEL+1GvCbdp$(<2_u*c++;h(5au0APND6=g04xCHa(@?_|86E1yLl#W+&gz) ztTvMXJk@;n>wnZA@684E9hVh%&jl-o7Q#xk?(E~Sf&~DDLP6dGE|8KO)qlC=kG!=+ zTIWe?GGOOfpQ*_v&2!`{HS+r#?r%JCv;#ui-Gro+08TG?Uu>Hv@w*djo$}PEqvClL zbJS7s)+tY6%zp`<nI(&}ODAi6>sm;PyCluprrp)1N}Y1m$5;G#+K*|IyrxK(<b)e> z*LjcnSUr4mmMl-4%CCw807e(;pL9-=2mWq^G0AyF&MER*bh}<xq)&2i##NcJiigf# zJ+U3Ib`_~f0pL<YJiB1W=+Geuz|w$L4KO5-)qu2i`+vZXCN<&I196>Z&vQ?h>wXvz z)B(T`<5V(=@#Tz%c3r}dK*o^hvLvc*j0=uJLJE9U^`I#OK}3T|!vuVx6F@d<&ORj5 zFV5Wxv8QZfOS^$HO95ZoV2Ym?ns_Rs;i4143nOGQCeyxs<M;(9Kwm*f0NCtb{dJ=W z5jA7BNq^!%w*@Vtc;|5wiHP{1JB^KLiO>uAq?HhzwV8=B;C%b`>q3$gmyZmVcAATm z*~}W<_EebC1Q5n((FLGl7!vUPP(g3eb{MtA^6+QJ)?#g#&*vfu0NaPg>+8pl?%mhn zTxrd=8HfM0X}du@GF^}AZWs+u*<2P`ea~a@ihora`t+O9*ty=m-lh;D1^^U`MGZjW zyZ!kWMkcB!-ze3>O+PtY|D(&E<12i%w8+Ebm!>}7Ke!jb)45!(6@b8MS|u467)Y!E zIu3sL{x;F`{1zjXZg03NjmBT6r;i*wRGCqj&*gH<l}g11!2dT@S63213xIY28vr~4 z;5uO-+t%OTpS&OQpf&Hj=y0W?`8RLMi`6RHdV8afUVcgOK~4MzMZ?7h!F%vn00000 LNkvXXu0mjf>vELe literal 1075 zcmaJ=&rj1(9512<`H{#)kqa+fOw_P--MZ=;1{vKZi<T^7ksUbDwGY-n`%3%91`#q1 zh#tHc{|C89NHoNRgNvFN<53T4gcyl2(SuQ=s3FW(VAF%MY5U&y<@5P`f4*yp{<AHO z?Tr*gwZ!`(NwOYxzJ`P3-|@99ljRtWrttt8!Fkz&R9HnB2;#at3X@P)rzW1jE{dwB zwNx6XrSpP<bdT&{JO$k(Y>MjYDVVY{1~JIMQOyX^pH}bFKvP5XU_kOprU<iI-?Rk> zru$RM^q3M<>7H)TRS<}P4zUah`nX{Wg%G`?E0Dc&%+O#5g2zJiZcu3{0Yqd$5b*fj zikD>p&wE%d!1HV;@OfDu<0UWeW;r3i3%=7}@1cn|OC1rCk=ULuVuk1|#-_k9`F!4! z_j`~v%CNy;(9!Vu+yvparwl9?+=lI{C`6#GSel77WB^A|&Y&C)(InE{6m+vHYuI~b zA_Zd#vdOR>uai;*C`tc^>UtGz<0SkO?>~j@)RYOCB(zb^Qb^-QT#hSK5G^QUWTg-q zuT(LSMHtyxWCC%32PXzKLq&P}<PKhvgt%d2*-&6S5~7KMN7Gb6<ilZ(3j{b$<XAS! z5krhcqyB&x=#9p>GZk(GDLEY)xWZNcaQT{CXB2dkc#c3zn}ll2LOR$<S<q_7;;*T< z$5m^`!qwz5BpAkN>|c$p9Fgg9w$-sEMs@I^L8jdzV}1OY-y&DyRy-0;6<%ew%H^JV zzVupXjlM;>ZWo{HyvOCIS2I^-|6J?Z0Wkk`VB^ijLzBFB=EJsl<;(3=cId&}xjPGs zpsi_Q`Qf|pQtxK_1*XV#|N6FYsjW08nU6nin%`GDdOo)o{msL(3qL#dFVEMxR<e(d zG`-+9xZ+J*qI}fR?%D0F^3wWx`NwlFn`nr&lv=N^&CH}XR_-n~xK7pWYo>;76pH}7 QeD7T2c(gyV)H{6nH~m6mg#Z8m diff --git a/apps/dm/public/images/map/layericon/RDL_TSCT_PS.png b/apps/dm/public/images/map/layericon/RDL_TSCT_PS.png index ffc22515996bacdfbece7d30e3d5afcfd20269d2..3776f6c0493ee2fb6717ff03adecb0f228bf8673 100644 GIT binary patch delta 901 zcmV;01A6?V4Vwp$BYy*8Nkl<Zc${TZYiL__96i7P&Fdy<+H7{U-DXp*Wn`VMs}ncJ zx~U+H>0Hs^2dQXj!PgXLQTF8~RVIGYfiSCxE$GAsKdi`F)Y+}`F$a5KX&|m$TbI_R zY5K_H-rU^W`}2d{gnB+6&iNhA4-R1!%uGZ8KrA}}wZQcN%6|b}1DxYTRQyjze9K2` zNmbR`zWgrHaW%GhpQ>3t*-7fX0eAe#eO0IG>t;?8ZO<!;A|jE91pqc?rf@h+%q*#z z{%MCY`oj53voMSTOw)uA!tHRln$G^7ZE8E{KbT7nKkKb}WbRfdF|)8qWDWdq{ln^- znm4YD-YgwGK7T@fpDX|gLX^M^YdK?Bf!b>Ov5t+yoOti>*laKx4u@F~kySGFrqgHt zdTsABUzpn(e4^*w7AccSli)e1szI7&NEKzKZDM?)^zHYl{Z(6DdTzA>2>|$UWb)~& zV@b&djSsbdE&LVb82Y>c=TG!f?>i?^;hu+@*Wq;;bbsmE6pxNut<86%JQRxldth>A zdHd{K3T3iEODlxI)30FX4j(o({ffsAx8lfC1IXkUlF(@>y+D7b3R`yW+ID9&8e%~J zjH2!~^c>8R3d^#%#y<(*9P*|IzysJ+xd_uxiA@cLk%ws&?OM?#0}z4%cw9W~b%Qlc zh1;H{zJH+y5x;l}9<v>@u{ZH?bO-Dr3ti8{?PT`YjrpH1#*EuP*cx#Cw6%U6WmYom zwC6FIkomx?yU^Np1CPGgjFD^A@Hn!_X0lwn(MNty{_@1le5R+T2ZEXD+=bquLyy&s zuJ^lbD@)6U$C;<pk{tsh_al*%;dAAn=CdWRDSth&|E|Rg!_hNdueZ?I*=Y&@=<50; zZ7arKKhpkiqVkS1dn%b?U0bl6V%9YD1#3Pz&kl!Vd-?f2s+PWd;+yE;AB~NTIU=$M z0Q&p;rBEp3Jg&U8x3X^cvEg5??~YF-rA)Q}*=5H)bsMnnq541Prhn^u|AUVPgTdf* zEPfVSyuAegP!z=$i9}?t1DlV&-L<D;U2U_F9P5ilp^!>W#lPzN?8;0sdm|VOCS$SK zG5`x}p(u&~AOr9N*bJZ^Km&j}02^9bT3l;Aw3b+1rwB)*HjIslsi`Rh0)bL@cXx@I b|EK*2JXN2b<c_UL00000NkvXXu0mjfL6OAJ literal 1700 zcmaJ?c~BE~7!4kP+-gKctlNlFwUP@GASK~Qf}|xDLd58lYK{#FklmPF$N^e~ieg(~ zP;3<usnDt@BPuP3f?BR3YFkB(1}$=VK}IM?P_P>W+CNHncK3J8d++<c-}iPlGjiQp zX9o`l91iEq3+D*1(arkU+hXr!{cpwCuo&fv&}dkWYQ-857b1ftAiz_J<3Ir@mg%?t z3I^hEGYLwe2o>=o7*be86k9Pwol1?dak#)BomwnS08u~!#wj5t!CX~C0F*K&VFQg% z=BwGDLK$w*fYF9^La8A^8XzMCv4B7w0~1hzs2I?x5+Q`4V-m)78Q9#qO(Fo}5Hx{F zc$buj9|^Ew4G7SPKHgF?g#ys&M2atsPN%E^sALM2M8<BqH^rAhqcf;}z{EwsqG@Du zhJX_`5er)}2?`WdGe{(@R!h|S5MfOmi4qVHVAY^fy)lG0qK8ni&Kp9OPbzRgM5<A$ zQ6&rkRz<M{PC}UkEYo)-sMJ%k5HfL0*nyFBVl|0EBwI_G1oHX+4^^qA&<H93|H=11 zg%P1%4Uz;P0w-ytSmWf&t)bKmwgwcVuto^OiIb-osen-!QNU_|9Zd&TZcsupSc|M0 z$Mg9N9)zG`NDA^eOai7rR4QeR05**p%B6?-`m#eP6t1s-s2`0>_6zk3poCKWLTQs+ z4lGSlfe<>$l}&N|$kTGIR#2(2$Q)3kOa^6P8dwF4m&{O3p9^PNy$P;t+Fa<|X}KgU z8IrZJ|7!H)7Umx7bjr5aV#@d+gt=XV*_sLU$g!_w5swoh)IA6k#40}H;>T{9-nPDk z^6DR$io9uMF|)VLSzRp(NnBP0h`4K5_Pf4Ugq%pTXYFw)v!8uZqzHa|>VEJxvg_3k z(!a@kRhYK^PUP*JqRj7F^KbNCPBDAlGQ}?S_d(=0hw{zMi<=fo@XMQ5@4480GKa-) z!5{Iz5`(*I^ILMAc4vf*?d>gwjc$BLBt_x5qj1%tr2Dp8Z`%pFzi{hz4|jL6Dah6f zU#=(vo4VJoxw@jFYa``~c!^i=^PN?v3XJm_n}*@k_Xm$$ADnl>h|7s+`lPnUE~mAr zzO42M`Im5|sj6h)<Fm~X=Q;B5sNT;vSDKIA<sI;v6CpRmS7Z}CO-C!L#`0bO`)khw z?lbas4WE9{BC0fus(boevug5-AEq29?^rg{c+M$5c}Yph3(@9LDKe5?-oIV(++wf@ z3U_2|y1X|H(igJ?^A<eccR0PZ%8n9Q0`Q|Rc=Y|LoH<fZN_c$0tz&T=cm7ChBs249 zQ!wGfTZor(#?S2wX8q)u664gHR~K#}!rWsT2VLUDLomLwVswcAMlapip>_P4V%wAK z(6BYJ@`tl$+)VagHk{*?_zxW4Z7y)kZQ{XpiVJv;!?JSQr!Ivp$zUHFvYqP~QZvf~ zZ;9^EuN`VVACaXZ8m^axX{*w68ok<&8Oisd&Xoa1wbAv_>?H>qf+RunJHL8WwD)Oq zuF;+KI;?$XiqEC~cxQcV+nKDqit>1M*RV_Aa3fA$dO_Xx!lhoa(423YQ*)Xn>`QV{ znIxA6tLr-tIhFa$y0cr|J44(j$w;Wt?HLl5Sw3pZMVuqPxOeSplxsB_|E#;iZMb2y zAHEdn{b(>VGu!fdW@`WS%YmY(I%9LkdtC+fmK)t#{Mi2abALpnZ|-e)t$Ul_8+edd zpOC)3E;r{%-KWy7Itt4oEVkeNsu9=ULaC<Hu61Tt;N3{6R6*?#MojJLwx{ghGZO!L z78if`+xmf*M)A^-qW0K*V*~wB`L|k&vzVLypmz<lufO5gKJqXtquiWRdO*>>*~S)^ X+MJ>?k7n6e{~J8+I!<ZmmbAYC)BCkP diff --git a/apps/fo/app/pages/map/page.tsx b/apps/fo/app/pages/map/page.tsx index 2c27869b0..1a84449a8 100644 --- a/apps/fo/app/pages/map/page.tsx +++ b/apps/fo/app/pages/map/page.tsx @@ -3,6 +3,7 @@ import Gis from "@common/business_components/ui/map/Gis"; import GisApp from "@common/business_components/ui/map/lib/gis.core"; import { useEffect, useRef, useState } from "react"; +import { SearchBar } from "./searchBar/searchBar"; interface FeatureData { fid?: string; @@ -123,22 +124,13 @@ const Map = () => { setIsSearchModalOpen(false); }; - // onCheckedLayersChange handler - const handleCheckedLayersChange = ( - checkedIds: string[], - checkedNodesData: unknown[] - ) => { - // Handle checked layers change if needed - console.log("Checked layers changed:", checkedIds, checkedNodesData); - }; - return ( <div className="bg-container"> <Gis treeData={treeData} isSearch={false} gisMaps={gisMaps} - isMiniMap={true} + isMiniMap={false} searchView={null} detailView={null} onFeatureSelect={onFeatureSelect} @@ -148,9 +140,9 @@ const Map = () => { setIsSearchModalOpen={setIsSearchModalOpen} isOpen={isOpen} isSearchModalOpen={isSearchModalOpen} - onCheckedLayersChange={handleCheckedLayersChange} + onCheckedLayersChange={undefined} imgVisble={false} - searchBar={undefined} + searchBar={(props:any) => <SearchBar onFeatureSelect={onFeatureSelect} gisMaps={gisMaps} />} /> </div> ); diff --git a/apps/fo/app/pages/map/searchBar/searchBar.tsx b/apps/fo/app/pages/map/searchBar/searchBar.tsx new file mode 100644 index 000000000..9b0800399 --- /dev/null +++ b/apps/fo/app/pages/map/searchBar/searchBar.tsx @@ -0,0 +1,158 @@ +"use client"; +import { SelectBox, type SelectDataType } from "@common/business_components/ui"; +import { Button } from "@common/components/ui"; +import { useCallback, useEffect, useState } from "react"; + +interface SearchBarProps { + onFeatureSelect: (feature: any) => void; + gisMaps: React.RefObject<any>; +} + +export function SearchBar({ onFeatureSelect, gisMaps }: SearchBarProps) { + const [sidoValue, setSidoValue] = useState("0"); + const [sigunValue, setSigunValue] = useState("0"); + const [sidoData, setSidoData] = useState<SelectDataType[]>([{ text: "선택", val: "0" }]); + const [sigunData, setSigunData] = useState<SelectDataType[]>([{ text: "선택", val: "0" }]); + const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([{ text: "선택", val: "0" }]); + const [facilityData, setFacilityData] = useState<SelectDataType[]>([{ text: "선택", val: "0" }]); + const [facilityValue, setFacilityValue] = useState("0"); + + const fetchSido = async () => { + const url = `http://rsone.iptime.org:10010/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); + const json = await res.json(); + + const list = json.features.map((f: any) => ({ + text: f.properties.mctpv_korn_nm, + val: f.properties.mctpv_cd, + })); + setSidoData([{ text: "선택", val: "0" }, ...list]); + }; + + const fetchSigun = async () => { + const url = `http://rsone.iptime.org:10010/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); + const json = await res.json(); + + const list = json.features.map((f: any) => ({ + text: f.properties.sgg_korn_nm, + val: f.properties.sgg_cd, + })); + setSigunData(list); + }; + + const fetchFacilitiesBySggNm = async (sggNm: string) => { + const encodedSggNm = encodeURIComponent(sggNm); + const url = `http://rsone.iptime.org:10010/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_il_swage_prcs_fclt&outputFormat=application/json&cql_filter=sgg_nm='${encodedSggNm}'`; + const res = await fetch(url); + const json = await res.json(); + + const list = json.features.map((f: any) => ({ + text: f.properties.swtrmt_fclt_nm ?? "(이름없음)", + val: f.id, // f.properties.swtrmt_fclt_cd 도 가능 + })); + setFacilityData([{ text: "선택", val: "0" }, ...list]); + setFacilityValue("0"); + }; + + useEffect(() => { + fetchSido(); + fetchSigun(); + }, []); + + const initializeSigunData = useCallback( + (sidoCd: string) => { + if (sidoCd === "0") { + setFilteredSigunData([{ text: "선택", val: "0" }]); + setSigunValue("0"); + return; + } + const prefix = sidoCd.substring(0, 2); + const filtered = sigunData.filter((item) => item.val.startsWith(prefix)); + setFilteredSigunData([{ text: "선택", val: "0" }, ...filtered]); + setSigunValue("0"); + }, + [sigunData] + ); + + const onSelectValue = useCallback( + (val: string, type: string) => { + if (type === "ctpvCd") { + setSidoValue(val); + initializeSigunData(val); + setFacilityData([{ text: "선택", val: "0" }]); + } else if (type === "sggCd") { + setSigunValue(val); + const sggNm = sigunData.find((item) => item.val === val)?.text || ""; + if (sggNm) fetchFacilitiesBySggNm(sggNm); + } else if (type === "fcltCd") { + setFacilityValue(val); + } + }, + [initializeSigunData, sigunData] + ); + + const handleSearch = () => { + if (!gisMaps.current || facilityValue === "0") return; + + const layers = gisMaps.current.getLayers().getArray(); + for (const layer of layers) { + const source = layer.getSource?.(); + const feature = source?.getFeatureById?.(facilityValue); + if (feature) { + onFeatureSelect(feature); + return; + } + } + + alert("해당 처리시설을 지도에서 찾을 수 없습니다."); + }; + + return ( + <div className="grid grid-cols-4 gap-4"> + <div className="col-span-4"> + <div className="card card-border flex"> + <div className="col-span-10 flex flex-row"> + <SelectBox + labelClass="w-[40px]" + className="mr-10 w-[200px]" + selectClass="rounded-lg bg-white" + label="시도" + selectArray={sidoData} + onSelectValue={(val) => onSelectValue(val.toString(), "ctpvCd")} + value={sidoValue} + /> + <SelectBox + labelClass="w-[65px]" + className="mr-10 w-[200px]" + selectClass="rounded-lg bg-white" + label="시군구" + selectArray={filteredSigunData} + onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")} + value={sigunValue} + /> + <SelectBox + labelClass="w-[140px]" + className="mr-3 w-[250px]" + selectClass="rounded-lg bg-white" + label="하수처리시설" + selectArray={facilityData} + onSelectValue={(val) => onSelectValue(val.toString(), "fcltCd")} + value={facilityValue} + /> + </div> + <div className="flex flex-row space-x-2"> + <Button + color="primary" + className="mx-2 mt-1 ml-10" + size={"sm"} + onClick={handleSearch} + > + 조회 + </Button> + </div> + </div> + </div> + </div> + ); +} diff --git a/apps/fo/public/images/map/layericon/BML_CBAS_PS.png b/apps/fo/public/images/map/layericon/BML_CBAS_PS.png index 5ff4add3ef67899ca56ef065952b919b8426d086..0e70939baeed2a0221089ebdf2ed19921495c8e9 100644 GIT binary patch delta 897 zcmV-{1AhFA43`IxBYy*4Nkl<Zc${TZT}+#07(LJXeue(PMzF0Gl#aAibkPX~Gt`K4 zL@G!^veC@NWm!z-#iEIq3o1VsCd(F0%obo?Ng^0((6}Yj5Qqgqkrb^I$|$Tb3bYjJ zr0lEf&-Z#^F$<o{ljofC<m7n>SqLGBhyXxHk_xF*(hA@J0Dl?45)q{yniG3EdYI&# zLzd+;Q{z9LUkL`EeefW0AU8*S-)JhjeYnEjXEGIc5s}>1*2X$IIurnqgb>u;-cCXY z?)Q1GyLvxA=l6M$PG`V4M>>_#sU)c~7?`g-QeD%yu@OI2WXj*%3nd{0V~i<*g}F~| z4Gz3NKRc7kQGaXLOLY!b|9TUJ*Vn|gD<3QJZd@s~SXD3AzcD=R-E6*aq2)dRFd|YE zMLF`*@X&iR-rq8uOI(we&y}1U+S!f6Vk@VH<`!-=6-j}>LV9-k*W*=HC8x7J5CZ_O zXR2j+DZq)C01?w^b-3f3!GwDR08rP^1hqy>fS|x_zki5^Lnllolh)~Uk^}(JNVsBa zGXlmqoqgwBR6bvW-s@NK`{d8CmOY77GKrPo9l@AH+uPf;^Jna-nwnz<m#c480)SK| ztx3o-)Y?3lORazqIApP5@T)Hoy1R@gtTt4?T1V4kZt+)a8<})QmFA=d@b3m1tuB~R zGOxUNtbY!V7!2^w`S6XaAIBYyXlOo(rQi|{S<4_P0z=;o3a(OxCr8JU|8-y}E*UnL zmeIuMh=|8`5RPrZWH#gUx%05t%JEu#BWxBM0&_m0H$F;St@|Ysxf}24=^+wAP*+!9 zfw@>S@<sP&&lQ`^se^i>YI$KE<xf9@6K}qSv44>vY(=A)vEd(h%bB;M-;Yk5y>;Wp zL@XAIQ}!UJx8HS?CGPd#{JO6s6j~K(wORmB@(&i!dT5my^ag4=d1`k{PJPgN@#43& zwY3qq+x<5Iz`(!&cRHQ?^5svDmY0=$^vBd>?fTk^l#pd`&hfap6o)ISeE!Ad?hjjA zhkERGd&J}M>;Mq7_Y_%^900~km#(~EFcefvjOml<Ok!;<GJCcAnkTxk5whFu_x8lt z4<Q5r$OVuGKo6h@Krw*F02DeLj@<nk+D~MSn8)Mc<KyFOad8oag@u{U&d#(D{}25K XcgcgJw%X%T00000NkvXXu0mjfo@TMS literal 1547 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`<jAm(=3qqRfJl%=|nBkco*&`K2Yc zN<f!FypUS}H#V;r8ce_d)2~P@&^OdG0C@?f(AO8g(%f9Q>f(~1RD^r68eAMwS&*t9 zlv<o$T9gcoxHM&uRRvbgMX8A;`9&f5`8lvq49LhY$uG{xFHmp}HdD|D&&*57FE7>v ztM~P_^2{qPNz6-5^>ndS0-B(gnVDi`<Z5p0Xk_kaV&V)8bypKdGh;(%XE$dj6H6Bh zS7&3GUYGpj(%jU%5}4i;gkC3{dO=Acw*Y9fOKMSOS!#+~QGTuh*vnR#xZPrb(>$o& z6x?pH#Hm*w=oo!a#3DsBObD2IKumbD1#;jCKQ#}S+KYh6+H&5{UIqrHdQTU}kcwM# zCdYbA4wN|lzxuh^-KyftM`9}$b|eHj#ydx=Nojj7R_fibWOhtktBRwzr;AGL6JLcX zP9asojgm^Nvyv>YoZNEAS66w8U5Los;>%~ht$SX1yNy%n%YpY#=RBYD{eR7zVv*&a zHg7yw)KPTEN8<3l%tLM_g0*X7YcHPdDrJgV)VE?sNS)uzi4)u2J~Hz-$nY#Z{b5O+ zn|F2jglp2BSwbJzieC`a_ZJb3;`&^C;m;P%xwd6GyY5cNP>d5PEO@UsWuC6v_uqA2 ztlg|m)V8_oF?{%<)YbL4?(SgT9XV^8jz4d=GUMYsCQ?~=c0bqc2kI7fy9%~0;^Ao3 z`RnX=Zd=fT{>}|zGDZ)d-L3kexg^7*Ma_@fQ6Qz_jGbq|BgbUpPoIh+uUG9-IKJeJ zkN3)jv-tO9Wgb5Agg?Wzc8g<qUWk*ktB=p$NzV<nOl#ugr-?nAn0{}$#OxW9ESQU{ zvW%{psx03-^`qSJ4;-6}E>~tflT*nqwc24D_r^eK(M07myPQdht9O1E(DK!JCiZNB zzeiH|raMOx65h_&*cMm)<@t$<#hNS+^COS+R2N!$F45U>`_2aQz0QG*+fLXNDYaDy zde2LpcWy(^SyL;u`NavPsi);W%v-$krbKb?sgs)yJid0_cHw8$;{vP29>hoX<vp8q z-TnF23PV0|y=f0zqr*G?r!wkodiZv?V@RxKv%=bg&c~m`e{`IrA}P1oe|eYV+qJJV z@}GBiu<hzBQ`CvGHL$s7`0uUyyZigtKL4|wQ1{!={BLZVtG}4s!NtF#ZrEE~y!kqz z^_8!DaAsknk#V-VkkHqFRaZagRDOK=T4kP1^}d(MzurIp<KDo?pc>2aQPz!58&o`d My85}Sb4q9e0Czo2EdT%j diff --git a/apps/fo/public/images/map/layericon/BML_STMS_PS.png b/apps/fo/public/images/map/layericon/BML_STMS_PS.png index 423f2e8fcb87d6c1b9192d1547a4cf97c3bb7292..bf4357181e9891bf71753cc3cd75aff9262de4a2 100644 GIT binary patch delta 788 zcmV+v1MB>T45|i@BYy(%Nkl<Zc${^TO-N&R6vfZ|f8?3iTChpuMs(1P77NAf#6nO6 zp<Rr$6|(KLiw3)xaUU(Sp00&1hS^P+nN88f*dZ&oQc#p;p++&OJ|p49<o~{JH_0$q zde--M@45FL;GURS03aa*+U@oWW6aM0P^nbZ{o4Pi2ZNcl<9|3W_V@RBcXv1Neg7u_ zD3{BUndw7DeE>@$ikLaoY&Kus+}wP9d3hP0pPx%9<yN=b{VbJAJuQ_=f|)@?3;=Ww z&NQ3NSM_@RtLy9QFp45otJT=^ym)GAO6GF8XX$kMNf?I2%tS=7DwoTB_`%iH)$2y1 z@uh9sp=DVr2!8@FGbIuUaddPP20`$+Uax<e$z&c8QOL~HcksDw+kez*wFi#lgj#C_ z0Iuue;^G25%Wz#c92*-`xm@l|Hk&OFkw?t@MYUS3oSd8tM^O|KkpciBf-weXXJ=q$ z0Duqzp63PGY*x?D&%c|Tocu-sXb2(R-QM1QSF6=vS$`Io8A1qjIvpGzAHQz^AU4LR zxw*MGl}h~yAXG$TTbA|x>FMe3dwY97RIAl+U|>M@58QXd%(3gbVsUXXEEbDD647%2 zB$$~z&!f@N(MJml3%||G%qU|_{QgZuh@vR=eP1juFT2HJag~Uk_kzWWh?tpaV`D=M z4-Y?f9Dk=JgxEYdIA9{;APAU<#LCJ_yHF^6OGIxgm5R#e^C19;-V_FaQmLedhK7D! zT3Y&Lc6OGGF_cUu#p>#6qfjU;6VcnPtu39;=cE6Pvk;=6%!k|C+h%8H=Wk}7?5}fQ zR4SE(<2Y8U)%pm)$5P56t@S5|hlgf;ef^<r+kY43a`~@`i3#nxZVNygK>P0Q?rwT| z+M~6#HOu$?bQDD+%$(I)XW}?cODQw0R*SUODw#|MVHny{%9|*PY$CdnQvNeCGGbG2 zci}jW<v31KDV0nl5(B>PTUu)k0G&=J5JLDt5SYQi!EU$PHRI#s{^sUp{4d9PpR{5; S2Mx6V0000<MNUMnLSTa3;)7@a literal 1542 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`<jAm(=3qqRfJl%=|nBkco*&`K2Yc zN<f!FypUS}H#V;r8ce_d)2~P@&^OdG0C@?f(AO8g(%f9Q>f(~1RD^r68eAMwS&*t9 zlv<o$T9gcoxHM&uRRvbgMX8A;`9&f5`8lvq49LhY$uG{xFHmp}HdD|D&&*57FE7>v ztM~P_^2{qPNz6-5^>ndS0-B(gnVDkc?Br<f<mO^%V&Y_MXy|I<XyN4I>}X<S=w$9< zX=Y&w)9aF-T$-DjR|3<Ug3xP(Q!gkf<Q4#Jc1bPDEK5ysE6UGR0DIXg6Q^68-Ef)* z)tiFbEe1IC>H{644~kf%h=vIPQxAv<Pqsh~JmIJ20aJSsFj-$;(cR9#z*Obw;uunK zt0c(RUpP?2_Vdk!+ghhNaj#`{R_sz!IkwbLsHd$}+C}UiyZF(i(!#>!Z9mxW?6};@ zEo2|D%REmdk7w!IEnAsXx3Fee%g-}U<hb@J?cVOs@AeeG+xy(^WNGXd>76loozD!P z&)&Lq>vfBCkG(7`X&G_Lf*+s096UWhW9E%h;$|<RRWGLLH{NOgQfXzo&1P25;|Ci$ z7v4}Xnt3JmSNzx04(~eU7Vnhr<vmy^>vw%~()q&4|I^Q@J~*G4D0Fh-ibWa?D}1IL z51*v6Bq*7&YTk!CH|nJ>%zXC!xsRIdY>y*~lO3j=&^@SJFq1VhVC9tnohe>l^nO*X zP<L6){rU6en{P~fHotk;b~y3HEWXvZkH)QLJ-w~)>nWL4S3e!)m$$clI?+9yv+1q9 z*{4e3_h$DN<(4m4J!?M0E|$|ij}FdN)#zfs_*bZgY4=sDBp2q})uC5rm1=ByboJdl z4oOayi!VzOt?$;mghbZQ`F8Kc3kw;yU3SLpZofGuJ+6AWS}R$@h)0*f*HnPlo#mZa zVdSe1!6_edtg0)s3{(zoGqu^X_eG->i}{RD4GRY41&6okY|)*q%AvciH|O7ve@!<; z9XA-woavCdymN6H^VUyh{3qjfojsf!BVmxh!!o0{)g_C`O{3{bg_KIf2h)PO>--B| zvZ<+0iiof8uQ}MVj8kwWqkQ*7VP(TL&+-z!A2_srZf)b%KiyAuP3k&0q0y_9{rFox zrd@uHp_4S`nU?gb-qe_7I&I14c^MYBSwknL=H!MamP>c=x+`vEeq{D5w?u~hVSvEz zuU4gr?rloTWkpWE+rB>DZ+(f4+~>6Yfm-4_#s0os7x9nFfMHhRx5p)mI~zeIv!|<{ J%Q~loCIHG1Mo<6% diff --git a/apps/fo/public/images/map/layericon/RDL_ETCT_PS.png b/apps/fo/public/images/map/layericon/RDL_ETCT_PS.png index 29c0b77b4ee74276df8de9416fe284e4c8bc15ec..e5a83f998a8ea4f36918482e08ec93f13fb6c40e 100644 GIT binary patch delta 874 zcmV-w1C{*v2Y?5VBYy)&Nkl<Zc${sMQD{>K7=_P&?@ex!Cb6k8%U0JFmZ}x(=At;Z zhq(C?nHyowhz<*T2|_^_+mJG7Ko~`bLx!++WwL=VsAG&FExNT6+p^(I5v^veuB~ZJ zG+mS2rb+L;x%d8iSVh#G$HV`f!~bxARWUPxK>%P!9hf=98h^jSDsSRmwmo+Dq#l|Q zWN1e9(D~x$Bd4<ODaW(B`Be7Z<^F}P)Vz}Zh<n)u0Lf%hcnnT*QebB3YH8ri2_?!0 zW^Ek%3;gy?a4Zdu&wxKIY~!K)cf;ii8~{BkC1w@`lB|is=ojA_9UqQo#%o^5DTpKr z7Bd78ELc|AtbbZB1RHG!%#%Zlhu(<oyA-GZfIvi+r5P{%Sp4$H@YJ~J#adC*1+iGw zsHO{0R&=VWEPAZ9()H<k#zp>SSM%|^2Z@LQkOTmi^8@>GJS84&X*b&HH;YSp89&Yc zhN0XQ+V0<s{Y_E$oj#hYWa)>6Upeg@+q(yev+;9rO@9Ii_tfdF|5QqFdF#n<uSc`} zS*+g}gkcD1Z`q9vaucdpK}oGrd0C^pkZax8+_LUu{F6Be0APvE*<t~mnKRhx5Aps` zgm$dkgpSs|aEnfi7H;6&-<NSEKM7T+U|UeK73I8R^#z7(dS~1e*r}TZT+L=^Ja-m5 zf*bhbmw#i_GkFo`Xa9s@nQ)3S+%6YOs^|Xb<o7xvAOQeE>XxBqc?%UPD$DEv3<qDj zdz;cq78ho2p{9v&uop^2<AC!;@;!Lwk11R)_a5vefthKdZ*Fjx^POvJ+(Bt^d8K9= zcCxb@5^S(rE?9;GN~LC)k}U4Dy|pm%_3uCX;D4(n5(!fPfcL-JqqxRA9UlY_XMAfK zZTFQWE|xV*uhq;_MK^QG5=%~x)c$;8Ss%n_eS>|s+9GWl5m^KP{r&x7JRTQMA3gnQ zeXOBtxHJ-(R%azoorqFZN0V(mBHq_076<Y@o!y<kgu~$nsZ?qSz@uTThS(i&1iHJr zUt_Cl^=wx~!!K#PQc4$Z_MGTRWsJ;xI2<lLg#Uk3A;<vS0Q>-+1JDQ{2%sSvjml3l zPfzo|AR(1XiDUUO;m++lXlQFNkG*-!V1ByvU-_e+CpFW^EdT%j07*qoM6N<$f?+_V AZvX%Q literal 1016 zcmaJ=OK8+k6b&tw(vJ!*{1ogXU8vB>XPTs)II*3XOznWFWjfFSH)fL8PUs{rO<tX} zn--yn3!xS_T?m4pE=1_Um4buR-%fF(?(9ZzBO-1Di7(U6)P-Y6@;;n%?s@m#cYSK| zd~er@E{dXha}#QwjEAGIvxEHme}p<2j^k_*Por5})jde1OjLp(XX|q?4|Q{C;SEeu zR6A`Iinyp<kPT!rdW2yD+a+v@N{$AuZp=drN^s6{6#CnfXEd-(g`N>LPIEJ`Y)veC zaC&*NU@XrY36mZ@2a<tI1Z;?P5ZD#Rmji{a>&j#vZL>6}L-4#p@0u!VQy_yp2t;Nm zW^g<YB#Ge#QIhyU5a;+f%aK=#@q#Q$a(o!<Jv52tnX__U9p8&ZRtjCl*p*qfTCFnG zAqIJKET2duB8_-FMi4Q7$-#OMbNqpZf(m`Zvs`Q;2Skc`2`yrUCQf&cV7pCO$KOj6 zNf;aGF3U4qbfgAQ)BX>&?IzmCdARTQpTd4&$%Skl`e@NJNa1D&qEN1!@t}^8S3s!J z$l_EPVdR&Q3o_FZI6Y%ICaU^p>Ud3)bB>R7$ACFip@{-xS*ARm&19rhd{__#k>|5Q zN)$#$QrT=;Oi1Y=Dc#_z$XK+YgBx6PpF7f$8?}P%lE^CbtSitQ_mB<hN0zPDUWk)c zUUs==YcEnuE=$a?QDOfobYqKjPc&_|Em<@hA3CJlJ<`@6+h6XGD^ba*sY39nv^Bc@ zD}4Vr>=~;C%<tj$t=ea<uh`$c@nPle=0mlwcK=1^z0LLQV_WaWX84`;SKR90YNfVP z5#C-37hWIvav&+(e!6<?<j?1KzPEJ?r#5c&r8W;fIJB`AhT+AVN2#_RYP~~TJ9`6t PjqYMDJE=ZOU%vVWRx?RH diff --git a/apps/fo/public/images/map/layericon/RDL_OCUP_PS.png b/apps/fo/public/images/map/layericon/RDL_OCUP_PS.png index 8a1ac0074ec2fb6ede26d23e927b6fca22809356..aeae3e26680a9415a77f0d9b310eb18b3e5f6c58 100644 GIT binary patch delta 815 zcmV+~1JL}X2*n1FBYy)7Nkl<Zc${sLT}a(^7{@=)@BecCo^#xhEi1weE2P?(GLto8 z!*y{c>rH6t=wcT|8WdD?9q2*`293yzvFajvAvhRF7aLP*qs7|9(uF2la}H0j>B^&> z7d_|y@^rB|g#27Se7|3KzRv@9QB_e804$Fc)kh1eyKbvK)_<yMuh+2-SsRLoVmXvc zg(LRFP`CMWs*y@571>@<@2kHO>}>n$n=N%GUJ+Tnrw43R75e%_RZVd9;wSddd#`fk z5|mcaFvPf40@rP}Zd_`9x#^|n>QoPdEUtx!sv0p?<j;(MXrKA$-C%mm7bhjsp0b$p zCAwHrNl2uXLVsjGw9P5)f8$J3>OlJ+4O9S(h(wD~*eK@*-wrO1g#<O0v?grR;)&T; zg?Y*ol45C)wEdacAU<)r?X=8x-Ce;LfU3!#JFFX%R#b9ST3lmV6R@ICZDHCsVGgCh zi9`bruKuQ*ua9=o+H2F-rv|{xXLs?}0@TLDI#>;k5PuH;OL#U9jvx=aSe+>p%dn6W zZ}H|1+V-a8=+Qgp(IBj1xdPkcu-PX1sX#Ee1PO!Q4ls>XnB8&AFDo#dC-g%%Zs(j5 zhyf_O$?Moj)m#N42u>{%`H^Zl!XH|qGO&Q&3gCXD;AuHloh^O-S*3TagZYNWVd@(s zyzsZ`Tz`Oh!b2AW(Lx9@P+uVw{LviLZk4$$b?5kfxbVWslOn1rM{W@x82|QM&A_pi zVxr{7y0<wxvx1f*%!3Z39Q=u;z&o{M=U;pCX7_yM`3nQbr?c5?8Pz*QW~OI$7QZ-g zO%LwXd}F;9UfdBBp55-}pLsmUKmACg`<k`*@qY))pJoOR12vtUo$mTqHX;(e|NZ%< z*DJaHO+Wr{z`Hi<vQh*u#%kSG3a$G`zYgtV?{svWO{df4k&%(&y#RnrCS!GVbqS=B z$G`h>_a34>@knb6QCR%7?2o_I-#^CG)IaHT+FvvO4^@>X!2xU_26#XmNIU?Eo}M0O tLnz}$L8@v`W-@N3x7SrwgUE*3{{XBoeqw|U;4}aL002ovPDHLkV1mCili~mX literal 1061 zcmaJ=O=#0#7>-tp>_^m#%!?s|Img;0{mI&}x^+$K0(R84*dBH;O}?(#mV7b!y0*iE z8*?alQ&5?^$i#!92*ZQF8;I!1o2VDBDvTW_3R9S0y0-IR4N1Nqp67Yr?|q-|a$@9U zd&`j)f*{((VIhgf1NOJiiT_78wj?}splBAQU>=nu6A)nq<^U;b(ilhrNvWKB3;GGd zL8<91%EnLeGSu9Xjd7PX1G5RDf1qqg@&rI+4veXKh+2R8k|I?lL}mPOCT>JPK^>kp zL27y=El*F#L4_JPLH3t<ET91-k!5XCxA=01s_OE1Zg0~RS%sj95Vf6DHl83O&;+F4 z?RCiv%aR=DW_^B+V|z&t!+K~2znqKp@qUi?^pUlP!qH46&nJagEf!vdr~*O;Pt&DR z$zAfgp*cpg!C=tV@OWGp;j$_^lFBaK>Z~gWz>-bXKq}NpTT#lvA_`GB)9oW@MnhJ& zYGuL&qsx*(vu?&dQXLqN{~xMp4YY-lU?<;y3R~%l0q7*KV9}Iu<MN$$D1(ofKtj+= zLpWKlVxj;Mv<lE5BPovT&ZxQqOV;r!J|5>q-9nNs15pT3Si!BT3h$3{0UyhReSU9@ zWuv};j|mL<W1g_bi>vMp*SP|eiyF{TovZ9{hnjM2D`*CeEC5rT0!qw;8d*IuuQtym z&{VI+Rhs7#Y|5o^GPK>;zZzZN!tSxB4cp>H!}vhQZa1;54?CBG_)6Rqg>bt3Dc9T6 zv-xhY>&x02P<F9PckYPqe}Dg)V%oWtdyi%mNB-{8tlD+s!mIoHoj<;f-u}oCQ>%|R zoz92LEzabJwgk=0?mnH#TvzDP7w0<;UZN<f?bpxsV?1+lZZ7ehaEy<S@9}?rQf&3M z8R8+w{6gy>8$Q$ftg<mbb8DICBd&G7*?VPc>+0gdDnYIg;-c_cm>i7R7gvmq2oHwN G&i(<yMpM!N diff --git a/apps/fo/public/images/map/layericon/RDL_SEPC_PS.png b/apps/fo/public/images/map/layericon/RDL_SEPC_PS.png index 087b4e94149966fd4edc1dd5b27ac50e40a4641f..b3db8e0a41bfd9e32d796bfa4035bde320607b2f 100644 GIT binary patch delta 767 zcmV<b0s#H22$lwrBYy(jNkl<Zc${rfOK6-`7(L&2??0JInuN9)XDBXGQ)!J<5D6lJ z;zkg3(M1*ANvjJXU07Wy9irkw7lIoph?If_i?1SXtaU)~1rcLyiosH`t?fKwI{D}E z|MSni_qb?NlHl2%2j_5rO(3ZNB?3_MJl@LO3jk0ht!x(mzkeAZ8C~%_{+=h_s;vwX z=bi_E{iGqeA;+#W8xip&hcEc>(T_$Szu4@!#p|&NQSNB$c-xrB8$v2chzM^5tTPvv z0zUrM=tH&Dz8hAt!yvz@HT^*J^?&+<t#_y%mJo!bib$|0Z<&*wX9GU@UU6^Zdg=<+ z*fxLwkx`+3cYn3!k{zWN&n5lsyMTit;z)|zY;gDQz!z0wXQ!RHNYx5}ZkFNv^1mPe z1EB4_yQ@^P&u+<mI-N7mh)7>Z-gCO!ub%eUrfKF>#gc%Epp*5nSZ{y;K)?vlbzx90 zPDC$_=g&N_b?gZX;9AayGxc_||9qo?F;#fn2xzA%et-GvZ;%84C=i14_OU@4wiS1O z4Zv9uX^t3u^5=H%{dcu=VE$U&jT<!pHr!=^;C;}icTc$!Gkc#Ckz*i5NlMpwxo<ds z@YU_3?>ut*4%_lRC~h<t5g>%%2|ci9Dm^i?_bCxMR;gC)+La(FAXNc0((K49wH40% z`bW6`r+>2nAAauT<d;1B+fq#OQ2?k^s}`G4sZ{jgn?#ajvv1Z{c;^obEPVDAk1YOq zmE?l}aCCk?+B|OqM0KszzSl0-leaHiS|Yh?J-0z$sZ=zM<DpiowFSVaF=i}^3gb)X z7Lu0_9oo0tXk7l_)TxC%Q&UlzrY!(%0PRkv(|DPlp6<)+?CemMWfR`}GRaaDMa2-p zgt4~RT3waMT3g8H2hO>sF=p9&-xQI$F{V~7mz%P-KaS&}IF1X}+Cnau%V$|O6h%=4 x0NrkPpsLwmFi1v5MtZ$oFPWU2%;x6i!hdSPmcBW5^N0Wd002ovPDHLkV1lGLdV>G} literal 1068 zcmaJ=TSyd97#_94Y=wl1?4`4#fk8X7v%9mG$<1_UH<wzobwOVWXJ?K&=**dBj_xSE zBuI!o^bkG;N<BmrLI_0{$d^RBKJ-*jgb>t&Bt>Dcv7J#@duSVG=3Mx`@BhyK|7X0t z?L>9efhvlks*|l^nvA=huW|?ZAN*dB$WV*pUAP1F;GASas#!r<2$GuA3)4_ihR-j; zMvAJS)l3)eN}Up9q%o3%VQkGHY>H}ZvJFY@hZtmGuc}AsuaBP4Kvkl2C!g}Bj2P@w zTSrXTG18WiNBZT6LN^@)jkZ7pG>9c&YXiC^*im{-S0Hm|o29`T1oubjbyHobb`V1* z1U%#S$X<>E!63s0_+XGb0(@T1$9l;d^l$-z4+_2z*m!6X%~X1Xw3yh4MOIO|4`V}M z*<3Ei<opaWds!|Li8vZQpNAkk*07Ex+oM}`MFkOBvZ)$aMLKX4r7Rl6QJOeiKZ0g# z%Ielenn=P}TQXRV@j6E;0#m8~Lp5y^ZQ(TB^7~I=D>H0BHVrK_Xv(B;J#|hfLx`DB z!pO`ZG*HZ9dmqBc>O%&Ibp$~}r>ZL`XB}R{r&2;vx3HwkFeyf9qQI!CB8VZLWVyv3 z;Qb=U#RCyB;g5N}VQ)Ab3Uh&Ykt-s3P=h)ya+NJ^pd{C61<fFlMQEx+P)V3b18YYX z)Y4u^*-Lp@=PISW_)2nFVup1J`&XfhTcmrO>1NxK#b)C}opifN+B&OUY9Uu*Iw>}1 z?04CGq0m&}YB>6{E*zeF|9kB6!i9axtNW*4*S2nN*da#p@XF-m{H@h5Z*HzuQ)O<q z`<aU>tEs7R-3_4+-Tc+@i!F1bCztYXXN`Mz9yhjCtURQq64zaJe#QOk9GD-v#?0+q z5+8j0_UZYar{y<hW|$Y#1rS^~4qmoS?&{uIHFdk)^?7-DY<6N|qSjbE!yhW&wx8-h V%kh;z>g%2Rn~b-KGcDbte*gsmT|@u? diff --git a/apps/fo/public/images/map/layericon/RDL_STAT_PS.png b/apps/fo/public/images/map/layericon/RDL_STAT_PS.png index 13d8ea6899c02aa0d0917b630ca9f697783fd6ff..9a0b11673abfd8ad6b85c32dcae55f5e3f7664b4 100644 GIT binary patch delta 833 zcmV-H1HSyT2-gOXBYy)PNkl<Zc${rhU1%I-6g}TJGrP01*-abMRBHUgpb3-|yA(?i zqaqTpDup(JBGi|K(wAT#N_}v_A1XzJA{tF44}I`q1s_UfEmngug>>mcY)EUft!dh{ z={BZjXEL+1GvCbdp$(<2_u*c++;h(5au0APND6=g04xCHa(@?_|86E1yLl#W+&gz) ztTvMXJk@;n>wnZA@684E9hVh%&jl-o7Q#xk?(E~Sf&~DDLP6dGE|8KO)qlC=kG!=+ zTIWe?GGOOfpQ*_v&2!`{HS+r#?r%JCv;#ui-Gro+08TG?Uu>Hv@w*djo$}PEqvClL zbJS7s)+tY6%zp`<nI(&}ODAi6>sm;PyCluprrp)1N}Y1m$5;G#+K*|IyrxK(<b)e> z*LjcnSUr4mmMl-4%CCw807e(;pL9-=2mWq^G0AyF&MER*bh}<xq)&2i##NcJiigf# zJ+U3Ib`_~f0pL<YJiB1W=+Geuz|w$L4KO5-)qu2i`+vZXCN<&I196>Z&vQ?h>wXvz z)B(T`<5V(=@#Tz%c3r}dK*o^hvLvc*j0=uJLJE9U^`I#OK}3T|!vuVx6F@d<&ORj5 zFV5Wxv8QZfOS^$HO95ZoV2Ym?ns_Rs;i4143nOGQCeyxs<M;(9Kwm*f0NCtb{dJ=W z5jA7BNq^!%w*@Vtc;|5wiHP{1JB^KLiO>uAq?HhzwV8=B;C%b`>q3$gmyZmVcAATm z*~}W<_EebC1Q5n((FLGl7!vUPP(g3eb{MtA^6+QJ)?#g#&*vfu0NaPg>+8pl?%mhn zTxrd=8HfM0X}du@GF^}AZWs+u*<2P`ea~a@ihora`t+O9*ty=m-lh;D1^^U`MGZjW zyZ!kWMkcB!-ze3>O+PtY|D(&E<12i%w8+Ebm!>}7Ke!jb)45!(6@b8MS|u467)Y!E zIu3sL{x;F`{1zjXZg03NjmBT6r;i*wRGCqj&*gH<l}g11!2dT@S63213xIY28vr~4 z;5uO-+t%OTpS&OQpf&Hj=y0W?`8RLMi`6RHdV8afUVcgOK~4MzMZ?7h!F%vn00000 LNkvXXu0mjf>vELe literal 1075 zcmaJ=&rj1(9512<`H{#)kqa+fOw_P--MZ=;1{vKZi<T^7ksUbDwGY-n`%3%91`#q1 zh#tHc{|C89NHoNRgNvFN<53T4gcyl2(SuQ=s3FW(VAF%MY5U&y<@5P`f4*yp{<AHO z?Tr*gwZ!`(NwOYxzJ`P3-|@99ljRtWrttt8!Fkz&R9HnB2;#at3X@P)rzW1jE{dwB zwNx6XrSpP<bdT&{JO$k(Y>MjYDVVY{1~JIMQOyX^pH}bFKvP5XU_kOprU<iI-?Rk> zru$RM^q3M<>7H)TRS<}P4zUah`nX{Wg%G`?E0Dc&%+O#5g2zJiZcu3{0Yqd$5b*fj zikD>p&wE%d!1HV;@OfDu<0UWeW;r3i3%=7}@1cn|OC1rCk=ULuVuk1|#-_k9`F!4! z_j`~v%CNy;(9!Vu+yvparwl9?+=lI{C`6#GSel77WB^A|&Y&C)(InE{6m+vHYuI~b zA_Zd#vdOR>uai;*C`tc^>UtGz<0SkO?>~j@)RYOCB(zb^Qb^-QT#hSK5G^QUWTg-q zuT(LSMHtyxWCC%32PXzKLq&P}<PKhvgt%d2*-&6S5~7KMN7Gb6<ilZ(3j{b$<XAS! z5krhcqyB&x=#9p>GZk(GDLEY)xWZNcaQT{CXB2dkc#c3zn}ll2LOR$<S<q_7;;*T< z$5m^`!qwz5BpAkN>|c$p9Fgg9w$-sEMs@I^L8jdzV}1OY-y&DyRy-0;6<%ew%H^JV zzVupXjlM;>ZWo{HyvOCIS2I^-|6J?Z0Wkk`VB^ijLzBFB=EJsl<;(3=cId&}xjPGs zpsi_Q`Qf|pQtxK_1*XV#|N6FYsjW08nU6nin%`GDdOo)o{msL(3qL#dFVEMxR<e(d zG`-+9xZ+J*qI}fR?%D0F^3wWx`NwlFn`nr&lv=N^&CH}XR_-n~xK7pWYo>;76pH}7 QeD7T2c(gyV)H{6nH~m6mg#Z8m diff --git a/apps/fo/public/images/map/layericon/RDL_TSCT_PS.png b/apps/fo/public/images/map/layericon/RDL_TSCT_PS.png index ffc22515996bacdfbece7d30e3d5afcfd20269d2..3776f6c0493ee2fb6717ff03adecb0f228bf8673 100644 GIT binary patch delta 901 zcmV;01A6?V4Vwp$BYy*8Nkl<Zc${TZYiL__96i7P&Fdy<+H7{U-DXp*Wn`VMs}ncJ zx~U+H>0Hs^2dQXj!PgXLQTF8~RVIGYfiSCxE$GAsKdi`F)Y+}`F$a5KX&|m$TbI_R zY5K_H-rU^W`}2d{gnB+6&iNhA4-R1!%uGZ8KrA}}wZQcN%6|b}1DxYTRQyjze9K2` zNmbR`zWgrHaW%GhpQ>3t*-7fX0eAe#eO0IG>t;?8ZO<!;A|jE91pqc?rf@h+%q*#z z{%MCY`oj53voMSTOw)uA!tHRln$G^7ZE8E{KbT7nKkKb}WbRfdF|)8qWDWdq{ln^- znm4YD-YgwGK7T@fpDX|gLX^M^YdK?Bf!b>Ov5t+yoOti>*laKx4u@F~kySGFrqgHt zdTsABUzpn(e4^*w7AccSli)e1szI7&NEKzKZDM?)^zHYl{Z(6DdTzA>2>|$UWb)~& zV@b&djSsbdE&LVb82Y>c=TG!f?>i?^;hu+@*Wq;;bbsmE6pxNut<86%JQRxldth>A zdHd{K3T3iEODlxI)30FX4j(o({ffsAx8lfC1IXkUlF(@>y+D7b3R`yW+ID9&8e%~J zjH2!~^c>8R3d^#%#y<(*9P*|IzysJ+xd_uxiA@cLk%ws&?OM?#0}z4%cw9W~b%Qlc zh1;H{zJH+y5x;l}9<v>@u{ZH?bO-Dr3ti8{?PT`YjrpH1#*EuP*cx#Cw6%U6WmYom zwC6FIkomx?yU^Np1CPGgjFD^A@Hn!_X0lwn(MNty{_@1le5R+T2ZEXD+=bquLyy&s zuJ^lbD@)6U$C;<pk{tsh_al*%;dAAn=CdWRDSth&|E|Rg!_hNdueZ?I*=Y&@=<50; zZ7arKKhpkiqVkS1dn%b?U0bl6V%9YD1#3Pz&kl!Vd-?f2s+PWd;+yE;AB~NTIU=$M z0Q&p;rBEp3Jg&U8x3X^cvEg5??~YF-rA)Q}*=5H)bsMnnq541Prhn^u|AUVPgTdf* zEPfVSyuAegP!z=$i9}?t1DlV&-L<D;U2U_F9P5ilp^!>W#lPzN?8;0sdm|VOCS$SK zG5`x}p(u&~AOr9N*bJZ^Km&j}02^9bT3l;Aw3b+1rwB)*HjIslsi`Rh0)bL@cXx@I b|EK*2JXN2b<c_UL00000NkvXXu0mjfL6OAJ literal 1700 zcmaJ?c~BE~7!4kP+-gKctlNlFwUP@GASK~Qf}|xDLd58lYK{#FklmPF$N^e~ieg(~ zP;3<usnDt@BPuP3f?BR3YFkB(1}$=VK}IM?P_P>W+CNHncK3J8d++<c-}iPlGjiQp zX9o`l91iEq3+D*1(arkU+hXr!{cpwCuo&fv&}dkWYQ-857b1ftAiz_J<3Ir@mg%?t z3I^hEGYLwe2o>=o7*be86k9Pwol1?dak#)BomwnS08u~!#wj5t!CX~C0F*K&VFQg% z=BwGDLK$w*fYF9^La8A^8XzMCv4B7w0~1hzs2I?x5+Q`4V-m)78Q9#qO(Fo}5Hx{F zc$buj9|^Ew4G7SPKHgF?g#ys&M2atsPN%E^sALM2M8<BqH^rAhqcf;}z{EwsqG@Du zhJX_`5er)}2?`WdGe{(@R!h|S5MfOmi4qVHVAY^fy)lG0qK8ni&Kp9OPbzRgM5<A$ zQ6&rkRz<M{PC}UkEYo)-sMJ%k5HfL0*nyFBVl|0EBwI_G1oHX+4^^qA&<H93|H=11 zg%P1%4Uz;P0w-ytSmWf&t)bKmwgwcVuto^OiIb-osen-!QNU_|9Zd&TZcsupSc|M0 z$Mg9N9)zG`NDA^eOai7rR4QeR05**p%B6?-`m#eP6t1s-s2`0>_6zk3poCKWLTQs+ z4lGSlfe<>$l}&N|$kTGIR#2(2$Q)3kOa^6P8dwF4m&{O3p9^PNy$P;t+Fa<|X}KgU z8IrZJ|7!H)7Umx7bjr5aV#@d+gt=XV*_sLU$g!_w5swoh)IA6k#40}H;>T{9-nPDk z^6DR$io9uMF|)VLSzRp(NnBP0h`4K5_Pf4Ugq%pTXYFw)v!8uZqzHa|>VEJxvg_3k z(!a@kRhYK^PUP*JqRj7F^KbNCPBDAlGQ}?S_d(=0hw{zMi<=fo@XMQ5@4480GKa-) z!5{Iz5`(*I^ILMAc4vf*?d>gwjc$BLBt_x5qj1%tr2Dp8Z`%pFzi{hz4|jL6Dah6f zU#=(vo4VJoxw@jFYa``~c!^i=^PN?v3XJm_n}*@k_Xm$$ADnl>h|7s+`lPnUE~mAr zzO42M`Im5|sj6h)<Fm~X=Q;B5sNT;vSDKIA<sI;v6CpRmS7Z}CO-C!L#`0bO`)khw z?lbas4WE9{BC0fus(boevug5-AEq29?^rg{c+M$5c}Yph3(@9LDKe5?-oIV(++wf@ z3U_2|y1X|H(igJ?^A<eccR0PZ%8n9Q0`Q|Rc=Y|LoH<fZN_c$0tz&T=cm7ChBs249 zQ!wGfTZor(#?S2wX8q)u664gHR~K#}!rWsT2VLUDLomLwVswcAMlapip>_P4V%wAK z(6BYJ@`tl$+)VagHk{*?_zxW4Z7y)kZQ{XpiVJv;!?JSQr!Ivp$zUHFvYqP~QZvf~ zZ;9^EuN`VVACaXZ8m^axX{*w68ok<&8Oisd&Xoa1wbAv_>?H>qf+RunJHL8WwD)Oq zuF;+KI;?$XiqEC~cxQcV+nKDqit>1M*RV_Aa3fA$dO_Xx!lhoa(423YQ*)Xn>`QV{ znIxA6tLr-tIhFa$y0cr|J44(j$w;Wt?HLl5Sw3pZMVuqPxOeSplxsB_|E#;iZMb2y zAHEdn{b(>VGu!fdW@`WS%YmY(I%9LkdtC+fmK)t#{Mi2abALpnZ|-e)t$Ul_8+edd zpOC)3E;r{%-KWy7Itt4oEVkeNsu9=ULaC<Hu61Tt;N3{6R6*?#MojJLwx{ghGZO!L z78if`+xmf*M)A^-qW0K*V*~wB`L|k&vzVLypmz<lufO5gKJqXtquiWRdO*>>*~S)^ X+MJ>?k7n6e{~J8+I!<ZmmbAYC)BCkP diff --git a/apps/sn/public/images/map/layericon/BML_CBAS_PS copy.png b/apps/sn/public/images/map/layericon/BML_CBAS_PS copy.png new file mode 100644 index 0000000000000000000000000000000000000000..0e70939baeed2a0221089ebdf2ed19921495c8e9 GIT binary patch literal 919 zcmV;I18Dq-P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV000ACNkl<Zc${TZ zT}+#07(LJXeue(PMzF0Gl#aAibkPX~Gt`K4L@G!^veC@NWm!z-#iEIq3o1VsCd(F0 z%obo?Ng^0((6}Yj5Qqgqkrb^I$|$Tb3bYjJr0lEf&-Z#^F$<o{ljofC<m7n>SqLGB zhyXxHk_xF*(hA@J02#m%5v3lQ6MH&(nB<&8mgO^3<3FBX2?n2i@E~y@H%EQnXezpW zxWe9NG8K0bk=)kS#yUDW6abKf5Y*n@PC^Lo_j#|odOtts_j!>{XTUf|I+fC?B&jkO zn6EriUDLR+5kFOA%HP}zB_RZ3j46SIxle8l4!l1<JCn*$YuHP54p#qq6NT5;#I-9Q zEAnn!DYaNtFW0{@Jnh|VzHp)CJ^(NxQWQlw^3(9pdo$kOGMr0Xlb6qxoE+NOjl*Iq zr-tShZZs81fxtp~cKX-jRaGUYvpo<40Iz4NWqB#UiI@Np(`j|M<D0>RdjtSb*U$vD zMoWO8z-_;XhC?SzCX?3bbdm%B(MY&rYcm4IIGugxT~t0_gWl^`@%!Y@u$DcER5FQ` z;2pu3MBCfjwDV`|shXN&2A8XERRVxiCap=xGSu2Um`kmI5IAJ9VeqRj5xTpKC#*J9 zzgkDrV{Y+RY#W($MwRBI2Jr6&8m%svQ8KT*c&rYO7!2^w`S6XaAIBYyXlOo(rQi|{ zS<4_P0z=;o3a(OxCr8JU|8-y}E*UnLmeIuMh=|8`5RPrZWH#gUx%05t%JEu#BWxBM z0&_m0H$F;St@|Ysxf}24=^+wAP*+!9fw@>S@<sP&&lQ`^se^i>YI$KE<xf9@6K}qS zv5_HcMWdOq;U9R*nYW|gk4~Jub>qfFEEbDX_8_RY-*uEF?)BgNy00V@S`})wS^!Y; z4;IjRXq6fC25LHaYIjRceb9RG;<vT6wGp@5{Wk%?z`y`^I-UIT<xh{6mz8|<$JAu) z`r3+=kY#Yr@wmAZhbyXl{>A0)4_jM@>~?#^<MHeO5VZFcS(6+9#!Hv3ykIaCR7;HM zlj%%iZ7ni;wfmYUy0H<m+wJ%E#MloZ1OdnekOx2ypa?)QfX4t7IvkGN{TkX&WQ~}| t<Kg4u<7{zp5ru_?na<A6v=ILf{Rel+gQK?E<5B<s002ovPDHLkV1k61vD*Lu literal 0 HcmV?d00001 diff --git a/apps/sn/public/images/map/layericon/BML_STMS_PS copy.png b/apps/sn/public/images/map/layericon/BML_STMS_PS copy.png new file mode 100644 index 0000000000000000000000000000000000000000..bf4357181e9891bf71753cc3cd75aff9262de4a2 GIT binary patch literal 810 zcmV+_1J(SAP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0008<Nkl<Zc${^T zO-N&R6vfZ|f8?3iTChpuMs(1P77NAf#6nO6p<Rr$6|(KLiw3)xaUU(Sp00&1hS^P+ znN88f*dZ&oQc#p;p++&OJ|p49<o~{JH_0$qde--M@45FL;GURS03aa*+U@oWW6aM0 zP^nbZ{o4Pi2ZNcl<2Wz&_xE{scQ^2T|0e(_m&=lw=|e_+081i@m^syKHecS{+<bj` zc^RIcpGzs_R=3;zER{+<EtN`wnL$Jh0CW$|G@H#=^?LoQ>+9<<iXv63)!6gAcxq}& z=5o1b>2&%@7>2~mL`1PFm&<+l!PV8(>qevTrES}xWmzf+0x&Zr5(#m1bQA_b@VH*D zf11f;9uZN<%+z=Axoz8j)M~W{j^l({YXtzV>*C_#0zJ!cT{j#X8&kPl?oBqEEfA4M z%=|^QTCJR%oD4@%6cUjF03w1h24`nyU}gY-5CWd(1=(y?&(F`lo1C2dMgeFDA>Q5I z-hNlB)nHi`m>EI{bUGazA0NMO03bHTsJXehIF(BM2_RHNWLuW?{psoH?|XZDKUAyL zaA06S_7B{5!_2Ykx?*v0F)S8~KN8V%03?{1JkO)i(a}c>3k$!^%*-fbO#J>$M2Mm& z_I+P0FE6{rVsVv-p7(;qiint*X=7tU3=a=Kb{wZAgxEYdIA9{;APAU<#LCJ_yHF^6 zOGIxgm5R#e^C19;-V_FaQmLedhK7D!T3Y&Lc6OGGF_cUu#p>#6qfjU;6VcnPtu39; z=cE6Pvk;=6%!k|C+h%8H=Wk}7?5}fQR4SE(<2Y8U)%pm)$5P56t@S5|hlgf;ef^<r z+ZW|>`LBtI3GKRW3qTt{`|j@UZhCs!qqVg)%lG|s6h$M<oYh)q;y6xADKo8Bi?r4% znM?*@7}`?Gn<$EGBD#`N{xdQ%VpDH-;W&=vI8IV2l}scO1HSKDT5AmeolYkZLij-t on8CrpZnxVt<KyH0=H_PnFUNYHv|>C5wEzGB07*qoM6N<$f<P^U=>Px# literal 0 HcmV?d00001 diff --git a/apps/sn/public/images/map/layericon/RDL_ETCT_PS copy.png b/apps/sn/public/images/map/layericon/RDL_ETCT_PS copy.png new file mode 100644 index 0000000000000000000000000000000000000000..e5a83f998a8ea4f36918482e08ec93f13fb6c40e GIT binary patch literal 896 zcmV-`1AqL9P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0009=Nkl<Zc${sM zQD{>K7=_P&?@ex!Cb6k8%U0JFmZ}x(=At;Zhq(C?nHyowhz<*T2|_^_+mJG7Ko~`b zLx!++WwL=VsAG&FExNT6+p^(I5v^veuB~ZJG+mS2rb+L;x%d8iSVh#G$HV`f!~bxA zRWUPxK>%P!9hf=98o$CSZ{l9IJ$Cn`9-0zlXh!wW`Qqmzr?T%U$FsZnRQBEF{)Mj8 zypsNid)Wm5$z)P^3{G-VU}ouRY2eHWCCUe8Z5;ax{Ps<7EDes&fIls4<DvX_!{rMc z06i)tW)=jJtck+t7vCBkAC70nYhKAIh$IRYGXxMUSXSArS}z0}Z3oPgLyL#ri0!)+ zr~rUKM3$u)Fa22j^2qSixaq}OQPTynSk<Ve3s6>cs;Vq{thLhh>3haS{$^M6@w*3! zhyjoU0GIOv`*J)b9&Kqi+UhrpOL`eU&Hsj>+!fmH-;DiDQTUxcnyX~#hlO7`?Ht>? z2Z^)sb8$@q2=~<Kt^ZU?aCz&=Z?8wQ{aLKv7=&R6Xm8n#4RRBzSV2jxQh8aUypU_% z*xa)2Wc-sk2>@V;&e>uCotZP(>JRb$P=t1@+k}qRy>N?8j23R-+~1dRB|iyOs9;-A zvK8gLWAz1wY<g$h6xgYo1zgQ$XgqfoJAxbd<CkO9GkFo`Xa9s@nQ)3S+%6YOs^|Xb z<o7xvAOQeE>XxBqc?%UPD$DEv3<qDjdz;cq78ho2p{9v&uop^2<AC!;@;!Lwk11R) z_a5vefthKdZ*Fjx^POvJ+(Bt^d8K9=cCxb@5^S(rE?9;GN~LC)k}U4Dy|pm%_3uCX z;HxDP2~z-o_rKbsxW+sk9|R9)d}|tQ_mw3smNiSS)yz^wH*?AoOHPl}{(NFtAH-*U zgMGK!B5fKGSp)$6{rzG*9v4p^J^gBZtf6bTG!mIsXC+Uah*DKYlWjdB-q$A<2l73g z-JQRL!{G<1RB8#pqhYLu*d1^Ly1Tkxt84XaS4G1wX}nTO7jO2Q=t*Ua%zQW;E<J?* ze^epJ0Neol0G<QT2p|ZcAsUU!PclzW^S>Y=l}d?Y`7z<n?K@~_YcP+!dCXvby7XW9 Wqn;-<)5t9V0000<MNUMnLSTaaMWt2% literal 0 HcmV?d00001 diff --git a/apps/sn/public/images/map/layericon/RDL_OCUP_PS copy.png b/apps/sn/public/images/map/layericon/RDL_OCUP_PS copy.png new file mode 100644 index 0000000000000000000000000000000000000000..aeae3e26680a9415a77f0d9b310eb18b3e5f6c58 GIT binary patch literal 837 zcmV-L1G@Z)P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0009FNkl<Zc${sL zT}a(^7{@=)@BecCo^#xhEi1weE2P?(GLto8!*y{c>rH6t=wcT|8WdD?9q2*`293yz zvFajvAvhRF7aLP*qs7|9(uF2la}H0j>B^&>7d_|y@^rB|g#27Se7|3KzRv@9QB_e8 z04$Fc)kh1eyKbvK)~af+*Rc*+8;XcxIh0F<Blg5lxA}9bkxD5Q*<MlatG^QLZ2Rh) zEp;be5m~*b2W(Xp`uapwO>p(%C-%^LuX5!QlvdF&#JE-h*KM|LTxx!~>80oDR1bqJ zu7!xI8ZlPn&y0U)pZVzBV0z3KCneIJvY7KFx>!<4NTiiQWIwdcDeZsbOjGJW`yUNd z0E~!4i&5Ap=Lg>oE{}x-HI}p{Y}4Y2*;j>m$`g`eX^^!2nb{ydak}la%y!*f!5Dz5 z$)7u{8<SR4a#UJeV_FliqEKyN+BabirND_q0}rnLrkk&icG22v)7Pg4z|3cN@z(;> z#>6^U4UP~F|4Vo_4~`%YyI7qm6w9!X6L0b64%+sn<mk~m=g}anVz~m_<FMH#`l&!L zxC9A<-VQL0RhZpz%r7f2oG0`{H*V*g5{LmPyUFX=N!45hA_z_`6Zw&9Il>=WqB5|6 z-U{G;qu^;dR-G+<{#m7Wt%Lc7#$oCkB)ssq>Rf<%!b2AW(Lx9@P+uVw{LviLZk4$$ zb?5kfxbVWslOn1rM{W@x82|QM&A_piVxr{7y0<wxvx1f*%!3Z39Q=u;z&o{M=U;pC zX7_yM`3nQbr?c5?8Pz*QW~OI$7QZ-gO%LwXd}F;9UfdBBp55-}pLsmUKmACg`<k`* z@dwMFW(E%fHJzQE?)q0YA`-p-{rRTXE4ltnKmKsQyEf~xQUou?YTZ@}t@}s64((&_ zbab3er_<$;k&)uP0Dw#;V|8_P38a$8zx#6c9-=+*NNWpGSp2o@kH6L5KgQJ5Kk0PZ zUo-y?Rh1{f0c;=!ct9LTJOGKFo*rjI<3>TMYENb|Zl<@_RaJw?hT8uCtT29Jgbv^| P00000NkvXXu0mjfj{B4n literal 0 HcmV?d00001 diff --git a/apps/sn/public/images/map/layericon/RDL_SEPC_PS copy.png b/apps/sn/public/images/map/layericon/RDL_SEPC_PS copy.png new file mode 100644 index 0000000000000000000000000000000000000000..b3db8e0a41bfd9e32d796bfa4035bde320607b2f GIT binary patch literal 790 zcmV+x1L^#UP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0008rNkl<Zc${rf zOK6-`7(L&2??0JInuN9)XDBXGQ)!J<5D6lJ;zkg3(M1*ANvjJXU07Wy9irkw7lIop zh?If_i?1SXtaU)~1rcLyiosH`t?fKwI{D}E|MSni_qb?NlHl2%2j_5rO(3ZNB?3_M zJl@LO3jk0ht!x(mzZoDIUGY5ro+sa`tqc<9o(F*aq#?N>$F4IQ5%DC4FZl4$k47KA z*zCB)>#+$@?r7|I+nC53LMlm!2yX?fGZ&WvKK|C|L$%eu8&<KyAit?K{Xq2ffBJ*1 zcc>ng5QL<PNU$ewnUkGo13vj)ac|>#>I&A_Hh=(;QK5c!wdRr?r5Dd7{q4JegCgQc zirj2)_wT?LRbpqSow-QW3V?2w;r#NyAOHiP?Y+CJRI<-*$$dJVGtY=fUr63_y4$aw z_SmLr=2XR!fQq1#^|4rQfB-<i2+(z5P%chHFOBEVJg{}_2@Bv_&WAJgcC!C`qk%D1 zc-#nRrzw8<>u-<*04NZG^Y*bp8nzX8e+|G{5owMXee&ma@BMeRbYT8k-HjVH05;rZ zfZ%=5r*}`e6El0C6Om&eMM+B6dAV;mfAH1qqwhR&`wrXkJ}7Q97ZD(Y;0ZmjXDU50 zv-c?xIaaAw?b?+fDIiq=G}7$IE43BQ{Q5_@|EIG7AAauT<d;1B+fq#OQ2?k^s}`G4 zsZ{jgn?#ajvv1Z{c;^obEPVDAk1YOqmE?l}aCCk?+B|OqM0KszzSl0-leaHiS|Yh? zJ-0z$sZ=zM<DpiowFSVaF=i}^3gb)X7Lu0_9oo0tXk7l_)TxC%Q&UlzrY!(%0PRkv z)0v*0?#t}#>`<0v6W;qW$x;+W#Sp@Tv9{P+U6sgMTgc}J&bg*BX4!k+6p^|yrdBSO zo3ge)j^m*?jtkb>LN1rfXIVBBMNtF*-EMcFs@Y&LNJd6Rdc9sRnVg)==H}+Ye`>*& UzBzXDhyVZp07*qoM6N<$f^J@W3IG5A literal 0 HcmV?d00001 diff --git a/apps/sn/public/images/map/layericon/RDL_STAT_PS copy.png b/apps/sn/public/images/map/layericon/RDL_STAT_PS copy.png new file mode 100644 index 0000000000000000000000000000000000000000..9a0b11673abfd8ad6b85c32dcae55f5e3f7664b4 GIT binary patch literal 855 zcmV-d1E~CoP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0009XNkl<Zc${rh zU1%I-6g}TJGrP01*-abMRBHUgpb3-|yA(?iqaqTpDup(JBGi|K(wAT#N_}v_A1XzJ zA{tF44}I`q1s_UfEmngug>>mcY)EUft!dh{={BZjXEL+1GvCbdp$(<2_u*c++;h(5 zau0APND6=g04xCHau=KbZYCGIc_we%J9l5KHj@B6)qMBsf7BoE%?0%xmlb!<1uKUZ z!b-L7?BlV51ptLYLEZx{kdhqLf4Sw4ytPDH=SgcaVCPw%smUhIbL1;E^7|X^Z#;3d z147*0grt-JPA_?1Y?~+XyAy1k^3<rK;&~Nw)KT%)DNkX{37(lHi?d57YklilNQ%28 z&Dy5j)uu|Fa@EII{CL`rX_LIBNSEY<8*$fpkNQ|Wd~=p8Pn^oHiUR;f7wVsMPLc=y zZiF$(c}31C@>+DeURR_~a&X2~nX-z9&R#vS9k6y4sYwCgQbRnuV8`gtAqc?IfL0AK zB#_mBw08Tzk0v$Y)B|yyX3uj^nCpHR5Yz#{593rait*))hjv}UkU++e=&~fLZj1|# zLP83BRrR1L13^TCNy7wup%XwhYR*0+(=X253bChbV@tb%GfM$q+hB^H7n*n~qv4_x z!3!f~GA7f$edG8ACqQ38NC4REU;TBX2@y48wn^eZw*@Vtc;|5wiHP{1JB^KLiO>uA zq?HhzwV8=B;C%b`>q3$gmyZmVcAATm*~}W<_EebC1Q5n((FLGl7!vUPP(g3eb{MtA z^6+QJ)?#g#&*vfu0NaPg>+8pl?%mhnTxrd=8HfM0X}du@GF^}AZWs+u*<2P`ea~a@ zid7o=^qbPyx!%6srVt_q02GTw4M5_%{rMM0CaNdjDAmGEKRI0gqsyM-D}1%I$iw58 zras?4xEH|Fxm>OlfWT^6B^ekPNUQ-m4u1IlHqrC^79*8zZ@4Rs#$TtWj~qNynNgU} z<#NlFO2r1i|2I`vR}w%AfOY^I06YTVVIbSq-`}6SAM>C!@4V=6rK0&aZ_10+D%yH` hqmN#GN%28V{0BwD#RtKA@K^u<002ovPDHLkV1j>(l-&RT literal 0 HcmV?d00001 diff --git a/apps/sn/public/images/map/layericon/RDL_TSCT_PS copy.png b/apps/sn/public/images/map/layericon/RDL_TSCT_PS copy.png new file mode 100644 index 0000000000000000000000000000000000000000..3776f6c0493ee2fb6717ff03adecb0f228bf8673 GIT binary patch literal 923 zcmV;M17!S(P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV000AGNkl<Zc${TZ zYiL__96i7P&Fdy<+H7{U-DXp*Wn`VMs}ncJx~U+H>0Hs^2dQXj!PgXLQTF8~RVIGY zfiSCxE$GAsKdi`F)Y+}`F$a5KX&|m$TbI_RY5K_H-rU^W`}2d{gnB+6&iNhA4-R1! z%uGZ8KrA}}wZQcN$^l&ioa01P{7*-G%SUTTRn^<R{4UXPHMV%4s#!kSN$R};cl^nH zRj2CfW=;}q&nt=|B9Vv%05)c(a5zlNEUB9QX@@fU!ud<HFpL6B(}WPh?Qpo7&i<Zl zYCGsZm`e^n>#cfZ?p7!<v#?2I4g7HZ!|IxvH?EA{EFC>QLVlkt00}~rzzl0SV_1RO zYWuN{jl-OH@9@}cFdGhsSrCy`GWDj@Xa9O_?=xSR+ZueL=iL@5lSz}{IjE{Znr289 zWu|Rne4_O2_o@9=TV8r@wE_tM_;F<N>8oQ&$p(!NwSO)A73CQEyaDG=^iuCTCsE;^ zhnm;nbs2Q&+7yqDTdmD^qdXLf{(E3@W_kPUTnc5fK}#!y!PBo`=MEn>HT{am54YmT zQv=B47?RLwDZM~{rwUtk?%H-|G#X+-0F0vUHuN0Kk_yYRxW+#T;2iR%2fzc^RJjP# zP>D?qhLMM9742HlB?AzG0eD<I?RA4SO@-T@roN#E5x;l}9<v>@u{ZH?bO-Dr3ti8{ z?PT`YjrpH1#*EuP*cx#Cw6%U6WmYomwC6FIkomx?yU^Np1CPGgjFD^A@Hn!_X0lwn z(MNty{_@1le5R+T2ZEXD+=bquLyy&suJ^lbD@)6U$C;<pk{tsh_al*%;dAAn=CdWR zDLt|OuEh(((KBAJx6s+yX$k=7>iQ&YE5=_x(*AIw@{TflDw$$kTd<sB)-?15Yd$&8 z4u@oW`T0GnmcD%Ao9N&ljg5^tBC-eo`uqE(P$=X)uDrFkvTpaW;a{%rj!z_|Ott{o zWyd{r8?f)8`akEUf9reygO3J-!QgZ(7F)c%1prVK#TJP~WUm98kG|ctr(#`gvydF? zi$<Z4N>0VU>ig`<Ofq{T7z`$3vDh*I3u~b$iU1%3@B`QkpdLU2fI0vhT3T9MYdy4< xSY4+GN24~3jfttLDFgz6Qg?TEiJAYW{Rcc%pPuB7tw{g?002ovPDHLkV1iM2#LoZ# literal 0 HcmV?d00001 diff --git a/apps/wr/public/images/map/layericon/BML_CBAS_PS.png b/apps/wr/public/images/map/layericon/BML_CBAS_PS.png index 5ff4add3ef67899ca56ef065952b919b8426d086..0e70939baeed2a0221089ebdf2ed19921495c8e9 100644 GIT binary patch delta 897 zcmV-{1AhFA43`IxBYy*4Nkl<Zc${TZT}+#07(LJXeue(PMzF0Gl#aAibkPX~Gt`K4 zL@G!^veC@NWm!z-#iEIq3o1VsCd(F0%obo?Ng^0((6}Yj5Qqgqkrb^I$|$Tb3bYjJ zr0lEf&-Z#^F$<o{ljofC<m7n>SqLGBhyXxHk_xF*(hA@J0Dl?45)q{yniG3EdYI&# zLzd+;Q{z9LUkL`EeefW0AU8*S-)JhjeYnEjXEGIc5s}>1*2X$IIurnqgb>u;-cCXY z?)Q1GyLvxA=l6M$PG`V4M>>_#sU)c~7?`g-QeD%yu@OI2WXj*%3nd{0V~i<*g}F~| z4Gz3NKRc7kQGaXLOLY!b|9TUJ*Vn|gD<3QJZd@s~SXD3AzcD=R-E6*aq2)dRFd|YE zMLF`*@X&iR-rq8uOI(we&y}1U+S!f6Vk@VH<`!-=6-j}>LV9-k*W*=HC8x7J5CZ_O zXR2j+DZq)C01?w^b-3f3!GwDR08rP^1hqy>fS|x_zki5^Lnllolh)~Uk^}(JNVsBa zGXlmqoqgwBR6bvW-s@NK`{d8CmOY77GKrPo9l@AH+uPf;^Jna-nwnz<m#c480)SK| ztx3o-)Y?3lORazqIApP5@T)Hoy1R@gtTt4?T1V4kZt+)a8<})QmFA=d@b3m1tuB~R zGOxUNtbY!V7!2^w`S6XaAIBYyXlOo(rQi|{S<4_P0z=;o3a(OxCr8JU|8-y}E*UnL zmeIuMh=|8`5RPrZWH#gUx%05t%JEu#BWxBM0&_m0H$F;St@|Ysxf}24=^+wAP*+!9 zfw@>S@<sP&&lQ`^se^i>YI$KE<xf9@6K}qSv44>vY(=A)vEd(h%bB;M-;Yk5y>;Wp zL@XAIQ}!UJx8HS?CGPd#{JO6s6j~K(wORmB@(&i!dT5my^ag4=d1`k{PJPgN@#43& zwY3qq+x<5Iz`(!&cRHQ?^5svDmY0=$^vBd>?fTk^l#pd`&hfap6o)ISeE!Ad?hjjA zhkERGd&J}M>;Mq7_Y_%^900~km#(~EFcefvjOml<Ok!;<GJCcAnkTxk5whFu_x8lt z4<Q5r$OVuGKo6h@Krw*F02DeLj@<nk+D~MSn8)Mc<KyFOad8oag@u{U&d#(D{}25K XcgcgJw%X%T00000NkvXXu0mjfo@TMS literal 1547 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`<jAm(=3qqRfJl%=|nBkco*&`K2Yc zN<f!FypUS}H#V;r8ce_d)2~P@&^OdG0C@?f(AO8g(%f9Q>f(~1RD^r68eAMwS&*t9 zlv<o$T9gcoxHM&uRRvbgMX8A;`9&f5`8lvq49LhY$uG{xFHmp}HdD|D&&*57FE7>v ztM~P_^2{qPNz6-5^>ndS0-B(gnVDi`<Z5p0Xk_kaV&V)8bypKdGh;(%XE$dj6H6Bh zS7&3GUYGpj(%jU%5}4i;gkC3{dO=Acw*Y9fOKMSOS!#+~QGTuh*vnR#xZPrb(>$o& z6x?pH#Hm*w=oo!a#3DsBObD2IKumbD1#;jCKQ#}S+KYh6+H&5{UIqrHdQTU}kcwM# zCdYbA4wN|lzxuh^-KyftM`9}$b|eHj#ydx=Nojj7R_fibWOhtktBRwzr;AGL6JLcX zP9asojgm^Nvyv>YoZNEAS66w8U5Los;>%~ht$SX1yNy%n%YpY#=RBYD{eR7zVv*&a zHg7yw)KPTEN8<3l%tLM_g0*X7YcHPdDrJgV)VE?sNS)uzi4)u2J~Hz-$nY#Z{b5O+ zn|F2jglp2BSwbJzieC`a_ZJb3;`&^C;m;P%xwd6GyY5cNP>d5PEO@UsWuC6v_uqA2 ztlg|m)V8_oF?{%<)YbL4?(SgT9XV^8jz4d=GUMYsCQ?~=c0bqc2kI7fy9%~0;^Ao3 z`RnX=Zd=fT{>}|zGDZ)d-L3kexg^7*Ma_@fQ6Qz_jGbq|BgbUpPoIh+uUG9-IKJeJ zkN3)jv-tO9Wgb5Agg?Wzc8g<qUWk*ktB=p$NzV<nOl#ugr-?nAn0{}$#OxW9ESQU{ zvW%{psx03-^`qSJ4;-6}E>~tflT*nqwc24D_r^eK(M07myPQdht9O1E(DK!JCiZNB zzeiH|raMOx65h_&*cMm)<@t$<#hNS+^COS+R2N!$F45U>`_2aQz0QG*+fLXNDYaDy zde2LpcWy(^SyL;u`NavPsi);W%v-$krbKb?sgs)yJid0_cHw8$;{vP29>hoX<vp8q z-TnF23PV0|y=f0zqr*G?r!wkodiZv?V@RxKv%=bg&c~m`e{`IrA}P1oe|eYV+qJJV z@}GBiu<hzBQ`CvGHL$s7`0uUyyZigtKL4|wQ1{!={BLZVtG}4s!NtF#ZrEE~y!kqz z^_8!DaAsknk#V-VkkHqFRaZagRDOK=T4kP1^}d(MzurIp<KDo?pc>2aQPz!58&o`d My85}Sb4q9e0Czo2EdT%j diff --git a/apps/wr/public/images/map/layericon/BML_STMS_PS.png b/apps/wr/public/images/map/layericon/BML_STMS_PS.png index 423f2e8fcb87d6c1b9192d1547a4cf97c3bb7292..bf4357181e9891bf71753cc3cd75aff9262de4a2 100644 GIT binary patch delta 788 zcmV+v1MB>T45|i@BYy(%Nkl<Zc${^TO-N&R6vfZ|f8?3iTChpuMs(1P77NAf#6nO6 zp<Rr$6|(KLiw3)xaUU(Sp00&1hS^P+nN88f*dZ&oQc#p;p++&OJ|p49<o~{JH_0$q zde--M@45FL;GURS03aa*+U@oWW6aM0P^nbZ{o4Pi2ZNcl<9|3W_V@RBcXv1Neg7u_ zD3{BUndw7DeE>@$ikLaoY&Kus+}wP9d3hP0pPx%9<yN=b{VbJAJuQ_=f|)@?3;=Ww z&NQ3NSM_@RtLy9QFp45otJT=^ym)GAO6GF8XX$kMNf?I2%tS=7DwoTB_`%iH)$2y1 z@uh9sp=DVr2!8@FGbIuUaddPP20`$+Uax<e$z&c8QOL~HcksDw+kez*wFi#lgj#C_ z0Iuue;^G25%Wz#c92*-`xm@l|Hk&OFkw?t@MYUS3oSd8tM^O|KkpciBf-weXXJ=q$ z0Duqzp63PGY*x?D&%c|Tocu-sXb2(R-QM1QSF6=vS$`Io8A1qjIvpGzAHQz^AU4LR zxw*MGl}h~yAXG$TTbA|x>FMe3dwY97RIAl+U|>M@58QXd%(3gbVsUXXEEbDD647%2 zB$$~z&!f@N(MJml3%||G%qU|_{QgZuh@vR=eP1juFT2HJag~Uk_kzWWh?tpaV`D=M z4-Y?f9Dk=JgxEYdIA9{;APAU<#LCJ_yHF^6OGIxgm5R#e^C19;-V_FaQmLedhK7D! zT3Y&Lc6OGGF_cUu#p>#6qfjU;6VcnPtu39;=cE6Pvk;=6%!k|C+h%8H=Wk}7?5}fQ zR4SE(<2Y8U)%pm)$5P56t@S5|hlgf;ef^<r+kY43a`~@`i3#nxZVNygK>P0Q?rwT| z+M~6#HOu$?bQDD+%$(I)XW}?cODQw0R*SUODw#|MVHny{%9|*PY$CdnQvNeCGGbG2 zci}jW<v31KDV0nl5(B>PTUu)k0G&=J5JLDt5SYQi!EU$PHRI#s{^sUp{4d9PpR{5; S2Mx6V0000<MNUMnLSTa3;)7@a literal 1542 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`<jAm(=3qqRfJl%=|nBkco*&`K2Yc zN<f!FypUS}H#V;r8ce_d)2~P@&^OdG0C@?f(AO8g(%f9Q>f(~1RD^r68eAMwS&*t9 zlv<o$T9gcoxHM&uRRvbgMX8A;`9&f5`8lvq49LhY$uG{xFHmp}HdD|D&&*57FE7>v ztM~P_^2{qPNz6-5^>ndS0-B(gnVDkc?Br<f<mO^%V&Y_MXy|I<XyN4I>}X<S=w$9< zX=Y&w)9aF-T$-DjR|3<Ug3xP(Q!gkf<Q4#Jc1bPDEK5ysE6UGR0DIXg6Q^68-Ef)* z)tiFbEe1IC>H{644~kf%h=vIPQxAv<Pqsh~JmIJ20aJSsFj-$;(cR9#z*Obw;uunK zt0c(RUpP?2_Vdk!+ghhNaj#`{R_sz!IkwbLsHd$}+C}UiyZF(i(!#>!Z9mxW?6};@ zEo2|D%REmdk7w!IEnAsXx3Fee%g-}U<hb@J?cVOs@AeeG+xy(^WNGXd>76loozD!P z&)&Lq>vfBCkG(7`X&G_Lf*+s096UWhW9E%h;$|<RRWGLLH{NOgQfXzo&1P25;|Ci$ z7v4}Xnt3JmSNzx04(~eU7Vnhr<vmy^>vw%~()q&4|I^Q@J~*G4D0Fh-ibWa?D}1IL z51*v6Bq*7&YTk!CH|nJ>%zXC!xsRIdY>y*~lO3j=&^@SJFq1VhVC9tnohe>l^nO*X zP<L6){rU6en{P~fHotk;b~y3HEWXvZkH)QLJ-w~)>nWL4S3e!)m$$clI?+9yv+1q9 z*{4e3_h$DN<(4m4J!?M0E|$|ij}FdN)#zfs_*bZgY4=sDBp2q})uC5rm1=ByboJdl z4oOayi!VzOt?$;mghbZQ`F8Kc3kw;yU3SLpZofGuJ+6AWS}R$@h)0*f*HnPlo#mZa zVdSe1!6_edtg0)s3{(zoGqu^X_eG->i}{RD4GRY41&6okY|)*q%AvciH|O7ve@!<; z9XA-woavCdymN6H^VUyh{3qjfojsf!BVmxh!!o0{)g_C`O{3{bg_KIf2h)PO>--B| zvZ<+0iiof8uQ}MVj8kwWqkQ*7VP(TL&+-z!A2_srZf)b%KiyAuP3k&0q0y_9{rFox zrd@uHp_4S`nU?gb-qe_7I&I14c^MYBSwknL=H!MamP>c=x+`vEeq{D5w?u~hVSvEz zuU4gr?rloTWkpWE+rB>DZ+(f4+~>6Yfm-4_#s0os7x9nFfMHhRx5p)mI~zeIv!|<{ J%Q~loCIHG1Mo<6% diff --git a/apps/wr/public/images/map/layericon/RDL_ETCT_PS.png b/apps/wr/public/images/map/layericon/RDL_ETCT_PS.png index 29c0b77b4ee74276df8de9416fe284e4c8bc15ec..e5a83f998a8ea4f36918482e08ec93f13fb6c40e 100644 GIT binary patch delta 874 zcmV-w1C{*v2Y?5VBYy)&Nkl<Zc${sMQD{>K7=_P&?@ex!Cb6k8%U0JFmZ}x(=At;Z zhq(C?nHyowhz<*T2|_^_+mJG7Ko~`bLx!++WwL=VsAG&FExNT6+p^(I5v^veuB~ZJ zG+mS2rb+L;x%d8iSVh#G$HV`f!~bxARWUPxK>%P!9hf=98h^jSDsSRmwmo+Dq#l|Q zWN1e9(D~x$Bd4<ODaW(B`Be7Z<^F}P)Vz}Zh<n)u0Lf%hcnnT*QebB3YH8ri2_?!0 zW^Ek%3;gy?a4Zdu&wxKIY~!K)cf;ii8~{BkC1w@`lB|is=ojA_9UqQo#%o^5DTpKr z7Bd78ELc|AtbbZB1RHG!%#%Zlhu(<oyA-GZfIvi+r5P{%Sp4$H@YJ~J#adC*1+iGw zsHO{0R&=VWEPAZ9()H<k#zp>SSM%|^2Z@LQkOTmi^8@>GJS84&X*b&HH;YSp89&Yc zhN0XQ+V0<s{Y_E$oj#hYWa)>6Upeg@+q(yev+;9rO@9Ii_tfdF|5QqFdF#n<uSc`} zS*+g}gkcD1Z`q9vaucdpK}oGrd0C^pkZax8+_LUu{F6Be0APvE*<t~mnKRhx5Aps` zgm$dkgpSs|aEnfi7H;6&-<NSEKM7T+U|UeK73I8R^#z7(dS~1e*r}TZT+L=^Ja-m5 zf*bhbmw#i_GkFo`Xa9s@nQ)3S+%6YOs^|Xb<o7xvAOQeE>XxBqc?%UPD$DEv3<qDj zdz;cq78ho2p{9v&uop^2<AC!;@;!Lwk11R)_a5vefthKdZ*Fjx^POvJ+(Bt^d8K9= zcCxb@5^S(rE?9;GN~LC)k}U4Dy|pm%_3uCX;D4(n5(!fPfcL-JqqxRA9UlY_XMAfK zZTFQWE|xV*uhq;_MK^QG5=%~x)c$;8Ss%n_eS>|s+9GWl5m^KP{r&x7JRTQMA3gnQ zeXOBtxHJ-(R%azoorqFZN0V(mBHq_076<Y@o!y<kgu~$nsZ?qSz@uTThS(i&1iHJr zUt_Cl^=wx~!!K#PQc4$Z_MGTRWsJ;xI2<lLg#Uk3A;<vS0Q>-+1JDQ{2%sSvjml3l zPfzo|AR(1XiDUUO;m++lXlQFNkG*-!V1ByvU-_e+CpFW^EdT%j07*qoM6N<$f?+_V AZvX%Q literal 1016 zcmaJ=OK8+k6b&tw(vJ!*{1ogXU8vB>XPTs)II*3XOznWFWjfFSH)fL8PUs{rO<tX} zn--yn3!xS_T?m4pE=1_Um4buR-%fF(?(9ZzBO-1Di7(U6)P-Y6@;;n%?s@m#cYSK| zd~er@E{dXha}#QwjEAGIvxEHme}p<2j^k_*Por5})jde1OjLp(XX|q?4|Q{C;SEeu zR6A`Iinyp<kPT!rdW2yD+a+v@N{$AuZp=drN^s6{6#CnfXEd-(g`N>LPIEJ`Y)veC zaC&*NU@XrY36mZ@2a<tI1Z;?P5ZD#Rmji{a>&j#vZL>6}L-4#p@0u!VQy_yp2t;Nm zW^g<YB#Ge#QIhyU5a;+f%aK=#@q#Q$a(o!<Jv52tnX__U9p8&ZRtjCl*p*qfTCFnG zAqIJKET2duB8_-FMi4Q7$-#OMbNqpZf(m`Zvs`Q;2Skc`2`yrUCQf&cV7pCO$KOj6 zNf;aGF3U4qbfgAQ)BX>&?IzmCdARTQpTd4&$%Skl`e@NJNa1D&qEN1!@t}^8S3s!J z$l_EPVdR&Q3o_FZI6Y%ICaU^p>Ud3)bB>R7$ACFip@{-xS*ARm&19rhd{__#k>|5Q zN)$#$QrT=;Oi1Y=Dc#_z$XK+YgBx6PpF7f$8?}P%lE^CbtSitQ_mB<hN0zPDUWk)c zUUs==YcEnuE=$a?QDOfobYqKjPc&_|Em<@hA3CJlJ<`@6+h6XGD^ba*sY39nv^Bc@ zD}4Vr>=~;C%<tj$t=ea<uh`$c@nPle=0mlwcK=1^z0LLQV_WaWX84`;SKR90YNfVP z5#C-37hWIvav&+(e!6<?<j?1KzPEJ?r#5c&r8W;fIJB`AhT+AVN2#_RYP~~TJ9`6t PjqYMDJE=ZOU%vVWRx?RH diff --git a/apps/wr/public/images/map/layericon/RDL_OCUP_PS.png b/apps/wr/public/images/map/layericon/RDL_OCUP_PS.png index 8a1ac0074ec2fb6ede26d23e927b6fca22809356..aeae3e26680a9415a77f0d9b310eb18b3e5f6c58 100644 GIT binary patch delta 815 zcmV+~1JL}X2*n1FBYy)7Nkl<Zc${sLT}a(^7{@=)@BecCo^#xhEi1weE2P?(GLto8 z!*y{c>rH6t=wcT|8WdD?9q2*`293yzvFajvAvhRF7aLP*qs7|9(uF2la}H0j>B^&> z7d_|y@^rB|g#27Se7|3KzRv@9QB_e804$Fc)kh1eyKbvK)_<yMuh+2-SsRLoVmXvc zg(LRFP`CMWs*y@571>@<@2kHO>}>n$n=N%GUJ+Tnrw43R75e%_RZVd9;wSddd#`fk z5|mcaFvPf40@rP}Zd_`9x#^|n>QoPdEUtx!sv0p?<j;(MXrKA$-C%mm7bhjsp0b$p zCAwHrNl2uXLVsjGw9P5)f8$J3>OlJ+4O9S(h(wD~*eK@*-wrO1g#<O0v?grR;)&T; zg?Y*ol45C)wEdacAU<)r?X=8x-Ce;LfU3!#JFFX%R#b9ST3lmV6R@ICZDHCsVGgCh zi9`bruKuQ*ua9=o+H2F-rv|{xXLs?}0@TLDI#>;k5PuH;OL#U9jvx=aSe+>p%dn6W zZ}H|1+V-a8=+Qgp(IBj1xdPkcu-PX1sX#Ee1PO!Q4ls>XnB8&AFDo#dC-g%%Zs(j5 zhyf_O$?Moj)m#N42u>{%`H^Zl!XH|qGO&Q&3gCXD;AuHloh^O-S*3TagZYNWVd@(s zyzsZ`Tz`Oh!b2AW(Lx9@P+uVw{LviLZk4$$b?5kfxbVWslOn1rM{W@x82|QM&A_pi zVxr{7y0<wxvx1f*%!3Z39Q=u;z&o{M=U;pCX7_yM`3nQbr?c5?8Pz*QW~OI$7QZ-g zO%LwXd}F;9UfdBBp55-}pLsmUKmACg`<k`*@qY))pJoOR12vtUo$mTqHX;(e|NZ%< z*DJaHO+Wr{z`Hi<vQh*u#%kSG3a$G`zYgtV?{svWO{df4k&%(&y#RnrCS!GVbqS=B z$G`h>_a34>@knb6QCR%7?2o_I-#^CG)IaHT+FvvO4^@>X!2xU_26#XmNIU?Eo}M0O tLnz}$L8@v`W-@N3x7SrwgUE*3{{XBoeqw|U;4}aL002ovPDHLkV1mCili~mX literal 1061 zcmaJ=O=#0#7>-tp>_^m#%!?s|Img;0{mI&}x^+$K0(R84*dBH;O}?(#mV7b!y0*iE z8*?alQ&5?^$i#!92*ZQF8;I!1o2VDBDvTW_3R9S0y0-IR4N1Nqp67Yr?|q-|a$@9U zd&`j)f*{((VIhgf1NOJiiT_78wj?}splBAQU>=nu6A)nq<^U;b(ilhrNvWKB3;GGd zL8<91%EnLeGSu9Xjd7PX1G5RDf1qqg@&rI+4veXKh+2R8k|I?lL}mPOCT>JPK^>kp zL27y=El*F#L4_JPLH3t<ET91-k!5XCxA=01s_OE1Zg0~RS%sj95Vf6DHl83O&;+F4 z?RCiv%aR=DW_^B+V|z&t!+K~2znqKp@qUi?^pUlP!qH46&nJagEf!vdr~*O;Pt&DR z$zAfgp*cpg!C=tV@OWGp;j$_^lFBaK>Z~gWz>-bXKq}NpTT#lvA_`GB)9oW@MnhJ& zYGuL&qsx*(vu?&dQXLqN{~xMp4YY-lU?<;y3R~%l0q7*KV9}Iu<MN$$D1(ofKtj+= zLpWKlVxj;Mv<lE5BPovT&ZxQqOV;r!J|5>q-9nNs15pT3Si!BT3h$3{0UyhReSU9@ zWuv};j|mL<W1g_bi>vMp*SP|eiyF{TovZ9{hnjM2D`*CeEC5rT0!qw;8d*IuuQtym z&{VI+Rhs7#Y|5o^GPK>;zZzZN!tSxB4cp>H!}vhQZa1;54?CBG_)6Rqg>bt3Dc9T6 zv-xhY>&x02P<F9PckYPqe}Dg)V%oWtdyi%mNB-{8tlD+s!mIoHoj<;f-u}oCQ>%|R zoz92LEzabJwgk=0?mnH#TvzDP7w0<;UZN<f?bpxsV?1+lZZ7ehaEy<S@9}?rQf&3M z8R8+w{6gy>8$Q$ftg<mbb8DICBd&G7*?VPc>+0gdDnYIg;-c_cm>i7R7gvmq2oHwN G&i(<yMpM!N diff --git a/apps/wr/public/images/map/layericon/RDL_SEPC_PS.png b/apps/wr/public/images/map/layericon/RDL_SEPC_PS.png index 087b4e94149966fd4edc1dd5b27ac50e40a4641f..b3db8e0a41bfd9e32d796bfa4035bde320607b2f 100644 GIT binary patch delta 767 zcmV<b0s#H22$lwrBYy(jNkl<Zc${rfOK6-`7(L&2??0JInuN9)XDBXGQ)!J<5D6lJ z;zkg3(M1*ANvjJXU07Wy9irkw7lIoph?If_i?1SXtaU)~1rcLyiosH`t?fKwI{D}E z|MSni_qb?NlHl2%2j_5rO(3ZNB?3_MJl@LO3jk0ht!x(mzkeAZ8C~%_{+=h_s;vwX z=bi_E{iGqeA;+#W8xip&hcEc>(T_$Szu4@!#p|&NQSNB$c-xrB8$v2chzM^5tTPvv z0zUrM=tH&Dz8hAt!yvz@HT^*J^?&+<t#_y%mJo!bib$|0Z<&*wX9GU@UU6^Zdg=<+ z*fxLwkx`+3cYn3!k{zWN&n5lsyMTit;z)|zY;gDQz!z0wXQ!RHNYx5}ZkFNv^1mPe z1EB4_yQ@^P&u+<mI-N7mh)7>Z-gCO!ub%eUrfKF>#gc%Epp*5nSZ{y;K)?vlbzx90 zPDC$_=g&N_b?gZX;9AayGxc_||9qo?F;#fn2xzA%et-GvZ;%84C=i14_OU@4wiS1O z4Zv9uX^t3u^5=H%{dcu=VE$U&jT<!pHr!=^;C;}icTc$!Gkc#Ckz*i5NlMpwxo<ds z@YU_3?>ut*4%_lRC~h<t5g>%%2|ci9Dm^i?_bCxMR;gC)+La(FAXNc0((K49wH40% z`bW6`r+>2nAAauT<d;1B+fq#OQ2?k^s}`G4sZ{jgn?#ajvv1Z{c;^obEPVDAk1YOq zmE?l}aCCk?+B|OqM0KszzSl0-leaHiS|Yh?J-0z$sZ=zM<DpiowFSVaF=i}^3gb)X z7Lu0_9oo0tXk7l_)TxC%Q&UlzrY!(%0PRkv(|DPlp6<)+?CemMWfR`}GRaaDMa2-p zgt4~RT3waMT3g8H2hO>sF=p9&-xQI$F{V~7mz%P-KaS&}IF1X}+Cnau%V$|O6h%=4 x0NrkPpsLwmFi1v5MtZ$oFPWU2%;x6i!hdSPmcBW5^N0Wd002ovPDHLkV1lGLdV>G} literal 1068 zcmaJ=TSyd97#_94Y=wl1?4`4#fk8X7v%9mG$<1_UH<wzobwOVWXJ?K&=**dBj_xSE zBuI!o^bkG;N<BmrLI_0{$d^RBKJ-*jgb>t&Bt>Dcv7J#@duSVG=3Mx`@BhyK|7X0t z?L>9efhvlks*|l^nvA=huW|?ZAN*dB$WV*pUAP1F;GASas#!r<2$GuA3)4_ihR-j; zMvAJS)l3)eN}Up9q%o3%VQkGHY>H}ZvJFY@hZtmGuc}AsuaBP4Kvkl2C!g}Bj2P@w zTSrXTG18WiNBZT6LN^@)jkZ7pG>9c&YXiC^*im{-S0Hm|o29`T1oubjbyHobb`V1* z1U%#S$X<>E!63s0_+XGb0(@T1$9l;d^l$-z4+_2z*m!6X%~X1Xw3yh4MOIO|4`V}M z*<3Ei<opaWds!|Li8vZQpNAkk*07Ex+oM}`MFkOBvZ)$aMLKX4r7Rl6QJOeiKZ0g# z%Ielenn=P}TQXRV@j6E;0#m8~Lp5y^ZQ(TB^7~I=D>H0BHVrK_Xv(B;J#|hfLx`DB z!pO`ZG*HZ9dmqBc>O%&Ibp$~}r>ZL`XB}R{r&2;vx3HwkFeyf9qQI!CB8VZLWVyv3 z;Qb=U#RCyB;g5N}VQ)Ab3Uh&Ykt-s3P=h)ya+NJ^pd{C61<fFlMQEx+P)V3b18YYX z)Y4u^*-Lp@=PISW_)2nFVup1J`&XfhTcmrO>1NxK#b)C}opifN+B&OUY9Uu*Iw>}1 z?04CGq0m&}YB>6{E*zeF|9kB6!i9axtNW*4*S2nN*da#p@XF-m{H@h5Z*HzuQ)O<q z`<aU>tEs7R-3_4+-Tc+@i!F1bCztYXXN`Mz9yhjCtURQq64zaJe#QOk9GD-v#?0+q z5+8j0_UZYar{y<hW|$Y#1rS^~4qmoS?&{uIHFdk)^?7-DY<6N|qSjbE!yhW&wx8-h V%kh;z>g%2Rn~b-KGcDbte*gsmT|@u? diff --git a/apps/wr/public/images/map/layericon/RDL_STAT_PS.png b/apps/wr/public/images/map/layericon/RDL_STAT_PS.png index 13d8ea6899c02aa0d0917b630ca9f697783fd6ff..9a0b11673abfd8ad6b85c32dcae55f5e3f7664b4 100644 GIT binary patch delta 833 zcmV-H1HSyT2-gOXBYy)PNkl<Zc${rhU1%I-6g}TJGrP01*-abMRBHUgpb3-|yA(?i zqaqTpDup(JBGi|K(wAT#N_}v_A1XzJA{tF44}I`q1s_UfEmngug>>mcY)EUft!dh{ z={BZjXEL+1GvCbdp$(<2_u*c++;h(5au0APND6=g04xCHa(@?_|86E1yLl#W+&gz) ztTvMXJk@;n>wnZA@684E9hVh%&jl-o7Q#xk?(E~Sf&~DDLP6dGE|8KO)qlC=kG!=+ zTIWe?GGOOfpQ*_v&2!`{HS+r#?r%JCv;#ui-Gro+08TG?Uu>Hv@w*djo$}PEqvClL zbJS7s)+tY6%zp`<nI(&}ODAi6>sm;PyCluprrp)1N}Y1m$5;G#+K*|IyrxK(<b)e> z*LjcnSUr4mmMl-4%CCw807e(;pL9-=2mWq^G0AyF&MER*bh}<xq)&2i##NcJiigf# zJ+U3Ib`_~f0pL<YJiB1W=+Geuz|w$L4KO5-)qu2i`+vZXCN<&I196>Z&vQ?h>wXvz z)B(T`<5V(=@#Tz%c3r}dK*o^hvLvc*j0=uJLJE9U^`I#OK}3T|!vuVx6F@d<&ORj5 zFV5Wxv8QZfOS^$HO95ZoV2Ym?ns_Rs;i4143nOGQCeyxs<M;(9Kwm*f0NCtb{dJ=W z5jA7BNq^!%w*@Vtc;|5wiHP{1JB^KLiO>uAq?HhzwV8=B;C%b`>q3$gmyZmVcAATm z*~}W<_EebC1Q5n((FLGl7!vUPP(g3eb{MtA^6+QJ)?#g#&*vfu0NaPg>+8pl?%mhn zTxrd=8HfM0X}du@GF^}AZWs+u*<2P`ea~a@ihora`t+O9*ty=m-lh;D1^^U`MGZjW zyZ!kWMkcB!-ze3>O+PtY|D(&E<12i%w8+Ebm!>}7Ke!jb)45!(6@b8MS|u467)Y!E zIu3sL{x;F`{1zjXZg03NjmBT6r;i*wRGCqj&*gH<l}g11!2dT@S63213xIY28vr~4 z;5uO-+t%OTpS&OQpf&Hj=y0W?`8RLMi`6RHdV8afUVcgOK~4MzMZ?7h!F%vn00000 LNkvXXu0mjf>vELe literal 1075 zcmaJ=&rj1(9512<`H{#)kqa+fOw_P--MZ=;1{vKZi<T^7ksUbDwGY-n`%3%91`#q1 zh#tHc{|C89NHoNRgNvFN<53T4gcyl2(SuQ=s3FW(VAF%MY5U&y<@5P`f4*yp{<AHO z?Tr*gwZ!`(NwOYxzJ`P3-|@99ljRtWrttt8!Fkz&R9HnB2;#at3X@P)rzW1jE{dwB zwNx6XrSpP<bdT&{JO$k(Y>MjYDVVY{1~JIMQOyX^pH}bFKvP5XU_kOprU<iI-?Rk> zru$RM^q3M<>7H)TRS<}P4zUah`nX{Wg%G`?E0Dc&%+O#5g2zJiZcu3{0Yqd$5b*fj zikD>p&wE%d!1HV;@OfDu<0UWeW;r3i3%=7}@1cn|OC1rCk=ULuVuk1|#-_k9`F!4! z_j`~v%CNy;(9!Vu+yvparwl9?+=lI{C`6#GSel77WB^A|&Y&C)(InE{6m+vHYuI~b zA_Zd#vdOR>uai;*C`tc^>UtGz<0SkO?>~j@)RYOCB(zb^Qb^-QT#hSK5G^QUWTg-q zuT(LSMHtyxWCC%32PXzKLq&P}<PKhvgt%d2*-&6S5~7KMN7Gb6<ilZ(3j{b$<XAS! z5krhcqyB&x=#9p>GZk(GDLEY)xWZNcaQT{CXB2dkc#c3zn}ll2LOR$<S<q_7;;*T< z$5m^`!qwz5BpAkN>|c$p9Fgg9w$-sEMs@I^L8jdzV}1OY-y&DyRy-0;6<%ew%H^JV zzVupXjlM;>ZWo{HyvOCIS2I^-|6J?Z0Wkk`VB^ijLzBFB=EJsl<;(3=cId&}xjPGs zpsi_Q`Qf|pQtxK_1*XV#|N6FYsjW08nU6nin%`GDdOo)o{msL(3qL#dFVEMxR<e(d zG`-+9xZ+J*qI}fR?%D0F^3wWx`NwlFn`nr&lv=N^&CH}XR_-n~xK7pWYo>;76pH}7 QeD7T2c(gyV)H{6nH~m6mg#Z8m diff --git a/apps/wr/public/images/map/layericon/RDL_TSCT_PS.png b/apps/wr/public/images/map/layericon/RDL_TSCT_PS.png index ffc22515996bacdfbece7d30e3d5afcfd20269d2..3776f6c0493ee2fb6717ff03adecb0f228bf8673 100644 GIT binary patch delta 901 zcmV;01A6?V4Vwp$BYy*8Nkl<Zc${TZYiL__96i7P&Fdy<+H7{U-DXp*Wn`VMs}ncJ zx~U+H>0Hs^2dQXj!PgXLQTF8~RVIGYfiSCxE$GAsKdi`F)Y+}`F$a5KX&|m$TbI_R zY5K_H-rU^W`}2d{gnB+6&iNhA4-R1!%uGZ8KrA}}wZQcN%6|b}1DxYTRQyjze9K2` zNmbR`zWgrHaW%GhpQ>3t*-7fX0eAe#eO0IG>t;?8ZO<!;A|jE91pqc?rf@h+%q*#z z{%MCY`oj53voMSTOw)uA!tHRln$G^7ZE8E{KbT7nKkKb}WbRfdF|)8qWDWdq{ln^- znm4YD-YgwGK7T@fpDX|gLX^M^YdK?Bf!b>Ov5t+yoOti>*laKx4u@F~kySGFrqgHt zdTsABUzpn(e4^*w7AccSli)e1szI7&NEKzKZDM?)^zHYl{Z(6DdTzA>2>|$UWb)~& zV@b&djSsbdE&LVb82Y>c=TG!f?>i?^;hu+@*Wq;;bbsmE6pxNut<86%JQRxldth>A zdHd{K3T3iEODlxI)30FX4j(o({ffsAx8lfC1IXkUlF(@>y+D7b3R`yW+ID9&8e%~J zjH2!~^c>8R3d^#%#y<(*9P*|IzysJ+xd_uxiA@cLk%ws&?OM?#0}z4%cw9W~b%Qlc zh1;H{zJH+y5x;l}9<v>@u{ZH?bO-Dr3ti8{?PT`YjrpH1#*EuP*cx#Cw6%U6WmYom zwC6FIkomx?yU^Np1CPGgjFD^A@Hn!_X0lwn(MNty{_@1le5R+T2ZEXD+=bquLyy&s zuJ^lbD@)6U$C;<pk{tsh_al*%;dAAn=CdWRDSth&|E|Rg!_hNdueZ?I*=Y&@=<50; zZ7arKKhpkiqVkS1dn%b?U0bl6V%9YD1#3Pz&kl!Vd-?f2s+PWd;+yE;AB~NTIU=$M z0Q&p;rBEp3Jg&U8x3X^cvEg5??~YF-rA)Q}*=5H)bsMnnq541Prhn^u|AUVPgTdf* zEPfVSyuAegP!z=$i9}?t1DlV&-L<D;U2U_F9P5ilp^!>W#lPzN?8;0sdm|VOCS$SK zG5`x}p(u&~AOr9N*bJZ^Km&j}02^9bT3l;Aw3b+1rwB)*HjIslsi`Rh0)bL@cXx@I b|EK*2JXN2b<c_UL00000NkvXXu0mjfL6OAJ literal 1700 zcmaJ?c~BE~7!4kP+-gKctlNlFwUP@GASK~Qf}|xDLd58lYK{#FklmPF$N^e~ieg(~ zP;3<usnDt@BPuP3f?BR3YFkB(1}$=VK}IM?P_P>W+CNHncK3J8d++<c-}iPlGjiQp zX9o`l91iEq3+D*1(arkU+hXr!{cpwCuo&fv&}dkWYQ-857b1ftAiz_J<3Ir@mg%?t z3I^hEGYLwe2o>=o7*be86k9Pwol1?dak#)BomwnS08u~!#wj5t!CX~C0F*K&VFQg% z=BwGDLK$w*fYF9^La8A^8XzMCv4B7w0~1hzs2I?x5+Q`4V-m)78Q9#qO(Fo}5Hx{F zc$buj9|^Ew4G7SPKHgF?g#ys&M2atsPN%E^sALM2M8<BqH^rAhqcf;}z{EwsqG@Du zhJX_`5er)}2?`WdGe{(@R!h|S5MfOmi4qVHVAY^fy)lG0qK8ni&Kp9OPbzRgM5<A$ zQ6&rkRz<M{PC}UkEYo)-sMJ%k5HfL0*nyFBVl|0EBwI_G1oHX+4^^qA&<H93|H=11 zg%P1%4Uz;P0w-ytSmWf&t)bKmwgwcVuto^OiIb-osen-!QNU_|9Zd&TZcsupSc|M0 z$Mg9N9)zG`NDA^eOai7rR4QeR05**p%B6?-`m#eP6t1s-s2`0>_6zk3poCKWLTQs+ z4lGSlfe<>$l}&N|$kTGIR#2(2$Q)3kOa^6P8dwF4m&{O3p9^PNy$P;t+Fa<|X}KgU z8IrZJ|7!H)7Umx7bjr5aV#@d+gt=XV*_sLU$g!_w5swoh)IA6k#40}H;>T{9-nPDk z^6DR$io9uMF|)VLSzRp(NnBP0h`4K5_Pf4Ugq%pTXYFw)v!8uZqzHa|>VEJxvg_3k z(!a@kRhYK^PUP*JqRj7F^KbNCPBDAlGQ}?S_d(=0hw{zMi<=fo@XMQ5@4480GKa-) z!5{Iz5`(*I^ILMAc4vf*?d>gwjc$BLBt_x5qj1%tr2Dp8Z`%pFzi{hz4|jL6Dah6f zU#=(vo4VJoxw@jFYa``~c!^i=^PN?v3XJm_n}*@k_Xm$$ADnl>h|7s+`lPnUE~mAr zzO42M`Im5|sj6h)<Fm~X=Q;B5sNT;vSDKIA<sI;v6CpRmS7Z}CO-C!L#`0bO`)khw z?lbas4WE9{BC0fus(boevug5-AEq29?^rg{c+M$5c}Yph3(@9LDKe5?-oIV(++wf@ z3U_2|y1X|H(igJ?^A<eccR0PZ%8n9Q0`Q|Rc=Y|LoH<fZN_c$0tz&T=cm7ChBs249 zQ!wGfTZor(#?S2wX8q)u664gHR~K#}!rWsT2VLUDLomLwVswcAMlapip>_P4V%wAK z(6BYJ@`tl$+)VagHk{*?_zxW4Z7y)kZQ{XpiVJv;!?JSQr!Ivp$zUHFvYqP~QZvf~ zZ;9^EuN`VVACaXZ8m^axX{*w68ok<&8Oisd&Xoa1wbAv_>?H>qf+RunJHL8WwD)Oq zuF;+KI;?$XiqEC~cxQcV+nKDqit>1M*RV_Aa3fA$dO_Xx!lhoa(423YQ*)Xn>`QV{ znIxA6tLr-tIhFa$y0cr|J44(j$w;Wt?HLl5Sw3pZMVuqPxOeSplxsB_|E#;iZMb2y zAHEdn{b(>VGu!fdW@`WS%YmY(I%9LkdtC+fmK)t#{Mi2abALpnZ|-e)t$Ul_8+edd zpOC)3E;r{%-KWy7Itt4oEVkeNsu9=ULaC<Hu61Tt;N3{6R6*?#MojJLwx{ghGZO!L z78if`+xmf*M)A^-qW0K*V*~wB`L|k&vzVLypmz<lufO5gKJqXtquiWRdO*>>*~S)^ X+MJ>?k7n6e{~J8+I!<ZmmbAYC)BCkP diff --git a/packages/common/business_components/src/ui/map/Gis.js b/packages/common/business_components/src/ui/map/Gis.js index eefb08da6..079506aca 100644 --- a/packages/common/business_components/src/ui/map/Gis.js +++ b/packages/common/business_components/src/ui/map/Gis.js @@ -1,321 +1,356 @@ -import { Search } from 'lucide-react'; -import OlMap from 'ol/Map'; -import View from 'ol/View'; -import { defaults as defaultControls, OverviewMap } from 'ol/control'; -import { defaults } from 'ol/interaction'; -import * as olProj from 'ol/proj'; -import { register } from 'ol/proj/proj4'; -import proj4 from 'proj4'; -import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; -import GisMapToggle from './GisMapToggle'; -import GisSelect from './GisSelect'; -import GisToolBar from './GisToolBar'; -import GisTree from './GisTree'; -import './lib/css/gis.common.css'; -import GisApp from './lib/gis.core'; +import { Search } from "lucide-react"; +import OlMap from "ol/Map"; +import View from "ol/View"; +import { defaults as defaultControls, OverviewMap } from "ol/control"; +import { defaults } from "ol/interaction"; +import * as olProj from "ol/proj"; +import { register } from "ol/proj/proj4"; +import proj4 from "proj4"; +import React, { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useRef, + useState, +} from "react"; +import GisMapToggle from "./GisMapToggle"; +import GisSelect from "./GisSelect"; +import GisToolBar from "./GisToolBar"; +import GisTree from "./GisTree"; +import "./lib/css/gis.common.css"; +import GisApp from "./lib/gis.core"; -export const GisContext = createContext({ gisCore: null, gisMap: null, treeData: null, checkedLayerIds: null }); +export const GisContext = createContext({ + gisCore: null, + gisMap: null, + treeData: null, + checkedLayerIds: null, +}); export const useGisContext = () => useContext(GisContext); export const searchUpperPpls = async (fcltMngNo) => { - const BASE_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || ''; + const BASE_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || ""; + const res = await fetch(`${BASE_URL}/v1/fcltmhl/upperPpls/${fcltMngNo}`, { + method: "GET", + }); - const res = await fetch(`${BASE_URL}/v1/fcltmhl/upperPpls/${fcltMngNo}`, { - method: "GET", - }); + let data = null; + if (res.ok) { + try { + // 응답이 비어있는지 확인 + const contentLength = res.headers.get("content-length"); + if (contentLength === "0") + alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); - let data = null; - if (res.ok) { - try { - // 응답이 비어있는지 확인 - const contentLength = res.headers.get('content-length'); - if (contentLength === '0') alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); + // 응답 텍스트를 먼저 가져와서 빈 문자열인지 확인 + const text = await res.text(); + if (!text || text.trim() === "") + alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); - // 응답 텍스트를 먼저 가져와서 빈 문자열인지 확인 - const text = await res.text(); - if (!text || text.trim() === '') alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); + // JSON 파싱 시도 + data = JSON.parse(text); + } catch (error) { + console.error("JSON parsing error:", error); + alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); + } + } - // JSON 파싱 시도 - data = JSON.parse(text); - } catch (error) { - console.error('JSON parsing error:', error); - alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); - } - } + const select = GisApp.Module.select; + const gisMap = GisApp.Module.core?.map; + let foundFeature = null; - const select = GisApp.Module.select; + data.forEach((item) => { + const pplMngNo = item.ppl_mng_no.trim(); - const gisMap = GisApp.Module.core?.map; + gisMap + .getLayers() + .getArray() + .filter((e) => e.get("lyrTyNm") == "tb_ms_swage_ppl") + .forEach((layer) => { + const source = layer.getSource?.(); + if (source?.getFeatures) { + const features = source.getFeatures(); + for (const f of features) { + if (f.values_.fclt_mng_no.trim() === pplMngNo) { + foundFeature = f; + break; + } + } + } + }); - let foundFeature = null; + if (foundFeature) select.selectMultiFeature(foundFeature, true); + }); - data.forEach(item => { - const pplMngNo = item.ppl_mng_no.trim(); + if (!foundFeature) alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); - gisMap.getLayers().getArray().filter(e => e.get("lyrTyNm") == 'tb_ms_swage_ppl').forEach(layer => { - const source = layer.getSource?.(); - if (source?.getFeatures) { - const features = source.getFeatures(); - for (const f of features) { - if (f.values_.fclt_mng_no.trim() === pplMngNo) { - foundFeature = f; - break; - } - } - } - }); + let geometry = foundFeature?.getGeometry(); + if (geometry) { + let extent = geometry.getExtent(); - if (foundFeature) select.selectMultiFeature(foundFeature, true); - }); - - if (!foundFeature) alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); - - let geometry = foundFeature?.getGeometry(); - if (geometry) { - let extent = geometry.getExtent(); - - gisMap.getView().fit(extent, { - duration: 300, - padding: [50, 50, 50, 50], - maxZoom: 14, - constrainResolution: true, - nearest: true, - }); - } + gisMap.getView().fit(extent, { + duration: 300, + padding: [50, 50, 50, 50], + maxZoom: 14, + constrainResolution: true, + nearest: true, + }); + } }; function Gis({ - isOpen, //우측 상세 레이어 팝업 - gisMaps, - isSearchModalOpen, - treeData = [], - isSearch = false, - isMiniMap = false, - setIsOpen, - setFeatureData, - featureData, - imgVisble = false, - searchView: SearchView, - detailView: DetailView, - onFeatureSelect, - setIsSearchModalOpen, - onCheckedLayersChange, - searchBar: SearchBar + isOpen, //우측 상세 레이어 팝업 + gisMaps, + isSearchModalOpen, + treeData = [], + isSearch = false, + isMiniMap = false, + setIsOpen, + setFeatureData, + featureData, + imgVisble = false, + searchView: SearchView, + detailView: DetailView, + onFeatureSelect, + setIsSearchModalOpen, + onCheckedLayersChange, + searchBar: SearchBar, + height:height="h-[calc(100vh-10rem)]", }) { - const mapRef = useRef(); - const [mapObject, setMapObject] = useState({}); - const [tabVisible, setTabVisible] = useState(true); - const [layerNm, setLayerNm] = useState('') - // const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태 - // const [featureData, setFeatureData] = useState(null) // 선택된 피쳐 데이터 - // const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); // SearchModal 열림 상태 - const gisCore = useMemo(() => new GisApp.core({ targetId: mapRef.current }), []); - const mapInstanceRef = useRef(null); - const checkedLayerIds = useRef([]); - const layerNmRef = useRef('') + const mapRef = useRef(); + const [mapObject, setMapObject] = useState({}); + const [tabVisible, setTabVisible] = useState(true); + const [layerNm, setLayerNm] = useState(""); + // const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태 + // const [featureData, setFeatureData] = useState(null) // 선택된 피쳐 데이터 + // const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); // SearchModal 열림 상태 + const gisCore = useMemo( + () => new GisApp.core({ targetId: mapRef.current }), + [], + ); + const mapInstanceRef = useRef(null); + const checkedLayerIds = useRef([]); + const layerNmRef = useRef(""); - // 팝업 데이터를 저장할 상태와 오버레이 참조를 저장할 ref 추가 - // const [facilityInfoPopupData, setFacilityInfoPopupData] = useState([]); - // const facilityOverlaysRef = useRef([]); - // 체크된 레이어 상태 관리 - const [checkedLayers, setCheckedLayers] = useState([]); - const [checkedLayersData, setCheckedLayersData] = useState([]); + // 팝업 데이터를 저장할 상태와 오버레이 참조를 저장할 ref 추가 + // const [facilityInfoPopupData, setFacilityInfoPopupData] = useState([]); + // const facilityOverlaysRef = useRef([]); + // 체크된 레이어 상태 관리 + const [checkedLayers, setCheckedLayers] = useState([]); + const [checkedLayersData, setCheckedLayersData] = useState([]); - let gisMap = null; - const closePopup = () => { - setIsOpen(false); // 팝업 닫기 - setFeatureData(null) - }; + let gisMap = null; + const closePopup = () => { + setIsOpen(false); // 팝업 닫기 + setFeatureData(null); + }; - // Feature Click Event - const handleFeatureSelect = useCallback((data) => { - onFeatureSelect?.(data); // 선택된 피쳐 데이터 콜백 호출 - }, [mapInstanceRef]); + // Feature Click Event + const handleFeatureSelect = useCallback( + (data) => { + onFeatureSelect?.(data); // 선택된 피쳐 데이터 콜백 호출 + }, + [mapInstanceRef], + ); - // 지도 생성 및 초기화 - useEffect(() => { - if (!mapRef.current) return; - if (mapInstanceRef.current) return; // 이미 생성된 맵이 있다면 중단 + // 지도 생성 및 초기화 + useEffect(() => { + if (!mapRef.current) return; + if (mapInstanceRef.current) return; // 이미 생성된 맵이 있다면 중단 - // EPSG:5179 등록 - proj4.defs([ - [ - 'EPSG:5179', - '+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs', - ], - ]); - register(proj4); + // EPSG:5179 등록 + proj4.defs([ + [ + "EPSG:5179", + "+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs", + ], + ]); + register(proj4); - // OpenLayers 지도 객체 생성 - const map = new OlMap({ - layers: [gisCore.baseLayers['base'], gisCore.baseLayers['satellite']], - renderer: 'webgl', - target: mapRef.current, - interactions: defaults({ doubleClickZoom: false }), - controls: defaultControls({ - zoom: false, - rotate: false, - attributionOptions: { - collapsible: false, - }, - }).extend([]), - view: new View({ - projection: GisApp.TO_PROJ, - zoom: gisCore.defaults.zoom, - center: olProj.transform( - [127.4875, 37.4916], - GisApp.FROM_PROJ, - GisApp.TO_PROJ - ), - minZoom: gisCore.defaults.minZoom, - maxZoom: gisCore.defaults.maxZoom, - }), - }); + // OpenLayers 지도 객체 생성 + const map = new OlMap({ + layers: [gisCore.baseLayers["base"], gisCore.baseLayers["satellite"]], + renderer: "webgl", + target: mapRef.current, + interactions: defaults({ doubleClickZoom: false }), + controls: defaultControls({ + zoom: false, + rotate: false, + attributionOptions: { + collapsible: false, + }, + }).extend([]), + view: new View({ + projection: GisApp.TO_PROJ, + zoom: gisCore.defaults.zoom, + center: olProj.transform( + [127.4875, 37.4916], + GisApp.FROM_PROJ, + GisApp.TO_PROJ, + ), + minZoom: gisCore.defaults.minZoom, + maxZoom: gisCore.defaults.maxZoom, + }), + }); - gisMaps.current = map + gisMaps.current = map; - // 미니맵 추가 - if (isMiniMap) { - const overviewMap = new OverviewMap({ - layers: [GisApp.Module.core.baseMiniMapLayers['base']], - view: new View({ - projection: GisApp.TO_PROJ, - minZoom: 9, - }), - collapsed: false, - collapseLabel: '\u00BB', - label: '\u00AB', - }); - map.addControl(overviewMap); - } + // 미니맵 추가 + if (isMiniMap) { + const overviewMap = new OverviewMap({ + layers: [GisApp.Module.core.baseMiniMapLayers["base"]], + view: new View({ + projection: GisApp.TO_PROJ, + minZoom: 9, + }), + collapsed: false, + collapseLabel: "\u00BB", + label: "\u00AB", + }); + map.addControl(overviewMap); + } - // 스케일 컨트롤 및 베이스 레이어 설정 - gisCore.__proto__.map = map; - gisCore.scaleControl(); - gisCore.changeBaseLayer('base'); - setMapObject({ map: map }); - mapInstanceRef.current = map; // 생성 완료 플래그 설정 + // 스케일 컨트롤 및 베이스 레이어 설정 + gisCore.__proto__.map = map; + gisCore.scaleControl(); + gisCore.changeBaseLayer("base"); + setMapObject({ map: map }); + mapInstanceRef.current = map; // 생성 완료 플래그 설정 + }, []); - }, []); + // treeData 변경 시 레이어 코드 생성 + useEffect(() => { + if (!treeData || treeData.length === 0) return; - // treeData 변경 시 레이어 코드 생성 - useEffect(() => { - if (!treeData || treeData.length === 0) return; + // 기존 오버레이 및 레이어 모두 삭제 + gisCore.deleteAllOverlay(); + gisCore.deleteAllLayer(); - // 기존 오버레이 및 레이어 모두 삭제 - gisCore.deleteAllOverlay(); - gisCore.deleteAllLayer(); + // 트리 데이터를 레이어 코드 객체로 변환 + const layerCode = gisCore.convertLayerInfosToLayerCode(treeData, "lyrSn"); + GisApp.layerCode = layerCode; // 전역 레이어 코드 설정 - // 트리 데이터를 레이어 코드 객체로 변환 - const layerCode = gisCore.convertLayerInfosToLayerCode(treeData, 'lyrSn'); - GisApp.layerCode = layerCode; // 전역 레이어 코드 설정 + //setTreeData(data); + // 편집 가능한 레이어 목록 생성 + //const layerItems = getLayerItems(layerCode); + //setEditLayerItems(prev => [...layerItems]) + }, [treeData]); - //setTreeData(data); - // 편집 가능한 레이어 목록 생성 - //const layerItems = getLayerItems(layerCode); - //setEditLayerItems(prev => [...layerItems]) - }, [treeData]); + const getLayerItems = (layerCode) => { + const layerItems = Object.entries(layerCode) + .filter(([key, obj], idx) => obj?.updtPsblYn === "Y") + .map(([key, obj]) => ({ + ...obj, + name: obj.lyrNm, + label: obj.lyrNm, + value: obj.lyrSn + "", + })) + .sort((a, b) => { + if (a.sortOrdr > b.sortOrdr) return 1; + if (a.sortOrdr < b.sortOrdr) return -1; + return 0; + }); + return layerItems; + }; - const getLayerItems = (layerCode) => { - const layerItems = Object.entries(layerCode) - .filter(([key, obj], idx) => obj?.updtPsblYn === 'Y') - .map(([key, obj]) => ({ - ...obj, - name: obj.lyrNm, - label: obj.lyrNm, - value: obj.lyrSn + '', - })) - .sort((a, b) => { - if (a.sortOrdr > b.sortOrdr) return 1; - if (a.sortOrdr < b.sortOrdr) return -1; - return 0; - }); - return layerItems; - }; + if (mapObject.map) { + try { + gisMap = mapObject.map; + } catch (e) { + console.error("오류 발생:", e); // 시큐어코딩 관련 수정 : 오류 정보를 로그로 출력 + } + } - if (mapObject.map) { - try { - gisMap = mapObject.map; - } catch (e) { - console.error('오류 발생:', e); // 시큐어코딩 관련 수정 : 오류 정보를 로그로 출력 - } - } + // 체크된 레이어 정보를 처리하는 함수 + const handleCheckedLayersChange = useCallback( + (checkedIds, checkedNodesData) => { + setTimeout(() => { + setCheckedLayers(checkedIds); + setCheckedLayersData(checkedNodesData); + onCheckedLayersChange?.(checkedIds, checkedNodesData); + }, 1000); + }, + [onCheckedLayersChange], + ); - // 체크된 레이어 정보를 처리하는 함수 - const handleCheckedLayersChange = useCallback((checkedIds, checkedNodesData) => { - setTimeout(() => { - setCheckedLayers(checkedIds); - setCheckedLayersData(checkedNodesData); - onCheckedLayersChange?.(checkedIds, checkedNodesData); - }, 1000); - }, [onCheckedLayersChange]); + return ( + <> + <GisContext.Provider + value={{ + gisCore, + gisMap: mapInstanceRef.current, + treeData, + checkedLayerIds, + }} + > + <div className={`relative flex ${height}`}> + <div + ref={mapRef} + className="gis-map relative flex-1" + style={{ height: "100%", padding: 0 }} + > + <GisTree + visible={tabVisible} + setVisible={setTabVisible} + onCheckedChange={handleCheckedLayersChange} + onLayerIconClick={(layerNm) => { + layerNmRef.current = layerNm; + setLayerNm(layerNm); + setIsOpen(true); + const dummyFeature = { + getProperties: () => ({}), // 최소 구조 + }; + onFeatureSelect(dummyFeature); + }} + imageVisible={imgVisble} + /> - return ( - <> - <GisContext.Provider value={{ gisCore, gisMap: mapInstanceRef.current, treeData, checkedLayerIds }}> - <div className="h-[calc(100vh-10rem)] flex relative"> - <div ref={mapRef} className="gis-map flex-1 relative" style={{ height: '100%', padding: 0 }} > - <GisTree - visible={tabVisible} - setVisible={setTabVisible} - onCheckedChange={handleCheckedLayersChange} - onLayerIconClick={(layerNm) => { - layerNmRef.current = layerNm - setLayerNm(layerNm); setIsOpen(true); const dummyFeature = { - getProperties: () => ({}), // 최소 구조 - }; - onFeatureSelect(dummyFeature); - }} - imageVisible={imgVisble} - /> + {/* DetailView가 존재할 때만 렌더링 isSearchModalOpen이 true면 visible=false로 팝업 숨김 */} + {isOpen && !isSearchModalOpen && ( + <DetailView + featureData={featureData || { getProperties: () => ({}) }} + seletectedLayerNm={layerNm} + onClose={closePopup} // 닫기 콜백 전달 + onFeatureSelect={handleFeatureSelect} + /> + )} + {/* SearchView가 존재할 때만 렌더링 */} + {SearchView && ( + <SearchView + open={isSearchModalOpen} + onOpenChange={setIsSearchModalOpen} + onFeatureSelect={handleFeatureSelect} + /> + )} + {/* 시도/시군구 조회 영역 */} + {SearchBar && ( + <div + className="absolute left-1/2 top-4 z-30 -translate-x-1/2 rounded" + style={{ maxWidth: "calc(100% - 2rem)" }} + > + <SearchBar /> + </div> + )} + <GisToolBar /> + <GisMapToggle /> + <GisSelect onFeatureSelect={handleFeatureSelect} /> + </div> + </div> - {/* DetailView가 존재할 때만 렌더링 isSearchModalOpen이 true면 visible=false로 팝업 숨김 */} - {isOpen && !isSearchModalOpen && ( - <DetailView - featureData={featureData || { getProperties: () => ({}) }} - seletectedLayerNm={layerNm} - onClose={closePopup} // 닫기 콜백 전달 - onFeatureSelect={handleFeatureSelect} - /> - )} - {/* SearchView가 존재할 때만 렌더링 */} - {SearchView && ( - <SearchView - open={isSearchModalOpen} - onOpenChange={setIsSearchModalOpen} - onFeatureSelect={handleFeatureSelect} - /> - )} - {/* 시도/시군구 조회 영역 */} - {SearchBar && ( - <div className="absolute top-4 left-1/2 -translate-x-1/2 z-30 bg-gray-300 rounded " style={{ maxWidth: 'calc(100% - 2rem)' }}> - <SearchBar/> - </div> - )} - <GisToolBar /> - <GisMapToggle /> - <GisSelect onFeatureSelect={handleFeatureSelect} /> - </div> - </div> - - {isSearch && ( - <div className="absolute right-8 top-[305px] z-20"> - <button - onClick={() => setIsSearchModalOpen(true)} - className="overflow-hidden w-[40px] h-[40px] bg-white - border border-[#9aa7b8] - rounded - shadow-[0_0_5px_#999] - flex items-center justify-center - p-0 - " - > - <Search size={24} className="text-gray-700" /> - </button> - </div> - )} - </GisContext.Provider> - </> - ); + {isSearch && ( + <div className="absolute right-8 top-[305px] z-20"> + <button + onClick={() => setIsSearchModalOpen(true)} + className="flex h-[40px] w-[40px] items-center justify-center overflow-hidden rounded border border-[#9aa7b8] bg-white p-0 shadow-[0_0_5px_#999]" + > + <Search size={24} className="text-gray-700" /> + </button> + </div> + )} + </GisContext.Provider> + </> + ); } export default React.memo(Gis); diff --git a/packages/common/business_components/src/ui/map/GisTree.js b/packages/common/business_components/src/ui/map/GisTree.js index 335b1b119..47e86d4dc 100644 --- a/packages/common/business_components/src/ui/map/GisTree.js +++ b/packages/common/business_components/src/ui/map/GisTree.js @@ -196,7 +196,7 @@ export default React.memo(function GisTree({ checkedNodes = [], setCheckedNodes return ( <> <div - className={`absolute top-0 left-0 w-[250px] h-[calc(100vh-10rem)] bg-white border-r border-gray-300 flex flex-col overflow-hidden transition-all duration-300 z-40 + className={`absolute top-0 left-0 w-[250px] h-full bg-white border-r border-gray-300 flex flex-col overflow-hidden transition-all duration-300 z-40 ${visible ? 'translate-x-0 opacity-100' : '-translate-x-full opacity-0 pointer-events-none'}`} > <div From 5e9a9c82ff82b00a25afd8900c2c40088b28d9b1 Mon Sep 17 00:00:00 2001 From: RSONE001 <rsone001@gmail.com> Date: Fri, 1 Aug 2025 17:54:30 +0900 Subject: [PATCH 7/9] =?UTF-8?q?=EC=97=B0=EA=B3=84=20=EC=86=8C=EC=8A=A4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cs/src/pages/link/ui/link-form.tsx | 4 ++-- apps/cs/src/pages/linkParams/ui/link-params-page.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/cs/src/pages/link/ui/link-form.tsx b/apps/cs/src/pages/link/ui/link-form.tsx index 05a3da0f1..172215662 100644 --- a/apps/cs/src/pages/link/ui/link-form.tsx +++ b/apps/cs/src/pages/link/ui/link-form.tsx @@ -52,9 +52,9 @@ const LinkForm = ({ form, linkSn, updateLinkInfo, handleInsertLink, deleteLink, if (await confirm(confirmMsg)) { if (linkSn) { updateLinkInfo?.(data); - } else { + } else { handleInsertLink?.(data); - } + } } }); }; diff --git a/apps/cs/src/pages/linkParams/ui/link-params-page.tsx b/apps/cs/src/pages/linkParams/ui/link-params-page.tsx index d46a9d863..4c811ce13 100644 --- a/apps/cs/src/pages/linkParams/ui/link-params-page.tsx +++ b/apps/cs/src/pages/linkParams/ui/link-params-page.tsx @@ -66,7 +66,7 @@ function LinkParamsPage() { const userUniqId = getCookie(AUTH_USER_ID) ?? ""; const { setMessage: alert } = useAlertStore((state) => state); - const dbIdList = ['link0001', 'link0002']; + const dbIdList = ['link0001', 'link0002', 'link0007']; // Link 목록 쿼리 const query = useQuery({ From 71aacf4c7679e77fddff81adc8c42300d53d43e8 Mon Sep 17 00:00:00 2001 From: yschoi <yschoi> Date: Sun, 3 Aug 2025 14:27:49 +0900 Subject: [PATCH 8/9] =?UTF-8?q?=EB=AC=BC=EC=9E=AC=EC=9D=B4=EC=9A=A9=20?= =?UTF-8?q?=EC=A7=80=EB=8F=84=EB=B3=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/pages/map/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/fo/app/pages/map/page.tsx b/apps/fo/app/pages/map/page.tsx index 1a84449a8..edd7b70d2 100644 --- a/apps/fo/app/pages/map/page.tsx +++ b/apps/fo/app/pages/map/page.tsx @@ -131,8 +131,8 @@ const Map = () => { isSearch={false} gisMaps={gisMaps} isMiniMap={false} - searchView={null} - detailView={null} + searchView={undefined} + detailView={undefined} onFeatureSelect={onFeatureSelect} setIsOpen={setIsOpen} setFeatureData={setFeatureData} From d45ce537a39d5abbae9204e1e0fe8d7bc5a22e66 Mon Sep 17 00:00:00 2001 From: yschoi <yschoi> Date: Sun, 3 Aug 2025 14:29:11 +0900 Subject: [PATCH 9/9] =?UTF-8?q?=EB=AC=BC=EC=9E=AC=EC=9D=B4=EC=9A=A9=20?= =?UTF-8?q?=EC=A7=80=EB=8F=84=EB=B3=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/app/pages/map/searchBar/searchBar.tsx | 7 +- apps/wr/.env.local | 2 + apps/wr/app/map/mainMap/page.tsx | 47 +-- apps/wr/app/map/searchBar/searchBar.tsx | 299 ++++++++++++++++++ apps/wr/middleware.ts | 11 + .../business_components/src/ui/map/Gis.js | 3 +- .../src/ui/map/lib/gis.layer.js | 10 +- 7 files changed, 351 insertions(+), 28 deletions(-) create mode 100644 apps/wr/app/map/searchBar/searchBar.tsx diff --git a/apps/fo/app/pages/map/searchBar/searchBar.tsx b/apps/fo/app/pages/map/searchBar/searchBar.tsx index 9b0800399..e9084870a 100644 --- a/apps/fo/app/pages/map/searchBar/searchBar.tsx +++ b/apps/fo/app/pages/map/searchBar/searchBar.tsx @@ -2,6 +2,7 @@ import { SelectBox, type SelectDataType } from "@common/business_components/ui"; import { Button } from "@common/components/ui"; import { useCallback, useEffect, useState } from "react"; +import { GEOSERVER_URL } from "@/src/shared/config/env"; interface SearchBarProps { onFeatureSelect: (feature: any) => void; @@ -18,7 +19,7 @@ export function SearchBar({ onFeatureSelect, gisMaps }: SearchBarProps) { const [facilityValue, setFacilityValue] = useState("0"); const fetchSido = async () => { - const url = `http://rsone.iptime.org:10010/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 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); const json = await res.json(); @@ -30,7 +31,7 @@ export function SearchBar({ onFeatureSelect, gisMaps }: SearchBarProps) { }; const fetchSigun = async () => { - const url = `http://rsone.iptime.org:10010/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 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); const json = await res.json(); @@ -43,7 +44,7 @@ export function SearchBar({ onFeatureSelect, gisMaps }: SearchBarProps) { const fetchFacilitiesBySggNm = async (sggNm: string) => { const encodedSggNm = encodeURIComponent(sggNm); - const url = `http://rsone.iptime.org:10010/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_il_swage_prcs_fclt&outputFormat=application/json&cql_filter=sgg_nm='${encodedSggNm}'`; + const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_il_swage_prcs_fclt&outputFormat=application/json&cql_filter=sgg_nm='${encodedSggNm}'`; const res = await fetch(url); const json = await res.json(); diff --git a/apps/wr/.env.local b/apps/wr/.env.local index 2543a96ad..4d00d1cab 100644 --- a/apps/wr/.env.local +++ b/apps/wr/.env.local @@ -10,6 +10,8 @@ NEXT_PUBLIC_CLAIM_NAME = Authorization NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token +NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver +NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver diff --git a/apps/wr/app/map/mainMap/page.tsx b/apps/wr/app/map/mainMap/page.tsx index 8cfb27e2f..420dfdfb0 100644 --- a/apps/wr/app/map/mainMap/page.tsx +++ b/apps/wr/app/map/mainMap/page.tsx @@ -5,6 +5,7 @@ import { useEffect, useRef, useState, useCallback } from "react"; import { mapService } from "../service"; import NewWindowPopup from "../newWindowPopup"; import GisApp from "@common/business_components/ui/map/lib/gis.core"; +import { SearchBar } from "../searchBar/searchBar"; const Map = () => { const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정 @@ -61,24 +62,28 @@ const Map = () => { // 2. data가 OpenLayers Feature 인스턴스인지 확인 let foundFeature: any = null; - console.log(data) + console.log(data); //console.log(data.getId()) let featureId = data.fid; const layerName = data.layerNm; - + if (layerName === "재이용시설") { // 재이용시설 featureId = `${layerName}.${data.searchPk}`; - } else if ( //빗물이용시설, 중수도시설 + } else if ( + //빗물이용시설, 중수도시설 layerName === "빗물이용시설" || layerName == "tb_wr_rswtr_fclt" ) { featureId = `${layerName}.${data.bdstInfoSn}`; - } else if (layerName === "tb_il_swage_prcs_fclt") { //하수처리시설 + } else if (layerName === "tb_il_swage_prcs_fclt") { + //하수처리시설 featureId = `${layerName}.${data.bscFctCd}`; - } else if (layerName === "tb_wr_htdfl_fclt") { //온배수시설 + } else if (layerName === "tb_wr_htdfl_fclt") { + //온배수시설 featureId = `${layerName}.${data.bdstRuseFcltSn}`; - } else if (layerName == "tb_wr_ruse_fclt_dmd_co") { //수요처 + } else if (layerName == "tb_wr_ruse_fclt_dmd_co") { + //수요처 featureId = `${layerName}.${data.dmdInfoId.replaceAll("-", "")}`; } else { console.warn("해당 레이어에 대한 featureId 매핑 없음", layerName); @@ -120,17 +125,6 @@ const Map = () => { setIsSearchModalOpen(false); }; - // MapSearchBar 래퍼 컴포넌트 - // const CustomMapSearchBar = (props: any) => { - // return ( - // <MapSearchBar - // {...props} - // searchType="공급처 후보지 조회" - // showApplyButton={false} - // /> - // ); - // }; - return ( <div className="bg-container"> <Gis @@ -156,7 +150,24 @@ const Map = () => { isSearchModalOpen={isSearchModalOpen} onCheckedLayersChange={handleCheckedLayersChange} imgVisble={true} - searchBar={undefined} + searchBar={(props: any) => { + const facilityTypes = [ + { text: "하수처리시설", val: "tb_il_swage_prcs_fclt" }, + { text: "하수재이용시설", val: "tb_wr_bdst_ruse_fclt" }, + { text: "빗물이용시설", val: "tb_wr_rnwtr_utztn_fclt" }, + { text: "중수도시설", val: "tb_wr_rswtr_fclt" }, + { text: "온배수시설", val: "tb_wr_htdfl_fclt" }, + { text: "수요처", val: "tb_wr_ruse_fclt_dmd_co" }, + { text: "잠재수요처", val: "tb_wr_tmpr_dmd_co" }, + ]; + return ( + <SearchBar + onFeatureSelect={onFeatureSelect} + gisMaps={gisMaps} + facilityTypes={facilityTypes} + /> + ); + }} /> </div> ); diff --git a/apps/wr/app/map/searchBar/searchBar.tsx b/apps/wr/app/map/searchBar/searchBar.tsx new file mode 100644 index 000000000..7502daf94 --- /dev/null +++ b/apps/wr/app/map/searchBar/searchBar.tsx @@ -0,0 +1,299 @@ +"use client"; +import { SelectBox, type SelectDataType } from "@common/business_components/ui"; +import { Button } from "@common/components/ui"; +import { useCallback, useEffect, useState } from "react"; +import { SERVER_API_WR_URL } from "@/src/shared/config"; + +const geoserverUrl = + "/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&outputFormat=application/json"; + +const FACILITY_TYPE_URL_MAP: Record<string, string> = { + tb_il_swage_prcs_fclt: geoserverUrl, //하수처리시설 + tb_wr_bdst_ruse_fclt: + "/reuse-service/reuseFc/pubDetailList/{year}/{sggCd}/1/1000", //재이용시설 post + tb_wr_rnwtr_utztn_fclt: "/reuse-service/reuseFc/rainyInfoList/1/1000/{sggCd}", //빗물이용시설 get + tb_wr_rswtr_fclt: "/reuse-service/reuseFc/waterreuseFc/1/1000/{sggCd}", //중수도시설 get + tb_wr_htdfl_fclt: "/reuse-service/drain/facilityList/1/1000/{sggCd}", //온배수시설 get + tb_wr_ruse_fclt_dmd_co: "/reuse-service/reuseFc/request/1/1000/{sggCd}", //수요처 get + tb_wr_tmpr_dmd_co: + "/reuse-service/reuseFc/request/temp/1/1000/{sidoNm} {sggNm}", //잠재수요처 get +}; + +interface SearchBarProps { + onFeatureSelect: (feature: any) => void; + gisMaps: React.RefObject<any>; + facilityTypes: { text: string; val: string }[]; +} + +export function SearchBar({ + onFeatureSelect, + gisMaps, + facilityTypes, +}: SearchBarProps) { + const [sidoValue, setSidoValue] = useState("0"); + const [sigunValue, setSigunValue] = useState("0"); + const [sidoData, setSidoData] = useState<SelectDataType[]>([ + { text: "선택", val: "0" }, + ]); + const [sigunData, setSigunData] = useState<SelectDataType[]>([ + { text: "선택", val: "0" }, + ]); + const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([ + { text: "선택", val: "0" }, + ]); + + const [facilityData, setFacilityData] = useState<SelectDataType[]>([ + { text: "선택", val: "0" }, + ]); + const [facilityValue, setFacilityValue] = useState("0"); + + const [facilityType, setFacilityType] = useState( + facilityTypes?.length === 1 && facilityTypes[0] ? facilityTypes[0].val : "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 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 fetchFacilitiesBySggNm = async ( + sggCd: string, + sggNm: string, + sidoNm: string, + currentFacilityType?: string + ) => { + const type = currentFacilityType ?? facilityType; + if (!type || type === "0") return; + + const baseUrlTemplate = FACILITY_TYPE_URL_MAP[type]; + if (!baseUrlTemplate) return; + + const year = new Date().getFullYear().toString(); + let url = baseUrlTemplate + .replace("{year}", year) + .replace("{sggCd}", sggCd) + .replace("{sidoNm}", encodeURIComponent(sidoNm)) + .replace("{sggNm}", encodeURIComponent(sggNm)); + + let list: SelectDataType[] = []; + + if ( + type === "tb_il_swage_prcs_fclt" //하수처리시설 + ) { + const cqlFilter = `ctpv_nm='${encodeURIComponent(sidoNm)}' AND sgg_nm='${encodeURIComponent(sggNm)}'`; + url = `${url}&typeName=hasudo:${type}&cql_filter=${cqlFilter}`; + const res = await fetch(url); + const json = await res.json(); + list = json.features.map((f: any) => ({ + text: f.properties.swtrmt_fclt_nm ?? "(이름없음)", + val: f.id, + })); + } else if ( + type === "tb_wr_bdst_ruse_fclt" // 재이용시설 + ) { + //재용에서 참조하는 하수처리시설 목록 + const paramsRes = await fetch("/reuse-service/reuseFc/pubFc"); + const paramsJson = await paramsRes.json(); + const params = paramsJson.data; + + const res = await fetch(url, { + method: "POST", + headers: { + accept: "application/json", + "Content-Type": "application/json", + }, + body: JSON.stringify(params), + }); + const json = await res.json(); + list = (json.data || []).map((item: any) => ({ + text: item.ruseUtztnFcltNm ?? "(이름없음)", + val: item.pbnstRuseFcltId, + })); + } else if ( + type === "tb_wr_ruse_fclt_dmd_co" //수요처 + ) { + const res = await fetch(url); + const json = await res.json(); + list = (json.data || []).map((item: any) => ({ + text: item.dmdCoNm ?? "(이름없음)", + val: item.dmdInfoId, + })); + } else if ( + type === "tb_wr_tmpr_dmd_co" //잠재수요처 + ) { + // GET 방식 + const res = await fetch(url); + const json = await res.json(); + list = (json.data || []).map((item: any) => ({ + text: item.dmdCoNm ?? "(이름없음)", + val: item.fctryMngSn, + })); + } else { + // GET 방식 + const res = await fetch(url); + const json = await res.json(); + list = (json.data || []).map((item: any) => ({ + text: item.bdstNm ?? "(이름없음)", + val: item.bdstInfoSn, + })); + } + + setFacilityData([{ text: "선택", val: "0" }, ...list]); + setFacilityValue("0"); + }; + + //시도, 시군구 초기 데이터 조회 + useEffect(() => { + fetchSido(); + }, []); + + //시군구 데이터 초기화 + const initializeSigunData = useCallback( + (sidoCd: string) => { + if (sidoCd === "0") { + setFilteredSigunData([{ text: "선택", val: "0" }]); + setSigunValue("0"); + return; + } + const prefix = sidoCd.substring(0, 2); + const filtered = sigunData.filter((item) => item.val.startsWith(prefix)); + setFilteredSigunData([{ text: "선택", val: "0" }, ...filtered]); + setSigunValue("0"); + }, + [sigunData] + ); + + //콤보박스 선택시 연관 콤보박스 처리 + const onSelectValue = useCallback( + (val: string, type: string) => { + if (type === "ctpvCd") { + setSidoValue(val); + initializeSigunData(val); + setFacilityData([{ text: "선택", val: "0" }]); + setFacilityValue("0"); + } else if (type === "sggCd") { + setSigunValue(val); + const sidoNm = + sidoData.find((item) => item.val === sidoValue)?.text || ""; + const sggNm = sigunData.find((item) => item.val === val)?.text || ""; + const sggCd = sigunData.find((item) => item.val === val)?.val || ""; + if (sggNm && sidoNm) + fetchFacilitiesBySggNm(sggCd, sggNm, sidoNm, facilityType); + } else if (type === "facilityType") { + setFacilityType(val); + setFacilityValue("0"); + setFacilityData([{ text: "선택", val: "0" }]); + const sidoNm = + sidoData.find((item) => item.val === sidoValue)?.text || ""; + const sggNm = + sigunData.find((item) => item.val === sigunValue)?.text || ""; + const sggCd = + sigunData.find((item) => item.val === sigunValue)?.val || ""; + if (sggNm && sidoNm) fetchFacilitiesBySggNm(sggCd, sggNm, sidoNm, val); + } else if (type === "fcltCd") { + setFacilityValue(val); + } + }, + [initializeSigunData, sigunData, sigunValue, sidoData, sidoValue] + ); + + //조회 버튼 클릭 + const handleSearch = () => { + if (!gisMaps.current || facilityValue === "0") return; + const layers = gisMaps.current.getLayers().getArray(); + for (const layer of layers) { + const source = layer.getSource?.(); + const feature = source?.getFeatureById?.(facilityValue); + if (feature) { + onFeatureSelect(feature); + return; + } + } + alert("해당 처리시설을 지도에서 찾을 수 없습니다."); + }; + + return ( + <div className="grid grid-cols-4 gap-4"> + <div className="col-span-4"> + <div className="card card-border flex"> + <div className="col-span-10 flex flex-row"> + {facilityTypes.length > 1 && ( + <SelectBox + labelClass="w-[120px]" + className="mr-10 w-[190px]" + selectClass="rounded-lg bg-white" + label="시설물유형" + selectArray={[{ text: "선택", val: "0" }, ...facilityTypes]} + onSelectValue={(val) => + onSelectValue(val.toString(), "facilityType") + } + value={facilityType} + /> + )} + <SelectBox + labelClass="w-[40px]" + className="mr-10 w-[150px]" + selectClass="rounded-lg bg-white" + label="시도" + selectArray={sidoData} + onSelectValue={(val) => onSelectValue(val.toString(), "ctpvCd")} + value={sidoValue} + /> + <SelectBox + labelClass="w-[65px]" + className="mr-10 w-[150px]" + selectClass="rounded-lg bg-white" + label="시군구" + selectArray={filteredSigunData} + onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")} + value={sigunValue} + /> + <SelectBox + labelClass="w-[60px]" + className="mr-3 w-[180px]" + selectClass="rounded-lg bg-white" + label="시설명" + selectArray={facilityData} + onSelectValue={(val) => onSelectValue(val.toString(), "fcltCd")} + value={facilityValue} + /> + </div> + <div className="flex flex-row space-x-2"> + <Button + color="primary" + className="mx-2 mt-1 ml-5" + size={"sm"} + onClick={handleSearch} + > + 조회 + </Button> + </div> + </div> + </div> + </div> + ); +} diff --git a/apps/wr/middleware.ts b/apps/wr/middleware.ts index 61f41d634..1a90a5591 100644 --- a/apps/wr/middleware.ts +++ b/apps/wr/middleware.ts @@ -8,6 +8,7 @@ const serverApiUrl = CS_URL; const GEOSERVER_URL = process.env.NEXT_PUBLIC_GEOSERVER_URL || ""; const LX_GEOSERVER_URL = process.env.NEXT_PUBLIC_LX_GEOSERVER_URL || ""; const SEWERAGE_API_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || ""; +const REUSE_API_URL = process.env.NEXT_PUBLIC_WR_SERVER_API_URL || ""; export function middleware(req: NextRequest) { const pathname = req.nextUrl.pathname; @@ -135,6 +136,15 @@ export function middleware(req: NextRequest) { return NextResponse.rewrite(new URL(newUrl)); } + if (pathname.startsWith("/reuse-service")) { + const queryParams = searchParams.toString(); + const newUrl = `${REUSE_API_URL}${pathname.replace("/reuse-service", "")}${ + queryParams ? `?${queryParams}` : "" + }`; + console.log(`[Middleware] Rewriting from '/reuse-service' path to: ${newUrl}`); + return NextResponse.rewrite(new URL(newUrl)); + } + return NextResponse.next(); } @@ -146,6 +156,7 @@ export const config = { "/attach-service/:path*", "/geoserver/:path*", "/sewerage-service/:path*", + "/reuse-service/:path*", "/" ], }; diff --git a/packages/common/business_components/src/ui/map/Gis.js b/packages/common/business_components/src/ui/map/Gis.js index 079506aca..013288df4 100644 --- a/packages/common/business_components/src/ui/map/Gis.js +++ b/packages/common/business_components/src/ui/map/Gis.js @@ -326,8 +326,7 @@ function Gis({ {/* 시도/시군구 조회 영역 */} {SearchBar && ( <div - className="absolute left-1/2 top-4 z-30 -translate-x-1/2 rounded" - style={{ maxWidth: "calc(100% - 2rem)" }} + className="absolute left-1/2 top-4 z-30 -translate-x-1/2 rounded w-max" > <SearchBar /> </div> diff --git a/packages/common/business_components/src/ui/map/lib/gis.layer.js b/packages/common/business_components/src/ui/map/lib/gis.layer.js index 412b0d8b9..f7bb7b3ac 100644 --- a/packages/common/business_components/src/ui/map/lib/gis.layer.js +++ b/packages/common/business_components/src/ui/map/lib/gis.layer.js @@ -143,11 +143,11 @@ GisOlLayer.prototype = { let source; let lyrTyNm = option.lyrTyNm; - if(lyrTyNm == 'tb_ms_flood_dngr_map' - || lyrTyNm == 'tb_ms_sbmrg_dngr_map' - || lyrTyNm == 'tb_ms_swage_mhl' - || lyrTyNm == 'tb_ms_swage_ppl' - || lyrTyNm == 'tb_ms_swage_pmstn' + if(lyrTyNm == 'tb_ms_flood_dngr_map' //침수위험지도 + || lyrTyNm == 'tb_ms_sbmrg_dngr_map' //도시침수지도 + || lyrTyNm == 'tb_ms_swage_mhl' //맨홀 + || lyrTyNm == 'tb_ms_swage_ppl' //관로 + || lyrTyNm == 'tb_ms_swage_pmstn' //펌프장 ) { source = this.getVectorSourceBbox(option); }else {