From 316222b9de39f4e2dcc85b96d0e960d2c125a145 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 23 Sep 2025 16:25:12 -0600 Subject: [PATCH 1/2] Switch to using MapboxOverlay --- package-lock.json | 14 ++++++ package.json | 1 + src/index.tsx | 112 ++++++++++++++++++++++++++++------------------ 3 files changed, 83 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index d86d2007..5b1b8376 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "@deck.gl/core": "^9.1.14", "@deck.gl/extensions": "^9.1.14", "@deck.gl/layers": "^9.1.14", + "@deck.gl/mapbox": "^9.1.14", "@deck.gl/react": "^9.1.14", "@geoarrow/deck.gl-layers": "^0.3.1", "@nextui-org/react": "^2.4.8", @@ -1398,6 +1399,19 @@ "@math.gl/core": "4.1.0" } }, + "node_modules/@deck.gl/mapbox": { + "version": "9.1.14", + "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-9.1.14.tgz", + "integrity": "sha512-l3c5NFwKjIOeVWMtqK5LR8MA4grRe7tpLctkovNIo+owPBoW+q7gAWBJ1hGFmE1sxVFhoqZx70FqBAT9Mqn1ow==", + "dependencies": { + "@luma.gl/constants": "~9.1.9", + "@math.gl/web-mercator": "^4.1.0" + }, + "peerDependencies": { + "@deck.gl/core": "^9.1.0", + "@luma.gl/core": "~9.1.9" + } + }, "node_modules/@deck.gl/mesh-layers": { "version": "9.1.14", "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-9.1.14.tgz", diff --git a/package.json b/package.json index 82f5c2cf..5b81614c 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@deck.gl/extensions": "^9.1.14", "@deck.gl/layers": "^9.1.14", "@deck.gl/react": "^9.1.14", + "@deck.gl/mapbox": "^9.1.14", "@geoarrow/deck.gl-layers": "^0.3.1", "@babel/runtime": "^7.28.4", "@nextui-org/react": "^2.4.8", diff --git a/src/index.tsx b/src/index.tsx index 901f6ef6..aa86598d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,8 +2,7 @@ import * as React from "react"; import { useEffect, useCallback, useState } from "react"; import { createRender, useModelState, useModel } from "@anywidget/react"; import type { Initialize, Render } from "@anywidget/types"; -import Map from "react-map-gl/maplibre"; -import DeckGL from "@deck.gl/react"; +import Map, { useControl } from "react-map-gl/maplibre"; import { MapViewState, PickingInfo, type Layer } from "@deck.gl/core"; import { BaseLayerModel, initializeLayer } from "./model/index.js"; import type { WidgetModel } from "@jupyter-widgets/base"; @@ -13,6 +12,10 @@ import { v4 as uuidv4 } from "uuid"; import { Message } from "./types.js"; import { flyTo } from "./actions/fly-to.js"; import { useViewStateDebounced } from "./state"; +import { + MapboxOverlay as DeckOverlay, + MapboxOverlayProps, +} from "@deck.gl/mapbox"; import { MachineContext, MachineProvider } from "./xstate"; import * as selectors from "./xstate/selectors"; @@ -38,6 +41,13 @@ const DEFAULT_INITIAL_VIEW_STATE = { const DEFAULT_MAP_STYLE = "https://basemaps.cartocdn.com/gl/positron-nolabels-gl-style/style.json"; +function DeckGLOverlay(props: MapboxOverlayProps) { + const overlay = useControl(() => new DeckOverlay(props)); + + overlay.setProps(props); + return null; +} + async function getChildModelState( childModels: WidgetModel[], childLayerIds: string[], @@ -230,8 +240,10 @@ function App() { /> )}
- Object.keys(initialViewState).includes(key), @@ -239,48 +251,60 @@ function App() { ? initialViewState : DEFAULT_INITIAL_VIEW_STATE } - controller={true} - layers={ - bboxSelectPolygonLayer - ? layers.concat(bboxSelectPolygonLayer) - : layers - } - getTooltip={(showTooltip && getTooltip) || undefined} - getCursor={() => (isDrawingBBoxSelection ? "crosshair" : "grab")} - pickingRadius={pickingRadius} - onClick={onMapClickHandler} - onHover={onMapHoverHandler} - useDevicePixels={ - isDefined(useDevicePixels) ? useDevicePixels : true - } - // https://deck.gl/docs/api-reference/core/deck#_typedarraymanagerprops - _typedArrayManagerProps={{ - overAlloc: 1, - poolSize: 0, + // boxZoom={false} + // dragRotate={false} + // maxPitch={0} + mapStyle={mapStyle || DEFAULT_MAP_STYLE} + attributionControl={{ customAttribution }} + onContextMenu={(e) => { + console.log("hi"); + + e.originalEvent.stopPropagation(); + // e.stopPropagation(); + e.preventDefault(); }} - onViewStateChange={(event) => { - const { viewState } = event; - - // This condition is necessary to confirm that the viewState is - // of type MapViewState. - if ("latitude" in viewState) { - const { longitude, latitude, zoom, pitch, bearing } = viewState; - setViewState({ - longitude, - latitude, - zoom, - pitch, - bearing, - }); - } - }} - parameters={parameters || {}} > - - + (isDrawingBBoxSelection ? "crosshair" : "grab")} + pickingRadius={pickingRadius} + onClick={onMapClickHandler} + onHover={onMapHoverHandler} + useDevicePixels={ + isDefined(useDevicePixels) ? useDevicePixels : true + } + // https://deck.gl/docs/api-reference/core/deck#_typedarraymanagerprops + _typedArrayManagerProps={{ + overAlloc: 1, + poolSize: 0, + }} + onViewStateChange={(event) => { + const { viewState } = event; + + // This condition is necessary to confirm that the viewState is + // of type MapViewState. + if ("latitude" in viewState) { + const { longitude, latitude, zoom, pitch, bearing } = + viewState; + setViewState({ + longitude, + latitude, + zoom, + pitch, + bearing, + }); + } + }} + parameters={parameters || {}} + /> +
From 6284374fd231cf63f19ee375cc425986e9b953f1 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Tue, 23 Sep 2025 18:04:30 -0600 Subject: [PATCH 2/2] Add controls --- src/index.tsx | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 97ea53be..37dad647 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,7 +2,12 @@ import * as React from "react"; import { useEffect, useCallback, useState } from "react"; import { createRender, useModelState, useModel } from "@anywidget/react"; import type { Initialize, Render } from "@anywidget/types"; -import Map, { useControl } from "react-map-gl/maplibre"; +import Map, { + useControl, + FullscreenControl, + NavigationControl, + ScaleControl, +} from "react-map-gl/maplibre"; import { MapViewState, PickingInfo, type Layer } from "@deck.gl/core"; import { BaseLayerModel, initializeLayer } from "./model/index.js"; import type { WidgetModel } from "@jupyter-widgets/base"; @@ -249,7 +254,6 @@ function App() {
@@ -258,19 +262,14 @@ function App() { ? initialViewState : DEFAULT_INITIAL_VIEW_STATE } - // boxZoom={false} - // dragRotate={false} - // maxPitch={0} mapStyle={mapStyle || DEFAULT_MAP_STYLE} - attributionControl={{ customAttribution }} - onContextMenu={(e) => { - console.log("hi"); - - e.originalEvent.stopPropagation(); - // e.stopPropagation(); - e.preventDefault(); + attributionControl={{ + customAttribution, }} > + + +