hhjk00 11 months ago
parent
commit
96f6e5bf5e
  1. 4
      src/components/laanc/map/LaancAreaMap.js
  2. 366
      src/components/laanc/map/LaancDrawControl.js
  3. 2
      src/components/laanc/map/LaancMapSearch.js
  4. 2
      src/utility/DrawUtil.js

4
src/components/laanc/map/LaancAreaMap.js

@ -30,8 +30,8 @@ import flatGimpo from '../../map/geojson/flatGimpoAirportAirArea.json';
import gimpo from '../../map/geojson/gimpoAirportAirArea.json';
import geoJson from '../../map/geojson/airArea.json';
import { FeatureAirZone } from '../../map/mapbox/feature/FeatureAirZone';
import LaancMapSearch from '../../map/mapbox/draw/LaancMapSearch';
import { LaancDrawControl } from '../../map/mapbox/draw/LaancDrawControl';
import LaancMapSearch from './LaancMapSearch';
import { LaancDrawControl } from './LaancDrawControl';
import LaancModal from '../../map/mapbox/draw/LaancModal';
export default function LaancAreaMap({

366
src/components/map/mapbox/draw/LaancDrawControl.js → src/components/laanc/map/LaancDrawControl.js

@ -1,5 +1,5 @@
import { useEffect, useState } from 'react';
import { InfoModal } from '../../../modal/InfoModal';
import { InfoModal } from '../../modal/InfoModal';
import { useDispatch, useSelector } from 'react-redux';
import {
CalculateDistance,
@ -9,11 +9,11 @@ import {
handlerRemoveAllMarker,
handlerRemoveGroupMarker,
handlerReturnMode
} from '../../../../utility/DrawUtil';
import { drawTypeChangeAction } from '../../../../modules/control/map/actions/controlMapActions';
} from '../../../utility/DrawUtil';
import { drawTypeChangeAction } from '../../../modules/control/map/actions/controlMapActions';
import MapboxDraw from '@mapbox/mapbox-gl-draw';
import { CircleMode } from 'mapbox-gl-draw-circle';
import axios from '../../../../modules/utils/customAxiosUtil';
import axios from '../../../modules/utils/customAxiosUtil';
export const LaancDrawControl = props => {
const dispatch = useDispatch();
@ -50,7 +50,7 @@ export const LaancDrawControl = props => {
const modeArr = [DrawLineStringMode, DrawPolygonMode, DrawCircleMode];
modeArr.forEach(m => {
m.onStop = state => handlerDblClickFinish(state);
m.onStop = state => handlerFinishDraw(state);
// onClick 이벤트 오버라이드
const origin = m.onClick;
@ -77,19 +77,19 @@ export const LaancDrawControl = props => {
const handlerCustomOnClick = (state, e) => {
console.log('click');
const type = handlerReturnMode(drawObj.getMode());
const obj = state[type?.toLowerCase()];
const mode = handlerReturnMode(drawObj.getMode());
const obj = state[mode?.toLowerCase()];
if (type && obj) {
if (mode && obj) {
const feature = drawObj.get(obj.id);
const coordinates = feature.geometry.coordinates;
if (type !== 'CIRCLE') {
const initCoords = feature.geometry.coordinates;
if (mode !== 'CIRCLE') {
if (state.currentVertexPosition > 1) {
const coords = [
...new Set(
type === 'LINE'
? coordinates.map(JSON.stringify)
: coordinates[0].map(JSON.stringify)
mode === 'LINE'
? initCoords.map(JSON.stringify)
: initCoords[0].map(JSON.stringify)
)
].map(JSON.parse);
@ -112,39 +112,58 @@ export const LaancDrawControl = props => {
};
// 도형 그리기 완료 시
// drawType을 바꾸면 종료처리가 돼서 이게 실행되는 듯
const handlerDblClickFinish = state => {
const handlerFinishDraw = state => {
console.log('finish');
const mode = handlerReturnMode(drawObj.getMode());
if (state.currentVertexPosition !== 0) {
console.log('dblclick');
const pointLength = state.currentVertexPosition;
if (pointLength > 0) {
if (mode === 'CIRCLE') {
const obj = state.polygon;
const { properties, id } = state.polygon;
const data = {
coord: obj.properties.center,
radius: obj.properties.radiusInKm * 1000,
id: obj.id
coords: properties.center,
mode: mode,
id: id,
radius: properties.radiusInKm * 1000
};
drawObj.setFeatureProperty(data.id, 'id', mode);
drawObj.setFeatureProperty(id, 'id', mode);
handlerAbnormalityCheck(data).then(areaInfo => {
if (areaInfo) {
handlerCreateOneMarker(
mapObject,
[0, -10],
data.coord,
data.coords,
data.radius,
data.id
);
handlerAbnormalityCheck(data, mode);
handlerSaveData(areaInfo);
}
});
} else {
const obj = state[mode.toLowerCase()];
const length = state.currentVertexPosition;
if (obj.coordinates.length > 0) {
drawObj?.setFeatureProperty(obj.id, 'id', mode);
const minPoint = mode === 'LINE' ? 2 : 3;
const desc = mode === 'LINE' ? '두' : '세';
// 좌표 최소 개수 체크
if (pointLength < minPoint) {
props.setModal({
title: '좌표 최소 개수',
desc: <>좌표를 {desc} 점으로 이어주세요.</>,
isOpen: true
});
handlerRemoveError(obj.id);
return;
}
const coords = mode === 'LINE' ? obj.coordinates : obj.coordinates[0];
coords.splice(-1);
const data = { coords: coords, mode: mode, id: obj.id };
handlerAbnormalityCheck(data).then(areaInfo => {
if (areaInfo) {
drawObj.setFeatureProperty(obj.id, 'id', mode);
// dbl클릭이 click 두번으로 인식돼서, 마지막 값을 없애버리기로 함
if (mode === 'LINE') {
obj.coordinates.splice(-1);
// 여기서 버퍼 빈양식 만들어주자!
const buffer = drawObj.get(bufferId);
if (buffer) drawObj.delete(bufferId);
@ -156,45 +175,11 @@ export const LaancDrawControl = props => {
drawObj.setFeatureProperty(newBufferId[0], 'id', 'BUFFER');
drawObj.setFeatureProperty(newBufferId[0], 'lineId', obj.id);
setBufferId(newBufferId[0]);
}
if (length < 2) {
// setAlertModal({
// isOpen: true,
// title: '좌표 최소 개수',
// desc: '좌표를 두 개 점으로 이어주세요.'
// });
props.setModal({
title: '좌표 최소 개수',
desc: <>좌표를 점으로 이어주세요.</>,
isOpen: true
});
handlerRemoveError(obj.id);
return;
handlerSaveData(areaInfo);
}
} else if (mode === 'POLYGON') {
obj.coordinates[0].splice(-1);
if (length < 3) {
// setAlertModal({
// isOpen: true,
// title: '좌표 최소 개수',
// desc: '좌표를 세 개 점으로 이어주세요.'
// });
props.setModal({
title: '좌표 최소 개수',
desc: <>좌표를 점으로 이어주세요.</>,
isOpen: true
});
handlerRemoveError(obj.id);
return;
}
}
const data = {
coord: obj.coordinates,
id: obj.id
};
handlerAbnormalityCheck(data, mode);
}
}
} else {
// 좌표가 찍히기도 전에 틀만 생성된 도형들 삭제
@ -208,72 +193,55 @@ export const LaancDrawControl = props => {
}
};
// 도형 수정 시
const handlerUpdateSetting = e => {
console.log('update');
// 모든 비정상상황 체크
const handlerAbnormalityCheck = async data => {
// radius도 있음
const { coords, mode, id } = data;
if (e.features[0]) {
const obj = e.features[0];
const mode = obj.properties.id;
const initCoord = obj.geometry.coordinates;
const areaInfo = handlerSettingAreaInfo(coords, mode);
const areaList = props.handlerAreaInfoToAreaList(areaInfo);
let isBreak = false;
// 비행금지 구역 체크
console.log('unableElev');
try {
const elev1 = await axios.post(`api/bas/laanc/valid/elev`, areaList);
const elev2 = [];
if (mode === 'CIRCLE') {
const data = {
coord: obj.properties.center,
radius: obj.properties.radiusInKm * 1000,
id: obj.id
};
handlerRemoveGroupMarker(obj.id);
handlerCreateOneMarker(
mapObject,
[0, -10],
data.coord,
data.radius,
data.id
);
handlerAbnormalityCheck(data, mode);
const point = mapObject.project(coords);
const maine = mapObject.queryRenderedFeatures(point, {
layers: ['maine']
});
if (maine.length > 0) {
if (maine[0].properties.description.includes('김포공항 비행불가')) {
elev2.push(maine[0]);
isBreak = true;
}
}
} else {
// 폴리곤은 중첩좌표 제거해서 서버에 넘겨야함
if (mode === 'POLYGON') initCoord[0].splice(-1);
const data = {
coord: initCoord,
id: obj.id
};
for (let i = 0; i < coords.length; i++) {
const point = mapObject.project(coords[i]);
const maine = mapObject.queryRenderedFeatures(point, {
layers: ['maine']
});
// handlerRemoveGroupMarker(obj.id);
// handlerCreateGroupMarker(data, mode);
handlerAbnormalityCheck(data, mode);
if (maine.length > 0) {
if (maine[0].properties.description.includes('김포공항 비행불가')) {
elev2.push(maine[0]);
isBreak = true;
break;
}
}
}
}
};
// 모든 비정상상황 체크
const handlerAbnormalityCheck = async (data, mode) => {
console.log('비정상체크');
const initCoord =
mode === 'LINE'
? data.coord
: mode === 'POLYGON'
? data.coord[0]
: mode === 'CIRCLE'
? data.coord
: null;
const datas = { coord: initCoord, mode: mode };
const areaInfo = handlerSettingAreaInfo(datas);
const areaList = props.handlerAreaInfoToAreaList(areaInfo);
const isBreak1 = handlerIsSpecialFlight(data, mode);
const isBreak2 = handlerIsUnableArea(data, mode);
if (isBreak1 || isBreak2) return;
try {
console.log('unableElev');
const result = await axios.post(`api/bas/laanc/valid/elev`, areaList);
if (elev1.data[0] === 0 || elev2.length > 0) isBreak = true;
} catch (error) {
alert('에러 발생');
}
if (result.data[0] === 0) {
if (isBreak) {
props.setModal({
title: '비행 불가 지역',
desc: (
@ -285,36 +253,34 @@ export const LaancDrawControl = props => {
),
isOpen: true
});
handlerRemoveError(data.id);
handlerRemoveError(id);
return;
} else {
props.handlerSaveCheck(true);
}
} catch (error) {
alert('에러 발생');
}
handlerSaveData(areaInfo);
};
// 비가시권 검사
const handlerIsSpecialFlight = (data, mode) => {
// 비가시권 체크
console.log('specialFlight');
let isBreak = false;
let text = '';
if (mode === 'CIRCLE') {
if (data.radius > 1000) {
text = 'circle의 경우 반경';
isBreak = true;
}
} else {
const coords = mode === 'LINE' ? data.coord : data.coord[0];
for (let point = 0; point < coords.length - 1; point++) {
const distance = CalculateDistance(coords[point], coords[point + 1]);
if (mode === 'POLYGON') coords.push(coords[0]);
for (let j = 0; j < coords.length - 1; j++) {
const distance = CalculateDistance(coords[j], coords[j + 1]);
if (distance > 1000) {
text =
mode === 'LINE'
? 'waypoint의 경우 점과 점 사이가'
: 'polygon의 경우 변과 변 사이가';
isBreak = true;
break;
}
}
if (mode === 'POLYGON') coords.splice(-1);
}
if (isBreak) {
@ -322,74 +288,65 @@ export const LaancDrawControl = props => {
title: '특별 비행 신청',
desc: (
<>
육안으로 기체 확인이 불가능 합니다.
<br /> 가시권 범위는 특별비행 신청을 진행하셔야 합니다. <br />
드론원스톱을 통해서 신청해 주시기 바랍니다.
{text} 1km 초과 가시권에 해당됩니다.
<br />
가시권의 경우 특별비행 승인 신청이 필요하니,
<br />
아래 링크를 통해 드론원스톱으로 신청해 주시기 바랍니다.
</>
),
isOpen: true
});
handlerRemoveError(data.id);
return true;
handlerRemoveError(id);
return;
} else {
props.handlerSaveCheck(true);
return false;
return areaInfo;
}
};
// 비행불가지역 검사
const handlerIsUnableArea = (data, mode) => {
console.log('unableArea');
let isBreak = false;
// 도형 수정 시
const handlerUpdateSetting = e => {
console.log('update');
if (mode === 'CIRCLE') {
const point = mapObject.project(data.coord);
const maine = mapObject.queryRenderedFeatures(point, {
layers: ['maine']
});
if (e.features[0]) {
const { geometry, properties, id } = e.features[0];
const mode = properties.id;
const coords =
mode === 'LINE' ? geometry.coordinates : geometry.coordinates[0];
if (maine.length > 0) {
if (maine[0].properties.description.includes('김포공항 비행불가')) {
isBreak = true;
// break;
}
if (mode === 'CIRCLE') {
const data = {
coords: properties.center,
mode: mode,
id: id,
radius: properties.radiusInKm * 1000
};
handlerAbnormalityCheck(data).then(areaInfo => {
if (areaInfo) {
handlerRemoveGroupMarker(id);
handlerCreateOneMarker(
mapObject,
[0, -10],
data.coords,
data.radius,
data.id
);
handlerSaveData(areaInfo);
}
});
} else {
const coord = mode === 'LINE' ? data.coord : data.coord[0];
// 폴리곤은 중첩좌표 제거해서 서버에 넘겨야함
if (mode === 'POLYGON') coords.splice(-1);
const data = { coords: coords, mode: mode, id: id };
for (let i = 0; i < coord.length; i++) {
const point = mapObject.project(coord[i]);
const maine = mapObject.queryRenderedFeatures(point, {
layers: ['maine']
// handlerRemoveGroupMarker(obj.id);
// handlerCreateGroupMarker(data, mode);
handlerAbnormalityCheck(data).then(areaInfo => {
if (areaInfo) handlerSaveData(areaInfo);
});
if (maine.length > 0) {
if (maine[0].properties.description.includes('김포공항 비행불가')) {
isBreak = true;
break;
}
}
}
}
if (isBreak) {
props.setModal({
title: '비행 불가 지역',
desc: (
<>
설정하신 비행구역 허용고도가 0m인 구역이 있습니다.
<br />
비행구역 설정 허용고도를 다시 확인해주시기 바랍니다.
</>
),
isOpen: true
});
handlerRemoveError(data.id);
return true;
} else {
props.handlerSaveCheck(true);
return false;
}
};
// 비정상 감지 시 해당 도형, 마커 삭제
@ -419,6 +376,7 @@ export const LaancDrawControl = props => {
// 정상 좌표 처리
const handlerSaveData = areaInfo => {
console.log('ok!!!');
props.handlerCoordinates(areaInfo);
setIsDrawDone(true);
@ -436,8 +394,8 @@ export const LaancDrawControl = props => {
};
// areaInfo 셋팅
const handlerSettingAreaInfo = data => {
if (!data.coord || !data.mode) {
const handlerSettingAreaInfo = (coord, mode) => {
if (!coord || !mode) {
alert('에러 발생. 다시 시도해 주세요.');
return;
}
@ -449,13 +407,13 @@ export const LaancDrawControl = props => {
areaType: ''
};
const bufferZone = data.mode === 'POLYGON' ? 0 : 100;
const bufferZone = mode === 'POLYGON' ? 0 : 100;
const prePath = [];
areaInfo.areaType = data.mode;
areaInfo.areaType = mode;
if (areaInfo.areaType !== 'CIRCLE') {
data.coord.forEach(item => {
coord.forEach(item => {
const p = {
lat: item[1],
lon: item[0]
@ -471,28 +429,14 @@ export const LaancDrawControl = props => {
const feature = obj.filter(o => o.properties.id === 'CIRCLE');
const point = {
lat: data.coord[1],
lon: data.coord[0]
lat: coord[1],
lon: coord[0]
};
areaInfo.coordinates = [point];
areaInfo.bufferZone = feature[0].properties.radiusInKm * 1000;
}
return areaInfo;
// props.handlerCoordinates(areaInfo);
// setIsDrawDone(true);
// const viewCoordObj = drawObj
// .getAll()
// .features.filter(o => o.properties.id !== 'BUFFER');
// props.setViewCoordObj(viewCoordObj);
// if (viewCoordObj.length > 19) {
// props.handlerAddChange('overAdd', true);
// } else {
// props.handlerAddChange('isViewAdd', true);
// }
};
// 두 좌표배열이 완전히 일치하는지 판단
@ -550,6 +494,8 @@ export const LaancDrawControl = props => {
}
}
if (lineId === '') return;
// features중에 위에서 찾은 lineId값을 properties로 갖고 있는 버퍼를 찾아서 지워줌
const oldBuffer = objs.find(
obj => obj.properties?.lineId === lineId

2
src/components/map/mapbox/draw/LaancMapSearch.js → src/components/laanc/map/LaancMapSearch.js

@ -1,7 +1,7 @@
import { Input, InputGroup, InputGroupAddon, InputGroupText } from 'reactstrap';
import { Search } from 'react-feather';
import { useState } from 'react';
import { flightPlanAPI } from '../../../../modules/basis/flight/apis/basisFlightApi';
import { flightPlanAPI } from '../../../modules/basis/flight/apis/basisFlightApi';
export default function LaancMapSearch({ mapObject }) {
const [query, setQuery] = useState('');

2
src/utility/DrawUtil.js

@ -136,6 +136,8 @@ export const handlerRemoveGroupMarker = id => {
// 개별 마커 생성
export const handlerCreateOneMarker = (map, anchor, lngLat, text, id) => {
if (!id) return;
const popup = new mapboxgl.Popup({
offset: anchor,
closeButton: false,

Loading…
Cancel
Save