Browse Source

비행계획서 draw기능 circle

pull/2/head
junh_eee(이준희) 1 year ago
parent
commit
d83545b86e
  1. 3
      src/components/basis/flight/plan/FlightPlanAreaMapBox.js
  2. 200
      src/components/map/mapbox/draw/MapBoxDraw.js

3
src/components/basis/flight/plan/FlightPlanAreaMapBox.js

@ -93,7 +93,8 @@ export const FlightPlanAreaMapBox = props => {
container: 'map', // container ID container: 'map', // container ID
style: 'mapbox://styles/mapbox/streets-v12', // style URL style: 'mapbox://styles/mapbox/streets-v12', // style URL
center: [126.612647, 37.519893], // starting position [lng, lat] center: [126.612647, 37.519893], // starting position [lng, lat]
zoom: !areaCoordList ? 11 : bufferZoom.bufferzoom, // starting zoom // zoom: !areaCoordList ? 14 : bufferZoom.bufferzoom, // starting zoom
zoom: 15,
antialias: true antialias: true
}); });

200
src/components/map/mapbox/draw/MapBoxDraw.js

@ -31,13 +31,16 @@ export const MapBoxDraw = props => {
let mode = props.mode; let mode = props.mode;
let circle;
let radiusline; let radiusline;
const eventListener = { const eventListener = {
clickEvent: '', clickEvent: '',
mousemoveEvent: '', mouseMoveEvent: '',
rightClickEvent: '' rightClickEvent: '',
mousedownEvent: '',
mouseUpEvent: '',
mouseEnterEvent: '',
mouseLeaveEvent: ''
}; };
const geojson = props.geojson; const geojson = props.geojson;
@ -47,6 +50,10 @@ export const MapBoxDraw = props => {
let polygon; let polygon;
let circle;
const canvas = mapObject.getCanvasContainer();
useEffect(() => { useEffect(() => {
setRadiusCircle(props.dragSize); setRadiusCircle(props.dragSize);
}, [props.dragSize]); }, [props.dragSize]);
@ -62,7 +69,7 @@ export const MapBoxDraw = props => {
type: type, type: type,
coordinates: [] coordinates: []
}, },
properties: { id: '' } properties: { id: '', center: '' }
}; };
}; };
@ -79,6 +86,9 @@ export const MapBoxDraw = props => {
polygon = initFeature('Polygon'); polygon = initFeature('Polygon');
polygon.properties.id = 'polygon'; polygon.properties.id = 'polygon';
circle = initFeature('Polygon');
circle.properties.id = 'polygon';
const drawType = mapControl.drawType; const drawType = mapControl.drawType;
handlerButtonClick(drawType); handlerButtonClick(drawType);
}; };
@ -118,8 +128,9 @@ export const MapBoxDraw = props => {
if (!mode) return; if (!mode) return;
eventListener.clickEvent = e => { eventListener.clickEvent = e => {
if (mode === 'LINE') onClickPolyline(e); if (mode === 'LINE') onClickFeature(e, lineString, 'polyline');
if (mode === 'POLYGON') onClickPolygon(e); if (mode === 'POLYGON') onClickFeature(e, polygon, 'polygon');
if (mode === 'CIRCLE') onClickCircle(e);
if (mode === 'RESET') handlerClearMode(); if (mode === 'RESET') handlerClearMode();
}; };
mapObject.on('click', eventListener.clickEvent); mapObject.on('click', eventListener.clickEvent);
@ -127,23 +138,24 @@ export const MapBoxDraw = props => {
const removeListener = () => { const removeListener = () => {
mapObject.off('click', eventListener.clickEvent); mapObject.off('click', eventListener.clickEvent);
mapObject.off('mousemove', eventListener.mousemoveEvent); mapObject.off('mousemove', eventListener.mouseMoveEvent);
mapObject.off('contextmenu', eventListener.rightClickEvent); mapObject.off('contextmenu', eventListener.rightClickEvent);
eventListener.clickEvent = ''; eventListener.clickEvent = '';
eventListener.mousemoveEvent = ''; eventListener.mouseMoveEvent = '';
eventListener.rightClickEvent = ''; eventListener.rightClickEvent = '';
}; };
const onClickPolyline = e => { //polyline, polygon 생성
const onClickFeature = (e, figureObj, id) => {
const features = mapObject.queryRenderedFeatures(e.point, { const features = mapObject.queryRenderedFeatures(e.point, {
layers: ['waypoint'] layers: ['waypoint']
}); });
lineString.properties.id = 'polyline'; figureObj.properties.id = id;
if (geojson.features.length > 1) { if (geojson.features.length > 1) {
geojson.features = geojson.features.filter( geojson.features = geojson.features.filter(
geo => geo.properties?.id !== 'polyline' geo => geo.properties?.id !== id
); );
} }
@ -168,97 +180,143 @@ export const MapBoxDraw = props => {
guideLine.geometry.coordinates = [[e.lngLat.lng, e.lngLat.lat]]; guideLine.geometry.coordinates = [[e.lngLat.lng, e.lngLat.lat]];
if (geojson.features.length > 1) { if (geojson.features.length > 1) {
//point들의 좌표만 뽑아서 polyline의 좌표로 넣어줌 const coordinates = geojson.features
lineString.geometry.coordinates = geojson.features
.filter(point => point.properties?.id === 'point') .filter(point => point.properties?.id === 'point')
.map(point => point.geometry.coordinates); .map(point => point.geometry.coordinates);
geojson.features.push(lineString); figureObj.geometry.coordinates =
console.log(lineString.geometry, '>>>lineString'); id === 'polyline' ? coordinates : [coordinates];
geojson.features.push(figureObj);
} else { } else {
eventListener.rightClickEvent = () => { eventListener.rightClickEvent = () => {
finishDraw(); finishDraw();
}; };
mapObject.on('contextmenu', eventListener.rightClickEvent); mapObject.on('contextmenu', eventListener.rightClickEvent);
eventListener.mousemoveEvent = e => { eventListener.mouseMoveEvent = e => {
onMouseMovePolyline(e); id === 'polyline' ? onMouseMovePolyline(e) : onMouseMovePolygon(e);
}; };
mapObject.on('mousemove', eventListener.mousemoveEvent); mapObject.on('mousemove', eventListener.mouseMoveEvent);
} }
mapObject.getSource('geojson').setData(geojson); mapObject.getSource('geojson').setData(geojson);
}; };
const onMouseMovePolyline = e => { //circle 생성
if (guideLine.geometry.coordinates.length > 1) { const onClickCircle = e => {
guideLine.geometry.coordinates.pop(); circle.properties.id = 'circle';
geojson.features.pop();
//기존 guideline 제거 const center = [e.lngLat.lng, e.lngLat.lat];
geojson.features = geojson.features.filter( const radius = 100;
point => point.properties?.id !== 'guideline' const options = {
); steps: 360,
//새로운 가이드라인 push units: 'kilometers'
geojson.features.push(guideLine); };
} const circleCoords = turf.circle(center, radius / 1000, options).geometry
guideLine.geometry.coordinates.push([e.lngLat.lng, e.lngLat.lat]); .coordinates;
circle.properties.center = center;
circle.geometry.coordinates = circleCoords;
geojson.features.push(circle);
eventListener.mouseEnterEvent = () => {
onMouseEnter();
};
mapObject.on('mouseenter', 'polygon', eventListener.mouseEnterEvent);
eventListener.mouseLeaveEvent = () => {
onMouseLeave();
};
mapObject.on('mouseleave', 'polygon', eventListener.mouseLeaveEvent);
eventListener.mousedownEvent = e => {
//mouseDown event추가하기
onMouseDown(e);
};
mapObject.on('mousedown', 'polygon', eventListener.mousedownEvent);
mapObject.getSource('geojson').setData(geojson); mapObject.getSource('geojson').setData(geojson);
}; };
const onClickPolygon = e => { //원에 마우스 닿았을 때
const features = mapObject.queryRenderedFeatures(e.point, { const onMouseEnter = () => {
layers: ['waypoint'] mapObject.setPaintProperty('polygon', 'fill-color', '#3bb2d0');
}); canvas.style.cursor = 'move';
};
polygon.properties.id = 'polygon'; //원에 마우스 떠났을 때
if (geojson.features.length > 1) { const onMouseLeave = () => {
geojson.features = geojson.features.filter( mapObject.setPaintProperty('polygon', 'fill-color', '#7367F0');
geo => geo.properties?.id !== 'polygon' canvas.style.cursor = '';
); };
}
if (features.length) { //원에 마우스 클릭되었을 때
const id = features[0].properties.id; const onMouseDown = e => {
geojson.features = geojson.features.filter( e.preventDefault();
point => point.properties.id !== id
); canvas.style.cursor = 'grab';
} else {
const point = { eventListener.mouseMoveEvent = e => {
type: 'Feature', onMouseMove(e);
geometry: {
type: 'Point',
coordinates: [e.lngLat.lng, e.lngLat.lat]
},
properties: { id: 'point' }
}; };
geojson.features.push(point); mapObject.on('mousemove', eventListener.mouseMoveEvent);
}
guideLine.properties.id = 'guideline'; eventListener.mouseUpEvent = e => {
guideLine.geometry.coordinates = [[e.lngLat.lng, e.lngLat.lat]]; onMouseUp(e);
};
mapObject.once('mouseup', eventListener.mouseUpEvent);
};
if (geojson.features.length > 1) { //원에 마우스 클릭되어서 움직일 때
//point들의 좌표만 뽑아서 Polygon의 좌표로 넣어줌 const onMouseMove = e => {
polygon.geometry.coordinates = [ canvas.style.cursor = 'grabbing';
geojson.features
.filter(point => point.properties?.id === 'point') const centerCoord = turf.point(circle.properties.center);
.map(point => point.geometry.coordinates) const currentCoord = turf.point([e.lngLat.lng, e.lngLat.lat]);
];
geojson.features.push(polygon); const distanceOptions = { units: 'kilometers' };
} else { //circle 센터와 e.coord간의 거리(meters)
eventListener.rightClickEvent = () => { const currentToCenter =
finishDraw(); turf.distance(centerCoord, currentCoord, distanceOptions) * 1000;
const center = circle.properties.center;
const options = {
steps: 360,
units: 'kilometers'
}; };
mapObject.on('contextmenu', eventListener.rightClickEvent); const circleCoords = turf.circle(center, currentToCenter / 1000, options)
.geometry.coordinates;
eventListener.mousemoveEvent = e => { circle.geometry.coordinates = circleCoords;
onMouseMovePolygon(e);
mapObject.getSource('geojson').setData(geojson);
}; };
mapObject.on('mousemove', eventListener.mousemoveEvent);
const onMouseUp = e => {
canvas.style.cursor = '';
mapObject.off('mousemove', eventListener.mouseMoveEvent);
eventListener.onMouseMove = '';
};
//polyline 가이드 생성
const onMouseMovePolyline = e => {
if (guideLine.geometry.coordinates.length > 1) {
guideLine.geometry.coordinates.pop();
//기존 guideline 제거
geojson.features = geojson.features.filter(
point => point.properties?.id !== 'guideline'
);
//새로운 가이드라인 push
geojson.features.push(guideLine);
} }
guideLine.geometry.coordinates.push([e.lngLat.lng, e.lngLat.lat]);
mapObject.getSource('geojson').setData(geojson); mapObject.getSource('geojson').setData(geojson);
}; };
//polygon 가이드 생성
const onMouseMovePolygon = e => { const onMouseMovePolygon = e => {
if (polygon.geometry.coordinates.length > 0) { if (polygon.geometry.coordinates.length > 0) {
if (polygon.geometry.coordinates[0].length > 1) { if (polygon.geometry.coordinates[0].length > 1) {

Loading…
Cancel
Save