@deck.gl/google-maps 9.2.8 → 9.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +74 -35
- package/dist/google-maps-overlay.d.ts +12 -4
- package/dist/google-maps-overlay.d.ts.map +1 -1
- package/dist/google-maps-overlay.js +78 -32
- package/dist/google-maps-overlay.js.map +1 -1
- package/dist/index.cjs +76 -37
- package/dist/index.cjs.map +2 -2
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +12 -7
- package/dist/utils.js.map +1 -1
- package/dist.min.js +2 -2
- package/package.json +2 -2
- package/src/google-maps-overlay.ts +86 -39
- package/src/utils.ts +13 -6
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Use deck.gl as a custom Google Maps overlay",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "9.2.
|
|
6
|
+
"version": "9.2.10",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"@luma.gl/core": "~9.2.6",
|
|
50
50
|
"@luma.gl/webgl": "~9.2.6"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "7527990f1bac132b5ce65026a448c6c86a9268cb"
|
|
53
53
|
}
|
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
createDeckInstance,
|
|
10
10
|
destroyDeckInstance,
|
|
11
11
|
getViewPropsFromOverlay,
|
|
12
|
-
getViewPropsFromCoordinateTransformer
|
|
12
|
+
getViewPropsFromCoordinateTransformer,
|
|
13
|
+
POSITIONING_CONTAINER_ID
|
|
13
14
|
} from './utils';
|
|
14
15
|
import {Deck} from '@deck.gl/core';
|
|
15
16
|
|
|
16
17
|
import type {DeckProps, MapViewState} from '@deck.gl/core';
|
|
17
18
|
import type {Device} from '@luma.gl/core';
|
|
18
|
-
|
|
19
19
|
const HIDE_ALL_LAYERS = () => false;
|
|
20
20
|
const GL_STATE: GLParameters = {
|
|
21
21
|
depthMask: true,
|
|
@@ -53,6 +53,7 @@ export default class GoogleMapsOverlay {
|
|
|
53
53
|
private _map: google.maps.Map | null = null;
|
|
54
54
|
private _deck: Deck | null = null;
|
|
55
55
|
private _overlay: google.maps.WebGLOverlayView | google.maps.OverlayView | null = null;
|
|
56
|
+
private _positioningOverlay: google.maps.OverlayView | null = null;
|
|
56
57
|
|
|
57
58
|
constructor(props: GoogleMapsOverlayProps) {
|
|
58
59
|
this.setProps({...defaultProps, ...props});
|
|
@@ -72,6 +73,7 @@ export default class GoogleMapsOverlay {
|
|
|
72
73
|
(this._overlay as google.maps.WebGLOverlayView).requestRedraw();
|
|
73
74
|
}
|
|
74
75
|
this._overlay?.setMap(null);
|
|
76
|
+
this._positioningOverlay?.setMap(null);
|
|
75
77
|
this._map = null;
|
|
76
78
|
}
|
|
77
79
|
if (map) {
|
|
@@ -129,7 +131,6 @@ export default class GoogleMapsOverlay {
|
|
|
129
131
|
|
|
130
132
|
/* Private API */
|
|
131
133
|
_createOverlay(map: google.maps.Map) {
|
|
132
|
-
const {interleaved} = this.props;
|
|
133
134
|
const {VECTOR, UNINITIALIZED} = google.maps.RenderingType;
|
|
134
135
|
const renderingType = map.getRenderingType();
|
|
135
136
|
if (renderingType === UNINITIALIZED) {
|
|
@@ -137,26 +138,46 @@ export default class GoogleMapsOverlay {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
const isVectorMap = renderingType === VECTOR && google.maps.WebGLOverlayView;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (overlay instanceof google.maps.WebGLOverlayView) {
|
|
144
|
-
if (interleaved) {
|
|
145
|
-
overlay.onAdd = noop;
|
|
146
|
-
overlay.onContextRestored = this._onContextRestored.bind(this);
|
|
147
|
-
overlay.onDraw = this._onDrawVectorInterleaved.bind(this);
|
|
148
|
-
} else {
|
|
149
|
-
overlay.onAdd = this._onAdd.bind(this);
|
|
150
|
-
overlay.onContextRestored = noop;
|
|
151
|
-
overlay.onDraw = this._onDrawVectorOverlay.bind(this);
|
|
152
|
-
}
|
|
153
|
-
overlay.onContextLost = this._onContextLost.bind(this);
|
|
141
|
+
if (isVectorMap) {
|
|
142
|
+
this._createOverlayVector(map);
|
|
154
143
|
} else {
|
|
155
|
-
|
|
156
|
-
overlay.draw = this._onDrawRaster.bind(this);
|
|
144
|
+
this._createOverlayRaster(map);
|
|
157
145
|
}
|
|
158
|
-
|
|
146
|
+
}
|
|
159
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Create overlays for vector maps.
|
|
150
|
+
* Uses OverlayView for DOM positioning (correct z-index) and
|
|
151
|
+
* WebGLOverlayView for camera data (smooth animations).
|
|
152
|
+
* In interleaved mode, WebGLOverlayView also provides the shared GL context.
|
|
153
|
+
*/
|
|
154
|
+
_createOverlayVector(map: google.maps.Map) {
|
|
155
|
+
const interleaved = this.props.interleaved ?? defaultProps.interleaved;
|
|
156
|
+
// Create positioning overlay for proper DOM placement
|
|
157
|
+
const positioningOverlay = new google.maps.OverlayView();
|
|
158
|
+
positioningOverlay.onAdd = this._onAddVectorOverlay.bind(this);
|
|
159
|
+
positioningOverlay.draw = this._updateContainerSize.bind(this);
|
|
160
|
+
positioningOverlay.onRemove = this._onRemove.bind(this);
|
|
161
|
+
this._positioningOverlay = positioningOverlay;
|
|
162
|
+
this._positioningOverlay.setMap(map);
|
|
163
|
+
|
|
164
|
+
// Create WebGL overlay for camera data (and GL context if interleaved)
|
|
165
|
+
const overlay = new google.maps.WebGLOverlayView();
|
|
166
|
+
overlay.onAdd = noop;
|
|
167
|
+
overlay.onContextRestored = interleaved ? this._onContextRestored.bind(this) : noop;
|
|
168
|
+
overlay.onDraw = this._onDrawVector.bind(this);
|
|
169
|
+
overlay.onContextLost = interleaved ? this._onContextLost.bind(this) : noop;
|
|
170
|
+
overlay.onRemove = interleaved ? this._onRemove.bind(this) : noop;
|
|
171
|
+
this._overlay = overlay;
|
|
172
|
+
this._overlay.setMap(map);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
_createOverlayRaster(map: google.maps.Map) {
|
|
176
|
+
// Raster maps use standard OverlayView
|
|
177
|
+
const overlay = new google.maps.OverlayView();
|
|
178
|
+
overlay.onAdd = this._onAdd.bind(this);
|
|
179
|
+
overlay.draw = this._onDrawRaster.bind(this);
|
|
180
|
+
overlay.onRemove = this._onRemove.bind(this);
|
|
160
181
|
this._overlay = overlay;
|
|
161
182
|
this._overlay.setMap(map);
|
|
162
183
|
}
|
|
@@ -166,6 +187,45 @@ export default class GoogleMapsOverlay {
|
|
|
166
187
|
this._deck = createDeckInstance(this._map, this._overlay, this._deck, this.props);
|
|
167
188
|
}
|
|
168
189
|
|
|
190
|
+
_onAddVectorOverlay() {
|
|
191
|
+
// For non-interleaved vector maps, create a positioning container
|
|
192
|
+
// that Google Maps will place correctly in the DOM with proper z-index
|
|
193
|
+
const overlay = this._positioningOverlay as google.maps.OverlayView;
|
|
194
|
+
const panes = overlay.getPanes();
|
|
195
|
+
if (panes) {
|
|
196
|
+
const container = document.createElement('div');
|
|
197
|
+
container.id = POSITIONING_CONTAINER_ID;
|
|
198
|
+
container.style.position = 'absolute';
|
|
199
|
+
panes.overlayLayer.appendChild(container);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// @ts-ignore (TS2345) map is defined at this stage
|
|
203
|
+
// Pass the positioning overlay for deck canvas creation (not WebGL overlay)
|
|
204
|
+
this._deck = createDeckInstance(this._map, overlay, this._deck, this.props);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
_updateContainerSize() {
|
|
208
|
+
// Update positioning container size and position to match map
|
|
209
|
+
if (!this._map) return;
|
|
210
|
+
|
|
211
|
+
const container = this._map
|
|
212
|
+
.getDiv()
|
|
213
|
+
.querySelector(`#${POSITIONING_CONTAINER_ID}`) as HTMLElement;
|
|
214
|
+
if (!container) return;
|
|
215
|
+
|
|
216
|
+
const mapContainer = this._map.getDiv().firstChild as HTMLElement;
|
|
217
|
+
if (!mapContainer) return;
|
|
218
|
+
|
|
219
|
+
const width = mapContainer.offsetWidth;
|
|
220
|
+
const height = mapContainer.offsetHeight;
|
|
221
|
+
|
|
222
|
+
container.style.width = `${width}px`;
|
|
223
|
+
container.style.height = `${height}px`;
|
|
224
|
+
// Position at top-left (overlayLayer uses centered coords, so offset by half)
|
|
225
|
+
container.style.left = `${-width / 2}px`;
|
|
226
|
+
container.style.top = `${-height / 2}px`;
|
|
227
|
+
}
|
|
228
|
+
|
|
169
229
|
_onContextRestored({gl}) {
|
|
170
230
|
if (!this._map || !this._overlay) {
|
|
171
231
|
return;
|
|
@@ -240,23 +300,21 @@ export default class GoogleMapsOverlay {
|
|
|
240
300
|
deck.redraw();
|
|
241
301
|
}
|
|
242
302
|
|
|
243
|
-
|
|
244
|
-
_onDrawVectorInterleaved({gl, transformer}) {
|
|
303
|
+
_onDrawVector({gl, transformer}) {
|
|
245
304
|
if (!this._deck || !this._map) {
|
|
246
305
|
return;
|
|
247
306
|
}
|
|
248
307
|
|
|
249
308
|
const deck = this._deck;
|
|
309
|
+
const {interleaved} = this.props;
|
|
250
310
|
|
|
251
311
|
deck.setProps({
|
|
252
312
|
...getViewPropsFromCoordinateTransformer(this._map, transformer),
|
|
253
|
-
|
|
254
313
|
// Using external gl context - do not set css size
|
|
255
|
-
width: null,
|
|
256
|
-
height: null
|
|
314
|
+
...(interleaved && {width: null, height: null})
|
|
257
315
|
});
|
|
258
316
|
|
|
259
|
-
if (deck.isInitialized) {
|
|
317
|
+
if (interleaved && deck.isInitialized) {
|
|
260
318
|
// @ts-expect-error
|
|
261
319
|
const device: Device = deck.device;
|
|
262
320
|
|
|
@@ -287,19 +345,8 @@ export default class GoogleMapsOverlay {
|
|
|
287
345
|
});
|
|
288
346
|
});
|
|
289
347
|
}
|
|
348
|
+
} else if (!interleaved) {
|
|
349
|
+
deck.redraw();
|
|
290
350
|
}
|
|
291
351
|
}
|
|
292
|
-
|
|
293
|
-
_onDrawVectorOverlay({transformer}) {
|
|
294
|
-
if (!this._deck || !this._map) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const deck = this._deck;
|
|
299
|
-
|
|
300
|
-
deck.setProps({
|
|
301
|
-
...getViewPropsFromCoordinateTransformer(this._map, transformer)
|
|
302
|
-
});
|
|
303
|
-
deck.redraw();
|
|
304
|
-
}
|
|
305
352
|
}
|
package/src/utils.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import {Deck, MapView} from '@deck.gl/core';
|
|
7
7
|
import {Matrix4, Vector2} from '@math.gl/core';
|
|
8
8
|
import type {MjolnirGestureEvent, MjolnirPointerEvent} from 'mjolnir.js';
|
|
9
|
+
export const POSITIONING_CONTAINER_ID = 'deck-gl-google-maps-container';
|
|
9
10
|
|
|
10
11
|
// https://en.wikipedia.org/wiki/Web_Mercator_projection#Formulas
|
|
11
12
|
const MAX_LATITUDE = 85.05113;
|
|
@@ -45,7 +46,8 @@ export function createDeckInstance(
|
|
|
45
46
|
|
|
46
47
|
const newDeck = new Deck({
|
|
47
48
|
...props,
|
|
48
|
-
|
|
49
|
+
// Default to true for high-DPI displays, but allow user override
|
|
50
|
+
useDevicePixels: props.useDevicePixels ?? true,
|
|
49
51
|
style: props.interleaved ? null : {pointerEvents: 'none'},
|
|
50
52
|
parent: getContainer(overlay, props.style),
|
|
51
53
|
views: new MapView({repeat: true}),
|
|
@@ -80,12 +82,17 @@ function getContainer(
|
|
|
80
82
|
container.style.position = 'absolute';
|
|
81
83
|
Object.assign(container.style, style);
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if
|
|
85
|
+
const googleMapsContainer = (overlay.getMap() as google.maps.Map).getDiv();
|
|
86
|
+
|
|
87
|
+
// Check if there's a pre-created positioning container (for vector maps)
|
|
88
|
+
const positioningContainer = googleMapsContainer.querySelector(`#${POSITIONING_CONTAINER_ID}`);
|
|
89
|
+
|
|
90
|
+
if (positioningContainer) {
|
|
91
|
+
// Vector maps (both interleaved and non-interleaved): Use positioning container
|
|
92
|
+
positioningContainer.appendChild(container);
|
|
93
|
+
} else if ('getPanes' in overlay) {
|
|
94
|
+
// Raster maps: Append to overlayLayer pane
|
|
86
95
|
overlay.getPanes()?.overlayLayer.appendChild(container);
|
|
87
|
-
} else {
|
|
88
|
-
overlay.getMap()?.getDiv().appendChild(container);
|
|
89
96
|
}
|
|
90
97
|
return container;
|
|
91
98
|
}
|