I'm trying to use fiBounds with the WebMercatorViewport object but getting an error about the padding property.
my code:
const initialViewState: IViewport | WebMercatorViewport = useMemo(() => {
if (locationsFitBounds) {
const minLat: number = Math.min(...locationsFitBounds.map((l: MapLocation) => l.latitude))
const maxLat: number = Math.max(...locationsFitBounds.map((l: MapLocation) => l.latitude))
const minLng: number = Math.min(...locationsFitBounds.map((l: MapLocation) => l.longitude))
const maxLng: number = Math.max(...locationsFitBounds.map((l: MapLocation) => l.longitude))
const southWest: [number, number] = [minLng, minLat]
const northEast: [number, number] = [maxLng, maxLat]
return new WebMercatorViewport({ width: 1920, height: 400 }).fitBounds([southWest, northEast], {padding: 200})
} else {
return viewport
}
}, [locationsFitBounds, viewport])
<React.Fragment>
<DeckGL
width="100%"
height="100%"
controller={true}
initialViewState={initialViewState}
>
<Map
attributionControl={false}
style={{ width: "100%", height: "100%" }}
/>
</DeckGL>
</React.Fragment>
The inital render is working well but when the state is changing (closing the map, updating states) I'm getting the error:
Uncaught TypeError: Cannot assign to read only property 'padding' of object '#<WebMercatorViewport>'
at positionChildrenUnderViews (position-children-under-views.ts:60:1)
at deckgl.ts:254:1
at renderWithHooks (react-dom.development.js:16175:1)
at updateForwardRef (react-dom.development.js:20023:1)
at beginWork (react-dom.development.js:22465:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4161:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4210:1)
at invokeGuardedCallback (react-dom.development.js:4274:1)
at beginWork$1 (react-dom.development.js:27405:1)
at performUnitOfWork (react-dom.development.js:26513:1)
I'm using: deck.gl: "8.8.20" react-map-gl": "7.0.20"
Got a solution from git discussion The useMemo should return a simple viewport and not a WebMercatorViewport object:
const initialViewState: IViewport = useMemo(() => {
if (fitLocations) {
const minLat: number = Math.min(...fitLocations.map((l: MapLocation) => l.latitude))
const maxLat: number = Math.max(...fitLocations.map((l: MapLocation) => l.latitude))
const minLng: number = Math.min(...fitLocations.map((l: MapLocation) => l.longitude))
const maxLng: number = Math.max(...fitLocations.map((l: MapLocation) => l.longitude))
const southWest: [number, number] = [minLng, minLat]
const northEast: [number, number] = [maxLng, maxLat]
const { latitude, longitude, zoom } = new WebMercatorViewport({ width: 800, height: 600 }).fitBounds(
[southWest, northEast],
{ padding: 100 }
)
return { ...viewport, latitude, longitude, zoom }
} else {
return viewport
}
}, [fitLocations, viewport])