Browse Source

laanc 비행구역 설정했던 구역 사라지는 현상 수정

pull/2/head
junh_eee(이준희) 11 months ago
parent
commit
4168a3fd23
  1. 198
      src/components/map/mapbox/draw/LaancDrawControl.js
  2. 36
      src/utility/DrawUtil.js

198
src/components/map/mapbox/draw/LaancDrawControl.js

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

36
src/utility/DrawUtil.js

@ -17,7 +17,6 @@ export const InitFeature = (type, id) => {
export const FormattingCoord = coord => { export const FormattingCoord = coord => {
const resultArr = []; const resultArr = [];
// console.log(coord, '>>>>>>>>coord');
if (!Array.isArray(coord)) return; if (!Array.isArray(coord)) return;
coord?.forEach(co => { coord?.forEach(co => {
@ -31,8 +30,6 @@ export const FormattingCoord = coord => {
}; };
// 거리 계산(meters로 리턴) // 거리 계산(meters로 리턴)
// 사용 1. 원의 센터로부터 e.coord까지
// 사용 2. distance 마커
export const CalculateDistance = (mouse, center) => { export const CalculateDistance = (mouse, center) => {
const centerCoord = turf.point(center); const centerCoord = turf.point(center);
const mouseCoord = turf.point(mouse); const mouseCoord = turf.point(mouse);
@ -76,7 +73,7 @@ export const fromMetersToText = meters => {
// circle 360도 좌표 반환 // circle 360도 좌표 반환
export const handlerGetCircleCoord = (center, distance) => { export const handlerGetCircleCoord = (center, distance) => {
const options = { const options = {
steps: 360, steps: 63,
units: 'kilometers' units: 'kilometers'
}; };
return turf.circle(center, distance / 1000, options).geometry.coordinates; return turf.circle(center, distance / 1000, options).geometry.coordinates;
@ -137,6 +134,37 @@ export const handlerRemoveGroupMarker = id => {
}); });
}; };
// 개별 마커 생성
export const handlerCreateOneMarker = (map, anchor, lngLat, text, id) => {
const popup = new mapboxgl.Popup({
offset: anchor,
closeButton: false,
closeOnClick: false
})
.setLngLat(lngLat)
.setHTML(handlerGetHtmlContent(text, id))
.addTo(map);
};
// 해당되는 id의 마커 생성
export const handlerCreateGroupMarker = (map, data, mode) => {
if (mode !== 'CIRCLE') {
const coord = mode === 'LINE' ? data.coord : data.coord[0];
for (let i = 0; i < coord.length; i++) {
const coords = coord;
if (i === 0) {
handlerCreateOneMarker(map, [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(map, [0, 0], lngLat, text, data.id);
}
}
} else {
handlerCreateOneMarker(map, [0, -10], data.coord, data.bufferZone, data.id);
}
};
// draw 레이어 // draw 레이어
export const layerWayPoint = source => { export const layerWayPoint = source => {
return { return {

Loading…
Cancel
Save