diff --git a/src/components/basis/flight/plan/FlightPlanAreaMapBox.js b/src/components/basis/flight/plan/FlightPlanAreaMapBox.js index 6f33087..bb0095b 100644 --- a/src/components/basis/flight/plan/FlightPlanAreaMapBox.js +++ b/src/components/basis/flight/plan/FlightPlanAreaMapBox.js @@ -3,12 +3,11 @@ import 'mapbox-gl/dist/mapbox-gl.css'; import mapboxgl from 'mapbox-gl'; import MapboxLanguage from '@mapbox/mapbox-gl-language'; import { MAPBOX_TOKEN } from '../../../../configs/constants'; -import * as turf from '@turf/turf'; -import proj4 from 'proj4/dist/proj4'; import { Card, CardBody, Button, + ButtonGroup, Input, InputGroup, InputGroupAddon, @@ -20,12 +19,17 @@ import { } from 'reactstrap'; import { useDispatch, useSelector } from 'react-redux'; import { initFlightBas } from '../../../../modules/basis/flight/models/basisFlightModel'; -import { AREA_DETAIL_INIT } from '../../../../modules/basis/flight/actions/basisFlightAction'; +import { + AREA_COORDINATE_LIST_SAVE, + AREA_DETAIL_INIT, + FLIGHT_PLAN_AREA_BUFFER_LIST +} from '../../../../modules/basis/flight/actions/basisFlightAction'; import { flightPlanAPI } from '../../../../modules/basis/flight/apis/basisFlightApi'; import { Search } from 'react-feather'; import { FeatureAirZone } from '../../../map/mapbox/feature/FeatureAirZone'; import { drawTypeChangeAction } from '../../../../modules/control/map/actions/controlMapActions'; import { MapBoxDraw } from '../../../map/mapbox/draw/MapBoxDraw'; +import { WeatherContainer } from '../../../../containers/basis/flight/plan/WeatherContainer'; export const FlightPlanAreaMapBox = props => { const dispatch = useDispatch(); @@ -45,12 +49,55 @@ export const FlightPlanAreaMapBox = props => { const [isSearch, setIsSearch] = useState(false); const [dragSize, setDragSize] = useState(70); - const [pastDragCircle, setDragCircle] = useState([]); + const [pastDragCircle, setDragCircle] = useState(); const [number, setNumber] = useState(0); const [formModal, setFormModal] = useState(false); + const [layerId, setLayerId] = useState(); + const buildingLayer = { + id: 'add-3d-buildings', + source: 'composite', + 'source-layer': 'building', + filter: ['==', 'extrude', 'true'], + type: 'fill-extrusion', + minzoom: 15, + paint: { + 'fill-extrusion-color': '#aaa', + + // Use an 'interpolate' expression to + // add a smooth transition effect to + // the buildings as the user zooms in. + 'fill-extrusion-height': [ + 'interpolate', + ['linear'], + ['zoom'], + 15, + 0, + 15.05, + ['get', 'height'] + ], + 'fill-extrusion-base': [ + 'interpolate', + ['linear'], + ['zoom'], + 15, + 0, + 15.05, + ['get', 'min_height'] + ], + 'fill-extrusion-opacity': 0.6 + } + }; + const terrainLayer = { + type: 'raster-dem', + url: 'mapbox://mapbox.mapbox-terrain-dem-v1' + // url: 'mapbox://mapbox.mapbox-street-v1', + // tileSize: 512, + // maxZoom: 16, + }; + const geojson = { type: 'FeatureCollection', features: [] @@ -64,6 +111,36 @@ export const FlightPlanAreaMapBox = props => { }; }, []); + // useEffect(() => { + // pastDragCircle.forEach(c => c.setRadius(dragSize)); + // }, [dragSize]); + + // useEffect(() => { + // setIsMapLoad(true); + // }, [airArea]); + + useEffect(() => { + setMode(mapControl.drawType); + }, [mapControl.drawType]); + + useEffect(() => { + if (areaCoordList && mapObject) { + if ( + areaCoordList[0].coordList[0].lat !== 0 && + areaCoordList[0].coordList[0].lon !== 0 + ) { + if (number === 0) { + mapObject.setCenter([ + areaCoordList[0].coordList[0].lon, + areaCoordList[0].coordList[0].lat + ]); + setNumber(number + 1); + } + } + setMapAreaCoordList(areaCoordList); + } + }, [areaCoordList, mapObject, number]); + const mapBoxMapInit = () => { const bufferZoom = {}; if (areaCoordList) { @@ -107,77 +184,31 @@ export const FlightPlanAreaMapBox = props => { const labelLayerId = layers.find( layer => layer.type === 'symbol' && layer.layout['text-field'] ).id; + setLayerId(labelLayerId); // 지형 3d start - map.addSource('mapbox-dem', { - type: 'raster-dem', - url: 'mapbox://mapbox.mapbox-terrain-dem-v1', - tileSize: 512, - maxZoom: 16 - }); + map.addSource('mapbox-dem', terrainLayer); map.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 }); - map.addLayer({ - id: 'contours', - type: 'line', - source: { - type: 'vector', - url: 'mapbox://mapbox.mapbox-terrain-v2' - }, - 'source-layer': 'contour', - layout: { - visibility: 'visible', - 'line-join': 'round', - 'line-cap': 'round' - }, - paint: { - 'line-color': '#877b59', - 'line-width': 1 - } - }); - map.addLayer( - { - id: 'add-3d-buildings', - source: 'composite', - 'source-layer': 'building', - filter: ['==', 'extrude', 'true'], - type: 'fill-extrusion', - minzoom: 15, - paint: { - 'fill-extrusion-color': '#aaa', - - // Use an 'interpolate' expression to - // add a smooth transition effect to - // the buildings as the user zooms in. - 'fill-extrusion-height': [ - 'interpolate', - ['linear'], - ['zoom'], - 15, - 0, - 15.05, - ['get', 'height'] - ], - 'fill-extrusion-base': [ - 'interpolate', - ['linear'], - ['zoom'], - 15, - 0, - 15.05, - ['get', 'min_height'] - ], - 'fill-extrusion-opacity': 0.6 - } - }, - labelLayerId - ); + map.addLayer(buildingLayer, labelLayerId); //mapDraw layer map.addSource('geojson', { type: 'geojson', data: geojson }); + map.addLayer({ + id: 'vertex', + type: 'circle', + source: 'geojson', + paint: { + 'circle-radius': 5, + 'circle-color': '#ffffff', + 'circle-stroke-color': '#000000', + 'circle-stroke-width': 1 + }, + filter: ['in', '$type', 'Point'] + }); map.addLayer({ id: 'waypoint', type: 'circle', @@ -236,6 +267,31 @@ export const FlightPlanAreaMapBox = props => { }); }; + const handlerMapTypeSwitch = type => { + if (type === '2d') { + mapObject.dragRotate.disable(); + if (mapObject.getLayer('add-3d-buildings')) { + mapObject.removeLayer('add-3d-buildings'); + + mapObject.setTerrain(); + mapObject.removeSource('mapbox-dem'); + mapObject.flyTo({ + pitch: 0, + bearing: 0 + }); + } + } else if (type === '3d') { + mapObject.dragRotate.enable(); + if (!mapObject.getLayer('add-3d-buildings')) { + mapObject.addLayer(buildingLayer, layerId); + + mapObject.addSource('mapbox-dem', terrainLayer); + mapObject.setTerrain({ source: 'mapbox-dem', exaggeration: 1.5 }); + } + } + }; + + //지역 검색 const handlerSearch = async () => { const res = await flightPlanAPI.searchArea({ query: query }); setIsSearch(true); @@ -285,6 +341,48 @@ export const FlightPlanAreaMapBox = props => { dispatch(drawTypeChangeAction(val)); }; + const handlerInitCoordinates = () => { + const init = initFlightBas.initDetail.areaList.concat(); + dispatch(AREA_COORDINATE_LIST_SAVE(init)); + }; + + const handlerCoordinates = areaInfo => { + const initAreaList = initFlightBas.initDetail.areaList.concat(); + const coordList = []; + + areaInfo.coordinates.forEach((c, idx) => { + const coord = Object.assign({}, initFlightBas['coord']); + coord.lat = c.lat; + coord.lon = c.lon; + + coordList.push(coord); + }); + + const areaList = initAreaList.map((area, idx) => { + return { + ...area, + bufferZone: areaInfo.bufferZone, + areaType: areaInfo.areaType, + coordList: coordList + }; + }); + + if (areaInfo.areaType === 'LINE') { + dispatch(FLIGHT_PLAN_AREA_BUFFER_LIST.request(areaList)); + } + + // setMapAreaCoordList(areaList); + }; + + const handlerConfirm = areaList => { + if (areaList === undefined) { + alert('영역을 설정해 주세요.'); + return false; + } + + dispatch(AREA_COORDINATE_LIST_SAVE(areaList)); + }; + return ( @@ -304,15 +402,19 @@ export const FlightPlanAreaMapBox = props => { > {isMapLoad && mapObject ? ( ) : null}
@@ -370,6 +472,12 @@ export const FlightPlanAreaMapBox = props => {
+
+ + + + +
@@ -421,6 +529,21 @@ export const FlightPlanAreaMapBox = props => { <> )} + + 날씨 정보 + + + + + + +
); diff --git a/src/components/map/mapbox/draw/MapBoxDraw.js b/src/components/map/mapbox/draw/MapBoxDraw.js index dd9bbcf..0053eee 100644 --- a/src/components/map/mapbox/draw/MapBoxDraw.js +++ b/src/components/map/mapbox/draw/MapBoxDraw.js @@ -1,12 +1,21 @@ import { useDispatch, useSelector } from 'react-redux'; import { InfoModal } from '../../../modal/InfoModal'; import * as turf from '@turf/turf'; -import { useCallback, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; + +export const InitFeature = (type, id) => { + return { + type: 'Feature', + geometry: { + type: type, + coordinates: [] + }, + properties: { id: id, center: '' } + }; +}; export const MapBoxDraw = props => { - const dispatch = useDispatch(); const mapControl = useSelector(state => state.controlMapReducer); - const mapboxgl = props.mapboxgl; const mapObject = props.mapObject; const isDone = props.isDone; const isDisabled = props.isDisabled; @@ -17,7 +26,7 @@ export const MapBoxDraw = props => { const [pastClickEvent, setPastClickEvent] = useState(); const [pastMarker, setPastMarker] = useState([]); - const [figure, setFigure] = useState(); + const [featureObj, setFeatureObj] = useState(); const [areaDetail, setAreaDetail] = useState(); @@ -34,25 +43,39 @@ export const MapBoxDraw = props => { let radiusline; const eventListener = { - clickEvent: '', - mouseMoveEvent: '', - rightClickEvent: '', - mousedownEvent: '', - mouseUpEvent: '', - mouseEnterEvent: '', - mouseLeaveEvent: '' + click: '', + mousemove: '', + contextmenu: '', + mousedown: '', + mouseup: '', + mouseenter: '', + mouseleave: '' + }; + const areaInfo = { + coordinates: [], + bufferZone: 0, + areaType: '' }; const geojson = props.geojson; - let wayPoint; - let guideLine; - let lineString; + let wayPoint = InitFeature('Point', 'point'); + let guideLine = InitFeature('LineString', 'guideline'); + let lineString = InitFeature('LineString', 'polyline'); + let bufferPolygon = InitFeature('Polygon', 'buffer'); - let polygon; + let polygon = InitFeature('Polygon', 'polygon'); - let circle; + let circle = InitFeature('Polygon', 'circle'); + + //꼭짓점(polyline, polygon 사용) + let vertex = InitFeature('MultiPoint', 'vertex'); + let dragCircleIdx; const canvas = mapObject.getCanvasContainer(); + const [pastPolyline, setPolyline] = useState(); + const [pastBuffer, setBuffer] = useState(); + const [pastPolygon, setPolygon] = useState(); + const [pastCircle, setCircle] = useState(); useEffect(() => { setRadiusCircle(props.dragSize); @@ -62,35 +85,29 @@ export const MapBoxDraw = props => { if (mapControl.drawType) drawInit(); }, [mapControl.drawType]); - const initFeature = type => { - return { - type: 'Feature', - geometry: { - type: type, - coordinates: [] - }, - properties: { id: '', center: '' } - }; - }; - - const drawInit = () => { - wayPoint = initFeature('Point'); - wayPoint.properties.id = 'point'; - - guideLine = initFeature('LineString'); - guideLine.properties.id = 'guideline'; - - lineString = initFeature('LineString'); - lineString.properties.id = 'polyline'; - - polygon = initFeature('Polygon'); - polygon.properties.id = 'polygon'; + useEffect(() => { + if (featureObj) { + props.handlerConfirm(props.areaCoordList); + } + }, [featureObj]); - circle = initFeature('Polygon'); - circle.properties.id = 'polygon'; + useEffect(() => { + const areaCoordList = props.areaCoordList[0]; + + if (areaCoordList.areaType === 'LINE') { + if ( + areaCoordList.bufferCoordList[0].lat !== 0 && + areaCoordList.bufferCoordList[0].lon !== 0 + ) { + handlerPastDraw(); + } + } else if (areaCoordList.areaType === 'POLYGON') { + handlerPastDraw(); + } + }, [props.areaCoordList]); - const drawType = mapControl.drawType; - handlerButtonClick(drawType); + const drawInit = () => { + handlerButtonClick(mapControl.drawType); }; //그리기 타입 선택 @@ -101,58 +118,101 @@ export const MapBoxDraw = props => { mode = null; return; } + handlerStartMode(newMode); }; const handlerClearMode = () => { - // geojson.features = []; - // wayPoint.geometry.coordinates = []; - // guideLine.geometry.coordinates = []; - // lineString.geometry.coordinates = []; - // mapObject.getSource('geojson').setData(geojson); + setPolyline(); + setPolygon(); + setCircle(); - finishDraw(); - }; - - const finishDraw = () => { - removeListener(); + geojson.features = []; + mapObject.getSource('geojson').setData(geojson); - // geojson.features = []; - // wayPoint.geometry.coordinates = []; - // guideLine.geometry.coordinates = []; - // lineString.geometry.coordinates = []; - // mapObject.getSource('geojson').setData(geojson); + finishDraw(); + props.handlerInitCoordinates(); }; const handlerStartMode = mode => { if (!mode) return; - eventListener.clickEvent = e => { - if (mode === 'LINE') onClickFeature(e, lineString, 'polyline'); - if (mode === 'POLYGON') onClickFeature(e, polygon, 'polygon'); - if (mode === 'CIRCLE') onClickCircle(e); - if (mode === 'RESET') handlerClearMode(); - }; - mapObject.on('click', eventListener.clickEvent); + handlerAddEvent('click', clickEve, '', 'on'); }; const removeListener = () => { - mapObject.off('click', eventListener.clickEvent); - mapObject.off('mousemove', eventListener.mouseMoveEvent); - mapObject.off('contextmenu', eventListener.rightClickEvent); + console.log('remove'); + mapObject.off('click', clickEve); + mapObject.off('mouseup', onMouseUp); + mapObject.off('mousedown', onMouseDown); + mapObject.off('mousemove', onMouseMove); + mapObject.off('mousemove', onMouseMovePolyline); + mapObject.off('mousemove', onMouseMovePolygon); + mapObject.off('contextmenu', finishDraw); + }; + + const finishDraw = e => { + removeListener(); + console.log('finish'); + + const drawType = mapControl.drawType; + const path = geojson.features + .filter(point => point.properties?.id === 'point') + .map(point => point.geometry.coordinates); + + if (path.length > 0) { + if (drawType === 'LINE') { + if (path.length > 1) { + geojson.features = geojson.features.filter( + geo => geo.properties?.id !== 'guideline' + ); + handlerAreaInfo(lineString.geometry.coordinates); + setFeatureObj(lineString); + } else { + setAlertModal({ + isOpen: true, + title: '좌표 최소 개수', + desc: '좌표를 두 개 점으로 이어주세요.' + }); + lineString.geometry.coordinates = []; + geojson.features = []; + handlerAddEvent('click', clickEve, '', 'on'); + } + mapObject.getSource('geojson').setData(geojson); + } else if (drawType === 'POLYGON') { + if (path.length > 2) { + polygon.geometry.coordinates = [path]; + handlerAreaInfo(polygon.geometry.coordinates[0]); + setFeatureObj(polygon); + } else { + setAlertModal({ + isOpen: true, + title: '좌표 최소 개수', + desc: '좌표를 세 개 점으로 이어주세요.' + }); + polygon.geometry.coordinates = []; + geojson.features = []; + handlerAddEvent('click', clickEve, '', 'on'); + } + mapObject.getSource('geojson').setData(geojson); + } + } + }; - eventListener.clickEvent = ''; - eventListener.mouseMoveEvent = ''; - eventListener.rightClickEvent = ''; + const clickEve = e => { + const drawType = mapControl.drawType; + if (drawType === 'LINE') onClickFeature(e, lineString, 'polyline'); + if (drawType === 'POLYGON') onClickFeature(e, polygon, 'polygon'); + if (drawType === 'CIRCLE') onClickCircle(e); }; //polyline, polygon 생성 - const onClickFeature = (e, figureObj, id) => { + const onClickFeature = (e, featureObj, id) => { const features = mapObject.queryRenderedFeatures(e.point, { layers: ['waypoint'] }); - figureObj.properties.id = id; + featureObj.properties.id = id; if (geojson.features.length > 1) { geojson.features = geojson.features.filter( geo => geo.properties?.id !== id @@ -165,13 +225,17 @@ export const MapBoxDraw = props => { point => point.properties.id !== id ); } else { + const index = geojson.features.filter( + geo => geo.properties?.id === 'point' + ).length; + const point = { type: 'Feature', geometry: { type: 'Point', coordinates: [e.lngLat.lng, e.lngLat.lat] }, - properties: { id: 'point' } + properties: { id: 'point', index: index } }; geojson.features.push(point); } @@ -184,25 +248,65 @@ export const MapBoxDraw = props => { .filter(point => point.properties?.id === 'point') .map(point => point.geometry.coordinates); - figureObj.geometry.coordinates = + featureObj.geometry.coordinates = id === 'polyline' ? coordinates : [coordinates]; - geojson.features.push(figureObj); + geojson.features.push(featureObj); } else { - eventListener.rightClickEvent = () => { - finishDraw(); - }; - mapObject.on('contextmenu', eventListener.rightClickEvent); + handlerAddEvent('contextmenu', finishDraw, '', 'on'); + handlerAddEvent( + 'mousemove', + id === 'polyline' ? onMouseMovePolyline : onMouseMovePolygon, + '', + 'on' + ); + } + mapObject.getSource('geojson').setData(geojson); + }; - eventListener.mouseMoveEvent = e => { - id === 'polyline' ? onMouseMovePolyline(e) : onMouseMovePolygon(e); - }; - mapObject.on('mousemove', eventListener.mouseMoveEvent); + //polyline 가이드 생성 + const onMouseMovePolyline = e => { + if (guideLine.geometry.coordinates.length > 1) { + guideLine.geometry.coordinates.pop(); + + //기존 guideline 제거 + geojson.features = geojson.features.filter( + point => point.properties?.id !== 'guideline' + ); + //새로운 가이드라인 push + geojson.features.push(guideLine); } + guideLine.geometry.coordinates.push([e.lngLat.lng, e.lngLat.lat]); + mapObject.getSource('geojson').setData(geojson); }; + //polygon 가이드 생성 + const onMouseMovePolygon = e => { + if (polygon.geometry.coordinates.length > 0) { + const proj = mapObject.getProjection(); + if (polygon.geometry.coordinates[0].length > 1) { + if (guideLine.geometry.coordinates.length > 1) { + guideLine.geometry.coordinates.pop(); + polygon.geometry.coordinates[0].pop(); + + geojson.features = geojson.features.filter( + point => point.properties?.id !== 'polygon' + ); + + geojson.features.push(polygon); + } + guideLine.geometry.coordinates.push([e.lngLat.lng, e.lngLat.lat]); + polygon.geometry.coordinates[0].push([e.lngLat.lng, e.lngLat.lat]); + + mapObject.getSource('geojson').setData(geojson); + } + } + }; + //circle 생성 const onClickCircle = e => { + console.log('click'); + circle.properties.id = 'circle'; geojson.features.pop(); @@ -219,75 +323,78 @@ export const MapBoxDraw = props => { circle.geometry.coordinates = circleCoords; geojson.features.push(circle); - eventListener.mouseEnterEvent = () => { - onMouseEnter(); - }; - mapObject.on('mouseenter', 'polygon', eventListener.mouseEnterEvent); - - eventListener.mouseLeaveEvent = () => { - onMouseLeave(); - }; - mapObject.on('mouseleave', 'polygon', eventListener.mouseLeaveEvent); - - eventListener.mousedownEvent = e => { - //mouseDown event추가하기 - onMouseDown(e); - }; - mapObject.on('mousedown', 'polygon', eventListener.mousedownEvent); + if (eventListener.mousedown === '') { + handlerAddEvent('mousedown', onMouseDown, 'polygon', 'on'); + } mapObject.getSource('geojson').setData(geojson); }; - //원에 마우스 닿았을 때 - const onMouseEnter = () => { - mapObject.setPaintProperty('polygon', 'fill-color', '#3bb2d0'); - canvas.style.cursor = 'move'; - }; - - //원에 마우스 떠났을 때 - const onMouseLeave = () => { - mapObject.setPaintProperty('polygon', 'fill-color', '#7367F0'); - canvas.style.cursor = ''; - }; - - //원에 마우스 클릭되었을 때 const onMouseDown = e => { e.preventDefault(); + console.log('down'); canvas.style.cursor = 'grab'; - eventListener.mouseMoveEvent = e => { - onMouseMove(e); - }; - mapObject.on('mousemove', eventListener.mouseMoveEvent); + if (vertex.geometry.coordinates.length > 0) { + dragCircleIdx = e.features[0].properties.index; + } - eventListener.mouseUpEvent = e => { - onMouseUp(e); - }; - mapObject.once('mouseup', eventListener.mouseUpEvent); + if (circle.geometry.coordinates.length > 0) { + //이벤트 다 지워 + removeListener(); + } + + handlerAddEvent('mousemove', onMouseMove, '', 'on'); + handlerAddEvent('mouseup', onMouseUp, '', 'on'); + + mapObject.off('click', clickEve); }; - //원에 마우스 클릭되어서 움직일 때 const onMouseMove = e => { canvas.style.cursor = 'grabbing'; - const centerCoord = turf.point(circle.properties.center); - const currentCoord = turf.point([e.lngLat.lng, e.lngLat.lat]); + if (vertex.geometry.coordinates.length > 0) { + geojson.features.map(geo => { + if (geo.properties?.id === 'polyline') { + geo.geometry.coordinates[dragCircleIdx] = [ + e.lngLat.lng, + e.lngLat.lat + ]; + } - const distanceOptions = { units: 'kilometers' }; - //circle 센터와 e.coord간의 거리(meters) - const currentToCenter = - turf.distance(centerCoord, currentCoord, distanceOptions) * 1000; + if (geo.properties?.id === 'polygon') { + geo.geometry.coordinates[0][dragCircleIdx] = [ + e.lngLat.lng, + e.lngLat.lat + ]; + } - const center = circle.properties.center; - const options = { - steps: 360, - units: 'kilometers' - }; - const circleCoords = turf.circle(center, currentToCenter / 1000, options) - .geometry.coordinates; + if (geo.properties?.index === dragCircleIdx) { + geo.geometry.coordinates = [e.lngLat.lng, e.lngLat.lat]; + } + }); + } - circle.geometry.coordinates = circleCoords; + if (circle.geometry.coordinates.length > 0) { + const centerCoord = turf.point(circle.properties.center); + const currentCoord = turf.point([e.lngLat.lng, e.lngLat.lat]); + + const distanceOptions = { units: 'kilometers' }; + //circle 센터와 e.coord간의 거리(meters) + const currentToCenter = + turf.distance(centerCoord, currentCoord, distanceOptions) * 1000; + + const center = circle.properties.center; + const options = { + steps: 360, + units: 'kilometers' + }; + const circleCoords = turf.circle(center, currentToCenter / 1000, options) + .geometry.coordinates; + + circle.geometry.coordinates = circleCoords; + } mapObject.getSource('geojson').setData(geojson); }; @@ -295,45 +402,149 @@ export const MapBoxDraw = props => { const onMouseUp = e => { canvas.style.cursor = ''; - mapObject.off('mousemove', eventListener.mouseMoveEvent); - eventListener.onMouseMove = ''; + console.log('up'); + + mapObject.off('mousemove', onMouseMove); + mapObject.off('mouseup', onMouseUp); + mapObject.off('click', clickEve); + + if (circle.geometry.coordinates.length > 0) { + handlerAddEvent('click', clickEve, '', 'on'); + } }; - //polyline 가이드 생성 - const onMouseMovePolyline = e => { - if (guideLine.geometry.coordinates.length > 1) { - guideLine.geometry.coordinates.pop(); + //이벤트 리스너 생성 + const handlerAddEvent = (eventType, eventFunction, target, time) => { + Object.keys(eventListener).map(eve => { + if (eve === eventType) { + eventListener[eve] = e => { + eventFunction(e); + }; + } + }); - //기존 guideline 제거 - geojson.features = geojson.features.filter( - point => point.properties?.id !== 'guideline' - ); - //새로운 가이드라인 push - geojson.features.push(guideLine); + if (time === 'on') { + target !== '' + ? mapObject.on(eventType, target, eventFunction) + : mapObject.on(eventType, eventFunction); + } else if (time === 'once') { + target !== '' + ? mapObject.once(eventType, target, eventFunction) + : mapObject.once(eventType, eventFunction); } - guideLine.geometry.coordinates.push([e.lngLat.lng, e.lngLat.lat]); + }; - mapObject.getSource('geojson').setData(geojson); + const handlerAreaInfo = path => { + let bufferZone = 100; + if (polygon.geometry.coordinates.length > 0) bufferZone = 0; + const prePath = []; + if (path) { + path.forEach(item => { + const p = { + lat: item[1], + lon: item[0] + }; + prePath.push(p); + }); + } + if (lineString.geometry.coordinates.length > 0) { + areaInfo.coordinates = prePath; + areaInfo.bufferZone = bufferZone; + areaInfo.areaType = 'LINE'; + } else if (polygon.geometry.coordinates.length > 0) { + areaInfo.coordinates = prePath; + areaInfo.bufferZone = bufferZone; + areaInfo.areaType = 'POLYGON'; + } else if (circle.geometry.coordinates.length > 0) { + const point = { + lat: circle.properties.center[1], + lon: circle.properties.center[0] + }; + areaInfo.coordinates.push(point); + areaInfo.bufferZone = + turf.distance( + turf.point(circle.properties.center), + turf.point(circle.geometry.coordinates[0]), + { units: 'kilometers' } + ) * 1000; + areaInfo.areaType = 'CIRCLE'; + } + props.handlerCoordinates(areaInfo); }; - //polygon 가이드 생성 - const onMouseMovePolygon = e => { - if (polygon.geometry.coordinates.length > 0) { - if (polygon.geometry.coordinates[0].length > 1) { - if (guideLine.geometry.coordinates.length > 1) { - guideLine.geometry.coordinates.pop(); - polygon.geometry.coordinates[0].pop(); + const handlerPastDraw = () => { + if (props.areaCoordList) { + console.log('pastDraw'); - geojson.features = geojson.features.filter( - point => point.properties?.id !== 'polygon' - ); + const areas = props.areaCoordList[0]; - geojson.features.push(polygon); - } - guideLine.geometry.coordinates.push([e.lngLat.lng, e.lngLat.lat]); - polygon.geometry.coordinates[0].push([e.lngLat.lng, e.lngLat.lat]); + const paths = []; + areas.coordList.forEach(coord => { + const path = [coord.lon, coord.lat]; + paths.push(path); + }); + + //let이라서 지워지는 도형 다시 생성 + const reCreatePoint = featureObj => { + const id = featureObj.properties?.id; + featureObj.geometry.coordinates = id === 'polyline' ? paths : [paths]; + if (id === 'polyline') { + setPolyline(featureObj); + + //버퍼 생성 + if (areas.bufferCoordList) { + const bufferPaths = []; + + areas.bufferCoordList.forEach(bfCoord => { + const path = [bfCoord.lon, bfCoord.lat]; + bufferPaths.push(path); + }); + + if (pastBuffer) { + geojson.features = geojson.features.filter( + geo => geo.properties?.id !== 'buffer' + ); + } + + bufferPolygon.geometry.coordinates = [bufferPaths]; + setBuffer(bufferPolygon); + + geojson.features.push(bufferPolygon); + } + } else if (id === 'polygon') { + setPolygon(featureObj); + } + geojson.features.push(featureObj); + + //서버에 좌표 전달 편하게 하기 위해서 vertex에 좌표를 저장해주지만 + //geojson에 넣어줄 데이터는 point임(index 때문에) + paths.map((path, index) => { + const point = { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: path + }, + properties: { id: 'point', index: index } + }; + vertex.geometry.coordinates.push(path); + geojson.features.push(point); + }); + + handlerAddEvent('mousedown', onMouseDown, 'waypoint', 'on'); + + mapObject.setPaintProperty('waypoint', 'circle-radius', 8); mapObject.getSource('geojson').setData(geojson); + }; + + if (areas.areaType === 'LINE') { + reCreatePoint(lineString); + } + if (areas.areaType === 'POLYGON') { + reCreatePoint(polygon); + } + if (areas.areaType === 'CIRCLE') { } } }; diff --git a/src/components/map/naver/draw/FlightPlanDraw.js b/src/components/map/naver/draw/FlightPlanDraw.js index d3043fd..ca835bc 100644 --- a/src/components/map/naver/draw/FlightPlanDraw.js +++ b/src/components/map/naver/draw/FlightPlanDraw.js @@ -69,6 +69,7 @@ export const FlightPlanDraw_init = props => { }, [mapControl.drawType]); useEffect(() => { + console.log(props.areaCoordList, '빈양식'); handleDetailDraw(); }, [props.areaCoordList]); @@ -80,6 +81,7 @@ export const FlightPlanDraw_init = props => { }, [figure]); useEffect(() => { + console.log(areaDetail, '채워진양식?'); if (pastPolyline) { handleBufferList(); } @@ -184,6 +186,7 @@ export const FlightPlanDraw_init = props => { if (polypaths.length >= 2) { setPolyline(polyline); setAreaInfo(polypaths); + setFigure(polyline); } else { setAlertModal({ isOpen: true, @@ -193,7 +196,6 @@ export const FlightPlanDraw_init = props => { polyline.setMap(null); polyline = ''; } - setFigure(polyline); } else if (polygon) { let path = polygon.getPath(); path.pop(); @@ -212,6 +214,7 @@ export const FlightPlanDraw_init = props => { if (polygonpaths.length >= 3) { setPolygon(polygon); setAreaInfo(polygonpaths); + setFigure(polygon); } else { setAlertModal({ isOpen: true, @@ -221,8 +224,6 @@ export const FlightPlanDraw_init = props => { polygon.setMap(null); polygon = ''; } - - setFigure(polygon); } }; @@ -634,6 +635,7 @@ export const FlightPlanDraw_init = props => { //bufferline 생성 if (areas.bufferCoordList) { + console.log(areas.bufferCoordList, '>>>'); const bufferPaths = []; areas.bufferCoordList.forEach(bfCoord => { @@ -879,8 +881,6 @@ export const FlightPlanDraw_init = props => { if (circle) { midPoint = coord; } else { - console.log(dis1.y + dis2.y, 'y더한 값'); - console.log((dis1.y + dis2.y) / 2, 'y나눈 값'); midPoint = new naver.maps.LatLng( (dis1.y + dis2.y) / 2, (dis1.x + dis2.x) / 2 diff --git a/src/containers/basis/flight/plan/FlightPlanAreaContainer.js b/src/containers/basis/flight/plan/FlightPlanAreaContainer.js index f52705d..f7dc74e 100644 --- a/src/containers/basis/flight/plan/FlightPlanAreaContainer.js +++ b/src/containers/basis/flight/plan/FlightPlanAreaContainer.js @@ -45,11 +45,7 @@ const FlightPlanAreaContainer = ({ handleModal, isDone, isDisabled }) => { isDone={isDone} isDisabled={isDisabled} /> - ) : // + ) : // null}