Browse Source

laanc 비행구역 에러 수정 및 비가시권 문구 수정

pull/2/head
junh_eee(이준희) 11 months ago
parent
commit
4d95904cbf
  1. 358
      src/components/map/mapbox/draw/LaancDrawControl.js
  2. 2
      src/utility/DrawUtil.js

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

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

2
src/utility/DrawUtil.js

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

Loading…
Cancel
Save