wr: 주석 추가

This commit is contained in:
dongsilove
2026-01-03 15:52:41 +09:00
parent 94b640d566
commit 897ce3eb24
2 changed files with 157 additions and 159 deletions
+113 -115
View File
@@ -21,7 +21,7 @@ import WrOverLay from "@/components/ui/map/wrOverLay/wrOverLay";
const Map = () => {
const {code, comMap ,rainMapDetile ,rswtMapDetile,getRuseMaplListReturn,pbnMapDetaile,ldrmntMapDetile,htdfMapDetile,coSttnMapDetail} = useWrStore((state) => state);
const { code, comMap, rainMapDetile, rswtMapDetile, getRuseMaplListReturn, pbnMapDetaile, ldrmntMapDetile, htdfMapDetile, coSttnMapDetail } = useWrStore((state) => state);
const { isFeatured } = comMap;
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
const gisMaps = useRef<any | null>(null);
@@ -93,7 +93,6 @@ const Map = () => {
return;
}
// 항상 같은 select 객체 사용
const select = GisApp.Module.select as any;
if (!select) return;
@@ -109,7 +108,6 @@ const Map = () => {
const layerName = getWrLayerNm(data);
const featurePk = getWrFeaturePk(layerName ?? "");
// 재이용시설
if (featurePk) {
const lastPk =
@@ -254,139 +252,139 @@ const Map = () => {
const OVERLAY_MIN_ZOOM = 16;
const OVERLAY_COORD_PRECISION = 5;
const OVERLAY_MAX_PER_VIEW = 800;
const OVERLAY_COORD_PRECISION = 5;
const OVERLAY_MAX_PER_VIEW = 800;
const overlayManagersRef = useRef<any[]>([]);
const overlayActiveRef = useRef(false);
const moveEndDebounceRef = useRef<number | null>(null);
const overlayManagersRef = useRef<any[]>([]);
const overlayActiveRef = useRef(false);
const moveEndDebounceRef = useRef<number | null>(null);
// 반환: Promise<HTMLDivElement | null>
const overlayFormatter = async (feature: any, props: any) => {
const p = props || {};
const featureId =
feature.getId?.() ?? p?.id ?? p?.fid ?? p?.ftrIdn ?? '';
if (!featureId) return null;
// 반환: Promise<HTMLDivElement | null>
const overlayFormatter = async (feature: any, props: any) => {
const p = props || {};
const featureId =
feature.getId?.() ?? p?.id ?? p?.fid ?? p?.ftrIdn ?? '';
if (!featureId) return null;
const tableId = String(featureId).split('.')[0]??'';
const fcltCd = getFeatureCd(props, tableId);
const tableId = String(featureId).split('.')[0] ?? '';
const fcltCd = getFeatureCd(props, tableId);
if (!fcltCd) return null;
if (!fcltCd) return null;
let data: any = null;
let title = '';
let data: any = null;
let title = '';
if (tableId === 'tb_il_swage_prcs_fclt') { data = await pbnMapDetaile(fcltCd); title = '하수처리시설'; }
else if (tableId === 'tb_wr_bdst_ruse_fclt') { data = await getRuseMaplListReturn(fcltCd); title = '하수재이용시설'; }
else if (tableId === 'tb_wr_rnwtr_utztn_fclt'){ data = await rainMapDetile(fcltCd); title = '빗물이용시설'; }
else if (tableId === 'tb_wr_rswtr_fclt') { data = await rswtMapDetile(fcltCd); title = '중수도시설'; }
else if (tableId === 'tb_wr_htdfl_fclt') { data = await htdfMapDetile(fcltCd); title = '온배수시설'; }
else if (tableId === 'tb_wr_ruse_fclt_dmd_co'){ data = await coSttnMapDetail(fcltCd); title = '수요처'; }
else if (tableId === 'tb_wr_tmpr_dmd_co') { data = await ldrmntMapDetile(fcltCd); title = '잠재수요처'; }
if (tableId === 'tb_il_swage_prcs_fclt') { data = await pbnMapDetaile(fcltCd); title = '하수처리시설'; }
else if (tableId === 'tb_wr_bdst_ruse_fclt') { data = await getRuseMaplListReturn(fcltCd); title = '하수재이용시설'; }
else if (tableId === 'tb_wr_rnwtr_utztn_fclt') { data = await rainMapDetile(fcltCd); title = '빗물이용시설'; }
else if (tableId === 'tb_wr_rswtr_fclt') { data = await rswtMapDetile(fcltCd); title = '중수도시설'; }
else if (tableId === 'tb_wr_htdfl_fclt') { data = await htdfMapDetile(fcltCd); title = '온배수시설'; }
else if (tableId === 'tb_wr_ruse_fclt_dmd_co') { data = await coSttnMapDetail(fcltCd); title = '수요처'; }
else if (tableId === 'tb_wr_tmpr_dmd_co') { data = await ldrmntMapDetile(fcltCd); title = '잠재수요처'; }
const empty =
data == null ||
(Array.isArray(data) && data.length === 0) ||
(typeof data === 'object' && !Array.isArray(data) && Object.keys(data).length === 0);
const empty =
data == null ||
(Array.isArray(data) && data.length === 0) ||
(typeof data === 'object' && !Array.isArray(data) && Object.keys(data).length === 0);
if (empty) return null;
if (empty) return null;
const div = document.createElement('div');
const root = createRoot(div);
(div as any).__dispose = () => { try { root.unmount(); } catch {} };
root.render(<WrOverLay title={title} data={data} code={code} />);
return div; // ← 데이터 있을 때만 HTMLElement 반환
};
const destroyAllManagers = () => {
overlayManagersRef.current.forEach(m => { try { m.destroy(); } catch {} });
overlayManagersRef.current = [];
overlayActiveRef.current = false;
};
const div = document.createElement('div');
const root = createRoot(div);
(div as any).__dispose = () => { try { root.unmount(); } catch { } };
root.render(<WrOverLay title={title} data={data} code={code} />);
return div; // ← 데이터 있을 때만 HTMLElement 반환
};
const destroyAllManagers = () => {
overlayManagersRef.current.forEach(m => { try { m.destroy(); } catch { } });
overlayManagersRef.current = [];
overlayActiveRef.current = false;
};
const mountOverlayManagers = () => {
const map = gisMaps.current;
if (!map) return;
const mountOverlayManagers = () => {
const map = gisMaps.current;
if (!map) return;
// 이전 것 정리
destroyAllManagers();
// 이전 것 정리
destroyAllManagers();
// 체크된 벡터 레이어만 골라 매니저 생성
const checkedSet = new Set(checkedLayers.map(String));
const layers: any[] = map.getLayers().getArray();
const targets = layers.filter((layer: any) => {
const src = layer.getSource?.();
const isVector = src && typeof src.getFeatures === "function";
const id = String(layer.get?.("lyrSn") ?? layer.get?.("id") ?? "");
return isVector && layer.getVisible?.() && checkedSet.has(id);
});
targets.forEach((layer: any) => {
const mgr = createOverlayManager(map, layer, overlayFormatter, {
coordPrecision: OVERLAY_COORD_PRECISION,
maxOverlaysPerViewport: OVERLAY_MAX_PER_VIEW,
// 체크된 벡터 레이어만 골라 매니저 생성
const checkedSet = new Set(checkedLayers.map(String));
const layers: any[] = map.getLayers().getArray();
const targets = layers.filter((layer: any) => {
const src = layer.getSource?.();
const isVector = src && typeof src.getFeatures === "function";
const id = String(layer.get?.("lyrSn") ?? layer.get?.("id") ?? "");
return isVector && layer.getVisible?.() && checkedSet.has(id);
});
mgr.mount(); // 리스너 1회 등록
mgr.enable(); // 표시 + 1회 sync
overlayManagersRef.current.push(mgr);
});
overlayActiveRef.current = overlayManagersRef.current.length > 0;
};
targets.forEach((layer: any) => {
const mgr = createOverlayManager(map, layer, overlayFormatter, {
coordPrecision: OVERLAY_COORD_PRECISION,
maxOverlaysPerViewport: OVERLAY_MAX_PER_VIEW,
});
mgr.mount(); // 리스너 1회 등록
mgr.enable(); // 표시 + 1회 sync
overlayManagersRef.current.push(mgr);
});
useEffect(() => {
const map = gisMaps.current;
if (!map) return;
const z = map.getView()?.getZoom?.() ?? 0;
if (z < OVERLAY_MIN_ZOOM) {
// 저줌에선 그냥 안 보이게만
overlayManagersRef.current.forEach(m => { try { m.disable({ clear:true, delayed:true }); } catch {} });
return;
}
mountOverlayManagers();
return () => { destroyAllManagers(); };
}, [checkedLayers]);
useEffect(() => {
const map = gisMaps.current;
if (!map) return;
const onMoveStart = () => {
// 숨기기만 (리스너/DOM 대량 제거 X)
overlayManagersRef.current.forEach(m => { try { m.disable({ clear:false }); } catch {} });
if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; }
overlayActiveRef.current = overlayManagersRef.current.length > 0;
};
const onMoveEnd = () => {
useEffect(() => {
const map = gisMaps.current;
if (!map) return;
const z = map.getView()?.getZoom?.() ?? 0;
const active = overlayActiveRef.current;
if (z < OVERLAY_MIN_ZOOM) {
// 저줌에선 그냥 안 보이게만
overlayManagersRef.current.forEach(m => { try { m.disable({ clear: true, delayed: true }); } catch { } });
return;
}
mountOverlayManagers();
if (moveEndDebounceRef.current) clearTimeout(moveEndDebounceRef.current);
moveEndDebounceRef.current = window.setTimeout(() => {
if (z < OVERLAY_MIN_ZOOM) {
if (active) overlayManagersRef.current.forEach(m => { try { m.disable({ clear:true, delayed:true }); } catch {} });
return;
}
if (!active) {
mountOverlayManagers();
} else {
// 다시 보이고 1회만 동기화
overlayManagersRef.current.forEach(m => { try { m.enable(); m.syncOverlays(); } catch {} });
}
}, 180) as unknown as number;
};
return () => { destroyAllManagers(); };
}, [checkedLayers]);
map.on("movestart", onMoveStart);
map.on("moveend", onMoveEnd);
return () => {
map.un("movestart", onMoveStart);
map.un("moveend", onMoveEnd);
if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; }
};
}, [checkedLayers]);
useEffect(() => {
const map = gisMaps.current;
if (!map) return;
const onMoveStart = () => {
// 숨기기만 (리스너/DOM 대량 제거 X)
overlayManagersRef.current.forEach(m => { try { m.disable({ clear: false }); } catch { } });
if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; }
};
const onMoveEnd = () => {
const z = map.getView()?.getZoom?.() ?? 0;
const active = overlayActiveRef.current;
if (moveEndDebounceRef.current) clearTimeout(moveEndDebounceRef.current);
moveEndDebounceRef.current = window.setTimeout(() => {
if (z < OVERLAY_MIN_ZOOM) {
if (active) overlayManagersRef.current.forEach(m => { try { m.disable({ clear: true, delayed: true }); } catch { } });
return;
}
if (!active) {
mountOverlayManagers();
} else {
// 다시 보이고 1회만 동기화
overlayManagersRef.current.forEach(m => { try { m.enable(); m.syncOverlays(); } catch { } });
}
}, 180) as unknown as number;
};
map.on("movestart", onMoveStart);
map.on("moveend", onMoveEnd);
return () => {
map.un("movestart", onMoveStart);
map.un("moveend", onMoveEnd);
if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; }
};
}, [checkedLayers]);
return (
<div className="bg-container">
<Gis
+44 -44
View File
@@ -1,22 +1,22 @@
import { formatCommaNumber, formatPhoneNumber } from "./commom";
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" },
{ 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: "searchPk", 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: "bscFctCd", val: "tb_il_swage_prcs_fclt" }, //하수처리시설
{ text: "searchPk", 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" },
@@ -29,18 +29,18 @@ const wrFeaturePK = [
export const getFeatureCd = (featurePropertise: any, layerNm: string) => {
const featureCd =
layerNm === "tb_wr_bdst_ruse_fclt"
layerNm === "tb_wr_bdst_ruse_fclt" //하수재이용시설
? featurePropertise?.swtrmt_fclt_cd
: [
"tb_wr_rswtr_fclt",
"tb_wr_htdfl_fclt",
"tb_wr_rnwtr_utztn_fclt",
"tb_wr_tmpr_dmd_co",
].includes(layerNm)
"tb_wr_rswtr_fclt", // 중수도시설
"tb_wr_htdfl_fclt", // 온배수시설
"tb_wr_rnwtr_utztn_fclt", // 빗물이용시설
"tb_wr_tmpr_dmd_co", // 잠재수요처
].includes(layerNm)
? featurePropertise?.bdst_nm
: layerNm === "tb_il_swage_prcs_fclt"
: layerNm === "tb_il_swage_prcs_fclt" //하수처리시설
? featurePropertise?.swtrmt_fclt_cd
: layerNm === "tb_wr_ruse_fclt_dmd_co"
: layerNm === "tb_wr_ruse_fclt_dmd_co" //수요처
? featurePropertise?.bdst_info_sn
: null;
@@ -71,9 +71,9 @@ export const getSelectedLayers = (isFeature: any, gisMaps: any) => {
let result = null;
const layers = map
? map
.getLayers()
.getArray()
.filter((l: any) => l.getVisible())
.getLayers()
.getArray()
.filter((l: any) => l.getVisible())
: []; // gisMap이 null인지 확인 후 레이어 가져오기
let featureLayer: { get: (key: string) => any } = { get: () => null };
@@ -119,12 +119,12 @@ export const getClickFeatureId = (data: any) => {
} else if (layerName == "수요처") {
//수요처
featureId = `${layerName}.${data.dmdInfoId.replaceAll("-", "")}`;
}else if (layerName == "잠재수요처") {
} else if (layerName == "잠재수요처") {
//잠재수요처
featureId = data.id_
} else {
} else {
featureId = data.id_
}
@@ -160,7 +160,7 @@ export function featurePopUpOpen(
);
}
export const getOverLayObj = (fclType: string, data: any,code?:any) => {
export const getOverLayObj = (fclType: string, data: any, code?: any) => {
let newObj = {};
let title = "";
@@ -169,11 +169,11 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => {
if (fclType === "하수재이용시설") {
newObj = {
"시설용량(톤/일)": formatCommaNumber(data?.fcltCpct) ??'확인불가',
"재이용률(%)": (data?.fcltCpct / data?.bscFctCpc)||0,
"시설용량(톤/일)": formatCommaNumber(data?.fcltCpct) ?? '확인불가',
"재이용률(%)": (data?.fcltCpct / data?.bscFctCpc) || 0,
"장내용수(m³/년)": formatCommaNumber(data?.inUsage) ?? '확인불가',
"장외용수(m3/년)":formatCommaNumber(data?.outUsage) ?? '확인불가',
// 수요처: data?.reuseBuilding[0]?.rainyObj.pntfColArea ?? '확인불가',
"장외용수(m3/년)": formatCommaNumber(data?.outUsage) ?? '확인불가',
// 수요처: data?.reuseBuilding[0]?.rainyObj.pntfColArea ?? '확인불가',
};
title = data?.bdstNm ?? '확인불가';
} else if (fclType === "하수처리시설") {
@@ -184,9 +184,9 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => {
"재이용시설 등록여부": data?.ruse ?? '확인불가',
};
title = data?.bscFctNm ?? '확인불가';
} else if (fclType === "빗물이용시설" ) {
} else if (fclType === "빗물이용시설") {
newObj = {
건물용도: code?.bdstUsgCd.find((item) => item.val=== String(data?.reuseBuilding[0].bdstUsgCd) )?.text ?? '확인불가',
건물용도: code?.bdstUsgCd.find((item) => item.val === String(data?.reuseBuilding[0].bdstUsgCd))?.text ?? '확인불가',
설치완료일: data?.reuseBuilding[0]?.instlCmptnDt ?? '확인불가',
처리시설유무: data?.reuseBuilding[0]?.rainyObj.filtrTrtmfctYn ?? '확인불가',
"처리시설용량(m³/일)": formatCommaNumber(data?.reuseBuilding[0]?.rainyObj.filtrTrtmfctCpct) ?? '확인불가',
@@ -195,25 +195,25 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => {
title = data?.bdstNm ?? '확인불가';
} else if (fclType === "중수도시설") {
newObj = {
건물용도: code?.bdstUsgCd.find((item) => item.val===String(data?.reuseBuilding[0].bdstUsgCd) )?.text ?? '확인불가',
건물용도: code?.bdstUsgCd.find((item) => item.val === String(data?.reuseBuilding[0].bdstUsgCd))?.text ?? '확인불가',
설치완료일: data?.reuseBuilding[0]?.instlCmptnDt ?? '확인불가',
"주요 처리공정": data?.reuseBuilding[0]?.rswtrObj.filtrTrtmfctProcs ?? '확인불가',
원수종류: code?.orgwtKndCd.find((item) => item.val === data?.reuseBuilding[0]?.rswtrObj.orgwtKndCd)?.text ?? '확인불가',
"주요 처리공정": data?.reuseBuilding[0]?.rswtrObj.filtrTrtmfctProcs ?? '확인불가',
원수종류: code?.orgwtKndCd.find((item) => item.val === data?.reuseBuilding[0]?.rswtrObj.orgwtKndCd)?.text ?? '확인불가',
//이용용도: isCode.filtrTrtmfctUsgCd data?.reuseBuilding[0]?.rswtrObj.altUswtrKndCd ?? '확인불가',
};
title = data?.bdstNm ?? '확인불가';
} else if (fclType === "온배수시설") {
newObj = {
'발전유형': data?.reuseBuilding[0]?.htdflObj.etgtType??'',
'설비용량': data?.reuseBuilding[0]?.htdflObj.fclCpct??'',
'담수화 여부': data?.reuseBuilding[0]?.htdflObj.plwtYn??'',
'발전유형': data?.reuseBuilding[0]?.htdflObj.etgtType ?? '',
'설비용량': data?.reuseBuilding[0]?.htdflObj.fclCpct ?? '',
'담수화 여부': data?.reuseBuilding[0]?.htdflObj.plwtYn ?? '',
};
title = data?.bdstNm ?? '확인불가';
} else if (fclType === "수요처") {
newObj = {
'사업자등록번호': data?.dmdInfoId??'',
'주소': data?.daddr??'',
'전화번호': formatPhoneNumber(data?.telno)??'',
'사업자등록번호': data?.dmdInfoId ?? '',
'주소': data?.daddr ?? '',
'전화번호': formatPhoneNumber(data?.telno) ?? '',
};
title = data?.dmdCoNm ?? '확인불가';