使用填充 deck.gl mapbox 来适配边界
2022-12-19
845
我尝试将 fiBounds 与 WebMercatorViewport 对象一起使用,但收到有关 padding 属性的错误。
我的代码:
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>
初始渲染运行良好,但当状态发生变化(关闭地图、更新状态)时,我收到错误:
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)
我正在使用: deck.gl:“8.8.20” react-map-gl:“7.0.20”
2个回答
Mapbox 将边界作为初始状态的一部分。
请参阅 Mapbox API options.bounds
The initial bounds of the map. If bounds is specified, it overrides center and zoom constructor options.
我没有使用
deck.gl
,但这是使用
react-map-gl
所做的。
<Map
initialViewState={{
bounds: getBoundingBox(fitLocations),
fitBoundsOptions: { padding: 60 },
}}
>
...
</Map>
为了生成边界框,我们可以使用 代码 提供的相同代码 。 href="https://stackoverflow.com/users/9596473/ar26">Ar26 。
const getBoundingBox = (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]
return [southWest, northEast]
}
Mark Nunes
2023-06-23
从 git 讨论 获得解决方案 useMemo 应返回一个简单的视口,而不是 WebMercatorViewport 对象:
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])
Ar26
2022-12-25