Browse Source

laanc 비행구역 주석

pull/1/head
junh_eee(이준희) 10 months ago
parent
commit
41aba97aab
  1. 237
      src/components/laanc/map/FlightArea.js
  2. 158
      src/components/laanc/map/LaancAreaMap.js
  3. 73
      src/components/laanc/map/LaancComn.js
  4. 64
      src/components/laanc/map/LaancDrawControl.js
  5. 34
      src/utility/DrawUtil.js

237
src/components/laanc/map/FlightArea.js

@ -1,6 +1,9 @@
import { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
// mapbox
import 'mapbox-gl/dist/mapbox-gl.css';
import mapboxgl from 'mapbox-gl';
import threebox from 'threebox-plugin';
import MapboxLanguage from '@mapbox/mapbox-gl-language';
import MapboxDraw from '@mapbox/mapbox-gl-draw';
import {
@ -10,18 +13,6 @@ import {
SimpleSelectMode
} from 'mapbox-gl-draw-circle';
import { MAPBOX_TOKEN } from '../../../configs/constants';
import { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import {
AREA_COORDINATE_LIST_SAVE,
AREA_DETAIL_LIST_SAVE
} from '../../../modules/basis/flight/actions/basisFlightAction';
import {
drawTypeChangeAction,
mapInitAction
} from '../../../modules/control/map/actions/controlMapActions';
import LaancAreaMap from './LaancAreaMap';
import {
InitFeature,
handlerCreatePoint,
@ -32,20 +23,26 @@ import {
layerPolyline,
layerWayPoint
} from '../../../utility/DrawUtil';
import flatGimpo from '../../map/geojson/flatGimpoAirportAirArea.json';
// actions
import {
AREA_COORDINATE_LIST_SAVE,
AREA_DETAIL_LIST_SAVE
} from '../../../modules/basis/flight/actions/basisFlightAction';
import {
drawTypeChangeAction,
mapInitAction
} from '../../../modules/control/map/actions/controlMapActions';
import * as LaancAction from '../../../modules/laanc/actions/laancActions';
// geojson
import gimpo from '../../map/geojson/gimpoAirportAirArea.json';
import geoJson from '../../map/geojson/airArea.json';
import threebox from 'threebox-plugin';
import { FeatureAirZone } from '../../map/mapbox/feature/FeatureAirZone';
import { WeatherContainer } from '../../../containers/basis/flight/plan/WeatherContainer';
import { initFlightBas } from '../../../modules/laanc/models/laancModels';
import * as LaancAction from '../../../modules/laanc/actions/laancActions';
import LaancAreaMap from './LaancAreaMap';
import LaancDrawModal from './LaancDrawModal';
const initialAddData = {
isAddable: false,
isViewAdd: false,
overAdd: false
};
import { handlerCreateAirSpace } from './LaancComn';
export default function FlightArea({
centeredModal,
@ -61,40 +58,65 @@ export default function FlightArea({
></script>;
const dispatch = useDispatch();
const { areaCoordList } = useSelector(state => state.flightState);
// 비행구역 타입 및 공역 타입
const mapControl = useSelector(state => state.controlMapReducer);
const mapContainer = useRef(null);
// 비행구역 정보 저장
const { areaCoordList } = useSelector(state => state.flightState);
// 지도
const [mapObject, setMapObject] = useState();
const [drawObj, setDrawObj] = useState();
const mapContainer = useRef(null);
// 지도 로드 여부
const [isMapLoad, setIsMapLoad] = useState(false);
// 비행구역 그리기
const [drawObj, setDrawObj] = useState();
// 미니맵 레이어
const [previewLayer, setPreviewLayer] = useState();
// 날씨 모달
const [formModal, setFormModal] = useState(false);
// 비행구역 설정 관련 모달
const [modal, setModal] = useState({
title: '',
desc: '',
isOpen: false
});
// 비행구역 저장 가능 여부
const [isSaveable, setIsSaveable] = useState(false);
const [addData, setAddData] = useState(initialAddData);
// 비행구역 추가 가능 여부 판단
const [addData, setAddData] = useState({
isAddable: false,
isViewAdd: false,
overAdd: false
});
// 저장된 비행구역 데이터
const [saveData, setSaveData] = useState();
// 비행구역 고도
const [saveElev, setSaveElev] = useState();
//날씨 임시 데이터
//날씨 위치 데이터
const [wheather, setWheather] = useState([]);
// 미니맵에 표출되는 비행구역 정보
const previewGeo = {
type: 'FeatureCollection',
features: []
};
// 지도 초기 셋팅
useEffect(() => {
handlerMapInit();
}, []);
// 미니맵에 비행구역 표출 및 날씨 정보 저장
useEffect(() => {
if (areaCoordList) {
const area = areaCoordList[0];
@ -105,78 +127,12 @@ export default function FlightArea({
}
}, [areaCoordList, centeredModal, previewLayer]);
const handlerCreateAirSpace = (
map,
useGeoJson = {
...geoJson,
...flatGimpo,
features: [...geoJson.features, ...flatGimpo.features]
}
) => {
if (map.getLayer('maine')) {
map.removeLayer('maine');
map.removeSource('maine');
}
let arrGeoJson = [];
useGeoJson.features.map(item => {
if (item.properties.type === '0001' && mapControl.area0001) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FF3648' }
});
} else if (item.properties.type === '0002' && mapControl.area0002) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FFA1AA' }
});
} else if (item.properties.type === '0003' && mapControl.area0003) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FFA800' }
});
} else if (item.properties.type === '0004' && mapControl.area0004) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#A16B00' }
});
} else if (item.properties.type === '0005' && mapControl.area0005) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#AB40FF' }
});
} else if (item.properties.type === '0006' && mapControl.area0006) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#009cad' }
});
}
});
useGeoJson.features = arrGeoJson.filter(i => i.geometry.type === 'Polygon');
// 공역 생성 start
map.addSource('maine', {
type: 'geojson',
data: {
...useGeoJson
}
});
map.addLayer({
id: 'maine',
type: 'fill',
source: 'maine',
layout: {},
paint: {
'fill-color': ['get', 'color'],
// 'fill-extrusion-height': 3000,
'fill-opacity': 0.5
}
});
};
// 비행구역 설정 관련 모달 표출
const handlerModal = () => {
setModal(!modal);
};
// 비행구역 타입 변경 시 그리기 모드 상태일 때 에러 표출
const handlerDrawType = val => {
if (drawObj.getMode().includes('draw')) {
setModal({
@ -195,6 +151,7 @@ export default function FlightArea({
}
};
// laanc계획서 비행구역 저장버튼 클릭 시 비행구역 정보 저장
const handlerSave = async () => {
if (areaCoordList) {
console.log('save');
@ -208,29 +165,28 @@ export default function FlightArea({
setCenteredModal(false);
dispatch(AREA_DETAIL_LIST_SAVE(resultAreaDetail));
} else {
alert('아무것도 작성 안함');
}
};
// 날씨 handler
// 날씨 모달 표출
const handlerWeather = () => {
setFormModal(!formModal);
};
// 지도 초기 셋팅
const handlerMapInit = () => {
mapboxgl.accessToken = MAPBOX_TOKEN;
const map = new mapboxgl.Map({
container: 'preview', // container ID
style: 'mapbox://styles/mapbox/streets-v12', // style URL
center: [126.612647, 37.519893], // starting position [lng, lat]
// zoom: !areaCoordList ? 14 : bufferZoom.bufferzoom, // starting zoom
container: 'preview',
style: 'mapbox://styles/mapbox/streets-v12',
center: [126.612647, 37.519893],
zoom: 15,
antialias: true,
attributionControl: false
});
// 비행구역 상세맵 draw 정보 셋팅
const draw = new MapboxDraw({
displayControlsDefault: false,
userProperties: true,
@ -243,16 +199,14 @@ export default function FlightArea({
simple_select: SimpleSelectMode
},
styles: [
// line stroke
{
// polyline
id: 'gl-draw-line',
type: 'line',
filter: [
'all',
['==', '$type', 'LineString'],
['!=', 'mode', 'static']
// ['==', 'meta', 'feature'],
// ['==', 'active', 'false']
],
layout: {
'line-cap': 'round',
@ -264,28 +218,8 @@ export default function FlightArea({
'line-width': 2
}
},
// direct line stroke
// {
// id: 'gl-draw-line-active',
// type: 'line',
// filter: [
// 'all',
// ['==', '$type', 'LineString'],
// ['==', 'meta', 'feature'],
// ['==', 'active', 'true']
// ],
// layout: {
// 'line-cap': 'round',
// 'line-join': 'round'
// },
// paint: {
// 'line-color': '#000000',
// 'line-dasharray': [0.2, 2],
// 'line-width': 2
// }
// },
// polygon fill
{
// polygon fill
id: 'gl-draw-polygon-fill',
type: 'fill',
filter: ['all', ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
@ -295,18 +229,7 @@ export default function FlightArea({
'fill-opacity': 0.1
}
},
// polygon mid points
{
id: 'gl-draw-polygon-midpoint',
type: 'circle',
filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'midpoint']],
paint: {
'circle-radius': 4,
'circle-color': '#8a1c05'
}
},
// polygon outline stroke
// This doesn't style the first edge of the polygon, which uses the line stroke styling instead
// polygon outline
{
id: 'gl-draw-polygon-stroke-active',
type: 'line',
@ -321,8 +244,8 @@ export default function FlightArea({
'line-width': 2
}
},
// vertex point halos
{
// vertex point halos
id: 'gl-draw-polygon-and-line-vertex-halo-active',
type: 'circle',
filter: [
@ -333,11 +256,11 @@ export default function FlightArea({
],
paint: {
'circle-radius': 8,
'circle-color': '#fff'
'circle-color': '#ffffff'
}
},
// vertex points
{
// vertex points
id: 'gl-draw-polygon-and-line-vertex-active',
type: 'circle',
filter: [
@ -359,7 +282,6 @@ export default function FlightArea({
const language = new MapboxLanguage();
map.addControl(language);
// map.addControl(draw);
const tb = (window.tb = new threebox.Threebox(
map,
@ -396,7 +318,7 @@ export default function FlightArea({
}
});
handlerCreateAirSpace(map);
handlerCreateAirSpace(map, mapControl);
// 미니맵 표출
map.addSource('preview', {
@ -417,6 +339,7 @@ export default function FlightArea({
dispatch(mapInitAction(map));
};
// 저장된 비행구역 미니맵에 표출
const handlerPreviewDraw = () => {
if (areaCoordList) {
const areas = areaCoordList[0];
@ -427,7 +350,6 @@ export default function FlightArea({
let fitZoomPaths = [];
// 기존
if (areas.areaType) {
if (areas.areaType === 'CIRCLE') {
const radius = areas.bufferZone;
@ -478,12 +400,8 @@ export default function FlightArea({
//지도 줌 좌표 설정
fitZoomPaths = paths.concat();
// 마커 삭제
// const ele = document.getElementById('mapboxgl-popup');
// const eleArr = Array.from(ele);
// eleArr?.forEach(marker => marker.remove());
}
handlerFitBounds(mapObject, fitZoomPaths, 50, areas.areaType);
mapObject.setPaintProperty('waypoint', 'circle-radius', 10);
@ -491,12 +409,13 @@ export default function FlightArea({
}
const coordValue = [];
const coord = paths?.map(coords => {
paths?.map(coords => {
coordValue.push({
lat: coords[1],
lon: coords[0]
});
});
if (page === 1) {
naver.maps.Service.reverseGeocode(
{
@ -527,7 +446,6 @@ export default function FlightArea({
name: 'latlon',
value: coordValue
});
//스텝1에 반경도 글씨가 바뀌어야 함...!!
handleChange({
type: 'area',
name: 'bufferZone',
@ -537,38 +455,33 @@ export default function FlightArea({
}
};
// 비행구역 추가 버튼 클릭 시
const handlerAddClick = () => {
if (!addData.isAddable || !addData.overAdd) {
handlerAddChange('isAddable', true);
const obj = drawObj
.getAll()
.features.filter(obj => obj.properties.id !== 'BUFFER');
// handlerDrawType(obj[0].properties.id);
}
};
// 비행구역 추가 관련 상태 변경
const handlerAddChange = (key, val) => {
// const [addData, setAddData] = useState({
// isAddalbe: false,
// isViewAdd: false,
// overAdd: false
// })
setAddData(prev => ({
...prev,
[key]: val
}));
};
// 비행구역 저장 가능 유무 체크
const handlerSaveCheck = save => {
setIsSaveable(save);
};
// 비행구역 데이터 초기화
const handlerInitCoordinates = () => {
const init = initFlightBas.initDetail.areaList.concat();
dispatch(AREA_COORDINATE_LIST_SAVE(init));
};
// 비행구역 고도 저장
const handlerSaveElev = elev => {
setSaveElev(elev);
};
@ -604,7 +517,6 @@ export default function FlightArea({
</ModalHeader>
<ModalBody>
<LaancAreaMap
centeredModal={centeredModal}
mapContainer={mapContainer}
drawObj={drawObj}
handlerInitCoordinates={handlerInitCoordinates}
@ -684,7 +596,6 @@ export default function FlightArea({
dispatch(LaancAction.LAANC_ALTITUDE.success(saveElev));
}}
>
{/* 닫기 */}
저장
</Button>
</div>

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

@ -3,7 +3,7 @@ import mapboxgl from 'mapbox-gl';
import threebox from 'threebox-plugin';
import MapboxLanguage from '@mapbox/mapbox-gl-language';
import { MAPBOX_TOKEN } from '../../../configs/constants';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Card, CardBody } from 'reactstrap';
import { initFlightBas } from '../../../modules/basis/flight/models/basisFlightModel';
@ -16,22 +16,15 @@ import { mapInitAction } from '../../../modules/control/map/actions/controlMapAc
import {
FormattingCoord,
handlerFitBounds,
handlerGetCircleCoord,
layerBuffer,
layerGuideLine,
layerPolygon,
layerPolyline,
layerWayPoint
handlerGetCircleCoord
} from '../../../utility/DrawUtil';
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 './LaancMapSearch';
import { LaancDrawControl } from './LaancDrawControl';
import { handlerCreateAirSpace } from './LaancComn';
export default function LaancAreaMap({
centeredModal,
mapContainer,
drawObj,
handlerSaveCheck,
@ -43,42 +36,38 @@ export default function LaancAreaMap({
setModal
}) {
const dispatch = useDispatch();
// 비행구역 타입 및 공역 타입
const mapControl = useSelector(state => state.controlMapReducer);
const { areaCoordList } = useSelector(state => state.flightState);
const [mapObject, setMapObject] = useState();
const [isMapLoad, setIsMapLoad] = useState(false);
const [mode, setMode] = useState();
// 비행구역 정보 저장
const { areaCoordList } = useSelector(state => state.flightState);
// 비행구역 초기값 포함 정보 저장
const [mapAreaCoordList, setMapAreaCoordList] = useState(
initFlightBas.initDetail.areaList
);
const [number, setNumber] = useState(0);
// 지도
const [mapObject, setMapObject] = useState();
// 지도 로드 여부
const [isMapLoad, setIsMapLoad] = useState(false);
// const [detailLayer, setDetailLayer] = useState();
// 지도 렌더 횟수
const [number, setNumber] = useState(0);
// 비행구역 좌표 카드에 표출될 좌표 정보
const [viewCoordObj, setViewCoordObj] = useState([]);
const detailGeo = useMemo(() => {
return {
type: 'FeatureCollection',
features: []
};
}, []);
// 좌표 정보 마우스 드래그
const scrollRef = useRef(null);
const [isDrag, setIsDrag] = useState(false);
const [startX, setStartX] = useState();
// 지도 초기 셋팅
useEffect(() => {
handlerMapInit();
}, []);
useEffect(() => {
setMode(mapControl.drawType);
}, [mapControl.drawType]);
// 첫 비행구역 생성 or 저장했던 비행구역 다시 열기 시 비행구역에 화면 맞추어서 zoom
useEffect(() => {
if (areaCoordList && mapObject) {
if (
@ -111,75 +100,7 @@ export default function LaancAreaMap({
}
}, [areaCoordList, mapObject, number]);
// 공역 생성
const handlerCreateAirSpace = (
map,
useGeoJson = {
...geoJson,
...flatGimpo,
features: [...geoJson.features, ...flatGimpo.features]
}
) => {
if (map.getLayer('maine')) {
map.removeLayer('maine');
map.removeSource('maine');
}
let arrGeoJson = [];
useGeoJson.features.map(item => {
if (item.properties.type === '0001' && mapControl.area0001) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FF3648' }
});
} else if (item.properties.type === '0002' && mapControl.area0002) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FFA1AA' }
});
} else if (item.properties.type === '0003' && mapControl.area0003) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FFA800' }
});
} else if (item.properties.type === '0004' && mapControl.area0004) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#A16B00' }
});
} else if (item.properties.type === '0005' && mapControl.area0005) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#AB40FF' }
});
} else if (item.properties.type === '0006' && mapControl.area0006) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#009cad' }
});
}
});
useGeoJson.features = arrGeoJson.filter(i => i.geometry.type === 'Polygon');
// 공역 생성 start
map.addSource('maine', {
type: 'geojson',
data: {
...useGeoJson
}
});
map.addLayer({
id: 'maine',
type: 'fill',
source: 'maine',
layout: {},
paint: {
'fill-color': ['get', 'color'],
// 'fill-extrusion-height': 3000,
'fill-opacity': 0.5
}
});
};
// 맵박스 지도 초기 셋팅
const handlerMapInit = () => {
mapboxgl.accessToken = MAPBOX_TOKEN;
@ -187,7 +108,6 @@ export default function LaancAreaMap({
container: 'detail', // container ID
style: 'mapbox://styles/mapbox/streets-v12', // style URL
center: [126.612647, 37.519893], // starting position [lng, lat]
// zoom: !areaCoordList ? 14 : bufferZoom.bufferzoom, // starting zoom
zoom: 15,
antialias: true,
attributionControl: false
@ -238,31 +158,15 @@ export default function LaancAreaMap({
}
});
map.addSource('detail', {
type: 'geojson',
data: detailGeo
});
map.addLayer(layerWayPoint('detail'));
map.addLayer(layerGuideLine('detail'));
map.addLayer(layerPolyline('detail'));
map.addLayer(layerPolygon('detail'));
map.addLayer(layerBuffer('detail'));
handlerCreateAirSpace(map);
handlerCreateAirSpace(map, mapControl);
setIsMapLoad(true);
// const detail = map.getSource('detail');
// if (detail) setDetailLayer(detail);
});
setMapObject(map);
dispatch(mapInitAction(map));
};
// const handlerInitCoordinates = () => {
// const init = initFlightBas.initDetail.areaList.concat();
// dispatch(AREA_COORDINATE_LIST_SAVE(init));
// };
// areaInfo를 areaList 형식으로 반환
const handlerAreaInfoToAreaList = areaInfo => {
const initAreaList = initFlightBas.initDetail.areaList.concat();
const coordList = [];
@ -287,10 +191,10 @@ export default function LaancAreaMap({
return areaList;
};
// 비행관제구역 체크 및 버퍼 생성
const handlerCoordinates = areaInfo => {
const areaList = handlerAreaInfoToAreaList(areaInfo);
// dispatch(LaancAction.LAANC_ALTITUDE.request(areaList));
dispatch(LaancAction.LAANC_VALID_AREA.request(areaList));
if (areaInfo.areaType === 'LINE' || areaInfo.areaType === 'POLYGON') {
dispatch(FLIGHT_PLAN_AREA_BUFFER_LIST.request(areaList));
@ -299,6 +203,7 @@ export default function LaancAreaMap({
}
};
// 비행구역 설정 후 저장
const handlerConfirm = areaList => {
if (areaList === undefined) {
alert('영역을 설정해 주세요.');
@ -308,17 +213,14 @@ export default function LaancAreaMap({
dispatch(AREA_COORDINATE_LIST_SAVE(areaList));
};
// const handlerModal = () => {
// setModal(!modal);
// };
// 좌표 정보 마우스 드래그
// [좌표 정보] 마우스 다운 시 스크롤 준비
const onMouseDown = e => {
e.preventDefault();
setIsDrag(true);
setStartX(e.pageX + scrollRef.current.scrollLeft);
};
// [좌표 정보] 마우스 드래그로 스크롤 이동
const onMouseMove = e => {
if (isDrag) {
const { scrollWidth, clientWidth, scrollLeft } = scrollRef.current;
@ -333,6 +235,7 @@ export default function LaancAreaMap({
}
};
// [좌표 정보] onMouseMove 이벤트 빈도 조절
const throttle = (func, ms) => {
let throttled = false;
return (...args) => {
@ -346,11 +249,13 @@ export default function LaancAreaMap({
};
};
// [좌표 정보] 마우스 업 시 스크롤 멈춤
const onMouseUp = e => {
e.preventDefault();
setIsDrag(false);
};
// [좌표 정보] 마우스 벗어날 시 스크롤 멈춤
const onMouseLeave = () => {
setIsDrag(false);
};
@ -455,21 +360,20 @@ export default function LaancAreaMap({
{isMapLoad && mapObject ? (
<>
<LaancDrawControl
handlerAddChange={handlerAddChange}
addData={addData}
drawObj={drawObj}
setModal={setModal}
mapboxgl={mapboxgl}
mapObject={mapObject}
setViewCoordObj={setViewCoordObj}
areaCoordList={mapAreaCoordList}
setSaveData={setSaveData}
setViewCoordObj={setViewCoordObj}
handlerConfirm={handlerConfirm}
handlerSaveElev={handlerSaveElev}
handlerAddChange={handlerAddChange}
handlerSaveCheck={handlerSaveCheck}
handlerCoordinates={handlerCoordinates}
handlerInitCoordinates={handlerInitCoordinates}
setSaveData={setSaveData}
handlerAreaInfoToAreaList={handlerAreaInfoToAreaList}
handlerSaveElev={handlerSaveElev}
/>
<FeatureAirZone map={mapObject} mapboxgl={mapboxgl} />
</>

73
src/components/laanc/map/LaancComn.js

@ -0,0 +1,73 @@
import { useSelector } from 'react-redux';
import geoJson from '../../map/geojson/airArea.json';
import flatGimpo from '../../map/geojson/flatGimpoAirportAirArea.json';
// 공역 생성
export const handlerCreateAirSpace = (
map,
mapControl,
useGeoJson = {
...geoJson,
...flatGimpo,
features: [...geoJson.features, ...flatGimpo.features]
}
) => {
if (map.getLayer('maine')) {
map.removeLayer('maine');
map.removeSource('maine');
}
let arrGeoJson = [];
useGeoJson.features.map(item => {
if (item.properties.type === '0001' && mapControl.area0001) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FF3648' }
});
} else if (item.properties.type === '0002' && mapControl.area0002) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FFA1AA' }
});
} else if (item.properties.type === '0003' && mapControl.area0003) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#FFA800' }
});
} else if (item.properties.type === '0004' && mapControl.area0004) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#A16B00' }
});
} else if (item.properties.type === '0005' && mapControl.area0005) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#AB40FF' }
});
} else if (item.properties.type === '0006' && mapControl.area0006) {
arrGeoJson.push({
...item,
properties: { ...item.properties, color: '#009cad' }
});
}
});
useGeoJson.features = arrGeoJson.filter(i => i.geometry.type === 'Polygon');
// 공역 생성 start
map.addSource('maine', {
type: 'geojson',
data: {
...useGeoJson
}
});
map.addLayer({
id: 'maine',
type: 'fill',
source: 'maine',
layout: {},
paint: {
'fill-color': ['get', 'color'],
// 'fill-extrusion-height': 3000,
'fill-opacity': 0.5
}
});
};

64
src/components/laanc/map/LaancDrawControl.js

@ -1,5 +1,4 @@
import { useEffect, useRef, useState } from 'react';
import { InfoModal } from '../../modal/InfoModal';
import { ErrorModal } from '../../modal/ErrorModal';
import { useDispatch, useSelector } from 'react-redux';
import {
@ -25,36 +24,42 @@ import Constants from 'mapbox-gl-draw-circle/node_modules/@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;
// 비행구역 타입
const { drawType } = useSelector(state => state.controlMapReducer);
// mapbox 기본 onClick 함수 저장
const originClickRef = useRef(null);
// 비행구역이 WayPoint일 때 bufferId
const [bufferId, setBufferId] = useState();
// 그리기모드 상태인지 유무 확인
const [isDrawDone, setIsDrawDone] = useState(false);
const [alertModal, setAlertModal] = useState({
isOpen: false,
title: '',
desc: ''
});
// 지도 렌더 횟수
const [number, setNumber] = useState(0);
// 에러 모달창 정보
const [isErrorModal, setIsErrorModal] = useState({
isOpen: false,
title: '',
desc: ''
});
const [number, setNumber] = useState(0);
// 비행구역 타입 변경에 따른 그리기모드 셋팅
useEffect(() => {
if (mapControl.drawType === 'DONE') {
// 구역 생성 후 바로 directMode
if (drawType === 'DONE') {
if (number !== 0) {
const obj = drawObj
.getAll()
.features.filter(o => o.properties.id !== 'BUFFER');
// 구역 생성 후 바로 directMode
if (obj.length > 0) {
drawObj.changeMode('direct_select', {
featureId: obj[obj.length - 1]?.id
@ -64,10 +69,9 @@ export const LaancDrawControl = props => {
} else {
drawInit();
}
}, [mapControl.drawType]);
const originClickRef = useRef(null);
}, [drawType]);
// mapbox 기본 함수 오버라이드 및 함수 중복 등록 방지
useEffect(() => {
if (mapObject) {
const DrawLineStringMode = MapboxDraw.modes.draw_line_string;
@ -75,6 +79,7 @@ export const LaancDrawControl = props => {
const DrawCircleMode = CircleMode;
const modeArr = [DrawLineStringMode, DrawPolygonMode, DrawCircleMode];
// 등록 함수 제거
const cleanUp = () => {
modeArr.forEach(m => {
m.onStop = null;
@ -154,6 +159,7 @@ export const LaancDrawControl = props => {
setNumber(number + 1);
}
// 컴포넌트 언마운트 시
return () => {
dispatch(drawTypeChangeAction('DONE'));
mapObject.off('draw.update', handlerUpdateSetting);
@ -162,10 +168,12 @@ export const LaancDrawControl = props => {
}
}, [mapObject]);
// 비행구역 데이터 지도에 다시 그려주기
useEffect(() => {
handlerPastDraw();
}, [props.areaCoordList]);
// 비행구역 설정을 올바르게 마쳤을 때 좌표 저장
useEffect(() => {
if (isDrawDone) {
props.handlerConfirm(props.areaCoordList);
@ -173,7 +181,7 @@ export const LaancDrawControl = props => {
}
}, [isDrawDone]);
// 클릭할 때마다 마커 찍어줌
// 클릭할 때마다 마커 표출
const handlerCustomOnClick = (state, e) => {
const mode = handlerReturnMode(drawObj.getMode());
const obj = state[mode?.toLowerCase()];
@ -181,7 +189,7 @@ export const LaancDrawControl = props => {
if (mode && obj) {
const feature = drawObj.get(obj.id);
if (!feature) {
console.log('2222222222');
// console.log('simple_select');
drawObj.changeMode('simple_select');
return;
}
@ -220,7 +228,7 @@ export const LaancDrawControl = props => {
}
};
// 도형 그리기 완료 시
// 비행구역 그리기 완료 시
const handlerFinishDraw = state => {
if (drawObj.getAll().features.length === 0) return;
@ -293,8 +301,7 @@ export const LaancDrawControl = props => {
});
}
} else {
console.log('333333333');
// 좌표가 찍히기도 전에 틀만 생성된 도형들 삭제
// console.log('좌표가 찍히기도 전에 틀만 생성된 도형들 삭제');
// if (mode === 'CIRCLE') {
// const obj = state.polygon;
// drawObj.delete(obj.id);
@ -307,7 +314,7 @@ export const LaancDrawControl = props => {
// 모든 비정상상황 체크
const handlerAbnormalityCheck = async data => {
// radius도 있음
// radius 존재함
const { coords, mode, id } = data;
const areaInfo = handlerSettingAreaInfo(coords, mode);
@ -411,7 +418,7 @@ export const LaancDrawControl = props => {
}
};
// 도형 수정 시
// 비행구역 수정 시
const handlerUpdateSetting = e => {
if (e.features[0]) {
const { geometry, properties, id } = e.features[0];
@ -482,7 +489,7 @@ export const LaancDrawControl = props => {
);
props.setViewCoordObj(viewCoordObj);
// 계속 20개 미만이라 overAdd false처리(임시)
// 계속 20개 미만이라 overAdd false처리
props.handlerAddChange('overAdd', false);
};
@ -565,12 +572,12 @@ export const LaancDrawControl = props => {
return true;
};
// 저장된 비행구역 데이터를 기반으로 지도에 다시 그려주기
const handlerPastDraw = () => {
if (props.areaCoordList) {
const objs = drawObj?.getAll().features;
const areas = props.areaCoordList;
if (areas.length > 0 && objs.length > 0) {
// areas -> 현재는 1개이지만 추후에 데이터가 바뀌면 여러개의 도형도 처리 가능!
areas.map((area, idx) => {
const paths = [];
area.coordList.forEach(coord => paths.push([coord.lon, coord.lat]));
@ -639,7 +646,7 @@ export const LaancDrawControl = props => {
}
objId = polygonId;
}
// 마커를 삭제하고 다시 그려주기
// 마커를 삭제하고 다시 그려
const data = {
coord: area.areaType === 'LINE' ? paths : [paths],
id: objId
@ -754,8 +761,9 @@ export const LaancDrawControl = props => {
return newObjId[0];
};
// 비행구역 기본셋팅
const drawInit = () => {
const mode = mapControl.drawType;
const mode = drawType;
if (mode !== 'DONE') {
if (!mode || mode === 'RESET') {
handlerResetMode();
@ -790,6 +798,7 @@ export const LaancDrawControl = props => {
drawObj.changeMode('simple_select');
};
// 그리기모드 셋팅
const handlerStartMode = mode => {
if (mode === 'LINE') {
drawObj.changeMode('draw_line_string');
@ -802,7 +811,6 @@ export const LaancDrawControl = props => {
return (
<>
<InfoModal modal={alertModal} setModal={setAlertModal} />
<ErrorModal modal={isErrorModal} setModal={setIsErrorModal} />
</>
);

34
src/utility/DrawUtil.js

@ -2,6 +2,7 @@ import * as turf from '@turf/turf';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
// geojson Feature 형식으로 반환
export const InitFeature = (type, id) => {
return {
type: 'Feature',
@ -43,6 +44,13 @@ export const CalculateDistance = (mouse, center) => {
return distance;
};
// 미터 반환(m붙여서)
export const fromMetersToText = meters => {
meters = meters || 0;
const text = parseFloat(meters.toFixed(1)) + 'm';
return text;
};
// 두 좌표 간의 중간 지점 좌표 반환
export const handlerGetMidPoint = (dis1, dis2) => {
return [(dis1[0] + dis2[0]) / 2, (dis1[1] + dis2[1]) / 2];
@ -63,13 +71,6 @@ export const handlerGetHtmlContent = (distance, id) => {
);
};
// 미터 반환(m붙여서)
export const fromMetersToText = meters => {
meters = meters || 0;
const text = parseFloat(meters.toFixed(1)) + 'm';
return text;
};
// circle 360도 좌표 반환
export const handlerGetCircleCoord = (center, distance) => {
const options = {
@ -183,25 +184,6 @@ export const layerWayPoint = source => {
};
};
export const layerGuideLine = source => {
return {
id: 'guideline',
type: 'line',
source: source,
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#283046',
'line-width': 2,
'line-opacity': 0.5,
'line-dasharray': [5, 5]
},
filter: ['==', ['get', 'id'], 'guideline']
};
};
export const layerPolyline = source => {
return {
id: 'polyline',

Loading…
Cancel
Save