diff --git "a/src/components/map/mapbox/draw/\bLaancModal.js" "b/src/components/map/mapbox/draw/\bLaancModal.js"
new file mode 100644
index 0000000..7999946
--- /dev/null
+++ "b/src/components/map/mapbox/draw/\bLaancModal.js"
@@ -0,0 +1,32 @@
+import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
+
+export default function LaancModal({ modal, handler }) {
+ const handlerDroneOneStop = () => {
+ window.open('https://drone.onestop.go.kr/', '드론원스탑');
+ handler();
+ };
+ return (
+
+
+ 특별 비행 신청
+
+ 육안으로 기체를 확인할 수 없는 가시권 밖 범위는 특별비행 신청을
+ 진행하셔야 합니다. 드론원스톱을 통해서 신청해 주시기 바랍니다.
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/map/mapbox/draw/LaancDrawControl.js b/src/components/map/mapbox/draw/LaancDrawControl.js
index 75411c7..d0b26d2 100644
--- a/src/components/map/mapbox/draw/LaancDrawControl.js
+++ b/src/components/map/mapbox/draw/LaancDrawControl.js
@@ -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);
diff --git a/src/utility/DrawUtil.js b/src/utility/DrawUtil.js
index 5fa1d29..01fc17f 100644
--- a/src/utility/DrawUtil.js
+++ b/src/utility/DrawUtil.js
@@ -49,7 +49,7 @@ export const handlerGetMidPoint = (dis1, dis2) => {
};
// html Content 반환
-export const handlerGetHtmlContent = distance => {
+export const handlerGetHtmlContent = (distance, id) => {
const text =
typeof distance === 'number'
? '거리 ' + fromMetersToText(distance)
@@ -57,6 +57,7 @@ export const handlerGetHtmlContent = distance => {
return (
''
);
diff --git a/src/views/laanc/FlightArea.js b/src/views/laanc/FlightArea.js
index 64811b1..98d087b 100644
--- a/src/views/laanc/FlightArea.js
+++ b/src/views/laanc/FlightArea.js
@@ -67,7 +67,8 @@ export default function FlightArea({
desc: ''
});
- // console.log('>>>');
+ const [isSaveable, setIsSaveable] = useState(false);
+
//날씨 임시 데이터
const [wheather, setWheather] = useState([]);
@@ -507,6 +508,7 @@ export default function FlightArea({
centeredModal={centeredModal}
mapContainer={mapContainer}
drawObj={drawObj}
+ setIsSaveable={setIsSaveable}
/>
@@ -577,6 +579,7 @@ export default function FlightArea({