|
|
@ -3,7 +3,8 @@ import { InfoModal } from '../../../modal/InfoModal'; |
|
|
|
import { useDispatch, useSelector } from 'react-redux'; |
|
|
|
import { useDispatch, useSelector } from 'react-redux'; |
|
|
|
import { |
|
|
|
import { |
|
|
|
CalculateDistance, |
|
|
|
CalculateDistance, |
|
|
|
handlerGetHtmlContent, |
|
|
|
handlerCreateGroupMarker, |
|
|
|
|
|
|
|
handlerCreateOneMarker, |
|
|
|
handlerGetMidPoint, |
|
|
|
handlerGetMidPoint, |
|
|
|
handlerRemoveAllMarker, |
|
|
|
handlerRemoveAllMarker, |
|
|
|
handlerRemoveGroupMarker, |
|
|
|
handlerRemoveGroupMarker, |
|
|
@ -12,7 +13,6 @@ import { |
|
|
|
import { drawTypeChangeAction } from '../../../../modules/control/map/actions/controlMapActions'; |
|
|
|
import { drawTypeChangeAction } from '../../../../modules/control/map/actions/controlMapActions'; |
|
|
|
import MapboxDraw from '@mapbox/mapbox-gl-draw'; |
|
|
|
import MapboxDraw from '@mapbox/mapbox-gl-draw'; |
|
|
|
import { CircleMode } from 'mapbox-gl-draw-circle'; |
|
|
|
import { CircleMode } from 'mapbox-gl-draw-circle'; |
|
|
|
import axios from '../../../../modules/utils/customAxiosUtil'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const LaancDrawControl = props => { |
|
|
|
export const LaancDrawControl = props => { |
|
|
|
const dispatch = useDispatch(); |
|
|
|
const dispatch = useDispatch(); |
|
|
@ -96,9 +96,10 @@ export const LaancDrawControl = props => { |
|
|
|
const lngLat = handlerGetMidPoint(coords[len - 2], coords[len - 1]); |
|
|
|
const lngLat = handlerGetMidPoint(coords[len - 2], coords[len - 1]); |
|
|
|
const text = CalculateDistance(coords[len - 2], coords[len - 1]); |
|
|
|
const text = CalculateDistance(coords[len - 2], coords[len - 1]); |
|
|
|
|
|
|
|
|
|
|
|
handlerCreateOneMarker([0, 0], lngLat, text, obj.id); |
|
|
|
handlerCreateOneMarker(mapObject, [0, 0], lngLat, text, obj.id); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
handlerCreateOneMarker( |
|
|
|
handlerCreateOneMarker( |
|
|
|
|
|
|
|
mapObject, |
|
|
|
[0, -10], |
|
|
|
[0, -10], |
|
|
|
[e.lngLat.lng, e.lngLat.lat], |
|
|
|
[e.lngLat.lng, e.lngLat.lat], |
|
|
|
'Start', |
|
|
|
'Start', |
|
|
@ -125,7 +126,13 @@ export const LaancDrawControl = props => { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
drawObj.setFeatureProperty(data.id, 'id', mode); |
|
|
|
drawObj.setFeatureProperty(data.id, 'id', mode); |
|
|
|
handlerCreateOneMarker([0, -10], data.coord, data.radius, data.id); |
|
|
|
handlerCreateOneMarker( |
|
|
|
|
|
|
|
mapObject, |
|
|
|
|
|
|
|
[0, -10], |
|
|
|
|
|
|
|
data.coord, |
|
|
|
|
|
|
|
data.radius, |
|
|
|
|
|
|
|
data.id |
|
|
|
|
|
|
|
); |
|
|
|
handlerAbnormalityCheck(data, mode); |
|
|
|
handlerAbnormalityCheck(data, mode); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
const obj = state[mode.toLowerCase()]; |
|
|
|
const obj = state[mode.toLowerCase()]; |
|
|
@ -204,7 +211,13 @@ export const LaancDrawControl = props => { |
|
|
|
id: obj.id |
|
|
|
id: obj.id |
|
|
|
}; |
|
|
|
}; |
|
|
|
handlerRemoveGroupMarker(obj.id); |
|
|
|
handlerRemoveGroupMarker(obj.id); |
|
|
|
handlerCreateOneMarker([0, -10], data.coord, data.radius, data.id); |
|
|
|
handlerCreateOneMarker( |
|
|
|
|
|
|
|
mapObject, |
|
|
|
|
|
|
|
[0, -10], |
|
|
|
|
|
|
|
data.coord, |
|
|
|
|
|
|
|
data.radius, |
|
|
|
|
|
|
|
data.id |
|
|
|
|
|
|
|
); |
|
|
|
handlerAbnormalityCheck(data, mode); |
|
|
|
handlerAbnormalityCheck(data, mode); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// 폴리곤은 중첩좌표 제거해서 서버에 넘겨야함
|
|
|
|
// 폴리곤은 중첩좌표 제거해서 서버에 넘겨야함
|
|
|
@ -294,7 +307,6 @@ export const LaancDrawControl = props => { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// areaInfo 셋팅
|
|
|
|
// areaInfo 셋팅
|
|
|
|
// const handlerSaveAreaInfo = (coord, mode) => {
|
|
|
|
|
|
|
|
const handlerSaveAreaInfo = data => { |
|
|
|
const handlerSaveAreaInfo = data => { |
|
|
|
if (!data.coord || !data.mode) { |
|
|
|
if (!data.coord || !data.mode) { |
|
|
|
alert('에러 발생. 다시 시도해 주세요.'); |
|
|
|
alert('에러 발생. 다시 시도해 주세요.'); |
|
|
@ -353,6 +365,7 @@ export const LaancDrawControl = props => { |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 두 좌표배열이 완전히 일치하는지 판단
|
|
|
|
const handlerArraysAreEqual = (arr1, arr2) => { |
|
|
|
const handlerArraysAreEqual = (arr1, arr2) => { |
|
|
|
if (arr1 === arr2) return true; |
|
|
|
if (arr1 === arr2) return true; |
|
|
|
if (arr1.length !== arr2.length) return false; |
|
|
|
if (arr1.length !== arr2.length) return false; |
|
|
@ -375,7 +388,7 @@ export const LaancDrawControl = props => { |
|
|
|
const areas = props.areaCoordList; |
|
|
|
const areas = props.areaCoordList; |
|
|
|
if (areas.length > 0 && objs.length > 0) { |
|
|
|
if (areas.length > 0 && objs.length > 0) { |
|
|
|
// areas -> 현재는 1개이지만 추후에 데이터가 바뀌면 여러개의 도형도 처리 가능!
|
|
|
|
// areas -> 현재는 1개이지만 추후에 데이터가 바뀌면 여러개의 도형도 처리 가능!
|
|
|
|
areas.forEach((area, idx) => { |
|
|
|
areas.map((area, idx) => { |
|
|
|
const paths = []; |
|
|
|
const paths = []; |
|
|
|
area.coordList.forEach(coord => paths.push([coord.lon, coord.lat])); |
|
|
|
area.coordList.forEach(coord => paths.push([coord.lon, coord.lat])); |
|
|
|
if (area.areaType) { |
|
|
|
if (area.areaType) { |
|
|
@ -411,16 +424,15 @@ export const LaancDrawControl = props => { |
|
|
|
const oldBuffer = objs.find( |
|
|
|
const oldBuffer = objs.find( |
|
|
|
obj => obj.properties?.lineId === lineId |
|
|
|
obj => obj.properties?.lineId === lineId |
|
|
|
); |
|
|
|
); |
|
|
|
drawObj.delete(oldBuffer.id); |
|
|
|
if (oldBuffer) drawObj.delete(oldBuffer?.id); |
|
|
|
|
|
|
|
|
|
|
|
// 새 버퍼 생성
|
|
|
|
// 새 버퍼 생성
|
|
|
|
const newBuffer = { |
|
|
|
const bufferId = handlerCreateDrawObj( |
|
|
|
type: 'LineString', |
|
|
|
'LineString', |
|
|
|
coordinates: bufferPaths |
|
|
|
bufferPaths, |
|
|
|
}; |
|
|
|
'BUFFER' |
|
|
|
const newBufferId = drawObj.add(newBuffer); |
|
|
|
); |
|
|
|
drawObj.setFeatureProperty(newBufferId[0], 'id', 'BUFFER'); |
|
|
|
drawObj.setFeatureProperty(bufferId, 'lineId', lineId); |
|
|
|
drawObj.setFeatureProperty(newBufferId[0], 'lineId', lineId); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
objId = lineId; |
|
|
|
objId = lineId; |
|
|
|
} |
|
|
|
} |
|
|
@ -449,94 +461,117 @@ export const LaancDrawControl = props => { |
|
|
|
id: objId |
|
|
|
id: objId |
|
|
|
}; |
|
|
|
}; |
|
|
|
handlerRemoveGroupMarker(data.id); |
|
|
|
handlerRemoveGroupMarker(data.id); |
|
|
|
handlerCreateGroupMarker(data, area.areaType); |
|
|
|
handlerCreateGroupMarker(mapObject, data, area.areaType); |
|
|
|
} |
|
|
|
} |
|
|
|
dispatch(drawTypeChangeAction('DONE')); |
|
|
|
dispatch(drawTypeChangeAction('DONE')); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} else if (areas.length > 0 && areas[0].areaType) { |
|
|
|
|
|
|
|
// 이미 그려진 지도 다시 열었을 때
|
|
|
|
|
|
|
|
areas.map(area => { |
|
|
|
|
|
|
|
const paths = []; |
|
|
|
|
|
|
|
area.coordList.forEach(coord => paths.push([coord.lon, coord.lat])); |
|
|
|
|
|
|
|
if (area.areaType) { |
|
|
|
|
|
|
|
console.log('ReDraw', area); |
|
|
|
|
|
|
|
if (area.areaType === 'CIRCLE') { |
|
|
|
|
|
|
|
const center = paths[0]; |
|
|
|
|
|
|
|
const km = area.bufferZone / 1000; |
|
|
|
|
|
|
|
const step = 64; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ret = []; |
|
|
|
|
|
|
|
const disX = |
|
|
|
|
|
|
|
km / (111.32 * Math.cos((center[1] * Math.PI) / 180)); |
|
|
|
|
|
|
|
const disY = km / 110.574; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < step; i++) { |
|
|
|
|
|
|
|
const theta = (i / step) * (2 * Math.PI); |
|
|
|
|
|
|
|
const x = disX * Math.cos(theta); |
|
|
|
|
|
|
|
const y = disY * Math.sin(theta); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret.push([center[0] + x, center[1] + y]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ret.push(ret[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const circle = { |
|
|
|
|
|
|
|
type: 'Feature', |
|
|
|
|
|
|
|
geometry: { |
|
|
|
|
|
|
|
type: 'Polygon', |
|
|
|
|
|
|
|
coordinates: [ret] |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
properties: { |
|
|
|
|
|
|
|
id: 'CIRCLE', |
|
|
|
|
|
|
|
isCircle: true, |
|
|
|
|
|
|
|
radiusInKm: km, |
|
|
|
|
|
|
|
center: center |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
const newCircleId = drawObj.add(circle); |
|
|
|
|
|
|
|
const data = { |
|
|
|
|
|
|
|
coord: paths[0], |
|
|
|
|
|
|
|
id: newCircleId[0], |
|
|
|
|
|
|
|
bufferZone: km * 1000 |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
handlerCreateGroupMarker(mapObject, data, area.areaType); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (area.areaType === 'LINE') { |
|
|
|
|
|
|
|
const lineId = handlerCreateDrawObj( |
|
|
|
|
|
|
|
'LineString', |
|
|
|
|
|
|
|
paths, |
|
|
|
|
|
|
|
'LINE' |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
// 버퍼 생성
|
|
|
|
|
|
|
|
if (area.bufferCoordList) { |
|
|
|
|
|
|
|
const bufferPaths = []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
area.bufferCoordList.forEach(bfCoord => |
|
|
|
|
|
|
|
bufferPaths.push([bfCoord.lon, bfCoord.lat]) |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// 기존에 그려진 도형 지우고 새 도형 생성
|
|
|
|
const bufferId = handlerCreateDrawObj( |
|
|
|
const handlerCreateDrawObj = (id, setter, type, data, propertyId) => { |
|
|
|
'LineString', |
|
|
|
const obj = drawObj.get(id); |
|
|
|
bufferPaths, |
|
|
|
if (obj) drawObj.delete(id); |
|
|
|
'BUFFER' |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
drawObj.setFeatureProperty(bufferId, 'lineId', lineId); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (area.areaType === 'POLYGON') { |
|
|
|
|
|
|
|
paths.push(paths[0]); |
|
|
|
|
|
|
|
handlerCreateDrawObj('Polygon', [paths], 'POLYGON'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
const viewCoordObj = drawObj |
|
|
|
|
|
|
|
.getAll() |
|
|
|
|
|
|
|
.features.filter(o => o.properties.id !== 'BUFFER'); |
|
|
|
|
|
|
|
props.setViewCoordObj(viewCoordObj); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 도형 생성 + 마커 생성(circle만 사용안함)
|
|
|
|
|
|
|
|
const handlerCreateDrawObj = (type, paths, propertyId) => { |
|
|
|
const newObj = { |
|
|
|
const newObj = { |
|
|
|
type: type, |
|
|
|
type: type, |
|
|
|
coordinates: data.path |
|
|
|
coordinates: paths |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const newObjId = drawObj.add(newObj); |
|
|
|
const newObjId = drawObj.add(newObj); |
|
|
|
if (propertyId === 'CIRCLE') { |
|
|
|
|
|
|
|
drawObj.setFeatureProperty(newObjId[0], 'isCircle', true); |
|
|
|
|
|
|
|
drawObj.setFeatureProperty(newObjId[0], 'center', data.center); |
|
|
|
|
|
|
|
drawObj.setFeatureProperty(newObjId[0], 'radiusInKm', data.radius / 1000); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
drawObj.setFeatureProperty(newObjId[0], 'id', propertyId); |
|
|
|
drawObj.setFeatureProperty(newObjId[0], 'id', propertyId); |
|
|
|
setter(newObjId[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (propertyId !== 'BUFFER') { |
|
|
|
|
|
|
|
drawObj.changeMode('direct_select', { |
|
|
|
|
|
|
|
featureId: newObjId[0] |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // 지도에 있는 모든 마커 삭제
|
|
|
|
const data = { |
|
|
|
// const handlerRemoveAllMarker = () => {
|
|
|
|
coord: paths, |
|
|
|
// const ele = document.getElementsByClassName('mapboxgl-popup');
|
|
|
|
id: newObjId[0] |
|
|
|
// const eleArr = Array.from(ele);
|
|
|
|
|
|
|
|
// eleArr?.forEach(marker => marker.remove());
|
|
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // 해당되는 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, id)) |
|
|
|
|
|
|
|
.addTo(mapObject); |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 해당되는 id의 마커 생성
|
|
|
|
if (propertyId !== 'BUFFER') |
|
|
|
const handlerCreateGroupMarker = (data, mode) => { |
|
|
|
handlerCreateGroupMarker(mapObject, data, propertyId); |
|
|
|
const areas = props.areaCoordList[0]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mode !== 'CIRCLE') { |
|
|
|
return newObjId[0]; |
|
|
|
const coord = mode === 'LINE' ? data.coord : data.coord[0]; |
|
|
|
|
|
|
|
for (let i = 0; i < coord.length; i++) { |
|
|
|
|
|
|
|
const coords = coord; |
|
|
|
|
|
|
|
if (i === 0) { |
|
|
|
|
|
|
|
handlerCreateOneMarker([0, -10], coords[i], 'Start', data.id); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
const lngLat = handlerGetMidPoint(coords[i - 1], coords[i]); |
|
|
|
|
|
|
|
const text = CalculateDistance(coords[i - 1], coords[i]); |
|
|
|
|
|
|
|
handlerCreateOneMarker([0, 0], lngLat, text, data.id); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
handlerCreateOneMarker([0, -10], coords[0], areas.bufferZone, data.id); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const drawInit = () => { |
|
|
|
const drawInit = () => { |
|
|
|
const mode = mapControl.drawType; |
|
|
|
const mode = mapControl.drawType; |
|
|
|
if (mode !== 'DONE') { |
|
|
|
if (mode !== 'DONE') { |
|
|
|
// console.log(mode, 'mode----');
|
|
|
|
|
|
|
|
if (!props.addData.isAddable) { |
|
|
|
if (!props.addData.isAddable) { |
|
|
|
// 추가 상태가 아닐 때
|
|
|
|
// 추가 상태가 아닐 때
|
|
|
|
drawObj.deleteAll(); |
|
|
|
drawObj.deleteAll(); |
|
|
@ -546,7 +581,6 @@ export const LaancDrawControl = props => { |
|
|
|
props.handlerSaveCheck(false); |
|
|
|
props.handlerSaveCheck(false); |
|
|
|
|
|
|
|
|
|
|
|
props.handlerInitCoordinates(); |
|
|
|
props.handlerInitCoordinates(); |
|
|
|
// setDrawObjId();
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!mode || mode === 'RESET') { |
|
|
|
if (!mode || mode === 'RESET') { |
|
|
|