From 60bdca20c8fbcec7aeace874d71395381badb523 Mon Sep 17 00:00:00 2001 From: sanguu516 Date: Wed, 3 Apr 2024 10:08:53 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B9=84=ED=96=89=20=EC=8A=B9=EC=9D=B8=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20=EB=AA=A9=EB=A1=9D=20=EB=B9=84=ED=96=89=20?= =?UTF-8?q?=EA=B5=AC=EC=97=AD=20=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 --- src/components/laanc/list/LaancGrid.js | 1 + .../flight/flightApprovalsContainer.js | 111 ++++++++++-------- src/utility/MapUtils.js | 77 +++++++++++- 3 files changed, 134 insertions(+), 55 deletions(-) diff --git a/src/components/laanc/list/LaancGrid.js b/src/components/laanc/list/LaancGrid.js index 3086880c..986df1ea 100644 --- a/src/components/laanc/list/LaancGrid.js +++ b/src/components/laanc/list/LaancGrid.js @@ -27,6 +27,7 @@ export default function LaancGrid({ isSearch }) { const { laancSearchData } = useSelector(state => state.laancState); const { laancDetail } = useSelector(state => state.laancState); + console.log('>>>', laancDetail); // 로딩 상태 const { loading } = useSelector(state => state.layoutState); diff --git a/src/containers/flight/flightApprovalsContainer.js b/src/containers/flight/flightApprovalsContainer.js index a979a591..7942099e 100644 --- a/src/containers/flight/flightApprovalsContainer.js +++ b/src/containers/flight/flightApprovalsContainer.js @@ -1,36 +1,28 @@ import { useEffect, useRef, useState, lazy, Suspense } from 'react'; import { useDispatch, useSelector } from '@src/redux/store'; -import { Card } from '@component/ui'; import { Map } from 'react-feather'; -import FlightApprovalsInfo from '../../components/flight/FlightApprovalsInfo'; import FlightApprovalsReport from '../../components/flight/FlightApprovalsReport'; -import MapboxDraw from '@mapbox/mapbox-gl-draw'; import { - CircleMode, - DragCircleMode, - DirectMode, - SimpleSelectMode -} from 'mapbox-gl-draw-circle'; -import MapboxLanguage from '@mapbox/mapbox-gl-language'; -import threebox from 'threebox-plugin'; -import mapboxgl from 'mapbox-gl'; -import { MAPBOX_TOKEN } from '../../configs/constants'; -import { getLaancDetail } from '@src/redux/features/laanc/laancThunk'; + getLaancDetail, + AreaBufferList +} from '@src/redux/features/laanc/laancThunk'; import { InitFeature, handlerCreatePoint, handlerFitBounds, handlerGetCircleCoord, - layerPolyline, - layerPolygon, - layerBuffer, - layerWayPoint + flightlayerWayPoint, + flightlayerPolyline, + flightlayerPolygon, + flightlayerBuffer } from '../../utility/MapUtils'; +import { clientSaveAreaCoordinateList } from '@src/redux/features/laanc/laancSlice'; import { MapControl } from '../../components/map/MapControl'; import { clientSetIsMapLoading } from '@src/redux/features/laanc/laancSlice'; // redux import { clientMapInit } from '@src/redux/features/control/map/mapSlice'; import FlightApprovalsTable from '@src/components/flight/FlightApprovalsTable'; +import { CgKey } from 'react-icons/cg'; export default function FlightApprovalsContainer() { const dispatch = useDispatch(); @@ -171,15 +163,19 @@ export default function FlightApprovalsContainer() { const [selected, setSelected] = useState(null); const [isMapLoading, setIsMapLoading] = useState(false); // 비행구역 그리기 - const [drawObj, setDrawObj] = useState(); const [filter, setFilter] = useState(''); // 지도 const [mapObject, setMapObject] = useState(); - const [areaCoordList, setAreaCoordList] = useState([]); + const { areaCoordList, isOpenModal } = useSelector(state => state.laancState); + // 미니맵 레이어 + const [previewLayer, setPreviewLayer] = useState(); + + const { laancDetail } = useSelector(state => state.laancState); const map = useSelector(state => state.mapState.map); + const previewGeo2 = { type: 'FeatureCollection', features: [] @@ -195,21 +191,19 @@ export default function FlightApprovalsContainer() { const handlerSearch = search => { setFilter(search); - - // setParams({ ...params, search1 }); - // dispatch( - // getSmltList({ - // searchParams: { ...params, search1 }, - // page: 1 - // }) - // ); }; - const handlerDetail = async id => { + const handlerDetail = id => { setSelected(id); - const res = await dispatch(getLaancDetail(id)); - setAreaCoordList(res.payload.areaList); + dispatch(getLaancDetail(id)); + handlerMapInit(); + // setAreaCoordList(res.payload.areaList); + // if (areaCoordList.areaType === 'LINE') { + // const val = await dispatch(AreaBufferList(areaCoordList)); + // setAreaBufferList(val.payload[0].bufferCoordList); + // } + // if (areaCoordList.length > 0) handlerMapInit(); }; useEffect(() => { if (map) { @@ -218,34 +212,42 @@ export default function FlightApprovalsContainer() { }, [map]); useEffect(() => { - if (mapObject) { - console.log('>>>', mapObject.getSource('preview')); + if (laancDetail.planSno) { + dispatch(AreaBufferList(laancDetail?.areaList)); + dispatch(clientSaveAreaCoordinateList(laancDetail?.areaList)); } - }, [mapObject]); + }, [laancDetail]); + + useEffect(async () => { + if (areaCoordList.length === 0) return; + }, [areaCoordList]); const handlerMapInit = () => { - mapObject.on('style.load', () => { - mapObject.addSource('preview', { + if (map.getSource('preview')) { + map.removeSource('preview'); + } else { + map.addSource('preview', { type: 'geojson', data: previewGeo2 }); - mapObject.addLayer(layerPolyline('preview')); - mapObject.addLayer(layerPolygon('preview')); - mapObject.addLayer(layerBuffer('preview')); - mapObject.addLayer(layerWayPoint('preview')); + map.addLayer(flightlayerWayPoint('preview')); + map.addLayer(flightlayerBuffer('preview')); + map.addLayer(flightlayerPolygon('preview')); + map.addLayer(flightlayerPolyline('preview')); + } - setDrawObj(draw); - map.dragRotate.disable(); + dispatch(clientSetIsMapLoading(true)); + const preview = map.getSource('preview'); - dispatch(clientSetIsMapLoading(true)); + if (preview) setPreviewLayer(preview); - setIsMapLoading(true); - setMapObject(map); - dispatch(clientMapInit(map)); - }); + setIsMapLoading(true); + + setMapObject(map); + dispatch(clientMapInit(map)); }; const handlerPreviewDraw = () => { - if (areaCoordList) { + if (areaCoordList.length > 0) { const areas = areaCoordList[0]; const paths = []; areas.coordList.forEach(coord => paths.push([coord.lon, coord.lat])); @@ -253,7 +255,6 @@ export default function FlightApprovalsContainer() { previewGeo2.features = []; let fitZoomPaths = []; - if (areas.areaType) { if (areas.areaType === 'CIRCLE') { const radius = areas.bufferZone; @@ -286,11 +287,11 @@ export default function FlightApprovalsContainer() { ); bufferPolyline.geometry.coordinates = bufferPaths; - previewGeo2features.push(bufferPolyline); + previewGeo2.features.push(bufferPolyline); } } else if (areas.areaType === 'POLYGON') { polygon.geometry.coordinates = [paths]; - previewGeo2features.push(polygon); + previewGeo2.features.push(polygon); } // 포인트 생성 paths.forEach((p, i) => { @@ -305,10 +306,16 @@ export default function FlightApprovalsContainer() { //지도 줌 좌표 설정 fitZoomPaths = paths.concat(); } + console.log('>>>', fitZoomPaths); - handlerFitBounds(mapObject, fitZoomPaths, 50, areas.areaType); + handlerFitBounds( + mapObject, + fitZoomPaths, + 450, + areas.areaType, + 'flight' + ); - console.log('>>>', map.getSource('preview')); mapObject.setPaintProperty('waypoint', 'circle-radius', 10); mapObject.getSource('preview').setData(previewGeo2); } diff --git a/src/utility/MapUtils.js b/src/utility/MapUtils.js index 5381bf1d..a88f807f 100644 --- a/src/utility/MapUtils.js +++ b/src/utility/MapUtils.js @@ -142,8 +142,9 @@ export const handlerCreatePoint = (coord, index, type) => { * @param {*} paths obj의 좌표 * @param {number} padding 도형과 지도 사이의 padding값 * @param {string} type custom 타입 + * @param [string} page 페이지에 따른 분기 처리 */ -export const handlerFitBounds = (map, paths, padding, type) => { +export const handlerFitBounds = (map, paths, padding, type, page) => { const bounds = new mapboxgl.LngLatBounds(paths[0], paths[0]); if (type !== 'CIRCLE') { @@ -155,8 +156,11 @@ export const handlerFitBounds = (map, paths, padding, type) => { bounds.extend(paths[i]); } } - - map.fitBounds(bounds, { padding: padding }); + if (page === 'flight') { + map.fitBounds(bounds, { padding: padding, offset: { x: -200, y: 0 } }); + } else { + map.fitBounds(bounds, { padding: padding }); + } }; /** @@ -382,3 +386,70 @@ export const getDrawFeatures = drawObj => { return viewCoordObj; }; + +// 드론 승인 결과 페이지 - draw 레이어 +export const flightlayerWayPoint = source => { + return { + id: 'waypoint-flight', + type: 'circle', + source: source, + paint: { + 'circle-radius': 5, + 'circle-color': '#ffffff', + 'circle-stroke-color': '#000000', + 'circle-stroke-width': 1 + }, + filter: ['in', '$type', 'Point'] + }; +}; + +export const flightlayerPolyline = source => { + return { + id: 'polyline-flight', + type: 'line', + source: source, + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#283046', + 'line-width': 2 + }, + filter: ['in', ['get', 'id'], ['literal', ['LINE', 'outline']]] + }; +}; + +export const flightlayerPolygon = source => { + return { + id: 'polygon-flight', + type: 'fill', + source: source, + layout: {}, + paint: { + 'fill-color': '#8a1c05', + 'fill-opacity': 0.5, + 'fill-outline-color': '#000000' + }, + //polygon, circle에 사용 + filter: ['in', '$type', 'Polygon'] + }; +}; + +export const flightlayerBuffer = source => { + return { + id: 'buffer-flight', + type: 'line', + source: source, + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#283046', + 'line-width': 1, + 'line-dasharray': [5, 5] + }, + filter: ['==', ['get', 'id'], 'buffer'] + }; +};