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