I have a map setup in my react app, which users will use to draw and save areas. The users will make the polygon initially by clicking points on the map, and then fine tune and position it using the built-in editable
and draggable
props. I can set the points path fine by clicking on the map, but changes made by dragging and editing the polygon do not reflect in the set path. This leads to changes made in this way being undone as soon as another node is added via clicking. Is there a way I can keep track of these changes?
Here's the code I have for the map
const MapContainer = (props) => {
// This is where the path is stored. Ideally, changes made by editable and onDrag would be reflected here
const [path, setPath] = useState([])
const [mapWidth, mapHeight] = useScreen()
const [polyObj, setPolyObj] = useState()
const handleMapClick = (e) => {
let coords = {
lat: e.latLng.lat(),
lng: e.latLng.lng()
}
// Add the coordinates of the click to the path
setPath([...path, coords])
}
return (
<>
<LoadScript googleMapsApiKey="API-KEY" >
<GoogleMap
zoom={14}
mapContainerStyle={{width: mapWidth, height: mapHeight}}
// Fake coords used here
center={{
lat: 0.0000,
lng: 0.0000
}}
onClick={handleMapClick}
>
<Polygon
editable
draggable
path={path}
onDragEnd={(e) => console.log(path)}
onLoad={(obj) => setPolyObj(obj)}
/>
</GoogleMap>
</LoadScript>
</>
)
}
Edit: I have found a solution to half of my problem. For keeping track of drag changes, I can use the onDragStart
and onDragEnd
events, take the difference between the coordinates returned from them, and subtract that difference from each node in path
, like so:
const [startCoords, setStartCoords] = useState({
lat: 0,
lng: 0
})
const dragStart = (e) => {
setStartCoords({
lat: e.latLng.lat(),
lng: e.latLng.lng()
})
}
const dragEnd = (e) => {
let coords = {
lat: e.latLng.lat(),
lng: e.latLng.lng()
}
let newPath = [...path]
for (let node in newPath) {
// For every node in path, add the diff between start coord and the new one
newPath[node].lat -= startCoords.lat - coords.lat
newPath[node].lng -= startCoords.lng - coords.lng
}
setPath(newPath)
}
...
<Polygon
editable
draggable
path={path}
onDragStart={(e) => {
setStartCoords({
lat: e.latLng.lat(),
lng: e.latLng.lng()
})
}}
onDragEnd={dragEnd}
onLoad={(obj) => setPolyObj(obj)}
/>
That's only half of the problem though, and it still leaves the changes from editable
unaccounted for.