Browse Source

거리측정 되돌리기 기능 작업 중간커밋

master
김장현 2 months ago
parent
commit
31a85a867c
  1. 59
      src/components/map/mapbox/MapBoxMap.js
  2. 70
      src/components/map/mapbox/feature/FeatureAirZone.js
  3. 99
      src/containers/flight/OperationApprovalsContainer.js
  4. 153
      src/utility/MapUtils.js

59
src/components/map/mapbox/MapBoxMap.js

@ -95,7 +95,7 @@ export default function MapBoxMap({ handlerDrawObjInit }) {
// 노탐 정보 모달
const [centeredModal, setCenteredModal] = useState(false);
let popup;
// 거리 측정
// 비행예상경로 geoJson 정보
@ -419,7 +419,6 @@ export default function MapBoxMap({ handlerDrawObjInit }) {
type: 'custom',
renderingMode: '3d',
onAdd: function () {
console.log(mapState.mapType);
for (let i = 0; i < gimPo.features.length; i++) {
let line;
const options = {
@ -572,11 +571,65 @@ export default function MapBoxMap({ handlerDrawObjInit }) {
setMapLoaded(true);
});
handlerDrawObjInit(drawObj);
map.on('click', 'maine', e => {
let isMaine = false;
let isOperation = false;
map.queryRenderedFeatures(e.point).map(feature => {
if (feature.source === 'operationLayer') isOperation = true;
if (feature.source === 'maine') isMaine = true;
});
if (isMaine && !isOperation) {
map.getCanvas().style.cursor = 'pointer';
const feature = e.features[0];
const data = feature.properties;
data.coord = e.lngLat;
data.title = feature.properties.name;
infowindowOpen(data, map);
}
});
handlerDrawObjInit(drawObj, map);
setMapObject(map);
dispatch(clientMapInit(map));
};
const infowindowOpen = (data, map) => {
const content =
'<div class="tooltip-box">' +
'<div class="tooltip-txt">' +
'<span>' +
data.title +
'</span>' +
'</div>' +
// '<div class="tooltip-txt">' +
// '<div class="tooltip-txt-list">' +
// '<span>' +
// data.description +
// '</span>' +
// '</div>' +
// '</div>' +
'</div>';
if (popup) {
popup.remove();
}
// Create a popup element
popup = new mapboxgl.Popup({
offset: [0, 0],
closeButton: false,
closeOnClick: true,
closeOnMove: false
})
.setLngLat(data.coord)
.setHTML(content)
.addTo(map);
};
return (
<>
<div

70
src/components/map/mapbox/feature/FeatureAirZone.js

@ -95,26 +95,26 @@ export default function FeatureAirZone(props) {
});
});
props.map.on('click', 'maine', e => {
let isMaine = false;
let isOperation = false;
// props.map.on('click', 'maine', e => {
// let isMaine = false;
// let isOperation = false;
props.map.queryRenderedFeatures(e.point).map(feature => {
if (feature.source === 'operationLayer') isOperation = true;
if (feature.source === 'maine') isMaine = true;
});
// props.map.queryRenderedFeatures(e.point).map(feature => {
// if (feature.source === 'operationLayer') isOperation = true;
// if (feature.source === 'maine') isMaine = true;
// });
if (isMaine && !isOperation) {
props.map.getCanvas().style.cursor = 'pointer';
// if (isMaine && !isOperation) {
// props.map.getCanvas().style.cursor = 'pointer';
const feature = e.features[0];
const data = feature.properties;
data.coord = e.lngLat;
data.title = feature.properties.name;
// const feature = e.features[0];
// const data = feature.properties;
// data.coord = e.lngLat;
// data.title = feature.properties.name;
infowindowOpen(data);
}
});
// infowindowOpen(data);
// }
// });
// props.map.on('mouseover', 'maine', e => {
// props.map.getCanvas().style.cursor = 'pointer';
@ -133,27 +133,27 @@ export default function FeatureAirZone(props) {
// }
// });
const buildingsLayer = props.map.getLayer('add-3d-buildings');
if (buildingsLayer) {
props.map.on('click', e => {
// 클릭한 지점의 피처들을 얻어옵니다.
const features = props.map.queryRenderedFeatures(e.point, {
layers: ['add-3d-buildings'] // 빌딩 레이어의 ID를 지정합니다.
});
// const buildingsLayer = props.map.getLayer('add-3d-buildings');
// if (buildingsLayer) {
// props.map.on('click', e => {
// // 클릭한 지점의 피처들을 얻어옵니다.
// const features = props.map.queryRenderedFeatures(e.point, {
// layers: ['add-3d-buildings'] // 빌딩 레이어의 ID를 지정합니다.
// });
// 빌딩 피처가 있는 경우
if (features.length > 0) {
// 첫 번째 빌딩 피처의 높이 값을 얻어옵니다.
const height = features[0].properties.height;
// // 빌딩 피처가 있는 경우
// if (features.length > 0) {
// // 첫 번째 빌딩 피처의 높이 값을 얻어옵니다.
// const height = features[0].properties.height;
// 팝업을 생성하고 지도에 추가합니다.
new props.mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(`Building height: ${height}m`)
.addTo(props.map);
}
});
}
// // 팝업을 생성하고 지도에 추가합니다.
// new props.mapboxgl.Popup()
// .setLngLat(e.lngLat)
// .setHTML(`Building height: ${height}m`)
// .addTo(props.map);
// }
// });
// }
};
// 이착륙장 마커 이벤트 로직

99
src/containers/flight/OperationApprovalsContainer.js

@ -62,7 +62,6 @@ export default function OperationApprovalsContainer({ mode }) {
// 비행구역 그리기
const [drawObj, setDrawObj] = useState();
const [filter, setFilter] = useState('');
const mouseCursorRef = useRef(null);
// 지도
const [mapObject, setMapObject] = useState();
@ -95,6 +94,12 @@ export default function OperationApprovalsContainer({ mode }) {
// 비행구역 데이터블록
const [dataBlocks, setDataBlocks] = useState([]);
// 거리측정
const [isDistanceStartPoint, setIsDistanceStartPoint] = useState(false);
const totalDistanceRef = useRef(null);
const mouseCursorRef = useRef(null);
const distanceBoxRef = useRef(null);
// 비행구역 (운항과) 레이어
const operationLayer = {
type: 'FeatureCollection',
@ -135,7 +140,6 @@ export default function OperationApprovalsContainer({ mode }) {
window._mapbox = map;
let mapInstance = mode === 'container' ? map : window.opener._mapbox;
setMapObject(mapInstance);
handlerOnClickDrawLineString(mapInstance, handlerDrawMarker);
}
}, [map]);
@ -461,46 +465,78 @@ export default function OperationApprovalsContainer({ mode }) {
const handlerDrawTypeChange = (e, val) => {
drawObj.deleteAll();
distanceMarkers.map(i => i.remove());
distanceBoxRef.current.style.display = 'block';
dispatch(clientChangeDrawType(val));
handlerStartMode(val, drawObj);
};
const handlerDrawObjInit = obj => {
const handlerDrawObjInit = (obj, mapInstance) => {
setDrawObj(obj);
handlerOnClickDrawLineString(
mapInstance,
handlerDrawPopup,
{
totalDistanceRef,
mouseCursorRef,
distanceBoxRef
},
obj
);
};
const handlerMapTypeChange = val => {
dispatch(clientChangeDrawType(''));
// dispatch(clientChangeDrawType(''));
drawObj.changeMode('simple_select');
setMapType(val);
};
const handlerDistanceClose = () => {
drawObj.deleteAll();
dispatch(clientChangeDrawType(''));
document.getElementById('distance_box').style.display = 'none';
dispatch(clientChangeDrawType('simple_select'));
drawObj.changeMode('simple_select');
mouseCursorRef.current.style.display = 'none';
distanceBoxRef.current.style.display = 'none';
};
const handlerDrawMarker = (mapInstance, markerList, startPoint) => {
const marker = markerList.filter(i => {
return i.coord[0][0] === startPoint.lng;
});
if (marker.length > 0) {
const handlerDistanceRevert = () => {
if (drawObj.getMode() === 'draw_line_string') {
const allFeatures = drawObj.getAll();
if (allFeatures.features.length > 0) {
allFeatures.features[0].geometry.coordinates.pop(); // 마지막 좌표 제거
allFeatures.features[0].geometry.coordinates.pop();
allFeatures.features[0].geometry.coordinates.push(
allFeatures.features[0].geometry.coordinates[
allFeatures.features[0].geometry.coordinates.length - 1
]
);
drawObj.set(allFeatures);
}
}
};
const handlerDrawPopup = (mapInstance, popupList) => {
// setIsDistanceStartPoint(true);
if (distanceMarkers.length > 0) {
distanceMarkers.map(i => i.remove());
}
if (popupList.length > 0) {
popupList.map(i => {
let distanceMarker = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false,
anchor: 'bottom',
focusAfterOpen: false
})
.setLngLat([
marker[0].coord[0][0].toFixed(6),
marker[0].coord[0][1].toFixed(6)
])
.setLngLat([i.coord[0][0].toFixed(6), i.coord[0][1].toFixed(6)])
.setHTML(
`<div style="color:#000000;font-weight:400;">${marker[0].text}</div>`
`<div style="color:#000000;font-weight:400;">${i.text}</div>`
)
.addTo(mapInstance);
distanceMarkers.push(distanceMarker);
});
}
};
@ -517,18 +553,6 @@ export default function OperationApprovalsContainer({ mode }) {
return (
<>
<div className='map' style={{ width: '100%' }}>
<div
ref={mouseCursorRef}
style={{
position: 'absolute',
display: 'none',
background: '#8a1c05',
color: '#fff',
padding: '5px',
borderRadius: '5px',
fontWeight: 500
}}
></div>
<div className='test_modal'>
<Button
color='primary'
@ -807,7 +831,7 @@ export default function OperationApprovalsContainer({ mode }) {
</div>
</div>
<div
id='distance_box'
ref={distanceBoxRef}
className='data-box-btn-list'
style={{ display: 'none' }}
>
@ -822,8 +846,9 @@ export default function OperationApprovalsContainer({ mode }) {
<FiRotateCw size={16} />
</Button>
<Button
onClick={handlerDistanceRevert}
className='btn-icon rounded-circle'
color='primary'
color={isDistanceStartPoint ? 'primary' : ''}
size='sm'
>
<FiCornerUpLeft size={16} />
@ -841,7 +866,7 @@ export default function OperationApprovalsContainer({ mode }) {
<p>
지도에서 지점을 클릭하여 거리를 측정하세요.
<span
id='total_distance'
ref={totalDistanceRef}
className='finish'
style={{ display: 'none' }}
>
@ -903,6 +928,18 @@ export default function OperationApprovalsContainer({ mode }) {
</div>
</div>
)}
<div
ref={mouseCursorRef}
style={{
position: 'absolute',
display: 'none',
background: '#8a1c05',
color: '#fff',
padding: '5px',
borderRadius: '5px',
fontWeight: 500
}}
></div>
</>
);
}

153
src/utility/MapUtils.js

@ -578,9 +578,7 @@ export const getDraw = mode => {
userProperties: true,
boxSelect: false,
modes: {
...modes,
draw_circle: CircleMode,
drag_circle: DragCircleMode
...modes
},
styles: [
{
@ -673,49 +671,72 @@ export const handlerStartMode = (mode, drawObj) => {
}
};
export const handlerOnClickDrawLineString = (mapInstance, callback) => {
const originClickHandler = MapboxDraw.modes.draw_line_string.onClick;
const originMouseMoveHandler = MapboxDraw.modes.draw_line_string.onMouseMove;
export const handlerOnClickDrawLineString = (
mapInstance,
callback,
refObj,
drawObj
) => {
const originLineClickHandler = MapboxDraw.modes.draw_line_string.onClick;
const { totalDistanceRef, mouseCursorRef, distanceBoxRef } = refObj;
let startPoint;
let markerList = [];
let distance = 0;
MapboxDraw.modes.draw_line_string.onClick = function (state, e) {
originClickHandler.call(this, state, e);
originLineClickHandler.call(this, state, e);
startPoint = e.lngLat;
state.line.coordinates.map((i, idx) => {
if (
i[0] !== state.line.coordinates[state.line.coordinates.length - 1][0]
) {
const obj = {
geometry: {
coordinates: [i, state.line.coordinates[idx + 1]],
type: 'LineString'
},
type: 'Feature'
const markerList = getDintancePointPopupList(drawObj);
callback(mapInstance, markerList);
};
let distance = turf.length(obj, { units: 'kilometers' });
distance = distance * 1000;
distance = distance.toFixed(2);
markerList.push({
text: `${distance.toLocaleString()}m`,
coord: [state.line.coordinates[idx + 1]]
mapInstance.on('mousemove', e => {
if (startPoint) {
mouseCursorRef.current.style.display = 'none';
if (drawObj.getMode() === 'direct_select') {
// distanceMarkers.map(i => i.remove());
const distance = getDrawDistance(drawObj);
totalDistanceRef.current.innerText = `총 거리 : ${distance.toLocaleString()}m`;
}
} else {
if (drawObj.getMode() === 'draw_line_string') {
console.log('@@@@');
mouseCursorRef.current.style.display = 'block';
mouseCursorRef.current.style.left = e.originalEvent.pageX + 'px';
mouseCursorRef.current.style.top = e.originalEvent.pageY + 45 + 'px';
mouseCursorRef.current.innerText = '시작점 선택';
}
}
});
mapInstance.on('draw.modechange', obj => {
if (obj.mode === 'simple_select') {
totalDistanceRef.current.style.display = 'block';
const distance = getDrawDistance(drawObj);
totalDistanceRef.current.innerText = `총 거리 : ${distance.toLocaleString()}m`;
mouseCursorRef.current.style.display = 'none';
mouseCursorRef.current.style.innerText = '';
const markerList = getDintancePointPopupList(drawObj);
callback(mapInstance, markerList);
} else if (obj.mode === 'direct_select') {
}
});
callback(mapInstance, markerList, startPoint);
};
};
MapboxDraw.modes.draw_line_string.onMouseMove = function (state, e) {
originMouseMoveHandler.call(this, state, e);
/**
*
* @param {MapboxDraw} drawObj
* @returns 거리 : number
*/
export const getDrawDistance = drawObj => {
const drawGeometry = drawObj.getAll().features[0];
let distance = 0;
console.log;
if (startPoint) {
console.log(state);
const drawGeometry = state.line.coordinates;
if (drawGeometry) {
const feature = [];
drawGeometry.map(i => feature.push(i));
drawGeometry.geometry.coordinates.map(i => feature.push(i));
const obj = {
geometry: {
coordinates: [...feature],
@ -726,32 +747,44 @@ export const handlerOnClickDrawLineString = (mapInstance, callback) => {
distance = turf.length(obj, { units: 'kilometers' });
distance = distance * 1000;
distance = distance.toFixed(2);
// mouseCursorRef.current.style.display = 'none';
}
// if (drawObj.getMode() === 'simple_select') {
// // startPoint = null;
// const totalDistance = document.getElementById('total_distance');
// totalDistance.style.display = 'block';
// totalDistance.innerText = `총 거리 : ${distance.toLocaleString()}m`;
// mouseCursorRef.current.style.display = 'none';
// mouseCursorRef.current.style.innerText = '';
// }
// if (drawObj.getMode() === 'direct_select') {
// distanceMarkers.map(i => i.remove());
// distanceMarkers = [];
// const totalDistance = document.getElementById('total_distance');
// totalDistance.innerText = `총 거리 : ${distance.toLocaleString()}m`;
// }
}
// else {
// if (drawObj.getMode() === 'draw_line_string') {
// document.getElementById('distance_box').style.display = 'block';
// mouseCursorRef.current.style.display = 'block';
// mouseCursorRef.current.style.left = e.originalEvent.pageX + 'px';
// mouseCursorRef.current.style.top = e.originalEvent.pageY + 45 + 'px';
// mouseCursorRef.current.innerText = '시작점 선택';
// }
// }
}
return distance;
};
/**
*
* @param {MapboxDraw} drawObj
* @returns Draw 포인트 거리 팝업 리스트
*/
export const getDintancePointPopupList = drawObj => {
const drawGeometry = drawObj.getAll().features[0];
console.log(drawObj.getAll().features[0]);
let markerList = [];
if (drawGeometry?.geometry) {
drawGeometry.geometry.coordinates.map((i, idx) => {
if (
i[0] !==
drawGeometry.geometry.coordinates[
drawGeometry.geometry.coordinates.length - 1
][0]
) {
const obj = {
geometry: {
coordinates: [i, drawGeometry.geometry.coordinates[idx + 1]],
type: 'LineString'
},
type: 'Feature'
};
let distance = turf.length(obj, { units: 'kilometers' });
distance = distance * 1000;
distance = distance.toFixed(2);
markerList.push({
text: `${distance.toLocaleString()}m`,
coord: [drawGeometry.geometry.coordinates[idx + 1]]
});
}
});
}
return markerList;
};

Loading…
Cancel
Save