Browse Source

laanc 상세맵 라이브러리로 재구축 중

pull/2/head
junh_eee(이준희) 11 months ago
parent
commit
956a99d6ec
  1. 244
      src/components/map/mapbox/draw/LaancDrawControl.js
  2. 13
      src/components/map/mapbox/draw/LaancDrawRe.js
  3. 104
      src/views/laanc/FlightArea.js
  4. 26
      src/views/laanc/LaancAreaMap.js

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

@ -0,0 +1,244 @@
import { useEffect, useState } from 'react';
import { InfoModal } from '../../../modal/InfoModal';
import { useSelector } from 'react-redux';
import {
CalculateDistance,
handlerGetHtmlContent,
handlerGetMidPoint
} from '../../../../utility/DrawUtil';
export const LaancDrawControl = props => {
const mapControl = useSelector(state => state.controlMapReducer);
const drawObj = props.drawObj;
const mapObject = props.mapObject;
const [bufferId, setBufferId] = useState();
const [geojson, setGeoJson] = useState();
const [alertModal, setAlertModal] = useState({
isOpen: false,
title: '',
desc: ''
});
useEffect(() => {
drawInit();
}, [mapControl.drawType]);
useEffect(() => {
if (mapObject) {
mapObject.on('draw.create', handlerCreateObj);
mapObject.on('draw.update', handlerFormatAreaInfo);
mapObject.on('click', handlerOnClick);
}
}, [mapObject]);
useEffect(() => {
handlerPastDraw();
}, [props.areaCoordList]);
const handlerOnClick = e => {
const featureIds = drawObj.getFeatureIdsAt(e.point);
const feature = drawObj.get(featureIds[0]);
const type = handlerReturnMode(drawObj.getMode());
if (type) {
if (feature) {
// 뒷 부분
const coordinates = feature.geometry.coordinates;
const coords = [
...new Set(
type === 'LINE'
? coordinates.map(JSON.stringify)
: coordinates[0].map(JSON.stringify)
)
].map(JSON.parse);
const len = coords.length;
const lngLat = handlerGetMidPoint(coords[len - 2], coords[len - 1]);
const text = CalculateDistance(coords[len - 2], coords[len - 1]);
handlerCreateOneMarker([0, 0], lngLat, text);
} else {
// Start
handlerCreateOneMarker([0, -10], [e.lngLat.lng, e.lngLat.lat], 'Start');
}
}
};
// 도형 첫 생성하면 properties.id에 현재 drawType 넣어줌
const handlerCreateObj = e => {
const id = e.features[0].id;
const mode = handlerReturnMode(drawObj.getMode());
if (mode) {
drawObj.setFeatureProperty(id, 'id', mode);
handlerFormatAreaInfo(e);
}
};
const handlerFormatAreaInfo = e => {
const coord = e.features[0].geometry.coordinates;
const mode = drawObj.get(e.features[0].id).properties.id;
const data =
mode === 'LINE'
? coord
: mode === 'POLYGON'
? coord[0]
: mode === 'CIRCLE'
? e.features[0].properties.center
: null;
handlerSaveAreaInfo(data, mode);
};
const handlerSaveAreaInfo = (coord, mode) => {
if (!coord || !mode) {
alert('에러 발생. 다시 시도해 주세요.');
return;
}
const areaInfo = {
coordinates: [],
bufferZone: 0,
areaType: ''
};
const bufferZone = mode === 'POLYGON' ? 0 : 100;
const prePath = [];
areaInfo.areaType = mode;
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 obj = drawObj.getAll();
const feature = obj.features[0];
const point = {
lat: coord[1],
lon: coord[0]
};
areaInfo.coordinates = [point];
areaInfo.bufferZone = feature.properties.radiusInKm * 1000;
}
props.handlerCoordinates(areaInfo);
};
const handlerPastDraw = () => {
if (props.areaCoordList) {
console.log(props.areaCoordList[0], '>>>>areaCoordList---');
const areas = props.areaCoordList[0];
const paths = [];
areas.coordList.forEach(coord => paths.push([coord.lon, coord.lat]));
if (areas.areaType) {
console.log('pastDraw');
const drawGeoJson = drawObj.getAll();
if (areas.areaType === 'CIRCLE') {
} else {
if (areas.areaType === 'LINE') {
// 버퍼 생성
if (areas.bufferCoordList) {
const bufferPaths = [];
areas.bufferCoordList.forEach(bfCoord =>
bufferPaths.push([bfCoord.lon, bfCoord.lat])
);
const buffer = drawObj.get(bufferId);
if (buffer) drawObj.delete(bufferId);
const newBuffer = {
type: 'LineString',
coordinates: bufferPaths
};
const newBufferId = drawObj.add(newBuffer);
setBufferId(newBufferId);
}
} else if (areas.areaType === 'POLYGON') {
}
}
// 현재 그려진 도형 저장
setGeoJson(drawGeoJson);
// 마커 재 생성
handlerRemoveMarker();
handlerCreateAllMarker(paths);
}
}
};
const handlerRemoveMarker = () => {
const ele = document.getElementsByClassName('mapboxgl-popup');
const eleArr = Array.from(ele);
eleArr?.forEach(marker => marker.remove());
};
const handlerCreateOneMarker = (anchor, lngLat, text) => {
const popup = new props.mapboxgl.Popup({
offset: anchor,
closeButton: false,
closeOnClick: false
})
.setLngLat(lngLat)
.setHTML(handlerGetHtmlContent(text))
.addTo(mapObject);
};
const handlerCreateAllMarker = coords => {
for (let i = 0; i < coords.length; i++) {
if (i === 0) {
handlerCreateOneMarker([0, -10], coords[i], 'Start');
} else {
const lngLat = handlerGetMidPoint(coords[i - 1], coords[i]);
const text = CalculateDistance(coords[i - 1], coords[i]);
handlerCreateOneMarker([0, 0], lngLat, text);
}
}
};
const drawInit = () => {
drawObj.deleteAll();
handlerRemoveMarker();
props.handlerInitCoordinates();
const mode = mapControl.drawType;
if (!mode || mode === 'RESET') {
return;
}
handlerStartMode(mode);
};
const handlerStartMode = mode => {
console.log('startMode');
if (mode === 'LINE') {
drawObj.changeMode('draw_line_string');
} else if (mode === 'POLYGON') {
drawObj.changeMode('draw_polygon');
} else if (mode === 'CIRCLE') {
drawObj.changeMode('draw_circle');
}
};
// drawMode에 따른 drawType 매칭
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';
};
return <InfoModal modal={alertModal} setModal={setAlertModal} />;
};

13
src/components/map/mapbox/draw/LaancDrawRe.js

@ -50,6 +50,7 @@ export const LaancDrawRe = props => {
useEffect(() => {
const areaType = props.areaCoordList[0].areaType;
console.log(props.areaCoordList, '>>----');
if (areaType && areaType !== '' && detailLayer) {
handlerPastDraw();
@ -76,6 +77,7 @@ export const LaancDrawRe = props => {
console.log('removeEvent');
mapObject.off('click', onClickDrawObj);
mapObject.off('mousemove', onMouseMoveDrawObj);
mapObject.off('mousedown', 'polygon', onMouseDown);
mapObject.off('contextmenu', onRightClick);
}, [mode]);
@ -104,9 +106,10 @@ export const LaancDrawRe = props => {
handlerSetDrawObj('Polygon', 'POLYGON');
} else if (mode === 'CIRCLE') {
handlerSetDrawObj('Polygon', 'CIRCLE');
mapObject.on('click', onClickCircle);
}
mapObject.on('click', onClickDrawObj);
if (mode !== 'CIRCLE') mapObject.on('click', onClickDrawObj);
};
const onClickDrawObj = useCallback(
@ -258,7 +261,6 @@ export const LaancDrawRe = props => {
handlerReplaceDuplicate(id, '');
return;
}
// if (coord.length === 0) return;
console.log('down');
if (id === 'CIRCLE') {
@ -289,6 +291,7 @@ export const LaancDrawRe = props => {
const center = drawObj.properties.center;
const circleCoords = handlerGetCircleCoord(center, distance);
drawObj.geometry.coordinates = circleCoords;
handlerReplaceDuplicate('CIRCLE', drawObj);
} else {
geojson.features = geojson.features.map(geo => {
const coord = formatCoord;
@ -370,7 +373,8 @@ export const LaancDrawRe = props => {
drawObj.properties.id = 'CIRCLE';
drawObj.geometry.type = 'Polygon';
geojson.features.push(drawObj);
// geojson.features.push(drawObj);
handlerReplaceDuplicate('CIRCLE', drawObj);
} else {
if (areas.areaType === 'LINE') {
drawObj.geometry.coordinates = paths;
@ -411,7 +415,7 @@ export const LaancDrawRe = props => {
// mouseDown이벤트
mapObject.on('mousedown', 'waypoint', onMouseDown);
}
// 기존 마커 제거 후 재 생성
handlerRemoveMarker();
handlerCreateAllMarker(paths);
@ -419,7 +423,6 @@ export const LaancDrawRe = props => {
mapObject.setPaintProperty('waypoint', 'circle-radius', 8);
handlerGetSourceSetData();
}
}
};
const handlerSaveAreaInfo = coord => {

104
src/views/laanc/FlightArea.js

@ -223,7 +223,95 @@ export default function FlightArea({
drag_circle: DragCircleMode,
direct_select: DirectMode,
simple_select: SimpleSelectMode
},
styles: [
// line stroke
{
id: 'gl-draw-line',
type: 'line',
filter: [
'all',
['==', '$type', 'LineString'],
['!=', 'mode', 'static']
],
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#8a1c05',
'line-dasharray': [0.2, 2],
'line-width': 2
}
},
// polygon fill
{
id: 'gl-draw-polygon-fill',
type: 'fill',
filter: ['all', ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
paint: {
'fill-color': '#8a1c05',
'fill-outline-color': '#8a1c05',
'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
{
id: 'gl-draw-polygon-stroke-active',
type: 'line',
filter: ['all', ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#8a1c05',
'line-dasharray': [0.2, 2],
'line-width': 2
}
},
// vertex point halos
{
id: 'gl-draw-polygon-and-line-vertex-halo-active',
type: 'circle',
filter: [
'all',
['==', 'meta', 'vertex'],
['==', '$type', 'Point'],
['!=', 'mode', 'static']
],
paint: {
'circle-radius': 8,
'circle-color': '#fff'
}
},
// vertex points
{
id: 'gl-draw-polygon-and-line-vertex-active',
type: 'circle',
filter: [
'all',
['==', 'meta', 'vertex'],
['==', '$type', 'Point'],
['!=', 'mode', 'static']
],
paint: {
'circle-radius': 6,
'circle-color': '#8a1c05'
}
}
]
});
setDrawObj(draw);
@ -439,8 +527,8 @@ export default function FlightArea({
<Button
color='primary'
onClick={() => {
// handlerDrawType('LINE');
drawObj.changeMode('draw_line_string');
handlerDrawType('LINE');
// drawObj.changeMode('draw_line_string');
}}
>
WayPoint
@ -448,8 +536,8 @@ export default function FlightArea({
<Button
color='primary'
onClick={() => {
// handlerDrawType('CIRCLE');
drawObj.changeMode('drag_circle');
handlerDrawType('CIRCLE');
// drawObj.changeMode('drag_circle');
}}
>
Circle
@ -457,8 +545,8 @@ export default function FlightArea({
<Button
color='primary'
onClick={() => {
// handlerDrawType('POLYGON');
drawObj.changeMode('draw_polygon');
handlerDrawType('POLYGON');
// drawObj.changeMode('draw_polygon');
}}
>
Polygon
@ -466,8 +554,8 @@ export default function FlightArea({
<Button
color='primary'
onClick={() => {
// handlerDrawType('RESET');
drawObj.deleteAll();
handlerDrawType('RESET');
// drawObj.deleteAll();
}}
>
초기화

26
src/views/laanc/LaancAreaMap.js

@ -32,6 +32,7 @@ import gimpo from '../../components/map/geojson/gimpoAirportAirArea.json';
import geoJson from '../../components/map/geojson/airArea.json';
import { FeatureAirZone } from '../../components/map/mapbox/feature/FeatureAirZone';
import LaancMapSearch from '../../components/map/mapbox/draw/LaancMapSearch';
import { LaancDrawControl } from '../../components/map/mapbox/draw/LaancDrawControl';
export default function LaancAreaMap({ centeredModal, mapContainer, drawObj }) {
const dispatch = useDispatch();
@ -198,20 +199,7 @@ export default function LaancAreaMap({ centeredModal, mapContainer, drawObj }) {
}
));
// 사용자가 비행구역 설정 드로우 완성시 실행됨
map.on('draw.create', e => {
console.log(drawObj.getAll());
});
// 수정할때
map.on('draw.update', e => {
console.log(drawObj.getAll());
});
// 삭제할때
map.on('draw.delete', e => {
console.log(drawObj.getAll());
});
map.on('contextmenu', function (e) {
map.on('contextmenu', e => {
e.preventDefault();
});
@ -332,7 +320,7 @@ export default function LaancAreaMap({ centeredModal, mapContainer, drawObj }) {
geojson={detailGeo}
detailLayer={detailLayer}
/> */}
<LaancDrawRe
{/* <LaancDrawRe
mapObject={mapObject}
areaCoordList={mapAreaCoordList}
geojson={detailGeo}
@ -341,6 +329,14 @@ export default function LaancAreaMap({ centeredModal, mapContainer, drawObj }) {
mode={mode}
handlerCoordinates={handlerCoordinates}
handlerInitCoordinates={handlerInitCoordinates}
/> */}
<LaancDrawControl
drawObj={drawObj}
mapboxgl={mapboxgl}
mapObject={mapObject}
areaCoordList={mapAreaCoordList}
handlerCoordinates={handlerCoordinates}
handlerInitCoordinates={handlerInitCoordinates}
/>
<FeatureAirZone map={mapObject} mapboxgl={mapboxgl} />
</>

Loading…
Cancel
Save