|
|
|
@ -50,7 +50,6 @@ export const CalculateDistance = (mouse, center) => {
|
|
|
|
|
// 꼭짓점 두개 찍었을 때는 영역 or 라인이 안보이기 때문
|
|
|
|
|
// 2. drawType을 바꾸고 그린 다음 도형을 수정하면
|
|
|
|
|
// move중에 처음 그린 도형 표출되는 현상도 수정해야 함
|
|
|
|
|
// 9. 타입 바꾸면 도형 꼬이는거 해결
|
|
|
|
|
export const MapBoxDraw = props => { |
|
|
|
|
const mapControl = useSelector(state => state.controlMapReducer); |
|
|
|
|
const mapObject = props.mapObject; |
|
|
|
@ -66,20 +65,16 @@ export const MapBoxDraw = props => {
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const canvas = mapObject.getCanvasContainer(); |
|
|
|
|
const [pastPoint, setPoint] = useState([]); |
|
|
|
|
const [pastPolyline, setPolyline] = useState(); |
|
|
|
|
const [pastBuffer, setBuffer] = useState(); |
|
|
|
|
const [pastPolygon, setPolygon] = useState(); |
|
|
|
|
const [pastCircle, setCircle] = useState(); |
|
|
|
|
|
|
|
|
|
const [pastMarker, setMarker] = useState([]); |
|
|
|
|
// const [pastPoint, setPoint] = useState([]);
|
|
|
|
|
// const [pastPolyline, setPolyline] = useState();
|
|
|
|
|
// const [pastBuffer, setBuffer] = useState();
|
|
|
|
|
// const [pastPolygon, setPolygon] = useState();
|
|
|
|
|
// const [pastCircle, setCircle] = useState();
|
|
|
|
|
|
|
|
|
|
//도형들이 온전히 그려진 후 변경 될 때 마다 감지
|
|
|
|
|
const [isDrawDone, setIsDrawDone] = useState(false); |
|
|
|
|
|
|
|
|
|
//polygon, circle에서 pastObj들 렌더링 문제로
|
|
|
|
|
//아직 undefined인 것과 onMouseDown이벤트 중복 막기 위한...
|
|
|
|
|
const [isRegistEvent, setIsRegistEvent] = useState(false); |
|
|
|
|
const [mouseDownEve, setMouseDownEve] = useState(false); |
|
|
|
|
|
|
|
|
|
const areaInfo = { |
|
|
|
|
coordinates: [], |
|
|
|
@ -104,8 +99,6 @@ export const MapBoxDraw = props => {
|
|
|
|
|
let vertex = InitFeature('MultiPoint', 'vertex'); |
|
|
|
|
let dragCircleIdx; |
|
|
|
|
|
|
|
|
|
let distanceMarker = []; |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
if (mapControl.drawType) drawInit(); |
|
|
|
|
}, [mapControl.drawType]); |
|
|
|
@ -118,8 +111,8 @@ export const MapBoxDraw = props => {
|
|
|
|
|
}, [isDrawDone]); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
const areaCoordList = props.areaCoordList[0]; |
|
|
|
|
if (areaCoordList.areaType && areaCoordList.areaType !== '') { |
|
|
|
|
const area = props.areaCoordList[0]; |
|
|
|
|
if (area.areaType && area.areaType !== '') { |
|
|
|
|
handlerPastDraw(); |
|
|
|
|
} |
|
|
|
|
}, [props.areaCoordList]); |
|
|
|
@ -144,8 +137,6 @@ export const MapBoxDraw = props => {
|
|
|
|
|
console.log('clearMode'); |
|
|
|
|
removeGeoJson(); |
|
|
|
|
|
|
|
|
|
setIsRegistEvent(false); |
|
|
|
|
|
|
|
|
|
finishDraw(); |
|
|
|
|
props.handlerInitCoordinates(); |
|
|
|
|
}; |
|
|
|
@ -168,21 +159,21 @@ export const MapBoxDraw = props => {
|
|
|
|
|
mapObject.off('mousemove', onMouseMovePolyline); |
|
|
|
|
mapObject.off('mousemove', onMouseMovePolygon); |
|
|
|
|
mapObject.off('contextmenu', finishDraw); |
|
|
|
|
|
|
|
|
|
// 이거 있나 없나 뭔 차이지?
|
|
|
|
|
setMouseDownEve(false); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const removeGeoJson = () => { |
|
|
|
|
console.log('removeGeoJson'); |
|
|
|
|
|
|
|
|
|
setPolyline(); |
|
|
|
|
setBuffer(); |
|
|
|
|
setPolygon(); |
|
|
|
|
setCircle(); |
|
|
|
|
setPoint([]); |
|
|
|
|
// setPolyline();
|
|
|
|
|
// setBuffer();
|
|
|
|
|
// setPolygon();
|
|
|
|
|
// setCircle();
|
|
|
|
|
// setPoint([]);
|
|
|
|
|
|
|
|
|
|
pastMarker?.forEach(marker => { |
|
|
|
|
marker.remove(); |
|
|
|
|
}); |
|
|
|
|
setMarker([]); |
|
|
|
|
handlerRemoveMarker(); |
|
|
|
|
|
|
|
|
|
guideLine.geometry.coordinates = []; |
|
|
|
|
lineString.geometry.coordinates = []; |
|
|
|
@ -225,7 +216,6 @@ export const MapBoxDraw = props => {
|
|
|
|
|
if (path.length > 2) { |
|
|
|
|
polygon.geometry.coordinates[0] = path; |
|
|
|
|
|
|
|
|
|
addMileStone(handlerGetPolygonCoord(polygon), ''); |
|
|
|
|
handlerReplaceDuplicate('polygon', polygon); |
|
|
|
|
handlerSaveAreaInfo(polygon.geometry.coordinates[0], polygon); |
|
|
|
|
} else { |
|
|
|
@ -238,8 +228,8 @@ export const MapBoxDraw = props => {
|
|
|
|
|
props.handlerDrawType('RESET'); |
|
|
|
|
mapObject.on('click', clickEve); |
|
|
|
|
} |
|
|
|
|
mapObject.getSource('geojson').setData(geojson); |
|
|
|
|
} |
|
|
|
|
mapObject.getSource('geojson').setData(geojson); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -271,16 +261,7 @@ export const MapBoxDraw = props => {
|
|
|
|
|
geo => geo.properties?.id === 'point' |
|
|
|
|
).length; |
|
|
|
|
|
|
|
|
|
const wayPoint = { |
|
|
|
|
type: 'Feature', |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: formatCoord |
|
|
|
|
}, |
|
|
|
|
properties: { id: 'point', index: index } |
|
|
|
|
}; |
|
|
|
|
point.push(wayPoint); |
|
|
|
|
|
|
|
|
|
const wayPoint = handlerCreatePoint(formatCoord, index); |
|
|
|
|
handlerReplaceDuplicate('Point', wayPoint); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -362,16 +343,7 @@ export const MapBoxDraw = props => {
|
|
|
|
|
const onMouseDown = e => { |
|
|
|
|
e.preventDefault(); |
|
|
|
|
console.log('down'); |
|
|
|
|
// console.log(
|
|
|
|
|
// mapObject.getLayer('waypoint')._eventedParent._otherSourceCaches.geojson
|
|
|
|
|
// ._source._data.features,
|
|
|
|
|
// '>>>>'
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
const features = mapObject.queryRenderedFeatures(e.point, { |
|
|
|
|
layers: ['waypoint'] |
|
|
|
|
}); |
|
|
|
|
// console.log(features, '>>>???');
|
|
|
|
|
//타입 교체만 하면 왜 처음엔 down이 두번 잡힐까...
|
|
|
|
|
|
|
|
|
|
canvas.style.cursor = 'grab'; |
|
|
|
|
|
|
|
|
@ -430,33 +402,41 @@ export const MapBoxDraw = props => {
|
|
|
|
|
canvas.style.cursor = ''; |
|
|
|
|
console.log('up'); |
|
|
|
|
|
|
|
|
|
setIsRegistEvent(true); |
|
|
|
|
|
|
|
|
|
mapObject.off('mousedown', 'waypoint', onMouseDown); |
|
|
|
|
mapObject.off('mousemove', onMouseMove); |
|
|
|
|
mapObject.off('mouseup', onMouseUp); |
|
|
|
|
mapObject.off('click', clickEve); |
|
|
|
|
setMouseDownEve(false); |
|
|
|
|
|
|
|
|
|
const obj = handlerMatchObj(mapControl.drawType); |
|
|
|
|
const id = obj.properties?.id; |
|
|
|
|
const coord = |
|
|
|
|
id === 'polyline' |
|
|
|
|
? obj.geometry.coordinates |
|
|
|
|
: obj.geometry.coordinates[0]; |
|
|
|
|
|
|
|
|
|
if (obj.geometry.coordinates.length > 0) { |
|
|
|
|
if (obj) { |
|
|
|
|
const id = obj.properties?.id; |
|
|
|
|
const coord = |
|
|
|
|
id === 'polyline' |
|
|
|
|
? obj.geometry.coordinates |
|
|
|
|
: obj.geometry.coordinates[0]; |
|
|
|
|
|
|
|
|
|
if (id === 'circle') { |
|
|
|
|
mapObject.on('click', clickEve); |
|
|
|
|
handlerSaveAreaInfo('', circle); |
|
|
|
|
|
|
|
|
|
const radius = CalculateDistance( |
|
|
|
|
circle.properties.center, |
|
|
|
|
circle.geometry.coordinates[0][0] |
|
|
|
|
); |
|
|
|
|
addMileStone(circle.properties.center, radius); |
|
|
|
|
} else { |
|
|
|
|
handlerSaveAreaInfo(coord, obj); |
|
|
|
|
handlerSaveMarkerInfo(obj); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
// 저장된 좌표 불러왔을 때
|
|
|
|
|
const areas = props.areaCoordList[0]; |
|
|
|
|
const type = areas.areaType; |
|
|
|
|
|
|
|
|
|
const paths = []; |
|
|
|
|
areas.coordList.forEach(coord => paths.push([coord.lon, coord.lat])); |
|
|
|
|
|
|
|
|
|
if (type === 'LINE') { |
|
|
|
|
handlerSaveAreaInfo(lineString.geometry.coordinates, lineString); |
|
|
|
|
} else if (type === 'POLYGON') { |
|
|
|
|
handlerSaveAreaInfo(polygon.geometry.coordinates[0], polygon); |
|
|
|
|
} else if (type === 'CIRCLE') { |
|
|
|
|
handlerSaveAreaInfo('', circle); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -466,7 +446,16 @@ export const MapBoxDraw = props => {
|
|
|
|
|
let bufferZone = 100; |
|
|
|
|
if (polygon.geometry.coordinates.length > 0) bufferZone = 0; |
|
|
|
|
const prePath = []; |
|
|
|
|
if (path) { |
|
|
|
|
|
|
|
|
|
if (lineString.geometry.coordinates.length > 0) { |
|
|
|
|
areaInfo.areaType = 'LINE'; |
|
|
|
|
} else if (polygon.geometry.coordinates.length > 0) { |
|
|
|
|
areaInfo.areaType = 'POLYGON'; |
|
|
|
|
} else if (circle.geometry.coordinates.length > 0) { |
|
|
|
|
areaInfo.areaType = 'CIRCLE'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (areaInfo.areaType !== 'CIRCLE') { |
|
|
|
|
path.forEach(item => { |
|
|
|
|
const p = { |
|
|
|
|
lat: item[1], |
|
|
|
@ -476,7 +465,6 @@ export const MapBoxDraw = props => {
|
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
areaInfo.areaType = mapControl.drawType; |
|
|
|
|
areaInfo.coordinates = prePath; |
|
|
|
|
areaInfo.bufferZone = bufferZone; |
|
|
|
|
if (areaInfo.areaType === 'CIRCLE') { |
|
|
|
@ -490,108 +478,168 @@ export const MapBoxDraw = props => {
|
|
|
|
|
circle.properties.center |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
props.handlerCoordinates(areaInfo); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//let이라서 지워지는 도형 재 생성
|
|
|
|
|
// let이라서 지워지는 도형 재 생성
|
|
|
|
|
const handlerPastDraw = () => { |
|
|
|
|
if (props.areaCoordList) { |
|
|
|
|
console.log('pastDraw'); |
|
|
|
|
|
|
|
|
|
const areas = props.areaCoordList[0]; |
|
|
|
|
|
|
|
|
|
const paths = []; |
|
|
|
|
areas.coordList.forEach(coord => paths.push([coord.lon, coord.lat])); |
|
|
|
|
|
|
|
|
|
const findObj = () => { |
|
|
|
|
if (areas.areaType === 'LINE') { |
|
|
|
|
return pastPolyline; |
|
|
|
|
} else if (areas.areaType === 'POLYGON') { |
|
|
|
|
return pastPolygon; |
|
|
|
|
} else if (areas.areaType === 'CIRCLE') { |
|
|
|
|
return pastCircle; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
if (areas.areaType) { |
|
|
|
|
if (areas.areaType === 'CIRCLE') { |
|
|
|
|
const radius = areas.bufferZone; |
|
|
|
|
const circleCoords = handlerGetCircleCoord(paths[0], radius); |
|
|
|
|
|
|
|
|
|
console.log(pastPolyline, '>>>>poly'); |
|
|
|
|
console.log(pastPolygon, '>>>polygon'); |
|
|
|
|
|
|
|
|
|
const obj = findObj(); |
|
|
|
|
const id = obj?.properties?.id; |
|
|
|
|
|
|
|
|
|
if (id === 'polyline' || id === 'polygon') { |
|
|
|
|
geojson.features.push(obj); |
|
|
|
|
|
|
|
|
|
//서버에 좌표 전달 편하게 하기 위해서 vertex에 좌표를 저장해주지만
|
|
|
|
|
//geojson에 넣어줄 데이터는 point임(index 때문에)
|
|
|
|
|
const length = paths.length; |
|
|
|
|
for (let i = 0; i < length; i++) { |
|
|
|
|
const wayPoint = { |
|
|
|
|
type: 'Feature', |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: paths[i] |
|
|
|
|
}, |
|
|
|
|
properties: { id: 'point', index: i } |
|
|
|
|
}; |
|
|
|
|
point.push(wayPoint); |
|
|
|
|
vertex.geometry.coordinates.push(paths[i]); |
|
|
|
|
|
|
|
|
|
// geojson.features.push(point);
|
|
|
|
|
} |
|
|
|
|
// handlerReplaceDuplicate('Point', point);
|
|
|
|
|
handlerReplaceDuplicate('point', ''); |
|
|
|
|
point.forEach(p => geojson.features.push(p)); |
|
|
|
|
} else if (id === 'circle') { |
|
|
|
|
const radius = props.areaCoordList[0].bufferZone; |
|
|
|
|
const circleCoords = handlerGetCircleCoord(paths[0], radius); |
|
|
|
|
|
|
|
|
|
const content = handlerGetReplaceContent(radius); |
|
|
|
|
if (pastMarker.length > 0) { |
|
|
|
|
pastMarker[0].setHTML(content); |
|
|
|
|
circle.properties.center = paths[0]; |
|
|
|
|
circle.geometry.coordinates = circleCoords; |
|
|
|
|
// setCircle(circle);
|
|
|
|
|
|
|
|
|
|
geojson.features.push(circle); |
|
|
|
|
} else { |
|
|
|
|
if (areas.areaType === 'LINE') { |
|
|
|
|
lineString.geometry.coordinates = paths; |
|
|
|
|
// setPolyline(lineString);
|
|
|
|
|
geojson.features.push(lineString); |
|
|
|
|
|
|
|
|
|
// 버퍼 생성
|
|
|
|
|
if (areas.bufferCoordList) { |
|
|
|
|
const bufferPaths = []; |
|
|
|
|
|
|
|
|
|
areas.bufferCoordList.forEach(bfCoord => |
|
|
|
|
bufferPaths.push([bfCoord.lon, bfCoord.lat]) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
bufferPolyline.geometry.coordinates = bufferPaths; |
|
|
|
|
// setBuffer(bufferPolyline);
|
|
|
|
|
|
|
|
|
|
handlerReplaceDuplicate('buffer', bufferPolyline); |
|
|
|
|
} |
|
|
|
|
} else if (areas.areaType === 'POLYGON') { |
|
|
|
|
polygon.geometry.coordinates = [paths]; |
|
|
|
|
// setPolygon(polygon);
|
|
|
|
|
geojson.features.push(polygon); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 포인트 생성
|
|
|
|
|
paths.forEach((p, i) => handlerCreatePoint(p, i)); |
|
|
|
|
handlerReplaceDuplicate('point', ''); |
|
|
|
|
point.forEach(p => geojson.features.push(p)); |
|
|
|
|
|
|
|
|
|
if (!mouseDownEve) { |
|
|
|
|
mapObject.on('mousedown', 'waypoint', onMouseDown); |
|
|
|
|
setMouseDownEve(true); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
circle.properties.center = paths[0]; |
|
|
|
|
circle.geometry.coordinates = circleCoords; |
|
|
|
|
// 기존 마커 제거 후 재 생성
|
|
|
|
|
handlerRemoveMarker(); |
|
|
|
|
handlerCreateAllMarker(paths); |
|
|
|
|
|
|
|
|
|
geojson.features.push(circle); |
|
|
|
|
mapObject.setPaintProperty('waypoint', 'circle-radius', 8); |
|
|
|
|
mapObject.getSource('geojson').setData(geojson); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//버퍼 생성
|
|
|
|
|
if (id === 'polyline') { |
|
|
|
|
if (areas.bufferCoordList) { |
|
|
|
|
const bufferPaths = []; |
|
|
|
|
// 새로운 popup 한 개 추가 (coord의 뒤에서 두개의 좌표 이용)
|
|
|
|
|
const addMileStone = (coord, radius) => { |
|
|
|
|
const len = coord.length; |
|
|
|
|
let lngLat = coord; |
|
|
|
|
let anchor; |
|
|
|
|
let distance; |
|
|
|
|
|
|
|
|
|
areas.bufferCoordList.forEach(bfCoord => { |
|
|
|
|
const path = [bfCoord.lon, bfCoord.lat]; |
|
|
|
|
bufferPaths.push(path); |
|
|
|
|
}); |
|
|
|
|
if (coord[0].length) { |
|
|
|
|
if ( |
|
|
|
|
mapControl.drawType !== '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 ( |
|
|
|
|
mapControl.drawType === 'CIRCLE' || |
|
|
|
|
props.areaCoordList[0].areaType === 'CIRCLE' |
|
|
|
|
) { |
|
|
|
|
anchor = [20, 35]; |
|
|
|
|
distance = radius; |
|
|
|
|
} else { |
|
|
|
|
anchor = [0, -10]; |
|
|
|
|
distance = 'Start'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pastBuffer) { |
|
|
|
|
handlerReplaceDuplicate('buffer', ''); |
|
|
|
|
} |
|
|
|
|
const content = handlerGetReplaceContent(distance); |
|
|
|
|
const popup = new props.mapboxgl.Popup({ |
|
|
|
|
offset: anchor, |
|
|
|
|
closeButton: false, |
|
|
|
|
closeOnClick: false |
|
|
|
|
}) |
|
|
|
|
.setLngLat(lngLat) |
|
|
|
|
.setHTML(content) |
|
|
|
|
.addTo(mapObject); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
bufferPolyline.geometry.coordinates = bufferPaths; |
|
|
|
|
setBuffer(bufferPolyline); |
|
|
|
|
// 좌표 기반으로 모든 마커 재 생성
|
|
|
|
|
const handlerCreateAllMarker = coord => { |
|
|
|
|
console.log('allCreateMarker'); |
|
|
|
|
const areas = props.areaCoordList[0]; |
|
|
|
|
|
|
|
|
|
geojson.features.push(bufferPolyline); |
|
|
|
|
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 (!isRegistEvent) {
|
|
|
|
|
mapObject.on('mousedown', 'waypoint', onMouseDown); |
|
|
|
|
setIsRegistEvent(false); |
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (id) { |
|
|
|
|
mapObject.setPaintProperty('waypoint', 'circle-radius', 8); |
|
|
|
|
mapObject.getSource('geojson').setData(geojson); |
|
|
|
|
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()); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 두 좌표 간의 중간 지점 좌표 반환
|
|
|
|
|
const handlerGetMidPoint = (dis1, dis2) => { |
|
|
|
|
return [(dis1[0] + dis2[0]) / 2, (dis1[1] + dis2[1]) / 2]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// html Content 반환
|
|
|
|
|
const handlerGetReplaceContent = distance => { |
|
|
|
|
const text = |
|
|
|
|
typeof distance === 'number' ? fromMetersToText(distance) : distance; |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
'<div style="display:inline-block;padding:5px;text-align:center;background-color:#fff;border:1px solid #000;font-size:13px;color:#ff0000;"><span>' + |
|
|
|
|
text + |
|
|
|
|
'</span></div>' |
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 미터 반환(m붙여서)
|
|
|
|
|
const fromMetersToText = meters => { |
|
|
|
|
meters = meters || 0; |
|
|
|
|
const text = parseFloat(meters.toFixed(1)) + 'm'; |
|
|
|
|
return text; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//중복되는 obj 제거 or 제거 후 새로 생성
|
|
|
|
|
const handlerReplaceDuplicate = (id, obj) => { |
|
|
|
|
geojson.features = geojson.features.filter( |
|
|
|
@ -603,15 +651,15 @@ export const MapBoxDraw = props => {
|
|
|
|
|
//도형 완성된 좌표 생성 or 변경 될 때 동작
|
|
|
|
|
const handlerSaveAreaInfo = (coord, obj) => { |
|
|
|
|
if (obj.properties?.id === 'polyline') { |
|
|
|
|
setPolyline(obj); |
|
|
|
|
// setPolyline(obj);
|
|
|
|
|
} else if (obj.properties?.id === 'polygon') { |
|
|
|
|
setPolygon(obj); |
|
|
|
|
// setPolygon(obj);
|
|
|
|
|
} else if (obj.properties?.id === 'circle') { |
|
|
|
|
setCircle(obj); |
|
|
|
|
// setCircle(obj);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (obj.properties?.id !== 'circle') { |
|
|
|
|
setPoint(point); |
|
|
|
|
// setPoint(point);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
handlerAreaInfo(coord); |
|
|
|
@ -625,53 +673,6 @@ export const MapBoxDraw = props => {
|
|
|
|
|
.map(geo => geo.geometry.coordinates); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 두 좌표 간의 중간 지점 좌표 반환
|
|
|
|
|
const handlerGetMidPoint = (dis1, dis2) => { |
|
|
|
|
return [(dis1[0] + dis2[0]) / 2, (dis1[1] + dis2[1]) / 2]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* number면 m붙여서, string이면 그대로 html에 포함시켜서 반환 |
|
|
|
|
* @param {number | string} distance |
|
|
|
|
*/ |
|
|
|
|
const handlerGetReplaceContent = distance => { |
|
|
|
|
const text = () => { |
|
|
|
|
if (typeof distance === 'number') { |
|
|
|
|
return fromMetersToText(distance); |
|
|
|
|
} else { |
|
|
|
|
return distance; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
const content = |
|
|
|
|
'<div style="display:inline-block;padding:5px;text-align:center;background-color:#fff;border:1px solid #000;font-size:13px;color:#ff0000;"><span>' + |
|
|
|
|
text() + |
|
|
|
|
'</span></div>'; |
|
|
|
|
return content; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 모든 popup 좌표 및 위치 수정
|
|
|
|
|
const handlerSaveMarkerInfo = obj => { |
|
|
|
|
const id = obj.properties?.id; |
|
|
|
|
const coord = |
|
|
|
|
id === 'polyline' |
|
|
|
|
? obj.geometry.coordinates |
|
|
|
|
: // : obj.geometry.coordinates[0];
|
|
|
|
|
handlerGetPolygonCoord(obj); |
|
|
|
|
|
|
|
|
|
const markers = pastMarker.map((marker, idx) => { |
|
|
|
|
if (idx > 0) { |
|
|
|
|
marker.setLngLat(handlerGetMidPoint(coord[idx], coord[idx - 1])); |
|
|
|
|
|
|
|
|
|
const distance = CalculateDistance(coord[idx], coord[idx - 1]); |
|
|
|
|
marker.setHTML(handlerGetReplaceContent(distance)); |
|
|
|
|
} else { |
|
|
|
|
marker.setLngLat([coord[0][0], coord[0][1]]); |
|
|
|
|
} |
|
|
|
|
return marker; |
|
|
|
|
}); |
|
|
|
|
setMarker(markers); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// drawType에 따른 obj 반환
|
|
|
|
|
const handlerMatchObj = drawType => { |
|
|
|
|
if (drawType === 'LINE') { |
|
|
|
@ -683,12 +684,6 @@ export const MapBoxDraw = props => {
|
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// polygon 좌표 배열에 첫 좌표 붙여서 반환
|
|
|
|
|
const handlerGetPolygonCoord = obj => { |
|
|
|
|
const coord = obj.geometry.coordinates[0]; |
|
|
|
|
return [...coord, coord[0]]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// circle 360도 좌표 반환
|
|
|
|
|
const handlerGetCircleCoord = (center, distance) => { |
|
|
|
|
const options = { |
|
|
|
@ -698,61 +693,19 @@ export const MapBoxDraw = props => {
|
|
|
|
|
return turf.circle(center, distance / 1000, options).geometry.coordinates; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 새로운 popup추가 or circle일 때 popup정보 수정
|
|
|
|
|
const addMileStone = (coord, radius) => { |
|
|
|
|
const len = coord.length; |
|
|
|
|
let lngLat = coord; |
|
|
|
|
let anchor; |
|
|
|
|
let distance; |
|
|
|
|
|
|
|
|
|
if (coord[0].length) { |
|
|
|
|
if (mapControl.drawType !== 'CIRCLE') { |
|
|
|
|
lngLat = handlerGetMidPoint(coord[len - 2], coord[len - 1]); |
|
|
|
|
anchor = [0, 0]; |
|
|
|
|
distance = CalculateDistance(coord[len - 2], coord[len - 1]); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (mapControl.drawType === 'CIRCLE') { |
|
|
|
|
anchor = [20, 35]; |
|
|
|
|
distance = radius; |
|
|
|
|
} else { |
|
|
|
|
anchor = [0, -10]; |
|
|
|
|
distance = 'Start'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const content = handlerGetReplaceContent(distance); |
|
|
|
|
const popup = new props.mapboxgl.Popup({ |
|
|
|
|
offset: anchor, |
|
|
|
|
closeButton: false, |
|
|
|
|
closeOnClick: false |
|
|
|
|
}) |
|
|
|
|
.setLngLat(lngLat) |
|
|
|
|
.setHTML(content); |
|
|
|
|
|
|
|
|
|
// popup 중복 제어
|
|
|
|
|
if (distanceMarker.length > 0) { |
|
|
|
|
if (mapControl.drawType === 'CIRCLE') { |
|
|
|
|
distanceMarker[0].setLngLat(lngLat); |
|
|
|
|
distanceMarker[0].setHTML(content); |
|
|
|
|
} else { |
|
|
|
|
if (coord.length > distanceMarker.length) { |
|
|
|
|
popup.addTo(mapObject); |
|
|
|
|
distanceMarker.push(popup); |
|
|
|
|
setMarker(prev => [...prev, popup]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
popup.addTo(mapObject); |
|
|
|
|
distanceMarker.push(popup); |
|
|
|
|
setMarker(prev => [...prev, popup]); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
// 포인트 생성
|
|
|
|
|
const handlerCreatePoint = (coord, index) => { |
|
|
|
|
const wayPoint = { |
|
|
|
|
type: 'Feature', |
|
|
|
|
geometry: { |
|
|
|
|
type: 'Point', |
|
|
|
|
coordinates: coord |
|
|
|
|
}, |
|
|
|
|
properties: { id: 'point', index: index } |
|
|
|
|
}; |
|
|
|
|
point.push(wayPoint); |
|
|
|
|
|
|
|
|
|
const fromMetersToText = meters => { |
|
|
|
|
meters = meters || 0; |
|
|
|
|
const text = parseFloat(meters.toFixed(1)) + 'm'; |
|
|
|
|
return text; |
|
|
|
|
return wayPoint; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
return <InfoModal modal={alertModal} setModal={setAlertModal} />; |
|
|
|
|