271 lines
8.3 KiB
TypeScript
271 lines
8.3 KiB
TypeScript
"use client";
|
|
|
|
import Gis from "@common/business_components/ui/map/Gis";
|
|
import { useEffect, useRef, useState } 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";
|
|
import SelectedFcltList from "./selectedFcltList";
|
|
import type { SubsInfo } from "@/app/store/map/type";
|
|
|
|
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 [selectDataPk, setSelectDataPk] = useState<Record<string, any>>({});
|
|
const [selectedFclts, setSelectedFclts] = useState<any[]>([]);
|
|
|
|
//적용 버튼 클릭 이벤트
|
|
const onApply = () => {
|
|
if (selectedFclts.length > 3) {
|
|
alert("재이용시설 후보지는 최대 3개까지만 선택할 수 있습니다.");
|
|
return;
|
|
}
|
|
|
|
const subsInfoList: SubsInfo[] = selectedFclts.map((fclt) => ({
|
|
ruseUtztnFcltNm: fclt.ruseUtztnFcltNm,
|
|
ruseUtztnFcltCd: fclt.pbnstRuseFcltId,
|
|
}));
|
|
|
|
window.opener.postMessage(
|
|
{
|
|
type: "SET_SUBS_INFO",
|
|
payload: subsInfoList, // 또는 필요한 데이터
|
|
},
|
|
"*"
|
|
);
|
|
|
|
window.close();
|
|
};
|
|
|
|
//트리 레이어 데이터 조회
|
|
const fetchData = async () => {
|
|
try {
|
|
const response = await mapService.getLyrStngs();
|
|
setTreeData(response); // API 응답 저장
|
|
} catch (error) {
|
|
console.error("데이터 불러오기 실패:", error);
|
|
}
|
|
};
|
|
|
|
//하수처리시설코드로 재이용시설 목록 조회
|
|
const reuseData = async (ruseFcltPk: any) => {
|
|
try {
|
|
const response = await mapService.getPbnstRuseFclts(ruseFcltPk);
|
|
const data = response.data || [];
|
|
setSelectedFclts((prev) => {
|
|
const newItems = data.filter(
|
|
(item: any) =>
|
|
item &&
|
|
Object.keys(item).length > 0 &&
|
|
!prev.some((f) => f.pbnstRuseFcltId === item.pbnstRuseFcltId)
|
|
);
|
|
console.log(newItems)
|
|
return [...prev, ...newItems];
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("데이터 불러오기 실패:", error);
|
|
}
|
|
};
|
|
|
|
// 컴포넌트 마운트 시 1회 실행
|
|
useEffect(() => {
|
|
fetchData();
|
|
}, []);
|
|
|
|
// 레이어 생성 후 초기화 처리
|
|
const onCheckedLayersChange = () => {
|
|
//수요처 ID
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const dmdInfoId = urlParams.get("dmdInfoId");
|
|
|
|
//수요처 위치로 화면 이동
|
|
const maps = gisMaps.current;
|
|
const layer = GisApp.Module.layer as any;
|
|
const layerNm = "tb_wr_ruse_fclt_dmd_co";
|
|
const featureId = `${layerNm}.${dmdInfoId}`;
|
|
let foundFeature: any = null;
|
|
|
|
maps
|
|
.getLayers()
|
|
.getArray()
|
|
.forEach((layer: any) => {
|
|
if (layer.get("lyrTyNm") == layerNm) {
|
|
const source = layer.getSource?.();
|
|
if (source?.getFeatureById) {
|
|
const feature = source.getFeatureById(String(featureId).trim());
|
|
if (feature) {
|
|
foundFeature = feature;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
if (foundFeature) {
|
|
const geometry = foundFeature.getGeometry();
|
|
|
|
if (geometry) {
|
|
const extent = geometry.getExtent();
|
|
|
|
if (geometry.getType() === "Point") {
|
|
maps.getView().setCenter(geometry.getCoordinates());
|
|
maps.getView().setZoom(11);
|
|
} else {
|
|
maps.getView().fit(extent, {
|
|
duration: 300,
|
|
padding: [30, 30, 30, 30],
|
|
maxZoom: 16,
|
|
});
|
|
}
|
|
}
|
|
|
|
layer.highLightFeature(
|
|
[foundFeature],
|
|
{
|
|
id: GisApp.hlLayerId,
|
|
zIndex: 10,
|
|
opacity: 1,
|
|
selectable: true,
|
|
},
|
|
{ width: 30 }
|
|
);
|
|
}
|
|
|
|
const formatNumber = (val: any) => {
|
|
const num = Number(val);
|
|
return isNaN(num) ? "-" : num.toLocaleString();
|
|
};
|
|
|
|
// 재이용시설 오버레이
|
|
maps
|
|
.getLayers()
|
|
.getArray()
|
|
.forEach((layer: any) => {
|
|
if (layer.get("lyrTyNm") === "tb_wr_bdst_ruse_fclt") {
|
|
const source = layer.getSource?.();
|
|
if (source?.getFeatures) {
|
|
const features = source.getFeatures();
|
|
|
|
features.forEach((feature: any) => {
|
|
// 필요한 고유 ID 또는 속성 가져오기 (예: ftrIdn 또는 feature.getId())
|
|
const featureId =
|
|
feature.getId() || feature.get("ftrIdn") || Math.random();
|
|
|
|
// HTML 또는 React 오버레이 컴포넌트 구성
|
|
const overlayContent = `
|
|
<div class="rounded-md border border-gray-300 bg-white shadow-md text-sm w-[120px]">
|
|
<!-- 헤더 -->
|
|
<div class="bg-cyan-700 text-white px-3 py-2 text-[11px] font-semibold text-center rounded-t-md">
|
|
${feature.get("swtrmt_fclt_nm") || "-"}
|
|
</div>
|
|
|
|
<!-- 테이블 -->
|
|
<table class="w-full text-sm text-gray-800 border-t border-gray-200">
|
|
<tbody>
|
|
<tr class="border-b border-gray-200">
|
|
<th class="bg-gray-100 text-gray-600 font-semibold text-[10px] text-left">용량(m³/일)</th>
|
|
<td class="text-right text-[10px] font-bold">${formatNumber(feature.get("fclt_cpct"))}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
`;
|
|
feature.set("html", overlayContent);
|
|
feature.set("overLayId", `overLay.${featureId}`);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
// 검색해서 재이용시설 선택하면 해당 시설로 화면 이동 처리
|
|
useEffect(() => {
|
|
if (!selectDataPk || Object.keys(selectDataPk).length === 0) return;
|
|
const maps = gisMaps.current;
|
|
let foundFeature: any = null;
|
|
const layerNm = "tb_wr_bdst_ruse_fclt";
|
|
const featureId = `${layerNm}.${selectDataPk.bscFctCd}`;
|
|
maps
|
|
.getLayers()
|
|
.getArray()
|
|
.forEach((layer: any) => {
|
|
if (layer.get("lyrTyNm") == layerNm) {
|
|
const source = layer.getSource?.();
|
|
if (source?.getFeatureById) {
|
|
const feature = source.getFeatureById(String(featureId).trim());
|
|
if (feature) {
|
|
foundFeature = feature;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
if (foundFeature) {
|
|
const geometry = foundFeature.getGeometry();
|
|
if (geometry) {
|
|
const extent = geometry.getExtent();
|
|
|
|
maps.getView().fit(extent, {
|
|
duration: 300,
|
|
padding: [50, 50, 50, 50],
|
|
maxZoom: 16,
|
|
constrainResolution: true,
|
|
nearest: true,
|
|
});
|
|
}
|
|
} else {
|
|
console.warn("OpenLayers Feature를 찾을 수 없습니다:", selectDataPk);
|
|
}
|
|
}, [selectDataPk]);
|
|
|
|
// 재이용시설 클릭 시 선택 시설목록에 추가
|
|
const onFeatureSelect = (data: any) => {
|
|
// 처리시설코드
|
|
const swtrmtFcltCd = data.get("swtrmt_fclt_cd");
|
|
reuseData(swtrmtFcltCd);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<SearchBar
|
|
setHasuPk={(hasuPk: any) => {
|
|
if (hasuPk) {
|
|
setSelectDataPk(hasuPk);
|
|
}
|
|
}}
|
|
onApply={onApply}
|
|
/>
|
|
<div className="bg-container">
|
|
<Gis
|
|
treeData={treeData}
|
|
isSearch={false}
|
|
gisMaps={gisMaps}
|
|
isMiniMap={false}
|
|
searchView={undefined}
|
|
detailView={undefined}
|
|
onFeatureSelect={onFeatureSelect}
|
|
setIsOpen={setIsOpen}
|
|
setFeatureData={setFeatureData}
|
|
featureData={featureData}
|
|
setIsSearchModalOpen={setIsSearchModalOpen}
|
|
isOpen={isOpen}
|
|
isSearchModalOpen={isSearchModalOpen}
|
|
onCheckedLayersChange={onCheckedLayersChange}
|
|
imgVisble={false}
|
|
/>
|
|
</div>
|
|
<SelectedFcltList
|
|
data={selectedFclts}
|
|
onRemove={(updatedList) => setSelectedFclts(updatedList)}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Map;
|