diff --git a/src/components/map/mapbox/draw/LaancDraw.js b/src/components/map/mapbox/draw/LaancDraw.js index 69bb618..191c408 100644 --- a/src/components/map/mapbox/draw/LaancDraw.js +++ b/src/components/map/mapbox/draw/LaancDraw.js @@ -1,6 +1,6 @@ import { useSelector } from 'react-redux'; import { InfoModal } from '../../../modal/InfoModal'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { CalculateDistance, FormattingCoord, @@ -20,6 +20,10 @@ export const LaancDraw = props => { // const isDone = props.isDone; // const isDisabled = props.isDisabled; + const [clickEve, setClickEve] = useState(); + + const [mouseMoveEve, setMouseMoveEve] = useState(false); + const [alertModal, setAlertModal] = useState({ isOpen: false, title: '', @@ -31,16 +35,12 @@ export const LaancDraw = props => { const [mouseDownEve, setMouseDownEve] = useState(false); - const areaInfo = { - coordinates: [], - bufferZone: 0, - areaType: '' - }; - const geojson = props.geojson; const [geoState, setGeoState] = useState(geojson); const detailLayer = props.detailLayer; + const [clickNum, setClickNum] = useState(0); + let mode = props.mode; let guideLine = InitFeature('LineString', 'guideline'); @@ -66,6 +66,17 @@ export const LaancDraw = props => { } }, [mapControl.drawType, detailLayer]); + useEffect(() => { + const area = props.areaCoordList[0]; + //자세히보기 두번째에는 area가 사라져..! 왜?! + //첫번째 열면 도형 그려진 다음에 areaCoordList가 사라짐 왜???? + //clearMode가 자동으로 실행돼서 props.handlerInitCoordinates도 실행되기 때문 ㅠㅠ 그래서 초기화 됨 + //해결완료. 나중에 꼬일 때 까먹지 말라고 주석 삭제 안함 + if (area.areaType && area.areaType !== '') { + if (detailLayer) handlerPastDraw(); + } + }, [props.areaCoordList, detailLayer]); + useEffect(() => { if (isDrawDone) { props.handlerConfirm(props.areaCoordList); @@ -74,15 +85,10 @@ export const LaancDraw = props => { }, [isDrawDone]); useEffect(() => { - const area = props.areaCoordList[0]; - //자세히보기 두번째에는 area가 사라져..! 왜?! - //첫번째 열면 도형 그려진 다음에 areaCoordList가 사라짐 왜???? - //clearMode가 자동으로 실행돼서 props.handlerInitCoordinates도 실행되기 때문 ㅠㅠ 그래서 초기화 됨 - //해결완료. 나중에 꼬일 때 까먹지 말라고 주석 삭제 안함 - if (area.areaType && area.areaType !== '') { - if (props.centeredModal && detailLayer) handlerPastDraw(); + if (clickEve) { + console.log('click>>>>>>>>>>>>>>>>>>>>>>>>>'); } - }, [props.areaCoordList, props.centeredModal, detailLayer]); + }, [clickEve]); const drawInit = () => { handlerButtonClick(mapControl.drawType); @@ -111,14 +117,23 @@ export const LaancDraw = props => { const handlerStartMode = mode => { if (!mode || mode === 'RESET') return; + // mapObject.off('click', onClickFeature); + console.log('startMode'); - mapObject.on('click', clickEve); + // mapObject.on('click', clickEve); + const drawType = mapControl.drawType; + if (drawType === 'LINE') mapObject.on('click', onClickFeature); + if (drawType === 'POLYGON') mapObject.on('click', onClickFeature); + if (drawType === 'RESET') mapObject.off('click', onClickFeature); + + // setClickEve(onClickFeature); }; const removeListener = () => { console.log('removeListener'); - mapObject.off('click', clickEve); + // mapObject.off('click', clickEve); + mapObject.off('click', onClickFeature); mapObject.off('click', onClickCircle); mapObject.off('mouseup', onMouseUp); mapObject.off('mousedown', 'waypoint', onMouseDown); @@ -128,8 +143,13 @@ export const LaancDraw = props => { mapObject.off('mousemove', onMouseMovePolygon); mapObject.off('contextmenu', onRightClick); + console.log(mapObject._listeners.click, '>>>>>'); + // mapObject.off('click', clickEve); + // console.log(mapObject._listeners.click, '>>>>>'); + // 이거 있나 없나 뭔 차이지? setMouseDownEve(false); + setClickNum(0); }; const removeGeoJson = () => { @@ -196,17 +216,18 @@ export const LaancDraw = props => { } }; - const clickEve = e => { - const drawType = mapControl.drawType; - if (drawType === 'LINE') onClickFeature(e, lineString); - if (drawType === 'POLYGON') onClickFeature(e, polygon); - if (drawType === 'CIRCLE') onClickCircle(e); - }; + // const clickEve = e => { + // const drawType = mapControl.drawType; + // if (drawType === 'LINE') onClickFeature(e, lineString); + // if (drawType === 'POLYGON') onClickFeature(e, polygon); + // if (drawType === 'CIRCLE') onClickCircle(e); + // }; // polyline, polygon 생성 - const onClickFeature = (e, obj) => { + const onClickFeature = e => { console.log('click'); const formatCoord = FormattingCoord([e.lngLat.lng, e.lngLat.lat]); + const obj = mapControl.drawType === 'LINE' ? lineString : polygon; //현재 내 좌표가 waypoint레이어의 geojson도형 안에 속해있는지 안해있는지? //geojson을 반환해주는 듯? const features = mapObject.queryRenderedFeatures(e.point, { @@ -223,11 +244,7 @@ export const LaancDraw = props => { const featuresId = features[0].properties.id; handlerReplaceDuplicate(featuresId, ''); } else { - // const index = geojson.features.filter( - // geo => geo.properties?.id === 'point' - // ).length; - const geoCopy = geojson.features.concat(); - const index = geoCopy.filter( + const index = geojson.features.filter( geo => geo.properties?.id === 'point' ).length; @@ -276,24 +293,27 @@ export const LaancDraw = props => { }; // polygon 가이드 생성 - const onMouseMovePolygon = e => { - const formatCoord = FormattingCoord([e.lngLat.lng, e.lngLat.lat]); - - if (polygon.geometry.coordinates.length > 0) { - if (polygon.geometry.coordinates[0].length > 1) { - if (guideLine.geometry.coordinates.length > 1) { - guideLine.geometry.coordinates.pop(); - polygon.geometry.coordinates[0].pop(); + const onMouseMovePolygon = useCallback( + e => { + const formatCoord = FormattingCoord([e.lngLat.lng, e.lngLat.lat]); + + if (polygon.geometry.coordinates.length > 0) { + if (polygon.geometry.coordinates[0].length > 1) { + if (guideLine.geometry.coordinates.length > 1) { + guideLine.geometry.coordinates.pop(); + polygon.geometry.coordinates[0].pop(); + } + guideLine.geometry.coordinates.push(formatCoord); + polygon.geometry.coordinates[0].push(formatCoord); } - guideLine.geometry.coordinates.push(formatCoord); - polygon.geometry.coordinates[0].push(formatCoord); } - } - // 이거.. 왜 안해도 잘 되지....? - // handlerReplaceDuplicate('polygon', polygon); - handlerGetSourceSetData(); - }; + // 이거.. 왜 안해도 잘 되지....? + // handlerReplaceDuplicate('polygon', polygon); + handlerGetSourceSetData(); + }, + [geoState] + ); // circle 생성 const onClickCircle = e => { @@ -315,27 +335,32 @@ export const LaancDraw = props => { handlerGetSourceSetData(); }; - const onMouseDown = e => { - e.preventDefault(); - console.log('down'); - //타입 교체만 하면 왜 처음엔 down이 두번 잡힐까... - // console.log(e.features[0].properties.type, '>>down e'); + const onMouseDown = useCallback( + e => { + e.preventDefault(); + console.log('down'); + //타입 교체만 하면 왜 처음엔 down이 두번 잡힐까... + // console.log(e.features[0].properties.type, '>>down e'); - canvas.style.cursor = 'grab'; + canvas.style.cursor = 'grab'; - if (circle.geometry.coordinates.length > 0) { - removeListener(); - mapObject.on('mousedown', 'polygon', onMouseDown); - } else { - dragCircleIdx = e.features[0].properties.index; - } + if (circle.geometry.coordinates.length > 0) { + removeListener(); + mapObject.on('mousedown', 'polygon', onMouseDown); + } else { + dragCircleIdx = e.features[0].properties.index; + } - mapObject.on('mousemove', onMouseMove); - mapObject.on('mouseup', onMouseUp); + mapObject.on('mousemove', onMouseMove); + setMouseDownEve(true); + mapObject.on('mouseup', onMouseUp); - // 이거 왜 필요했던 거지? - mapObject.off('click', clickEve); - }; + // 이거 왜 필요했던 거지? + // mapObject.off('click', clickEve); + mapObject.off('click', onClickFeature); + }, + [mapControl.drawType] + ); const onMouseMove = e => { const formatCoord = FormattingCoord([e.lngLat.lng, e.lngLat.lat]); @@ -375,6 +400,10 @@ export const LaancDraw = props => { handlerGetSourceSetData(); }; + useEffect(() => { + console.log('-------------'); + }, [onMouseMovePolyline]); + const onMouseUp = () => { canvas.style.cursor = ''; console.log('up'); @@ -385,7 +414,8 @@ export const LaancDraw = props => { mapObject.off('mouseup', onMouseUp); // 이거 왜 필요했던 거지? - mapObject.off('click', clickEve); + // mapObject.off('click', clickEve); + mapObject.off('click', onClickFeature); setMouseDownEve(false); const type = mapControl.drawType; @@ -406,7 +436,8 @@ export const LaancDraw = props => { : obj.geometry.coordinates[0]; if (id === 'circle') { - mapObject.on('click', clickEve); + // mapObject.on('click', clickEve); + mapObject.on('click', onClickFeature); handlerSaveAreaInfo(''); } else { // mapObject.on('mousedown', 'waypoint', onMouseDown); @@ -433,6 +464,12 @@ export const LaancDraw = props => { // 도형 정보 변경되면 저장 const handlerSaveAreaInfo = coord => { console.log('areaInfo'); + const areaInfo = { + coordinates: [], + bufferZone: 0, + areaType: '' + }; + const bufferZone = polygon.geometry.coordinates.length > 0 ? 0 : 100; const prePath = []; diff --git a/src/components/map/mapbox/draw/LaancDrawRe.js b/src/components/map/mapbox/draw/LaancDrawRe.js new file mode 100644 index 0000000..e967ec0 --- /dev/null +++ b/src/components/map/mapbox/draw/LaancDrawRe.js @@ -0,0 +1,571 @@ +import { useDispatch, useSelector } from 'react-redux'; +import { InfoModal } from '../../../modal/InfoModal'; +import { FormattingCoord, InitFeature } from './MapBoxDraw'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { AREA_COORDINATE_LIST_SAVE } from '../../../../modules/basis/flight/actions/basisFlightAction'; +import { + CalculateDistance, + handlerCreatePoint, + handlerGetCircleCoord, + handlerGetHtmlContent, + handlerGetMidPoint +} from '../../../../utility/DrawUtil'; + +export const LaancDrawRe = props => { + const dispatch = useDispatch(); + const mapControl = useSelector(state => state.controlMapReducer); + const mapObject = props.mapObject; + const canvas = mapObject.getCanvasContainer(); + + const [isDrawDone, setIsDrawDone] = useState(false); + const [alertModal, setAlertModal] = useState({ + isOpen: false, + title: '', + desc: '' + }); + + const detailLayer = props.detailLayer; + const geojson = props.geojson; + + const [clickCoord, setClickCoord] = useState([]); + + const drawObj = InitFeature('', ''); + const guideLine = InitFeature('LineString', 'guideline'); + const bufferLine = InitFeature('LineString', 'buffer'); + + const [pastPoint, setPoint] = useState([]); + let point = []; + + const mode = props.mode; + + let dragCircleIdx; + + useEffect(() => { + const areaType = props.areaCoordList[0].areaType; + + if (areaType !== mode && detailLayer) { + drawInit(); + } + }, [mode, detailLayer]); + + useEffect(() => { + const areaType = props.areaCoordList[0].areaType; + + if (areaType && areaType !== '' && detailLayer) { + handlerPastDraw(); + } + }, [props.areaCoordList, detailLayer]); + + useEffect(() => { + if (isDrawDone) { + handlerDrawConfirm(props.areaCoordList); + setIsDrawDone(false); + } + }, [isDrawDone]); + + const drawInit = useCallback(() => { + console.log('drawInit'); + handlerRemoveEvent(); + handlerRemoveGeoJson(); + props.handlerInitCoordinates(); + + handlerStartMode(); + }, [mode]); + + const handlerRemoveEvent = useCallback(() => { + console.log('removeEvent'); + mapObject.off('click', onClickDrawObj); + mapObject.off('mousemove', onMouseMoveDrawObj); + mapObject.off('contextmenu', onRightClick); + }, [mode]); + + const handlerRemoveGeoJson = useCallback(() => { + console.log('removeGeoJson'); + handlerRemoveMarker(); + + guideLine.geometry.coordinates = []; + bufferLine.geometry.coordinates = []; + drawObj.geometry.coordinates = []; + geojson.features = []; + + point = []; + setPoint([]); + + handlerGetSourceSetData(); + }, [mode]); + + const handlerStartMode = () => { + if (!mode || mode === 'RESET') return; + + console.log('startMode'); + if (mode === 'LINE') { + handlerSetDrawObj('LineString', 'LINE'); + } else if (mode === 'POLYGON') { + handlerSetDrawObj('Polygon', 'POLYGON'); + } else if (mode === 'CIRCLE') { + handlerSetDrawObj('Polygon', 'CIRCLE'); + } + + mapObject.on('click', onClickDrawObj); + }; + + const onClickDrawObj = useCallback( + e => { + console.log('click'); + const formatCoord = FormattingCoord([e.lngLat.lng, e.lngLat.lat]); + const id = drawObj.properties.id; + + const features = mapObject.queryRenderedFeatures(e.point, { + layers: ['waypoint'] + }); + + if (geojson.features.length > 1) { + handlerReplaceDuplicate(drawObj.properties.id, ''); + } + + if (features.length) { + const featuresId = features[0].properties.id; + handlerReplaceDuplicate(featuresId, ''); + } else { + const index = geojson.features.filter( + geo => geo.properties.id === 'point' + ).length; + + const wayPoint = handlerCreatePoint(formatCoord, index, id); + point.push(wayPoint); + handlerReplaceDuplicate('point', ''); + point.forEach(p => geojson.features.push(p)); + setPoint(p => [...p, wayPoint]); + } + + if (id === 'LINE') guideLine.geometry.coordinates = [formatCoord]; + + if (geojson.features.length > 1) { + const coordinates = handlerGetGeoJsonCoord('point'); + + drawObj.geometry.coordinates = + id === 'LINE' ? coordinates : [coordinates]; + + geojson.features.push(drawObj); + + addMileStone(coordinates, ''); + } else { + mapObject.on('contextmenu', onRightClick); + mapObject.on('mousemove', onMouseMoveDrawObj); + addMileStone(formatCoord, ''); + } + handlerGetSourceSetData(); + setClickCoord(coord => [...coord, [formatCoord]]); + }, + [clickCoord, point] + ); + + const onMouseMoveDrawObj = e => { + const formatCoord = FormattingCoord([e.lngLat.lng, e.lngLat.lat]); + const id = drawObj.properties.id; + if (id === 'LINE') { + if (guideLine.geometry.coordinates.length > 1) { + guideLine.geometry.coordinates.pop(); + handlerReplaceDuplicate('guideline', guideLine); + } + guideLine.geometry.coordinates.push(formatCoord); + } else if (id === 'POLYGON') { + if (drawObj.geometry.coordinates.length > 0) { + if (drawObj.geometry.coordinates[0].length > 1) { + if (guideLine.geometry.coordinates.length > 1) { + guideLine.geometry.coordinates.pop(); + drawObj.geometry.coordinates[0].pop(); + } + guideLine.geometry.coordinates.push(formatCoord); + drawObj.geometry.coordinates[0].push(formatCoord); + } + } + } + + handlerGetSourceSetData(); + }; + + const onRightClick = e => { + handlerRemoveEvent(); + + const drawType = mapControl.drawType; + const path = handlerGetGeoJsonCoord('point'); + + if (path.length > 0) { + if (drawType === 'LINE') { + if (path.length > 1) { + handlerReplaceDuplicate('guideline', ''); + handlerSaveAreaInfo(drawObj.geometry.coordinates); + } else { + setAlertModal({ + isOpen: true, + title: '좌표 최소 개수', + desc: '좌표를 두 개 점으로 이어주세요.' + }); + handlerRemoveGeoJson(); + // props.handlerDrawType('RESET'); + } + handlerGetSourceSetData(); + } else if (drawType === 'POLYGON') { + if (path.length > 2) { + drawObj.geometry.coordinates[0] = path; + + handlerReplaceDuplicate('POLYGON', drawObj); + handlerSaveAreaInfo(drawObj.geometry.coordinates[0]); + } else { + setAlertModal({ + isOpen: true, + title: '좌표 최소 개수', + desc: '좌표를 세 개 점으로 이어주세요.' + }); + handlerRemoveGeoJson(); + // props.handlerDrawType('RESET'); + } + } + handlerGetSourceSetData(); + } + }; + + const onClickCircle = e => { + console.log('click'); + const formatCoord = FormattingCoord([e.lngLat.lng, e.lngLat.lat]); + + if (drawObj.geometry.coordinates.length === 0) { + mapObject.on('mousedown', 'polygon', onMouseDown); + } + + const circleCoords = handlerGetCircleCoord(formatCoord, 100); + drawObj.properties.center = formatCoord; + drawObj.geometry.coordinates = circleCoords; + + handlerReplaceDuplicate('CIRCLE', drawObj); + handlerSaveAreaInfo(''); + + addMileStone(formatCoord, 100); + handlerGetSourceSetData(); + }; + + const onMouseDown = e => { + e.preventDefault(); + + canvas.style.cursor = 'grab'; + + const id = drawObj.properties.id; + const coord = handlerGetGeoJsonCoord(id); + + if (id !== mode || coord.length === 0) { + mapObject.off('mousedown', 'waypoint', onMouseDown); + handlerReplaceDuplicate(id, ''); + return; + } + // if (coord.length === 0) return; + + console.log('down'); + if (id === 'CIRCLE') { + handlerRemoveEvent(); + mapObject.on('mousedown', 'polygon', onMouseDown); + } else { + dragCircleIdx = e.features[0].properties.index; + } + + mapObject.on('mousemove', onMouseMove); + mapObject.on('mouseup', onMouseUp); + + mapObject.off('click', onClickDrawObj); + mapObject.off('click', onClickCircle); + }; + + const onMouseMove = e => { + const formatCoord = FormattingCoord([e.lngLat.lng, e.lngLat.lat]); + canvas.style.cursor = 'grabbing'; + + const id = drawObj.properties.id; + + if (id === 'CIRCLE') { + const distance = CalculateDistance( + formatCoord, + drawObj.properties.center + ); + const center = drawObj.properties.center; + const circleCoords = handlerGetCircleCoord(center, distance); + drawObj.geometry.coordinates = circleCoords; + } else { + geojson.features = geojson.features.map(geo => { + const coord = formatCoord; + + if (geo.properties?.index === dragCircleIdx) { + geo.geometry.coordinates = coord; + } + + if (geo.properties?.id === 'LINE') { + geo.geometry.coordinates[dragCircleIdx] = coord; + drawObj.geometry.coordinates = geo.geometry.coordinates; + } + + if (geo.properties?.id === 'buffer') { + geo.geometry.coordinates = []; + } + + if (geo.properties?.id === 'POLYGON') { + geo.geometry.coordinates[0][dragCircleIdx] = coord; + drawObj.geometry.coordinates[0] = geo.geometry.coordinates[0]; + } + + return geo; + }); + } + + handlerGetSourceSetData(); + }; + + const onMouseUp = e => { + canvas.style.cursor = ''; + console.log('up'); + + mapObject.off('mousedown', 'waypoint', onMouseDown); + mapObject.off('mousemove', onMouseMove); + mapObject.off('mouseup', onMouseUp); + + const obj = + mode === 'LINE' || mode === 'POLYGON' || mode === 'CIRCLE' ? true : false; + + const objGeo = drawObj.geometry; + const coord = mode === 'LINE' ? objGeo.coordinates : objGeo.coordinates[0]; + + if (obj) { + if (mode === 'CIRCLE') { + mapObject.on('click', onClickCircle); + handlerSaveAreaInfo(''); + } else { + handlerSaveAreaInfo(coord); + } + } else { + const areas = props.areaCoordList[0]; + const type = areas.areaType; + + const paths = []; + areas.coordList.forEach(coord => paths.push([coord.lon, coord.lat])); + + if (type === 'CIRCLE') { + handlerSaveAreaInfo(''); + } else { + handlerSaveAreaInfo(coord); + } + } + }; + + const handlerPastDraw = () => { + console.log('pastDraw'); + const areas = props.areaCoordList[0]; + const paths = []; + areas.coordList.forEach(coord => paths.push([coord.lon, coord.lat])); + + if (areas.areaType) { + if (areas.areaType === 'CIRCLE') { + const radius = areas.bufferZone; + const circleCoords = handlerGetCircleCoord(paths[0], radius); + + drawObj.properties.center = paths[0]; + drawObj.geometry.coordinates = circleCoords; + drawObj.properties.id = 'CIRCLE'; + drawObj.geometry.type = 'Polygon'; + + geojson.features.push(drawObj); + } else { + if (areas.areaType === 'LINE') { + drawObj.geometry.coordinates = paths; + drawObj.properties.id = 'LINE'; + drawObj.geometry.type = 'LineString'; + geojson.features.push(drawObj); + + // 버퍼 생성 + if (areas.bufferCoordList) { + const bufferPaths = []; + + areas.bufferCoordList.forEach(bfCoord => + bufferPaths.push([bfCoord.lon, bfCoord.lat]) + ); + + bufferLine.geometry.coordinates = bufferPaths; + + handlerReplaceDuplicate('buffer', bufferLine); + } + } else if (areas.areaType === 'POLYGON') { + drawObj.geometry.coordinates = [paths]; + drawObj.properties.id = 'POLYGON'; + drawObj.geometry.type = 'Polygon'; + geojson.features.push(drawObj); + } + + handlerReplaceDuplicate(drawObj.properties.id, drawObj); + + // 포인트 생성 + paths.forEach((p, i) => { + const wayPoint = handlerCreatePoint(p, i, areas.areaType); + point.push(wayPoint); + // setPoint(po => [...po, wayPoint]); + }); + handlerReplaceDuplicate('point', ''); + point.forEach(p => geojson.features.push(p)); + // pastPoint.forEach(p => geojson.features.push(p)); + + // mouseDown이벤트 + mapObject.on('mousedown', 'waypoint', onMouseDown); + + // 기존 마커 제거 후 재 생성 + handlerRemoveMarker(); + handlerCreateAllMarker(paths); + + mapObject.setPaintProperty('waypoint', 'circle-radius', 8); + handlerGetSourceSetData(); + } + } + }; + + const handlerSaveAreaInfo = coord => { + console.log('areaInfo', coord); + const type = mapControl.drawType; + + const areaInfo = { + coordinates: [], + bufferZone: 0, + areaType: '' + }; + + const bufferZone = type === 'POLYGON' ? 0 : 100; + const prePath = []; + + areaInfo.areaType = type; + + if (areaInfo.areaType !== 'CIRCLE') { + coord.forEach(item => { + const p = { + lat: item[1], + lon: item[0] + }; + prePath.push(p); + }); + } + + areaInfo.coordinates = prePath; + areaInfo.bufferZone = bufferZone; + if (areaInfo.areaType === 'CIRCLE') { + const point = { + lat: drawObj.properties.center[1], + lon: drawObj.properties.center[0] + }; + areaInfo.coordinates = [point]; + areaInfo.bufferZone = CalculateDistance( + drawObj.geometry.coordinates[0][0], + drawObj.properties.center + ); + } + + props.handlerCoordinates(areaInfo); + setIsDrawDone(true); + }; + + const handlerDrawConfirm = useCallback( + areaList => { + if (areaList === undefined) { + alert('영역을 설정해 주세요.'); + return false; + } + + dispatch(AREA_COORDINATE_LIST_SAVE(areaList)); + }, + [isDrawDone] + ); + + const handlerSetDrawObj = useCallback( + (type, id) => { + drawObj.geometry.type = type; + drawObj.properties.id = id; + }, + [mode] + ); + + // 새로운 popup 한 개 추가 (coord의 뒤에서 두개의 좌표 이용) + const addMileStone = (coord, radius) => { + const len = coord.length; + let lngLat = coord; + let anchor; + let distance; + + if (coord[0].length) { + if (mode !== 'CIRCLE' || props.areaCoordList[0].areaType !== 'CIRCLE') { + lngLat = handlerGetMidPoint(coord[len - 2], coord[len - 1]); + anchor = [0, 0]; + distance = CalculateDistance(coord[len - 2], coord[len - 1]); + } + } else { + if (mode === 'CIRCLE' || props.areaCoordList[0].areaType === 'CIRCLE') { + anchor = [20, 35]; + distance = radius; + } else { + anchor = [0, -10]; + distance = 'Start'; + } + } + + const popup = new props.mapboxgl.Popup({ + offset: anchor, + closeButton: false, + closeOnClick: false + }) + .setLngLat(lngLat) + .setHTML(handlerGetHtmlContent(distance)) + .addTo(mapObject); + }; + + // 좌표 기반으로 모든 마커 재 생성 + const handlerCreateAllMarker = coord => { + console.log('allCreateMarker'); + const areas = props.areaCoordList[0]; + + if (areas.areaType !== 'CIRCLE') { + for (let i = 0; i < coord.length; i++) { + if (i == 0) { + addMileStone(coord[i], ''); + } else { + addMileStone([coord[i], coord[i - 1]], ''); + } + } + + if (areas.areaType === 'POLYGON') { + addMileStone([coord[0], coord[coord.length - 1]], ''); + } + } else { + addMileStone(coord[0], areas.bufferZone); + } + }; + + // 모든 마커 삭제 + const handlerRemoveMarker = () => { + const ele = document.getElementsByClassName('mapboxgl-popup'); + const eleArr = Array.from(ele); + eleArr?.forEach(marker => marker.remove()); + }; + + // geojson에서 중복되는 obj 제거 or 제거 후 새로 생성 + const handlerReplaceDuplicate = (id, obj) => { + geojson.features = geojson.features.filter( + geo => geo.properties?.id !== id + ); + if (obj !== '') geojson.features.push(obj); + }; + + // geojson에서 원하는 Id의 coord만 추출 + const handlerGetGeoJsonCoord = id => { + return geojson.features + .filter(geo => geo.properties?.id === id) + .map(geo => geo.geometry.coordinates); + }; + + // 지도에 geojson데이터 새로고침 + const handlerGetSourceSetData = () => { + mapObject.getSource('detail').setData(geojson); + }; + + return ; +}; diff --git a/src/utility/DrawUtil.js b/src/utility/DrawUtil.js index e77f2b1..5fa1d29 100644 --- a/src/utility/DrawUtil.js +++ b/src/utility/DrawUtil.js @@ -158,7 +158,7 @@ export const layerPolyline = source => { 'line-color': '#283046', 'line-width': 2 }, - filter: ['in', ['get', 'id'], ['literal', ['polyline', 'outline']]] + filter: ['in', ['get', 'id'], ['literal', ['LINE', 'outline']]] }; }; diff --git a/src/views/laanc/FlightArea.js b/src/views/laanc/FlightArea.js index d951be6..1a8447d 100644 --- a/src/views/laanc/FlightArea.js +++ b/src/views/laanc/FlightArea.js @@ -59,7 +59,7 @@ export default function FlightArea({ desc: '' }); - console.log('>>>'); + // console.log('>>>'); //날씨 임시 데이터 const [wheather, setWheather] = useState([]); @@ -279,7 +279,7 @@ export default function FlightArea({ const radius = areas.bufferZone; const circleCoords = handlerGetCircleCoord(paths[0], radius); - const circle = InitFeature('Polygon', 'circle'); + const circle = InitFeature('Polygon', 'CIRCLE'); circle.properties.center = paths[0]; circle.geometry.coordinates = circleCoords; @@ -289,9 +289,9 @@ export default function FlightArea({ fitZoomPaths = circleCoords[0]; } else { - const lineString = InitFeature('LineString', 'polyline'); + const lineString = InitFeature('LineString', 'LINE'); const bufferPolyline = InitFeature('LineString', 'buffer'); - const polygon = InitFeature('Polygon', 'polygon'); + const polygon = InitFeature('Polygon', 'POLYGON'); const point = []; if (areas.areaType === 'LINE') { lineString.geometry.coordinates = paths; diff --git a/src/views/laanc/LaancAreaMap.js b/src/views/laanc/LaancAreaMap.js index c7e69b1..ed49971 100644 --- a/src/views/laanc/LaancAreaMap.js +++ b/src/views/laanc/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, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Card, CardBody } from 'reactstrap'; import { initFlightBas } from '../../modules/basis/flight/models/basisFlightModel'; @@ -12,6 +12,7 @@ import { FLIGHT_PLAN_AREA_BUFFER_LIST } from '../../modules/basis/flight/actions/basisFlightAction'; import { LaancDraw } from '../../components/map/mapbox/draw/LaancDraw'; +import { LaancDrawRe } from '../../components/map/mapbox/draw/LaancDrawRe'; import { drawTypeChangeAction, mapInitAction @@ -48,10 +49,12 @@ export default function LaancAreaMap({ centeredModal, mapContainer }) { const [detailLayer, setDetailLayer] = useState(); - const detailGeo = { - type: 'FeatureCollection', - features: [] - }; + const detailGeo = useMemo(() => { + return { + type: 'FeatureCollection', + features: [] + }; + }, []); useEffect(() => { handlerMapInit(); @@ -302,7 +305,7 @@ export default function LaancAreaMap({ centeredModal, mapContainer }) { > {isMapLoad && mapObject ? ( <> - */} +