detaile시설 입력 팝업 셀누르면 이동및 팝업 창 뜨도록 수정

This commit is contained in:
leedj312
2025-08-11 15:58:41 +09:00
parent 39fe92154f
commit 7d137c93c5
4 changed files with 225 additions and 129 deletions
+76 -102
View File
@@ -6,7 +6,14 @@ import { mapService } from "../../service";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
import { SearchBar } from "@common/business_components/ui/map/searchBar/searchBar";
import { useWrStore } from "@/app/store";
import { getFeatureCd } from "@/components/lib/func/mapUtil";
import {
featurePopUpOpen,
getClickFeatureId,
getFeatureCd,
getSelectedLayers,
getWrFeaturePk,
getWrLayerNm,
} from "@/components/lib/func/mapUtil";
import toast, { Toaster } from "react-hot-toast";
const Map = () => {
@@ -24,7 +31,7 @@ const Map = () => {
const fetchData = async () => {
try {
const response = await mapService.getLyrStngs('WR_NETWORK');
const response = await mapService.getLyrStngs("WR_NETWORK");
setTreeData(response); // API 응답 저장
} catch (error) {
console.error("데이터 불러오기 실패:", error);
@@ -71,11 +78,11 @@ const Map = () => {
};
// SearchModal, GisContent 등에서 호출
const onFeatureFocus = () => {
console.log("onFeatureFocus");
const onFeatureFocus = (data: any) => {
console.log('data',data)
};
const onFeatureSelect = (data: any) => {
const onFeatureSelect = (data: any ,popUpClick?:boolean) => {
const map = gisMaps.current;
if (!map) {
@@ -93,27 +100,19 @@ const Map = () => {
// 2. data가 OpenLayers Feature 인스턴스인지 확인
let foundFeature: any = null;
let featureId = data.fid;
const layerName = data.layerNm;
if (layerName === "하수재이용시설") {
if(popUpClick){
const layerName = getWrLayerNm(data);
const featurePk = getWrFeaturePk(layerName ?? "");
// 재이용시설
featureId = `${layerName}.${data.searchPk}`;
} else if (
//빗물이용시설, 중수도시설
layerName === "빗물이용시설" ||
layerName == "중수도시설"
) {
featureId = `${layerName}.${data.bdstInfoSn}`;
} else if (layerName === "하수처리시설") {
//하수처리시설
featureId = `${layerName}.${data.bscFctCd}`;
} else if (layerName === "온배수시설") {
//온배수시설
featureId = `${layerName}.${data.bdstRuseFcltSn}`;
} else if (layerName == "수요처") {
//수요처
featureId = `${layerName}.${data.dmdInfoId.replaceAll("-", "")}`;
} else {
featureId = `${layerName}.${data.fid || data.id || data.ftrIdn}`;
if (featurePk) {
featureId = `${layerName}.${data[featurePk]}`;
} else {
console.warn("해당 피처는 선택된 레이어에서 찾을수 없습니다.");
}
}else{
featureId=getClickFeatureId(data)
}
map
.getLayers()
@@ -143,6 +142,10 @@ const Map = () => {
select.selectFeature(foundFeature, true);
} else {
console.warn("OpenLayers Feature를 찾을 수 없습니다:");
console.log("foundFeature :", foundFeature );
console.warn("featureId : ", featureId);
console.warn("data : ", data);
console.warn(": 끝");
}
const currentId = data?.fid || data?.id || data?.ftrIdn;
const lastId = featureData?.fid || featureData?.id || featureData?.ftrIdn;
@@ -150,10 +153,16 @@ const Map = () => {
setFeatureData(data);
setIsOpen(true);
setIsSearchModalOpen(false);
if (popUpClick ){
const layerName = getWrLayerNm(data);
const isColumn = getFeatureCd(foundFeature.getProperties(), String(layerName));
if(layerName&&isColumn)
featurePopUpOpen(layerName,isColumn,popupDetailRef)
}
};
useEffect(() => {
if (isFeatured) {
onFeatureSelect(isFeatured);
}
@@ -163,41 +172,13 @@ const Map = () => {
const bc = new BroadcastChannel("mapDetailPopUp");
bc.onmessage = (event) => {
if (event.data.type === "SELECT_FEATURE") {
onFeatureSelect(event.data.feature);
onFeatureSelect(event.data.feature,true);
closePopup();
}
};
}, []);
const getSelectedLayers = (isFeature: any) => {
const map = gisMaps.current;
if (!map) {
console.warn("지도가 초기화되지 않았습니다.");
return;
}
let result = null;
const layers = map
? map
.getLayers()
.getArray()
.filter((l: any) => l.getVisible())
: []; // gisMap이 null인지 확인 후 레이어 가져오기
let featureLayer: { get: (key: string) => any } = { get: () => null };
layers.forEach((layer: any) => {
const source = layer.getSource();
if (
source &&
source.hasFeature &&
isFeature &&
typeof isFeature.getId === "function" &&
source.hasFeature(isFeature)
) {
featureLayer = layer; // 피처가 속한 레이어 찾기)
}
});
result = featureLayer.get("lyrNm");
return result;
};
const renderDetailView = useCallback(
(props: any) => {
@@ -208,44 +189,38 @@ const Map = () => {
}
const isFeature = props?.featureData;
if( typeof isFeature.getProperties === "function" ){
if (typeof isFeature.getProperties === "function") {
if (
Object.keys(isFeature?.getProperties()).length === 0 &&
isFeature.constructor === Object
!(
Object.keys(isFeature?.getProperties()).length === 0 &&
isFeature.constructor === Object
)
) {
const url = `/mapDetailPopUp?layerNm=${encodeURIComponent(props.seletectedLayerNm)}`;
const width = window.screen.availWidth;
const height = window.screen.availHeight;
const left = 0;
const top = 0;
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=no`;
popupRef.current = window.open(url, "지도 레이어 팝업", popupOptions);
} else {
const layerNm = getSelectedLayers(isFeature);
const safeProps = isFeature.getProperties();
const featureCd = getFeatureCd(safeProps, String(layerNm));
const url = `/mapFeaturePopup?layerNm=${encodeURIComponent(String(layerNm))}&featureCd=${encodeURIComponent(featureCd)} `;
const width =
String(layerNm) === "하수재이용시설"
? Math.floor(window.innerWidth * 0.8)
: Math.floor(window.innerWidth * 0.4); // 화면 폭의 40%
const height =
String(layerNm) === "하수재이용시설"
? Math.floor(window.innerHeight - 150)
: Math.floor(window.innerHeight - 450); // 150px 여백 확보; // calc(100% - 70px)
const left = (window.screen.availWidth - width) / 2;
const top = (window.screen.availHeight - height) / 2;
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`;
popupDetailRef.current = window.open(
url,
"지도 시설 상세정보 팝업",
popupOptions
);
const layerNm = getSelectedLayers(isFeature,gisMaps);
const safeProps = isFeature.getProperties();
const featureCd = getFeatureCd(safeProps, String(layerNm));
// const url = `/mapFeaturePopup?layerNm=${encodeURIComponent(String(layerNm))}&featureCd=${encodeURIComponent(featureCd)} `;
// const width =
// String(layerNm) === "하수재이용시설"
// ? Math.floor(window.innerWidth * 0.8)
// : Math.floor(window.innerWidth * 0.4); // 화면 폭의 40%
// const height =
// String(layerNm) === "하수재이용시설"
// ? Math.floor(window.innerHeight - 150)
// : Math.floor(window.innerHeight - 450); // 150px 여백 확보; // calc(100% - 70px)
// const left = (window.screen.availWidth - width) / 2;
// const top = (window.screen.availHeight - height) / 2;
// const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`;
// popupDetailRef.current = window.open(
// url,
// "지도 시설 상세정보 팝업",
// popupOptions
// );
if(layerNm)
featurePopUpOpen(layerNm,featureCd,popupDetailRef)
}
}else{
console.log(' data확인 필요')
} else {
console.log(" data확인 필요");
}
},
[checkedLayers, checkedLayersData, featureData] // 필요 시 의존성 넣기
@@ -259,9 +234,10 @@ const Map = () => {
}
};
const onOpenPopup = (data:any) => {
if(data){
const onOpenPopup = (data: any) => {
if (data) {
setIsOpen(true);
setFeatureData(null);
const url = `/mapDetailPopUp?layerNm=${encodeURIComponent(data)}`;
const width = window.screen.availWidth;
const height = window.screen.availHeight;
@@ -269,12 +245,10 @@ const Map = () => {
const top = 0;
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=no`;
popupRef.current = window.open(url, "지도 레이어 팝업", popupOptions);
}else{
toast.error('시설 및 수요처가 선택되지 않았습니다.')
} else {
toast.error("시설 및 수요처가 선택되지 않았습니다.");
}
}
};
return (
<div className="bg-container">
@@ -310,12 +284,12 @@ const Map = () => {
/>
}
waterDepth={undefined}
onOpenPopup={(data:any) =>{
onOpenPopup(data)
onOpenPopup={(data: any) => {
onOpenPopup(data);
}}
/>
<Toaster position="top-center" />
</div>
</div>
);
};
@@ -44,6 +44,7 @@ export default function MapDetailPopUp() {
return (
<RswtFacility
rtnFeature={(feature) => {
bc.postMessage({ type: "SELECT_FEATURE", feature });
}}
/>
@@ -45,25 +45,25 @@ export default function MapFeaturePopup() {
useEffect(() => {
if (isFeatureCd && layerNm) {
if (layerNm === "하수재이용시설") {
setIsDetail(isFeatureCd);
} else if (layerNm === "하수처리시설") {
if (layerNm === "tb_wr_bdst_ruse_fclt") {
setIsDetail(isFeatureCd);
} else if (layerNm === "tb_il_swage_prcs_fclt") {
pbnMapDetaile(isFeatureCd, isFeatureCd).then((res) => {
setIsDetail(res);
});
} else if (layerNm === "빗물이용시설") {
} else if (layerNm === "tb_wr_rnwtr_utztn_fclt") {
rainMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
} else if (layerNm === "중수도시설") {
} else if (layerNm === "tb_wr_rswtr_fclt") {
rswtMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
} else if (layerNm === "온배수시설") {
} else if (layerNm === "tb_wr_htdfl_fclt") {
htdfMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
} else if (layerNm === "잠재수요처") {
} else if (layerNm === "tb_wr_tmpr_dmd_co") {
ldrmntMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
@@ -76,9 +76,9 @@ export default function MapFeaturePopup() {
<>
{isDetail ? (
<div className="fixed inset-0 w-screen h-screen m-0 p-0 bg-white">
{layerNm === "하수재이용시설" ? (
{layerNm === "tb_wr_bdst_ruse_fclt" ? (
<RuseDetailPopup bscFctCd={isDetail} />
) : layerNm === "하수처리시설" ? (
) : layerNm === "tb_il_swage_prcs_fclt" ? (
<div style={{ overflowX: "hidden" }}>
<div className="flex justify-between items-center mb-4">
<Title title="하수처리시설 상세정보" />
@@ -103,21 +103,21 @@ export default function MapFeaturePopup() {
onPageChange={() => {}}
/>
</div>
) : layerNm === "잠재수요처" ? (
) : layerNm === "tb_wr_tmpr_dmd_co" ? (
<CoDetailModal
formObj={isDetail}
readonly={false}
onFormSubmit={async (value) => {
console.log(value)
console.log(value);
}}
isMap={true}
/>
) : (
<SttnDetailModal
type={
layerNm === "빗물이용시설"
layerNm === "tb_wr_rnwtr_utztn_fclt"
? "RNB"
: layerNm === "중수도시설"
: layerNm === "tb_wr_rswtr_fclt"
? "RST"
: "HTB"
}
+135 -14
View File
@@ -1,21 +1,142 @@
const wrLayerList = [
{ text: "tb_il_swage_prcs_fclt", val: "bscFctCd" },
{ text: "tb_wr_bdst_ruse_fclt", val: "pbnstRuseFcltId" },
{ text: "tb_wr_rnwtr_utztn_fclt", val: "rainyObj" },
{ text: "tb_wr_rswtr_fclt", val: "rswtrObj" },
{ text: "tb_wr_htdfl_fclt", val: "htdflObj" },
{ text: "tb_wr_ruse_fclt_dmd_co", val: "dmdInfoId" },
{ text: "tb_wr_tmpr_dmd_co", val: "fctryMngSn" },
];
const wrFeaturePK = [
{ text: "bscFctCd", val: "tb_il_swage_prcs_fclt" },
{ text: "pbnstRuseFcltId", val: "tb_wr_bdst_ruse_fclt" },
{ text: "bdstInfoSn", val: "tb_wr_rnwtr_utztn_fclt" },
{ text: "bdstInfoSn", val: "tb_wr_rswtr_fclt" },
{ text: "bdstInfoSn", val: "tb_wr_htdfl_fclt" },
{ text: "dmdInfoId", val: "tb_wr_ruse_fclt_dmd_co" },
{ text: "fctryMngSn", val: "tb_wr_tmpr_dmd_co" },
];
// { 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" },
export const getFeatureCd = (featurePropertise:any, layerNm:string) => {
console.log('layerNm ', layerNm )
console.log('featurePropertise ', featurePropertise )
const featureCd =
layerNm === "하수재이용시설"
export const getFeatureCd = (featurePropertise: any, layerNm: string) => {
const featureCd =
layerNm === "tb_wr_bdst_ruse_fclt"
? featurePropertise?.swtrmt_fclt_cd
: ["빗물이용시설", "중수도시설", "온배수시설", "수요처" ,'잠재수요처'].includes(
layerNm
)
: [
"tb_wr_ruse_fclt_dmd_co",
"tb_wr_rswtr_fclt",
"tb_wr_htdfl_fclt",
"tb_wr_rnwtr_utztn_fclt",
"tb_wr_tmpr_dmd_co",
].includes(layerNm)
? featurePropertise?.bdst_nm
: layerNm === "하수처리시설"
: layerNm === "tb_il_swage_prcs_fclt"
? featurePropertise?.swtrmt_fclt_nm
: null;
console.log('featureCd ', featureCd)
return featureCd;
};
return featureCd;
};
export const getWrLayerNm = (featurePropertise: any) => {
const result = wrLayerList
.filter(item => item.val in featurePropertise) // 키 존재 여부 체크
.map(item => item.text);
return result[0];
};
export const getWrFeaturePk = (layerName :string) => {
const result = wrFeaturePK
.filter(item => item.val === layerName) // 키 존재 여부 체크
.map(item => item.text);
return result[0];
};
export const getSelectedLayers = (isFeature: any, gisMaps:any) => {
const map = gisMaps.current;
if (!map) {
console.warn("지도가 초기화되지 않았습니다.");
return;
}
let result = null;
const layers = map
? map
.getLayers()
.getArray()
.filter((l: any) => l.getVisible())
: []; // gisMap이 null인지 확인 후 레이어 가져오기
let featureLayer: { get: (key: string) => any } = { get: () => null };
layers.forEach((layer: any) => {
const source = layer.getSource();
if (
source &&
source.hasFeature &&
isFeature &&
typeof isFeature.getId === "function" &&
source.hasFeature(isFeature)
) {
featureLayer = layer; // 피처가 속한 레이어 찾기)
}
});
result = featureLayer.get("lyrTyNm");
return result;
};
export const getClickFeatureId = (data: any) => {
let featureId =''
const layerName = data.layerNm;
if (layerName === "하수재이용시설") {
// 재이용시설
featureId = `${layerName}.${data.searchPk}`;
} else if (
//빗물이용시설, 중수도시설
layerName === "빗물이용시설" ||
layerName == "중수도시설"
) {
featureId = `${layerName}.${data.bdstInfoSn}`;
} else if (layerName === "하수처리시설") {
//하수처리시설
featureId = `${layerName}.${data.bscFctCd}`;
} else if (layerName === "온배수시설") {
//온배수시설
featureId = `${layerName}.${data.bdstRuseFcltSn}`;
} else if (layerName == "수요처") {
//수요처
featureId = `${layerName}.${data.dmdInfoId.replaceAll("-", "")}`;
} else {
featureId = `${layerName}.${data.fid || data.id || data.ftrIdn}`;
}
return featureId;
};
export function featurePopUpOpen(layerNm:string,featureCd:string,popupDetailRef){
const url = `/mapFeaturePopup?layerNm=${encodeURIComponent(String(layerNm))}&featureCd=${encodeURIComponent(featureCd)} `;
const width =
String(layerNm) === "tb_wr_bdst_ruse_fclt"
? Math.floor(window.innerWidth * 0.8)
: Math.floor(window.innerWidth * 0.4); // 화면 폭의 40%
const height =
String(layerNm) === "tb_wr_bdst_ruse_fclt"
? Math.floor(window.innerHeight - 150)
: Math.floor(window.innerHeight - 450); // 150px 여백 확보; // calc(100% - 70px)
const left = (window.screen.availWidth - width) / 2;
const top = (window.screen.availHeight - height) / 2;
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`;
popupDetailRef.current = window.open(
url,
"지도 시설 상세정보 팝업",
popupOptions
);
}