diff --git a/apps/dm/.env.local b/apps/dm/.env.local
index 106493928..a561c3904 100644
--- a/apps/dm/.env.local
+++ b/apps/dm/.env.local
@@ -8,6 +8,8 @@ NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11035
NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1
NEXT_PUBLIC_FO_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1
NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000
+NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
+NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver
NEXT_PUBLIC_CS_TUS_UPLOAD = /attach-service/api/v1/tus/upload
NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성
diff --git a/apps/dm/app/(base-layout)/layout.tsx b/apps/dm/app/(base-layout)/layout.tsx
new file mode 100644
index 000000000..56260331f
--- /dev/null
+++ b/apps/dm/app/(base-layout)/layout.tsx
@@ -0,0 +1,20 @@
+"use client"
+import Base from "../base";
+import "../globals.css";
+import { StoreProvider } from "../store";
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ return (
+
+
+
+ {children}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/apps/dm/app/pages/sdmMng/sdmApplyList/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmApplyList/page.tsx
similarity index 100%
rename from apps/dm/app/pages/sdmMng/sdmApplyList/page.tsx
rename to apps/dm/app/(base-layout)/pages/sdmMng/sdmApplyList/page.tsx
diff --git a/apps/dm/app/pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx
similarity index 100%
rename from apps/dm/app/pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx
rename to apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page.tsx
diff --git a/apps/dm/app/pages/sdmMng/sdmInfoInsert/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page.tsx
similarity index 100%
rename from apps/dm/app/pages/sdmMng/sdmInfoInsert/page.tsx
rename to apps/dm/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page.tsx
diff --git a/apps/dm/app/pages/sdmMng/sdmInsert/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInsert/page.tsx
similarity index 100%
rename from apps/dm/app/pages/sdmMng/sdmInsert/page.tsx
rename to apps/dm/app/(base-layout)/pages/sdmMng/sdmInsert/page.tsx
diff --git a/apps/dm/app/pages/sdmMng/sdmLogin/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmLogin/page.tsx
similarity index 100%
rename from apps/dm/app/pages/sdmMng/sdmLogin/page.tsx
rename to apps/dm/app/(base-layout)/pages/sdmMng/sdmLogin/page.tsx
diff --git a/apps/dm/app/pages/wrAbout/page.tsx b/apps/dm/app/(base-layout)/pages/wrAbout/page.tsx
similarity index 100%
rename from apps/dm/app/pages/wrAbout/page.tsx
rename to apps/dm/app/(base-layout)/pages/wrAbout/page.tsx
diff --git a/apps/dm/app/pages/wrExample/page.tsx b/apps/dm/app/(base-layout)/pages/wrExample/page.tsx
similarity index 100%
rename from apps/dm/app/pages/wrExample/page.tsx
rename to apps/dm/app/(base-layout)/pages/wrExample/page.tsx
diff --git a/apps/dm/app/pages/wrOverview/page.tsx b/apps/dm/app/(base-layout)/pages/wrOverview/page.tsx
similarity index 100%
rename from apps/dm/app/pages/wrOverview/page.tsx
rename to apps/dm/app/(base-layout)/pages/wrOverview/page.tsx
diff --git a/apps/dm/app/pages/wrStatus/page.tsx b/apps/dm/app/(base-layout)/pages/wrStatus/page.tsx
similarity index 100%
rename from apps/dm/app/pages/wrStatus/page.tsx
rename to apps/dm/app/(base-layout)/pages/wrStatus/page.tsx
diff --git a/apps/dm/app/(popup-layout)/layout.tsx b/apps/dm/app/(popup-layout)/layout.tsx
new file mode 100644
index 000000000..60d925f3e
--- /dev/null
+++ b/apps/dm/app/(popup-layout)/layout.tsx
@@ -0,0 +1,19 @@
+"use client"
+import "../globals.css";
+import { StoreProvider } from "../store";
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode;
+}>) {
+ return (
+
+
+
+ {children}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/apps/dm/app/pages/map/mainMap/page.tsx b/apps/dm/app/(popup-layout)/map/mainMap/page.tsx
similarity index 100%
rename from apps/dm/app/pages/map/mainMap/page.tsx
rename to apps/dm/app/(popup-layout)/map/mainMap/page.tsx
diff --git a/apps/dm/app/(popup-layout)/map/popup/page.tsx b/apps/dm/app/(popup-layout)/map/popup/page.tsx
new file mode 100644
index 000000000..84dc49119
--- /dev/null
+++ b/apps/dm/app/(popup-layout)/map/popup/page.tsx
@@ -0,0 +1,147 @@
+"use client";
+
+import Gis from "@common/business_components/ui/map/Gis";
+import { useEffect, useRef, useState, useCallback } from "react";
+import { mapService } from "../service";
+import GisApp from "@common/business_components/ui/map/lib/gis.core";
+import { SearchBar } from "@/components/ui/map/searchBar/searchBar";
+
+const Map = () => {
+ const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
+ const gisMaps = useRef(null);
+ const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
+ const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태
+ const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
+ const [checkedLayers, setCheckedLayers] = useState([]);
+ const [checkedLayersData, setCheckedLayersData] = useState([]);
+ const [selectDataPk, setSelectDataPk] = useState("");
+
+ const fetchData = async () => {
+ try {
+ const response = await mapService.getLyrStngs();
+ setTreeData(response); // API 응답 저장
+ } catch (error) {
+ console.error("데이터 불러오기 실패:", error);
+ }
+ };
+
+ // 팝업 닫기 핸들러를 useCallback으로 메모이제이션
+ const handlePopupClose = useCallback(() => {
+ setIsOpen(false);
+ setFeatureData(null);
+ }, []);
+
+ // 컴포넌트 마운트 시 1회 실행
+ useEffect(() => {
+ fetchData();
+ }, []);
+
+ useEffect(() => {
+ console.log("Selected Data Pk: ", selectDataPk);
+ }, [selectDataPk]);
+
+ // 체크된 레이어 정보를 받는 핸들러
+ const handleCheckedLayersChange = (
+ checkedIds: string[],
+ checkedNodesData: any[]
+ ) => {
+ setCheckedLayers(checkedIds);
+ setCheckedLayersData(checkedNodesData);
+ };
+
+ // SearchModal, GisContent 등에서 호출
+ const onFeatureSelect = (data: any) => {
+ const map = gisMaps.current;
+ if (!map) {
+ console.warn("지도가 초기화되지 않았습니다.");
+ return;
+ }
+
+ // 항상 같은 select 객체 사용
+ const select = GisApp.Module.select as any;
+ if (!select) return;
+
+ // 1. 기존 선택 초기화
+ select.resetSelectedFeature();
+
+ // 2. data가 OpenLayers Feature 인스턴스인지 확인
+ let foundFeature: any = null;
+ if (
+ data &&
+ typeof data.getGeometry === "function" &&
+ typeof data.setStyle === "function"
+ ) {
+ // 이미 Feature 인스턴스라면 그대로 사용
+ foundFeature = data;
+ } else {
+ // 아니면 featureId로 맵에서 Feature 인스턴스를 찾아서 사용
+ const featureId = data.fid || data.ftrIdn || data.id;
+ map
+ .getLayers()
+ .getArray()
+ .forEach((layer: any) => {
+ const source = layer.getSource?.();
+ if (source?.getFeatureById) {
+ const feature = source.getFeatureById(String(featureId).trim());
+ if (feature) foundFeature = feature;
+ }
+ });
+ }
+
+ // 3. 피처 선택
+ if (foundFeature) {
+ const geometry = foundFeature.getGeometry();
+ if (geometry) {
+ const extent = geometry.getExtent();
+
+ map.getView().fit(extent, {
+ duration: 300,
+ padding: [50, 50, 50, 50],
+ maxZoom: 16,
+ constrainResolution: true,
+ nearest: true,
+ });
+ }
+ select.selectFeature(foundFeature, true);
+ } else {
+ console.warn("OpenLayers Feature를 찾을 수 없습니다:", data);
+ }
+
+ setFeatureData(data);
+ setIsOpen(true);
+ setIsSearchModalOpen(false);
+ };
+
+ return (
+ <>
+ {
+ if (hasuPk !== "") {
+ setSelectDataPk(hasuPk);
+ }
+ }}
+ />
+
+
+
+ >
+ );
+};
+
+export default Map;
diff --git a/apps/dm/app/pages/map/popup/sdmInfoMap.tsx b/apps/dm/app/(popup-layout)/map/popup/sdmInfoMap.tsx
similarity index 77%
rename from apps/dm/app/pages/map/popup/sdmInfoMap.tsx
rename to apps/dm/app/(popup-layout)/map/popup/sdmInfoMap.tsx
index 21b76f943..84dc49119 100644
--- a/apps/dm/app/pages/map/popup/sdmInfoMap.tsx
+++ b/apps/dm/app/(popup-layout)/map/popup/sdmInfoMap.tsx
@@ -4,6 +4,7 @@ import Gis from "@common/business_components/ui/map/Gis";
import { useEffect, useRef, useState, useCallback } from "react";
import { mapService } from "../service";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
+import { SearchBar } from "@/components/ui/map/searchBar/searchBar";
const Map = () => {
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
@@ -13,6 +14,7 @@ const Map = () => {
const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
const [checkedLayers, setCheckedLayers] = useState([]);
const [checkedLayersData, setCheckedLayersData] = useState([]);
+ const [selectDataPk, setSelectDataPk] = useState("");
const fetchData = async () => {
try {
@@ -34,6 +36,10 @@ const Map = () => {
fetchData();
}, []);
+ useEffect(() => {
+ console.log("Selected Data Pk: ", selectDataPk);
+ }, [selectDataPk]);
+
// 체크된 레이어 정보를 받는 핸들러
const handleCheckedLayersChange = (
checkedIds: string[],
@@ -107,25 +113,34 @@ const Map = () => {
};
return (
-
-
+ {
+ if (hasuPk !== "") {
+ setSelectDataPk(hasuPk);
+ }
+ }}
/>
-
+
+
+
+ >
);
};
diff --git a/apps/dm/app/pages/map/popup/windowPotal.tsx b/apps/dm/app/(popup-layout)/map/popup/windowPotal.tsx
similarity index 98%
rename from apps/dm/app/pages/map/popup/windowPotal.tsx
rename to apps/dm/app/(popup-layout)/map/popup/windowPotal.tsx
index e601e7c9c..38b8fc7db 100644
--- a/apps/dm/app/pages/map/popup/windowPotal.tsx
+++ b/apps/dm/app/(popup-layout)/map/popup/windowPotal.tsx
@@ -85,7 +85,7 @@ const NewWindowPortal: React.FC = ({ children, onClose, ti
alert('팝업이 차단되었습니다. 팝업 차단을 해제하고 다시 시도해주세요.');
onCloseRef.current();
}
- }, [handleUnload, onClose, title]);
+ }, []);
// `createPortal`을 사용해 children을 새 창의 container div에 렌더링합니다.
return container ? createPortal(children, container) : null;
diff --git a/apps/dm/app/pages/map/service/index.ts b/apps/dm/app/(popup-layout)/map/service/index.ts
similarity index 100%
rename from apps/dm/app/pages/map/service/index.ts
rename to apps/dm/app/(popup-layout)/map/service/index.ts
diff --git a/apps/dm/app/pages/map/service/map.ts b/apps/dm/app/(popup-layout)/map/service/map.ts
similarity index 100%
rename from apps/dm/app/pages/map/service/map.ts
rename to apps/dm/app/(popup-layout)/map/service/map.ts
diff --git a/apps/dm/app/layout.tsx b/apps/dm/app/layout.tsx
index 7c0f47a30..119daee77 100644
--- a/apps/dm/app/layout.tsx
+++ b/apps/dm/app/layout.tsx
@@ -11,9 +11,7 @@ export default function RootLayout({
return (
-
- {children}
-
+ {children}
);
diff --git a/apps/dm/app/middleware.ts b/apps/dm/app/middleware.ts
new file mode 100644
index 000000000..6ddf29f9f
--- /dev/null
+++ b/apps/dm/app/middleware.ts
@@ -0,0 +1,130 @@
+import { NextRequest, NextResponse } from "next/server";
+import path from "path";
+
+const AUTH_USER_ID = process.env.NEXT_PUBLIC_AUTH_USER_ID || "token-id";
+const CLAIM_NAME = process.env.NEXT_PUBLIC_CLAIM_NAME || "Authorization";
+const SERVER_API_URL = process.env.NEXT_PUBLIC_SERVER_API_URL || "";
+const SEWERAGE_API_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || "";
+const GEOSERVER_URL = process.env.NEXT_PUBLIC_GEOSERVER_URL || "";
+const LX_GEOSERVER_URL = process.env.NEXT_PUBLIC_LX_GEOSERVER_URL || "";
+const DC_URL = process.env.NEXT_PUBLIC_DC_URL || "";
+
+export function middleware(req: NextRequest) {
+ console.log("Middleware 진입:", req.nextUrl.pathname);
+ const pathname = req.nextUrl.pathname;
+ const searchParams = req.nextUrl.searchParams;
+
+ if (pathname.startsWith("/server")) {
+
+ const decodedParams = Array.from(searchParams.entries())
+ .map(([key, value]) => `${key}=${decodeURIComponent(value)}`)
+ .join("&");
+
+ const newUrl = `${SERVER_API_URL}${pathname.replace("/server", "")}${
+ decodedParams ? `?${decodedParams}` : ""
+ }`;
+ return NextResponse.rewrite(new URL(newUrl));
+ }
+
+ if (pathname.startsWith("/geoserver")) {
+ let queryParams = searchParams.toString();
+ const typename = searchParams.get("TYPENAME");
+
+ let newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`;
+
+ if (
+ typename == "hasudo:tb_il_swage_prcs_fclt" //하수처리시설
+ || typename == "hasudo:tb_ms_swage_prcs_zone" //하수처리구역
+ || typename == "hasudo:tb_ms_sbmrg_dngr_map" //침수위험지도
+ || typename == "hasudo:tb_ms_flood_dngr_map" //도시침수지도
+ ) {
+ newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`;
+ }
+ else if (
+ typename == "hasudo:tb_ms_swage_ppl" //관로
+ || typename == "hasudo:tb_ms_swage_mhl" //맨홀
+ || typename == "hasudo:tb_ms_swage_pmstn" //펌프장
+ || typename == "hasudo:tb_ms_stofcbr" //우수토실
+ ) {
+ newUrl = `${LX_GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`;
+ }
+ else if (
+ typename == "hasudo:om_dt_untrt_swg_rain" //중점우수토실
+ || typename == "hasudo:om_wqlt_station" //관측소
+ || typename == "hasudo:tb_wr_bdst_ruse_fclt" //재이용시설
+ || typename == "hasudo:tb_wr_rnwtr_utztn_fclt" //빗물이용시설
+ || typename == "hasudo:tb_wr_rswtr_fclt" //중수도시설
+ || typename == "hasudo:tb_wr_htdfl_fclt" //온배수시설
+ || typename == "hasudo:tb_wr_ruse_fclt_dmd_co" //수요처
+ || typename == "hasudo:tb_wr_tmpr_dmd_co" //잠재수요처
+ ){
+ const url = req.nextUrl.clone();
+ url.searchParams.set('TYPENAME', typename.replace("hasudo:",""));
+ queryParams = url.searchParams.toString();
+ newUrl = `${SEWERAGE_API_URL}/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`;
+ }
+
+ console.log(`[Middleware] Rewriting from '/geoserver' path to: ${newUrl}`);
+ return NextResponse.rewrite(new URL(newUrl));
+ }
+
+ if (
+ pathname.startsWith("/attach-service") ||
+ pathname.startsWith("/cms-service")
+ ) {
+ const requestHeaders = new Headers(req.headers);
+ const token = req.cookies.get(CLAIM_NAME)?.value;
+ const userId = req.cookies.get(AUTH_USER_ID)?.value;
+ const newUrl = `${SERVER_API_URL}${pathname}`;
+
+ if (token) requestHeaders.set(CLAIM_NAME, token);
+ if (userId) requestHeaders.set(AUTH_USER_ID, userId);
+
+ console.log(
+ `[Middleware] Rewriting from '/attach-service' path to: ${newUrl}`,
+ );
+ return NextResponse.rewrite(new URL(newUrl), {
+ headers: requestHeaders,
+ });
+ }
+
+ if (pathname.startsWith("/user-service")) {
+ const requestHeaders = new Headers(req.headers);
+ const newUrl = `${SERVER_API_URL}${pathname}`;
+
+ console.log(
+ `[Middleware] Rewriting from '/user-service' path to: ${newUrl}`,
+ );
+ return NextResponse.rewrite(new URL(newUrl), {
+ headers: requestHeaders,
+ });
+ }
+
+ if (pathname.startsWith("/dc-service")) {
+ const requestHeaders = new Headers(req.headers);
+ const decodedParams = Array.from(searchParams.entries())
+ .map(([key, value]) => `${key}=${decodeURIComponent(value)}`)
+ .join("&");
+
+ const newUrl = `${DC_URL}${pathname}${decodedParams ? `?${decodedParams}` : ""}`;
+ console.log(
+ `[Middleware] Rewriting from '/dc-service' path to: ${newUrl}`,
+ );
+ return NextResponse.rewrite(new URL(newUrl), {
+ headers: requestHeaders,
+ });
+ }
+ return NextResponse.next();
+}
+
+export const config = {
+ matcher: [
+ "/server/:path*",
+ "/geoserver/:path*",
+ "/attach-service/:path*",
+ "/user-service/:path*",
+ "/cms-service/:path*",
+ "/dc-service/:path*",
+ ],
+
+};
diff --git a/apps/dm/app/page.tsx b/apps/dm/app/page.tsx
index a5f49f0bc..fdb323086 100644
--- a/apps/dm/app/page.tsx
+++ b/apps/dm/app/page.tsx
@@ -30,9 +30,6 @@ export default function Home() {
-
>
);
diff --git a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx
index a63244b98..94ebe1057 100644
--- a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx
+++ b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx
@@ -1,5 +1,5 @@
-import ModalSimilarPage from "@/app/pages/sdmMng/sdmInfoInsert/modalSimilar/page";
-import type { FormData } from "@/app/pages/sdmMng/sdmInfoInsert/page";
+import ModalSimilarPage from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page";
+import type { FormData } from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page";
import { useDmStore } from "@/app/store";
import {
CANDIDATE,
@@ -18,8 +18,8 @@ import { AccessibleFormField } from "./AccessibleFormField";
import type { ControllerRenderProps, UseFormReturn } from "react-hook-form";
import SearchInputText from "../common/searhDemandInput/component";
import type { DemandCompType } from "@/app/store/sdmMng";
-import NewWindowPortal from "@/app/pages/map/popup/windowPotal";
-import Map from "@/app/pages/map/popup/sdmInfoMap";
+import NewWindowPortal from "@/app/(popup-layout)/map/popup/windowPotal";
+import Map from "@/app/(popup-layout)/map/popup/sdmInfoMap";
export interface SdmInfoRegFormProps {
form: UseFormReturn;
@@ -82,11 +82,17 @@ export function SdmInfoRegForm({
}
}, [searchParams, form]);
+ const handleCandidateClose = useCallback(
+ () => setIsCandidatePopup(false),
+ []
+ );
+
const searchCandidate = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
- console.log(1);
- setIsCandidatePopup(true);
+ //setIsCandidatePopup(true);
+ const popupOptions = `width=1920,height=1080,resizable='y',scrollbars='y'`;
+ window.open('/map/popup', 'title', popupOptions);
};
const searchSimilarCase = (e: React.MouseEvent) => {
@@ -610,19 +616,6 @@ export function SdmInfoRegForm({
/>
)}
- {/* 후보지 조회 새 창 포털 */}
- {isCandidatePopup && (
- setIsCandidatePopup(false)}
- title="공급처 후보지 조회"
- width={window.screen.availWidth}
- height={window.screen.availHeight}
- resizable="no"
- scrollbars="yes"
- >
-
-
- )}
>
);
}
diff --git a/packages/common/business_components/src/ui/map/Gis.js b/packages/common/business_components/src/ui/map/Gis.js
index 5386207d8..18ef123c3 100644
--- a/packages/common/business_components/src/ui/map/Gis.js
+++ b/packages/common/business_components/src/ui/map/Gis.js
@@ -38,6 +38,7 @@ function Gis({
setIsSearchModalOpen,
onCheckedLayersChange
}) {
+
const mapRef = useRef();
const [mapObject, setMapObject] = useState({});
const [tabVisible, setTabVisible] = useState(true);
@@ -151,6 +152,7 @@ function Gis({
// 지도 생성 및 초기화
useEffect(() => {
+
if (!mapRef.current) return;
if (mapInstanceRef.current) return; // 이미 생성된 맵이 있다면 중단
@@ -257,120 +259,6 @@ function Gis({
}
}
- // // 데이터 로드 및 팝업 생성 로직
- // useEffect(() => {
- // if (!mapInstanceRef.current) return; // 맵이 생성되지 않았으면 실행 안 함
-
- // // 1. 팝업 데이터 가져오기 (feature.js의 getData와 유사)
- // const fetchPopupData = async () => {
- // // 실제 API 호출 로직으로 대체해야 합니다.
- // // 예시: const response = await yourApiService.getFcltyWtCnt();
- // // setFacilityInfoPopupData(response.data);
-
- // // 임시 목업 데이터
- // const mockData = [
- // { ftrIdn: 1, ftrCde: 'SA206', bplcNm: '처리장A', fcltyUseYn: 'Y', x: 127.005, y: 37.282, aCnt: 10, cCnt: 5, eCnt: 3, mCnt: 8, iCnt: 2 },
- // { ftrIdn: 2, ftrCde: 'SA112', bplcNm: '처리장B', fcltyUseYn: 'N', x: 127.010, y: 37.285, aCnt: 8, cCnt: 4, eCnt: 2, mCnt: 6, iCnt: 1 }
- // ];
- // setFacilityInfoPopupData(mockData);
- // };
-
- // fetchPopupData();
-
- // }, [mapInstanceRef.current]); // 맵 인스턴스가 생성된 후 한 번만 실행
-
- // // 데이터가 변경되면 오버레이를 생성/업데이트하는 로직
- // useEffect(() => {
- // const map = mapInstanceRef.current;
- // if (!map || facilityInfoPopupData.length === 0) return;
-
- // // 기존 오버레이 정리
- // facilityOverlaysRef.current.forEach(overlay => map.removeOverlay(overlay));
- // facilityOverlaysRef.current = [];
-
- // facilityInfoPopupData.forEach(data => {
- // const popupId = `${data.ftrIdn}_${data.ftrCde}`;
-
- // // 팝업을 담을 div 엘리먼트 생성
- // const popupElement = document.createElement('div');
- // popupElement.id = popupId;
-
- // // OpenLayers Overlay 생성
- // const position = olProj.transform([Number(data.x), Number(data.y)], GisApp.FROM_PROJ, GisApp.TO_PROJ);
- // const overlay = new Overlay({
- // element: popupElement,
- // position: position,
- // offset: [-75, -210], // 팝업 너비의 절반, 높이만큼 오프셋 조정
- // positioning: 'bottom-center',
- // className: 'facility-popup-overlay' // 필요시 공통 클래스 추가
- // });
-
- // map.addOverlay(overlay);
- // facilityOverlaysRef.current.push(overlay);
-
- // // React 컴포넌트를 popupElement에 렌더링
- // const root = createRoot(popupElement);
- // root.render();
- // });
-
- // // 초기 가시성 업데이트
- // updatePopupVisibility();
-
- // }, [facilityInfoPopupData]); // 팝업 데이터가 변경될 때마다 실행
-
- // // 레이어 가시성에 따라 팝업 가시성을 제어하는 함수
- // const updatePopupVisibility = useCallback(() => {
- // const map = mapInstanceRef.current;
- // if (!map) return;
-
- // const visibleLayers = new Set();
- // map.getLayers().forEach(layer => {
- // if (layer.getVisible()) {
- // // feature.js의 로직처럼 typeName이나 ftrCde를 사용해 필터링
- // const typeName = layer.get('typeName');
- // if (typeName === 'VW_WTL_FCLTY_AS') { // 예시 레이어 이름
- // visibleLayers.add(layer.get('ftrCde'));
- // }
- // }
- // });
-
- // facilityOverlaysRef.current.forEach(overlay => {
- // const element = overlay.getElement();
- // const ftrCde = element.querySelector('table')?.classList[0]; // FacilityPopup의 클래스에서 ftrCde 가져오기
-
- // if (visibleLayers.has(ftrCde)) {
- // element.style.display = '';
- // } else {
- // element.style.display = 'none';
- // }
- // });
- // }, []);
-
- // GisTree에서 체크 상태가 변경될 때 이 함수를 호출하도록 연결해야 합니다.
- // 예시: GisTree 컴포넌트에 onCheck 콜백을 추가하고, 그 콜백에서 이 함수를 호출
- // useEffect(() => {
- // // 레이어 가시성이 변경될 때마다 팝업 가시성 업데이트
- // const map = mapInstanceRef.current;
- // if (!map) return;
-
- // const handleLayerVisibilityChange = () => {
- // updatePopupVisibility();
- // };
-
- // map.getLayers().on('change:length', handleLayerVisibilityChange);
- // map.getLayers().forEach(layer => {
- // layer.on('change:visible', handleLayerVisibilityChange);
- // });
-
- // return () => {
- // // 클린업
- // map.getLayers().un('change:length', handleLayerVisibilityChange);
- // map.getLayers().forEach(layer => {
- // layer.un('change:visible', handleLayerVisibilityChange);
- // });
- // };
- // }, [updatePopupVisibility]);
-
// 체크된 레이어 정보를 처리하는 함수
const handleCheckedLayersChange = useCallback((checkedIds, checkedNodesData) => {
setTimeout(() => {
@@ -418,7 +306,6 @@ function Gis({
onFeatureSelect={handleFeatureSelect}
/>
)}
-