|
|
|
@ -1,14 +1,18 @@
|
|
|
|
|
import { useEffect, useState } from 'react'; |
|
|
|
|
import { InfoModal } from '../../../modal/InfoModal'; |
|
|
|
|
import { useSelector } from 'react-redux'; |
|
|
|
|
import { useDispatch, useSelector } from 'react-redux'; |
|
|
|
|
import { |
|
|
|
|
CalculateDistance, |
|
|
|
|
handlerGetCircleCoord, |
|
|
|
|
handlerGetHtmlContent, |
|
|
|
|
handlerGetMidPoint |
|
|
|
|
} from '../../../../utility/DrawUtil'; |
|
|
|
|
import { drawTypeChangeAction } from '../../../../modules/control/map/actions/controlMapActions'; |
|
|
|
|
import MapboxDraw from '@mapbox/mapbox-gl-draw'; |
|
|
|
|
|
|
|
|
|
export const LaancDrawControl = props => { |
|
|
|
|
const dispatch = useDispatch(); |
|
|
|
|
|
|
|
|
|
const mapControl = useSelector(state => state.controlMapReducer); |
|
|
|
|
const drawObj = props.drawObj; |
|
|
|
|
const mapObject = props.mapObject; |
|
|
|
@ -34,10 +38,22 @@ export const LaancDrawControl = props => {
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
if (mapObject) { |
|
|
|
|
mapObject.on('draw.create', handlerSetId); |
|
|
|
|
mapObject.on('draw.update', handlerFormatAreaInfo); |
|
|
|
|
mapObject.on('draw.update', handlerUpdateSetting); |
|
|
|
|
|
|
|
|
|
const DrawLineStringMode = MapboxDraw.modes.draw_line_string; |
|
|
|
|
const DrawPolygonMode = MapboxDraw.modes.draw_polygon; |
|
|
|
|
const modeArr = [DrawLineStringMode, DrawPolygonMode]; |
|
|
|
|
|
|
|
|
|
mapObject.on('click', handlerOnClick); |
|
|
|
|
modeArr.forEach(m => { |
|
|
|
|
m.onStop = state => handlerDblClickFinish(state); |
|
|
|
|
|
|
|
|
|
// onClick 이벤트 오버라이드
|
|
|
|
|
const origin = m.onClick; |
|
|
|
|
m.onClick = function (state, e) { |
|
|
|
|
origin.call(this, state, e); |
|
|
|
|
handlerCustomOnClick(state, e); |
|
|
|
|
}; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
}, [mapObject]); |
|
|
|
|
|
|
|
|
@ -53,17 +69,15 @@ export const LaancDrawControl = props => {
|
|
|
|
|
}, [isDrawDone]); |
|
|
|
|
|
|
|
|
|
// 클릭할 때마다 마커 찍어줌
|
|
|
|
|
const handlerOnClick = e => { |
|
|
|
|
const handlerCustomOnClick = (state, e) => { |
|
|
|
|
console.log('click'); |
|
|
|
|
|
|
|
|
|
const featureIds = drawObj.getFeatureIdsAt(e.point); |
|
|
|
|
const feature = drawObj.get(featureIds[0]); |
|
|
|
|
const type = handlerReturnMode(drawObj.getMode()); |
|
|
|
|
const obj = state[type?.toLowerCase()]; |
|
|
|
|
|
|
|
|
|
if (type) { |
|
|
|
|
if (type && obj) { |
|
|
|
|
if (type !== 'CIRCLE') { |
|
|
|
|
if (feature) { |
|
|
|
|
// 뒷 부분
|
|
|
|
|
if (state.currentVertexPosition > 1) { |
|
|
|
|
const feature = drawObj.get(obj.id); |
|
|
|
|
const coordinates = feature.geometry.coordinates; |
|
|
|
|
const coords = [ |
|
|
|
|
...new Set( |
|
|
|
@ -77,48 +91,110 @@ export const LaancDrawControl = props => {
|
|
|
|
|
const lngLat = handlerGetMidPoint(coords[len - 2], coords[len - 1]); |
|
|
|
|
const text = CalculateDistance(coords[len - 2], coords[len - 1]); |
|
|
|
|
|
|
|
|
|
handlerCreateOneMarker([0, 0], lngLat, text); |
|
|
|
|
handlerCreateOneMarker([0, 0], lngLat, text, obj.id); |
|
|
|
|
} else { |
|
|
|
|
// Start
|
|
|
|
|
if (type !== 'CIRCLE') |
|
|
|
|
handlerCreateOneMarker( |
|
|
|
|
[0, -10], |
|
|
|
|
[e.lngLat.lng, e.lngLat.lat], |
|
|
|
|
'Start' |
|
|
|
|
); |
|
|
|
|
handlerCreateOneMarker( |
|
|
|
|
[0, -10], |
|
|
|
|
[e.lngLat.lng, e.lngLat.lat], |
|
|
|
|
'Start', |
|
|
|
|
obj.id |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 도형 첫 생성하면 properties.id에 현재 drawType 넣어줌
|
|
|
|
|
const handlerSetId = e => { |
|
|
|
|
console.log('create'); |
|
|
|
|
const id = e.features[0].id; |
|
|
|
|
const handlerDblClickFinish = state => { |
|
|
|
|
console.log('dblclick'); |
|
|
|
|
const mode = handlerReturnMode(drawObj.getMode()); |
|
|
|
|
if (mode) { |
|
|
|
|
drawObj.setFeatureProperty(id, 'id', mode); |
|
|
|
|
setDrawObjId(id); |
|
|
|
|
handlerFormatAreaInfo(e); |
|
|
|
|
|
|
|
|
|
const obj = state[mode.toLowerCase()]; |
|
|
|
|
console.log(obj, '>>>>>>obj'); |
|
|
|
|
const length = state.currentVertexPosition; |
|
|
|
|
drawObj.setFeatureProperty(obj.id, 'id', mode); |
|
|
|
|
|
|
|
|
|
// dbl클릭이 click 두번으로 인식돼서, 마지막 값을 없애버리기로 함
|
|
|
|
|
if (mode === 'LINE') { |
|
|
|
|
obj.coordinates.splice(-1); |
|
|
|
|
if (length < 1) { |
|
|
|
|
setAlertModal({ |
|
|
|
|
isOpen: true, |
|
|
|
|
title: '좌표 최소 개수', |
|
|
|
|
desc: '좌표를 두 개 점으로 이어주세요.' |
|
|
|
|
}); |
|
|
|
|
handlerRemoveError(obj.id); |
|
|
|
|
} |
|
|
|
|
} else if (mode === 'POLYGON') { |
|
|
|
|
obj.coordinates[0].splice(-1); |
|
|
|
|
if (length < 2) { |
|
|
|
|
setAlertModal({ |
|
|
|
|
isOpen: true, |
|
|
|
|
title: '좌표 최소 개수', |
|
|
|
|
desc: '좌표를 세 개 점으로 이어주세요.' |
|
|
|
|
}); |
|
|
|
|
handlerRemoveError(obj.id); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
handlerAbnormalityCheck(obj.coordinates, obj.id, mode); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handlerFormatAreaInfo = e => { |
|
|
|
|
const coord = e.features[0].geometry.coordinates; |
|
|
|
|
const mode = drawObj.get(e.features[0].id).properties.id; |
|
|
|
|
// 변수들 이름 겹쳐서 헷갈리니까 정리하기
|
|
|
|
|
const handlerAbnormalityCheck = (coord, id, mode) => { |
|
|
|
|
console.log('check', coord, id, mode); |
|
|
|
|
const isBreak = handlerIsSpecialFlight(coord, id, mode); |
|
|
|
|
if (isBreak) return; |
|
|
|
|
|
|
|
|
|
const data = |
|
|
|
|
mode === 'LINE' |
|
|
|
|
? coord |
|
|
|
|
: mode === 'POLYGON' |
|
|
|
|
? coord[0] |
|
|
|
|
: mode === 'CIRCLE' |
|
|
|
|
? e.features[0].properties.center |
|
|
|
|
: null; |
|
|
|
|
const initCoord = coord; |
|
|
|
|
const coords = |
|
|
|
|
mode === 'LINE' ? initCoord : mode === 'POLYGON' ? initCoord[0] : null; |
|
|
|
|
handlerSaveAreaInfo(coords, mode); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
handlerSaveAreaInfo(data, mode); |
|
|
|
|
// 현재 그려진 모든 도형에 대한 비가시권 검사
|
|
|
|
|
const handlerIsSpecialFlight = (coord, id, mode) => { |
|
|
|
|
// console.log(obj, 'specialFlight');
|
|
|
|
|
console.log('specialFlight'); |
|
|
|
|
let isBreak = false; |
|
|
|
|
const coords = mode === 'LINE' ? coord : coord[0]; |
|
|
|
|
|
|
|
|
|
for (let point = 0; point < coords.length - 1; point++) { |
|
|
|
|
const distance = CalculateDistance(coords[point], coords[point + 1]); |
|
|
|
|
if (distance > 1000) { |
|
|
|
|
isBreak = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (isBreak) { |
|
|
|
|
props.setModal(true); |
|
|
|
|
handlerRemoveError(id); |
|
|
|
|
return true; |
|
|
|
|
} else { |
|
|
|
|
props.handlerSaveCheck(true); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 비정상 감지 시 해당 도형, 마커 삭제
|
|
|
|
|
const handlerRemoveError = id => { |
|
|
|
|
drawObj.delete(id); |
|
|
|
|
handlerRemoveGroupMarker(id); |
|
|
|
|
props.handlerSaveCheck(false); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 도형 수정 시
|
|
|
|
|
const handlerUpdateSetting = e => { |
|
|
|
|
console.log('update'); |
|
|
|
|
|
|
|
|
|
if (e.features[0]) { |
|
|
|
|
const obj = e.features[0]; |
|
|
|
|
const mode = obj.properties.id; |
|
|
|
|
const initCoord = obj.geometry.coordinates; |
|
|
|
|
const coords = mode === 'LINE' ? initCoord : initCoord[0]; |
|
|
|
|
handlerAbnormalityCheck(coords, obj.id, mode); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// areaInfo 셋팅
|
|
|
|
|
const handlerSaveAreaInfo = (coord, mode) => { |
|
|
|
|
if (!coord || !mode) { |
|
|
|
|
alert('에러 발생. 다시 시도해 주세요.'); |
|
|
|
@ -163,6 +239,10 @@ export const LaancDrawControl = props => {
|
|
|
|
|
setIsDrawDone(true); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 버퍼 및 기존 도형 재생성
|
|
|
|
|
// 해당되는 도형 및 마커만 다시 그려지게 해야함(버퍼 포함)
|
|
|
|
|
// 해당 Id 마커 지우고 path만 받아서 다시 그려지도록...
|
|
|
|
|
// 근데 areaCoordList[0]이.. 도형을 하나만 받아오는걸로 알고 있어서 그거 확인해야함
|
|
|
|
|
const handlerPastDraw = () => { |
|
|
|
|
if (props.areaCoordList) { |
|
|
|
|
const areas = props.areaCoordList[0]; |
|
|
|
@ -187,13 +267,13 @@ export const LaancDrawControl = props => {
|
|
|
|
|
); |
|
|
|
|
} else { |
|
|
|
|
if (areas.areaType === 'LINE') { |
|
|
|
|
handlerCreateDrawObj( |
|
|
|
|
drawObjId, |
|
|
|
|
setDrawObjId, |
|
|
|
|
'LineString', |
|
|
|
|
{ path: paths }, |
|
|
|
|
'LINE' |
|
|
|
|
); |
|
|
|
|
// handlerCreateDrawObj(
|
|
|
|
|
// drawObjId,
|
|
|
|
|
// setDrawObjId,
|
|
|
|
|
// 'LineString',
|
|
|
|
|
// { path: paths },
|
|
|
|
|
// 'LINE'
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
// 버퍼 생성
|
|
|
|
|
if (areas.bufferCoordList) { |
|
|
|
@ -212,21 +292,21 @@ export const LaancDrawControl = props => {
|
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} else if (areas.areaType === 'POLYGON') { |
|
|
|
|
handlerCreateDrawObj( |
|
|
|
|
drawObjId, |
|
|
|
|
setDrawObjId, |
|
|
|
|
'Polygon', |
|
|
|
|
{ path: [paths] }, |
|
|
|
|
'POLYGON' |
|
|
|
|
); |
|
|
|
|
// handlerCreateDrawObj(
|
|
|
|
|
// drawObjId,
|
|
|
|
|
// setDrawObjId,
|
|
|
|
|
// 'Polygon',
|
|
|
|
|
// { path: [paths] },
|
|
|
|
|
// 'POLYGON'
|
|
|
|
|
// );
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// 현재 그려진 도형 저장
|
|
|
|
|
setGeoJson(drawGeoJson); |
|
|
|
|
|
|
|
|
|
// 마커 재 생성
|
|
|
|
|
handlerRemoveMarker(); |
|
|
|
|
handlerCreateAllMarker(paths); |
|
|
|
|
// handlerRemoveMarker();
|
|
|
|
|
// handlerCreateAllMarker(paths);
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -257,23 +337,35 @@ export const LaancDrawControl = props => {
|
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 지도에 있는 모든 마커 삭제
|
|
|
|
|
const handlerRemoveMarker = () => { |
|
|
|
|
const ele = document.getElementsByClassName('mapboxgl-popup'); |
|
|
|
|
const eleArr = Array.from(ele); |
|
|
|
|
eleArr?.forEach(marker => marker.remove()); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const handlerCreateOneMarker = (anchor, lngLat, text) => { |
|
|
|
|
// 해당되는 id의 마커 삭제
|
|
|
|
|
const handlerRemoveGroupMarker = id => { |
|
|
|
|
const ele = document.getElementsByClassName('mapboxgl-popup'); |
|
|
|
|
const eleArr = Array.from(ele); |
|
|
|
|
eleArr?.forEach(marker => { |
|
|
|
|
if (marker.innerHTML.includes(id)) marker.remove(); |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 개별 마커 생성
|
|
|
|
|
const handlerCreateOneMarker = (anchor, lngLat, text, id) => { |
|
|
|
|
const popup = new props.mapboxgl.Popup({ |
|
|
|
|
offset: anchor, |
|
|
|
|
closeButton: false, |
|
|
|
|
closeOnClick: false |
|
|
|
|
}) |
|
|
|
|
.setLngLat(lngLat) |
|
|
|
|
.setHTML(handlerGetHtmlContent(text)) |
|
|
|
|
.setHTML(handlerGetHtmlContent(text, id)) |
|
|
|
|
.addTo(mapObject); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 모든 마커 생성
|
|
|
|
|
const handlerCreateAllMarker = coords => { |
|
|
|
|
const areas = props.areaCoordList[0]; |
|
|
|
|
|
|
|
|
@ -293,15 +385,17 @@ export const LaancDrawControl = props => {
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const drawInit = () => { |
|
|
|
|
// console.log('drawInit');
|
|
|
|
|
drawObj.deleteAll(); |
|
|
|
|
handlerRemoveMarker(); |
|
|
|
|
// drawObj.deleteAll();
|
|
|
|
|
// handlerRemoveMarker();
|
|
|
|
|
props.handlerSaveCheck(false); |
|
|
|
|
setDrawObjId(); |
|
|
|
|
|
|
|
|
|
props.handlerInitCoordinates(); |
|
|
|
|
|
|
|
|
|
const mode = mapControl.drawType; |
|
|
|
|
if (!mode || mode === 'RESET') { |
|
|
|
|
drawObj.deleteAll(); |
|
|
|
|
handlerRemoveMarker(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
handlerStartMode(mode); |
|
|
|
|