From 7f07a82a2f3b14cd99274ae4d630ee68e95316ae Mon Sep 17 00:00:00 2001 From: JANGHYUNn Date: Mon, 22 Jul 2024 13:53:47 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B4=80=EC=A0=9C=EA=B3=BC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B1=B0=EB=A6=AC=EC=B8=A1=EC=A0=95=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flight/ControlApprovalsContainer.js | 232 +++++++++++++++++- 1 file changed, 221 insertions(+), 11 deletions(-) diff --git a/src/containers/flight/ControlApprovalsContainer.js b/src/containers/flight/ControlApprovalsContainer.js index 2b2ffed9..dfff6e68 100644 --- a/src/containers/flight/ControlApprovalsContainer.js +++ b/src/containers/flight/ControlApprovalsContainer.js @@ -8,11 +8,17 @@ import { flightlayerWayPoint, flightlayerPolyline, flightlayerPolygon, - flightlayerBuffer + flightlayerBuffer, + handlerStartMode, + handlerDrawEvents, + getDintancePointPopupList } from '../../utility/MapUtils'; import { useHistory } from 'react-router-dom'; import useMapType from '@hooks/useMapType'; -import { clientSaveAreaCoordinateList } from '@src/redux/features/laanc/laancSlice'; +import { + clientSaveAreaCoordinateList, + clientChangeDrawType +} from '@src/redux/features/laanc/laancSlice'; import { MapControl } from '../../components/map/MapControl'; import { clientSetIsMapLoading } from '@src/redux/features/laanc/laancSlice'; import { clientMapInit } from '@src/redux/features/control/map/mapSlice'; @@ -28,6 +34,8 @@ import { FiRotateCw, FiCornerUpLeft } from 'react-icons/fi'; import { X } from 'react-feather'; import mapboxgl from 'mapbox-gl'; +let distanceMarkers = []; + export default function ControlApprovalsContainer({ mode }) { const dispatch = useDispatch(); const history = useHistory(); @@ -41,7 +49,7 @@ export default function ControlApprovalsContainer({ mode }) { // 지도 const [mapObject, setMapObject] = useState(); const [setMapType] = useMapType(); - const { areaCoordList, isOpenModal } = useSelector(state => state.laancState); + const { areaCoordList, drawType } = useSelector(state => state.laancState); const [startDate, setStartDate] = useState(dayjs().format('YYYY-MM-DD')); const [endDate, setEndDate] = useState(dayjs().format('YYYY-MM-DD')); @@ -68,6 +76,14 @@ export default function ControlApprovalsContainer({ mode }) { // 비행구역 데이터블록 const [dataBlocks, setDataBlocks] = useState([]); + // 거리측정 + const [isDistanceRevert, setIsDistanceRevert] = useState(true); + const [isResetDisabled, setIsResetDisabled] = useState(true); + const totalDistanceRef = useRef(null); + const totalAreaRef = useRef(null); + const mouseCursorRef = useRef(null); + const distanceBoxRef = useRef(null); + // 비행구역 (관제과) 레이어 const controlLayer = { type: 'FeatureCollection', @@ -375,6 +391,155 @@ export default function ControlApprovalsContainer({ mode }) { } }; + const handlerDrawTypeChange = (e, val) => { + drawObj.deleteAll(); + distanceMarkers.map(i => i.remove()); + setIsResetDisabled(true); + distanceBoxRef.current.style.display = 'block'; + totalDistanceRef.current.innerText = ''; + totalAreaRef.current.innerText = ''; + dispatch(clientChangeDrawType(val)); + handlerStartMode(val, drawObj); + }; + + const handlerDrawObjInit = (obj, mapInstance) => { + setDrawObj(obj); + + handlerDrawEvents( + mapInstance, + handlerDrawPopup, + handlerDrawEnd, + { + totalDistanceRef, + mouseCursorRef, + totalAreaRef + }, + obj + ); + }; + + const handlerMapTypeChange = val => { + handlerDistanceClose(); + setMapType(val); + }; + + const handlerDistanceClose = () => { + drawObj.deleteAll(); + distanceMarkers.map(i => i.remove()); + dispatch(clientChangeDrawType('simple_select')); + drawObj.changeMode('simple_select'); + totalDistanceRef.current.innerText = ''; + mouseCursorRef.current.style.display = 'none'; + distanceBoxRef.current.style.display = 'none'; + }; + + const handlerDrawReset = () => { + drawObj.deleteAll(); + distanceMarkers.map(i => i.remove()); + if (drawType === 'LINE') { + drawObj.changeMode('draw_line_string'); + } else { + drawObj.changeMode('draw_polygon'); + totalAreaRef.current.style.display = 'none'; + } + + totalDistanceRef.current.style.display = 'none'; + setIsResetDisabled(true); + }; + + const handlerDrawEnd = featuresLength => { + if (!featuresLength) { + dispatch(clientChangeDrawType('simple_select')); + totalDistanceRef.current.innerText = ''; + mouseCursorRef.current.style.display = 'none'; + distanceBoxRef.current.style.display = 'none'; + } else { + setIsResetDisabled(false); + } + }; + + const handlerDistanceRevert = () => { + if (drawObj.getMode() === 'draw_line_string') { + const allFeatures = drawObj.getAll(); + if (allFeatures.features.length > 0) { + drawObj.deleteAll(); + const coords = allFeatures.features[0].geometry.coordinates; + + // 새로운 배열로 마지막 두 개의 값을 제거 + if (coords.length > 1) { + // 최소한 두 개의 좌표가 있어야 함 + const newCoords = coords.slice(0, -2); // 마지막 두 개의 값을 제거 + + newCoords.push(newCoords[newCoords.length - 1]); // 마지막 값을 다시 추가 + + // 중복 배열 제거 + const uniqueArray = Array.from( + new Set(newCoords.map(JSON.stringify)) + ).map(JSON.parse); + + if (uniqueArray.length === 1) { + uniqueArray.push(uniqueArray[uniqueArray.length - 1]); + } + + drawObj.set({ + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: {}, + id: 'pal_line_string', + geometry: { type: 'LineString', coordinates: [...uniqueArray] } + } + ] + }); + const markerList = getDintancePointPopupList(drawObj); + handlerDrawPopup(mapObject, markerList, drawObj); + // 다시 이어그리기 + let feature = drawObj.getAll().features[0]; + drawObj.changeMode('draw_line_string', { + featureId: 'pal_line_string', + from: feature.geometry.coordinates[ + feature.geometry.coordinates.length - 1 + ] + }); + } + } + } + }; + + const handlerDrawPopup = (mapInstance, popupList, draw = undefined) => { + if (distanceMarkers.length > 0) { + distanceMarkers.map(i => i.remove()); + } + if (popupList.length > 0) { + popupList.map(i => { + let distanceMarker = new mapboxgl.Popup({ + closeButton: false, + closeOnClick: false, + offset: { + bottom: [0, -10] + }, + focusAfterOpen: false + }) + .setLngLat([i.coord[0][0].toFixed(6), i.coord[0][1].toFixed(6)]) + .setHTML( + `
${i.text}
` + ) + .addTo(mapInstance); + + distanceMarkers.push(distanceMarker); + }); + } + + if (draw.getMode() === 'simple_select') { + setIsDistanceRevert(true); + } else { + if (draw.getMode() === 'draw_line_string') { + setIsDistanceRevert(false); + } + } + }; + const handlerLogout = async () => { const { payload } = await dispatch(setLogout()); @@ -383,10 +548,6 @@ export default function ControlApprovalsContainer({ mode }) { } }; - const handlerDrawObjInit = obj => { - setDrawObj(obj); - }; - return ( <>
@@ -422,12 +583,30 @@ export default function ControlApprovalsContainer({ mode }) {

거리측정

- - + +
-
+

측정

@@ -435,13 +614,18 @@ export default function ControlApprovalsContainer({ mode }) { className='btn-icon rounded-circle' color='primary' size='sm' + disabled={isResetDisabled} + onClick={handlerDrawReset} > @@ -449,6 +633,7 @@ export default function ControlApprovalsContainer({ mode }) { className='btn-icon rounded-circle' color='dark' size='sm' + onClick={handlerDistanceClose} > @@ -456,7 +641,20 @@ export default function ControlApprovalsContainer({ mode }) {

지도에서 지점을 클릭하여 거리를 측정하세요. - 총 거리 : 1050.24m + + 총 거리 : 1050.24m + + + 총 거리 : 1050.24m +

@@ -512,6 +710,18 @@ export default function ControlApprovalsContainer({ mode }) {
)} +
); }