junh_eee(이준희)
11 months ago
4 changed files with 365 additions and 34 deletions
@ -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} />; |
||||||
|
}; |
Loading…
Reference in new issue