159 lines
4.8 KiB
TypeScript
159 lines
4.8 KiB
TypeScript
"use client";
|
|
|
|
import Gis from "@common/business_components/ui/map/Gis";
|
|
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";
|
|
|
|
const Map = () => {
|
|
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
|
|
const gisMaps = useRef<any | null>(null);
|
|
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
|
|
const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태
|
|
const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
|
|
const [checkedLayers, setCheckedLayers] = useState<string[]>([]);
|
|
const [checkedLayersData, setCheckedLayersData] = useState<any[]>([]);
|
|
|
|
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();
|
|
}, []);
|
|
|
|
// 체크된 레이어 정보를 받는 핸들러
|
|
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);
|
|
};
|
|
|
|
// MapSearchBar 래퍼 컴포넌트
|
|
// const CustomMapSearchBar = (props: any) => {
|
|
// return (
|
|
// <MapSearchBar
|
|
// {...props}
|
|
// searchType="공급처 후보지 조회"
|
|
// showApplyButton={false}
|
|
// />
|
|
// );
|
|
// };
|
|
|
|
return (
|
|
<div className="bg-container">
|
|
<Gis
|
|
treeData={treeData}
|
|
isSearch={false}
|
|
gisMaps={gisMaps}
|
|
isMiniMap={false}
|
|
searchView={undefined}
|
|
// searchView={(props: any) => (
|
|
// <MapSearchBar
|
|
// searchType="공급처 후보지 조회"
|
|
// showApplyButton={false}
|
|
// checkedLayers={checkedLayers}
|
|
// checkedLayersData={checkedLayersData}
|
|
// {...props}
|
|
// />
|
|
// )
|
|
// }
|
|
detailView={(props: any) =>(
|
|
<NewWindowPopup
|
|
onClose={handlePopupClose} // 메모이제이션된 함수 사용
|
|
checkedLayers={checkedLayers}
|
|
checkedLayersData={checkedLayersData}
|
|
{...props}
|
|
/>
|
|
)}
|
|
onFeatureSelect={onFeatureSelect}
|
|
setIsOpen={setIsOpen}
|
|
setFeatureData={setFeatureData}
|
|
featureData={featureData}
|
|
setIsSearchModalOpen={setIsSearchModalOpen}
|
|
isOpen={isOpen}
|
|
isSearchModalOpen={isSearchModalOpen}
|
|
onCheckedLayersChange={handleCheckedLayersChange}
|
|
imgVisble={true}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Map;
|