|
|
|
@ -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') { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|