From 625c8e6f0f4775bf29a6cc2c0131eaab2b12a2fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?junh=5Feee=28=EC=9D=B4=EC=A4=80=ED=9D=AC=29?= Date: Wed, 13 Dec 2023 20:53:15 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B9=84=ED=96=89=EA=B5=AC=EC=97=AD=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/laanc/map/FlightArea.js | 49 +++++++--- src/components/laanc/map/LaancAreaMap.js | 50 ++++++++--- src/components/laanc/map/LaancDrawControl.js | 79 ++++++++++++---- src/utility/MapUtils.js | 95 +++++++++++++++++--- 4 files changed, 223 insertions(+), 50 deletions(-) diff --git a/src/components/laanc/map/FlightArea.js b/src/components/laanc/map/FlightArea.js index 64fa6c0..bf01f14 100644 --- a/src/components/laanc/map/FlightArea.js +++ b/src/components/laanc/map/FlightArea.js @@ -127,12 +127,17 @@ export default function FlightArea({ } }, [areaCoordList, centeredModal, previewLayer]); - // 비행구역 설정 관련 모달 표출 + /** + * 비행구역 설정 관련 모달 표출 + */ const handlerModal = () => { setModal(!modal); }; - // 비행구역 타입 변경 시 그리기 모드 상태일 때 에러 표출 + /** + * 비행구역 타입 변경 시 그리기 모드 상태일 때 에러 표출 + * @param {string} val 비행구역 타입 + */ const handlerDrawType = val => { if (drawObj.getMode().includes('draw')) { setModal({ @@ -151,7 +156,9 @@ export default function FlightArea({ } }; - // laanc계획서 비행구역 저장버튼 클릭 시 비행구역 정보 저장 + /** + * laanc계획서 비행구역 저장버튼 클릭 시 비행구역 정보 저장 + */ const handlerSave = async () => { if (areaCoordList) { console.log('save'); @@ -168,12 +175,16 @@ export default function FlightArea({ } }; - // 날씨 모달 표출 + /** + * 날씨 모달 표출 + */ const handlerWeather = () => { setFormModal(!formModal); }; - // 지도 초기 셋팅 + /** + * 지도 초기 셋팅 + */ const handlerMapInit = () => { mapboxgl.accessToken = MAPBOX_TOKEN; @@ -339,7 +350,9 @@ export default function FlightArea({ dispatch(mapInitAction(map)); }; - // 저장된 비행구역 미니맵에 표출 + /** + * 저장된 비행구역 미니맵에 표출 + */ const handlerPreviewDraw = () => { if (areaCoordList) { const areas = areaCoordList[0]; @@ -455,14 +468,20 @@ export default function FlightArea({ } }; - // 비행구역 추가 버튼 클릭 시 + /** + * 비행구역 추가 버튼 클릭 시 + */ const handlerAddClick = () => { if (!addData.isAddable || !addData.overAdd) { handlerAddChange('isAddable', true); } }; - // 비행구역 추가 관련 상태 변경 + /** + * 비행구역 추가 관련 상태 변경 + * @param {string} key addData의 key + * @param {boolean} val addData의 value + */ const handlerAddChange = (key, val) => { setAddData(prev => ({ ...prev, @@ -470,18 +489,26 @@ export default function FlightArea({ })); }; - // 비행구역 저장 가능 유무 체크 + /** + * 비행구역 저장 가능 유무 체크 + * @param {boolean} save 비행구역 저장 가능 유무 + */ const handlerSaveCheck = save => { setIsSaveable(save); }; - // 비행구역 데이터 초기화 + /** + * 비행구역 데이터 초기화 + */ const handlerInitCoordinates = () => { const init = initFlightBas.initDetail.areaList.concat(); dispatch(AREA_COORDINATE_LIST_SAVE(init)); }; - // 비행구역 고도 저장 + /** + * 비행구역 고도 저장 + * @param {number} elev 비행고도 + */ const handlerSaveElev = elev => { setSaveElev(elev); }; diff --git a/src/components/laanc/map/LaancAreaMap.js b/src/components/laanc/map/LaancAreaMap.js index eb8de5b..dd92c77 100644 --- a/src/components/laanc/map/LaancAreaMap.js +++ b/src/components/laanc/map/LaancAreaMap.js @@ -36,6 +36,7 @@ export default function LaancAreaMap({ setModal }) { const dispatch = useDispatch(); + // 비행구역 타입 및 공역 타입 const mapControl = useSelector(state => state.controlMapReducer); @@ -100,7 +101,9 @@ export default function LaancAreaMap({ } }, [areaCoordList, mapObject, number]); - // 맵박스 지도 초기 셋팅 + /** + * 맵박스 지도 초기 셋팅 + */ const handlerMapInit = () => { mapboxgl.accessToken = MAPBOX_TOKEN; @@ -166,7 +169,11 @@ export default function LaancAreaMap({ dispatch(mapInitAction(map)); }; - // areaInfo를 areaList 형식으로 반환 + /** + * areaInfo를 areaList 형식으로 반환 + * @param {*} areaInfo + * @returns areaList로 반환 + */ const handlerAreaInfoToAreaList = areaInfo => { const initAreaList = initFlightBas.initDetail.areaList.concat(); const coordList = []; @@ -191,7 +198,10 @@ export default function LaancAreaMap({ return areaList; }; - // 비행관제구역 체크 및 버퍼 생성 + /** + * 비행관제구역 체크 및 버퍼 생성 + * @param {*} areaInfo + */ const handlerCoordinates = areaInfo => { const areaList = handlerAreaInfoToAreaList(areaInfo); @@ -203,24 +213,34 @@ export default function LaancAreaMap({ } }; - // 비행구역 설정 후 저장 + /** + * 비행구역 설정 후 저장 + * @param {*} areaList + * @returns 영역이 없으면 그냥 리턴 + */ const handlerConfirm = areaList => { if (areaList === undefined) { alert('영역을 설정해 주세요.'); - return false; + return; } dispatch(AREA_COORDINATE_LIST_SAVE(areaList)); }; - // [좌표 정보] 마우스 다운 시 스크롤 준비 + /** + * [좌표 정보] 마우스 다운 시 스크롤 준비 + * @param {Event} e 이벤트 + */ const onMouseDown = e => { e.preventDefault(); setIsDrag(true); setStartX(e.pageX + scrollRef.current.scrollLeft); }; - // [좌표 정보] 마우스 드래그로 스크롤 이동 + /** + * [좌표 정보] 마우스 드래그로 스크롤 이동 + * @param {Event} e 이벤트 + */ const onMouseMove = e => { if (isDrag) { const { scrollWidth, clientWidth, scrollLeft } = scrollRef.current; @@ -235,7 +255,12 @@ export default function LaancAreaMap({ } }; - // [좌표 정보] onMouseMove 이벤트 빈도 조절 + /** + * [좌표 정보] onMouseMove 이벤트 빈도 조절 + * @param {*} func 적용할 함수 + * @param {number} ms 딜레이 시간 + * @returns + */ const throttle = (func, ms) => { let throttled = false; return (...args) => { @@ -249,13 +274,18 @@ export default function LaancAreaMap({ }; }; - // [좌표 정보] 마우스 업 시 스크롤 멈춤 + /** + * [좌표 정보] 마우스 업 시 스크롤 멈춤 + * @param {Event} e 이벤트 + */ const onMouseUp = e => { e.preventDefault(); setIsDrag(false); }; - // [좌표 정보] 마우스 벗어날 시 스크롤 멈춤 + /** + * [좌표 정보] 마우스 벗어날 시 스크롤 멈춤 + */ const onMouseLeave = () => { setIsDrag(false); }; diff --git a/src/components/laanc/map/LaancDrawControl.js b/src/components/laanc/map/LaancDrawControl.js index 94a8d96..d58b153 100644 --- a/src/components/laanc/map/LaancDrawControl.js +++ b/src/components/laanc/map/LaancDrawControl.js @@ -87,6 +87,7 @@ export const LaancDrawControl = props => { }); }; + // 함수 등록 if (number === 0) { mapObject.on('draw.update', handlerUpdateSetting); modeArr.forEach(m => { @@ -104,7 +105,7 @@ export const LaancDrawControl = props => { } }); - // 버퍼 select 모드 방지를 위한 오버라이드 + // 버퍼 simpleSelect 모드 방지를 위한 오버라이드 const SimpleSelect = SimpleSelectMode; SimpleSelect.toDisplayFeatures = function (state, geojson, display) { geojson.properties.active = this.isSelected(geojson.properties.id) @@ -131,7 +132,7 @@ export const LaancDrawControl = props => { } }; - // 버퍼 select 모드 방지, midPoint 생성 방지를 위한 오버라이드 + // 버퍼 directSelect 모드 방지, midPoint 생성 방지를 위한 오버라이드 const DirectSelect = DirectMode; DirectSelect.toDisplayFeatures = function (state, geojson, push) { if (state.featureId === geojson.properties.id) { @@ -181,7 +182,12 @@ export const LaancDrawControl = props => { } }, [isDrawDone]); - // 클릭할 때마다 마커 표출 + /** + * 클릭할 때마다 마커 표출 + * @param {*} state + * @param {Event} e 이벤트 + * @returns + */ const handlerCustomOnClick = (state, e) => { const mode = handlerReturnMode(drawObj.getMode()); const obj = state[mode?.toLowerCase()]; @@ -228,7 +234,11 @@ export const LaancDrawControl = props => { } }; - // 비행구역 그리기 완료 시 + /** + * 비행구역 그리기 완료 시 + * @param {*} state + * @returns 좌표 최소 개수 미달 시 + */ const handlerFinishDraw = state => { if (drawObj.getAll().features.length === 0) return; @@ -312,7 +322,11 @@ export const LaancDrawControl = props => { } }; - // 모든 비정상상황 체크 + /** + * 모든 비정상상황 체크 + * @param {*} data + * @returns 에러 발생시 undefined, 이상 없으면 areaInfo + */ const handlerAbnormalityCheck = async data => { // radius 존재함 const { coords, mode, id } = data; @@ -418,7 +432,10 @@ export const LaancDrawControl = props => { } }; - // 비행구역 수정 시 + /** + * 비행구역 수정 시 + * @param {Event} e 이벤트 + */ const handlerUpdateSetting = e => { if (e.features[0]) { const { geometry, properties, id } = e.features[0]; @@ -458,7 +475,10 @@ export const LaancDrawControl = props => { } }; - // 비정상 감지 시 해당 도형, 마커 삭제 + /** + * 비정상 감지 시 해당 도형, 마커 삭제 + * @param {string} id 삭제할 obj의 id + */ const handlerRemoveError = id => { // 삭제대상인 obj를 제외하고 남은 obj가 있는지 확인 const isRemain = drawObj @@ -493,7 +513,10 @@ export const LaancDrawControl = props => { props.handlerAddChange('overAdd', false); }; - // 정상 좌표 처리 + /** + * 정상 좌표 처리 + * @param {*} areaInfo + */ const handlerSaveData = areaInfo => { props.handlerCoordinates(areaInfo); setIsDrawDone(true); @@ -510,7 +533,12 @@ export const LaancDrawControl = props => { } }; - // areaInfo 셋팅 + /** + * areaInfo 셋팅 + * @param {*} coord + * @param {string} mode 비행구역 타입 + * @returns 에러 발생시 undefined, 이상 없으면 areaInfo + */ const handlerSettingAreaInfo = (coord, mode) => { if (!coord || !mode) { alert('에러 발생. 다시 시도해 주세요.'); @@ -555,7 +583,12 @@ export const LaancDrawControl = props => { return areaInfo; }; - // 두 좌표배열이 완전히 일치하는지 판단 + /** + * 두 좌표배열이 완전히 일치하는지 판단 + * @param {[number, number]} arr1 좌표배열1 + * @param {[number, number]} arr2 좌표배열2 + * @returns 일치 true, 불일치 false + */ const handlerArraysAreEqual = (arr1, arr2) => { if (arr1 === arr2) return true; if (arr1.length !== arr2.length) return false; @@ -572,7 +605,9 @@ export const LaancDrawControl = props => { return true; }; - // 저장된 비행구역 데이터를 기반으로 지도에 다시 그려주기 + /** + * 저장된 비행구역 데이터를 기반으로 지도에 다시 그려주기 + */ const handlerPastDraw = () => { if (props.areaCoordList) { const objs = drawObj?.getAll().features; @@ -741,7 +776,13 @@ export const LaancDrawControl = props => { } }; - // 도형 생성 + 마커 생성(circle만 사용안함) + /** + * 도형 생성 + 마커 생성(circle만 사용안함) + * @param {string} type geometry 타입 LineString, Point, Polygon + * @param {*} paths + * @param {'LINE' | 'POLYGON' | 'BUFFER'} propertyId custom 타입 + * @returns + */ const handlerCreateDrawObj = (type, paths, propertyId) => { const newObj = { type: type, @@ -761,7 +802,10 @@ export const LaancDrawControl = props => { return newObjId[0]; }; - // 비행구역 기본셋팅 + /** + * 비행구역 기본셋팅 + * @returns 첫 진입이거나 초기화상태일 때 + */ const drawInit = () => { const mode = drawType; if (mode !== 'DONE') { @@ -785,7 +829,9 @@ export const LaancDrawControl = props => { } }; - // 초기화 + /** + * 초기화 + */ const handlerResetMode = () => { props.handlerAddChange('isAddable', false); props.handlerAddChange('isViewAdd', false); @@ -798,7 +844,10 @@ export const LaancDrawControl = props => { drawObj.changeMode('simple_select'); }; - // 그리기모드 셋팅 + /** + * 그리기모드 셋팅 + * @param {'LINE' | 'POLYGON' | 'CIRCLE'} mode custom 타입 + */ const handlerStartMode = mode => { if (mode === 'LINE') { drawObj.changeMode('draw_line_string'); diff --git a/src/utility/MapUtils.js b/src/utility/MapUtils.js index d5266fd..8812c0f 100644 --- a/src/utility/MapUtils.js +++ b/src/utility/MapUtils.js @@ -5,7 +5,11 @@ import 'mapbox-gl/dist/mapbox-gl.css'; import geoJson from '../components/map/geojson/airArea.json'; import flatGimpo from '../components/map/geojson/flatGimpoAirportAirArea.json'; -// geojson Feature 형식으로 반환 +/** + * geojson Feature 형식으로 반환 + * @param {'LineString' | 'Polygon' | 'Point'} type geometry 타입 + * @param {string} id 생성할 obj의 Id + */ export const InitFeature = (type, id) => { return { type: 'Feature', @@ -17,7 +21,11 @@ export const InitFeature = (type, id) => { }; }; -//소수점 7자리까지만 자름 / coord = [lng, lat] +/** + * 소수점 7자리까지만 자름 + * @param {[number, number]} coord [lng, lat] + * @returns + */ export const FormattingCoord = coord => { const resultArr = []; @@ -33,7 +41,12 @@ export const FormattingCoord = coord => { return resultArr; }; -// 거리 계산(meters로 리턴) +/** + * center로부터 mouse까지의 거리 계산 + * @param {[number, number]} mouse 현재 마우스가 위치한 좌표 + * @param {[number, number]} center 기준점 좌표 + * @returns meter단위로 리턴 + */ export const CalculateDistance = (mouse, center) => { const centerCoord = turf.point(center); const mouseCoord = turf.point(mouse); @@ -47,19 +60,34 @@ export const CalculateDistance = (mouse, center) => { return distance; }; -// 미터 반환(m붙여서) +/** + * 입력 값에 m 붙여줌 + * @param {number} meters + * @returns ex) 100 -> 100m + */ export const fromMetersToText = meters => { meters = meters || 0; const text = parseFloat(meters.toFixed(1)) + 'm'; return text; }; -// 두 좌표 간의 중간 지점 좌표 반환 +/** + * 두 좌표 간의 중간 지점 좌표 반환 + * @param {[number, number]} dis1 좌표1 + * @param {[number, number]} dis2 좌표2 + * @returns 중간 지점 좌표 + */ export const handlerGetMidPoint = (dis1, dis2) => { + console.log(dis1, dis2, '--'); return [(dis1[0] + dis2[0]) / 2, (dis1[1] + dis2[1]) / 2]; }; -// html Content 반환 +/** + * html Content 반환 + * @param {number} distance + * @param {string} id obj의 id + * @returns + */ export const handlerGetHtmlContent = (distance, id) => { const text = typeof distance === 'number' @@ -74,7 +102,12 @@ export const handlerGetHtmlContent = (distance, id) => { ); }; -// circle 360도 좌표 반환 +/** + * circle 360도 좌표 반환 + * @param {[number, number]} center 원의 중심 좌표 + * @param {number} distance meter단위 거리 + * @returns + */ export const handlerGetCircleCoord = (center, distance) => { const options = { steps: 63, @@ -83,7 +116,13 @@ export const handlerGetCircleCoord = (center, distance) => { return turf.circle(center, distance / 1000, options).geometry.coordinates; }; -// 포인트 생성 +/** + * 포인트 생성 + * @param {[number, number]} coord 포인트 생성할 좌표 + * @param {number} index 좌표 순서 + * @param {string} type + * @returns + */ export const handlerCreatePoint = (coord, index, type) => { const wayPoint = { type: 'Feature', @@ -98,7 +137,13 @@ export const handlerCreatePoint = (coord, index, type) => { return wayPoint; }; -// 그려진 도형이 지도 전체화면에 보여지도록 +/** + * 그려진 도형이 지도 전체화면에 보여지도록 + * @param {*} map 지도 오브젝트 + * @param {*} paths obj의 좌표 + * @param {number} padding 도형과 지도 사이의 padding값 + * @param {string} type custom 타입 + */ export const handlerFitBounds = (map, paths, padding, type) => { const bounds = new mapboxgl.LngLatBounds(paths[0], paths[0]); @@ -115,21 +160,30 @@ export const handlerFitBounds = (map, paths, padding, type) => { map.fitBounds(bounds, { padding: padding }); }; -// drawMode에 따른 drawType 매칭 +/** + * drawMode에 따른 drawType 매칭 + * @param {string} mode drawobj.getMode로 얻은 값 + * @returns custom 타입 반환 + */ export const handlerReturnMode = mode => { if (mode.includes('line') || mode.includes('Line')) return 'LINE'; if (mode.includes('polygon') || mode.includes('Polygon')) return 'POLYGON'; if (mode.includes('circle') || mode.includes('Circle')) return 'CIRCLE'; }; -// 지도에 있는 모든 마커 삭제 +/** + * 지도에 있는 모든 마커 삭제 + */ export const handlerRemoveAllMarker = () => { const ele = document.getElementsByClassName('mapboxgl-popup'); const eleArr = Array.from(ele); eleArr?.forEach(marker => marker.remove()); }; -// 해당되는 id의 마커 삭제 +/** + * 해당되는 id의 마커 삭제 + * @param {string} id obj의 id + */ export const handlerRemoveGroupMarker = id => { const ele = document.getElementsByClassName('mapboxgl-popup'); const eleArr = Array.from(ele); @@ -138,7 +192,15 @@ export const handlerRemoveGroupMarker = id => { }); }; -// 개별 마커 생성 +/** + * 개별 마커 생성 + * @param {*} map 지도 오브젝트 + * @param {*} anchor + * @param {*} lngLat 마커가 위치할 좌표 + * @param {*} text + * @param {string} id obj의 id + * @returns + */ export const handlerCreateOneMarker = (map, anchor, lngLat, text, id) => { if (!id) return; @@ -152,7 +214,12 @@ export const handlerCreateOneMarker = (map, anchor, lngLat, text, id) => { .addTo(map); }; -// 해당되는 id의 마커 생성 +/** + * 해당되는 id의 마커 생성 + * @param {*} map 지도 오브젝트 + * @param {*} data + * @param {string} mode custom 타입 + */ export const handlerCreateGroupMarker = (map, data, mode) => { if (mode !== 'CIRCLE') { const coord = mode === 'LINE' ? data.coord : data.coord[0];