@trackunit/react-map-adapter-google 0.0.152 → 0.0.154
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/index.cjs.js
CHANGED
|
@@ -5,6 +5,7 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
5
5
|
var reactGoogleMaps = require('@vis.gl/react-google-maps');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var geoJsonUtils = require('@trackunit/geo-json-utils');
|
|
8
|
+
var reactMapDraw = require('@trackunit/react-map-draw');
|
|
8
9
|
var markerclusterer = require('@googlemaps/markerclusterer');
|
|
9
10
|
var reactMapColorUtils = require('@trackunit/react-map-color-utils');
|
|
10
11
|
var esToolkit = require('es-toolkit');
|
|
@@ -55,6 +56,29 @@ const GoogleApiProvider = ({ apiKey, language, children }) => {
|
|
|
55
56
|
return (jsxRuntime.jsx(reactGoogleMaps.APIProvider, { apiKey: apiKey, language: language, libraries: libraries, version: GOOGLE_MAPS_API_VERSION, children: children }));
|
|
56
57
|
};
|
|
57
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Builds the Google Maps bridge for the shared drawing engine (ADR 0030).
|
|
61
|
+
*
|
|
62
|
+
* One loader per `google.maps.Map` instance: theme switches and traffic toggles
|
|
63
|
+
* recreate the map, and `GoogleMapsAdapterInstance.connect` hands the controller a
|
|
64
|
+
* fresh loader each time so the engine is rebuilt on the live map. Terra Draw and its
|
|
65
|
+
* Google adapter are only downloaded when the loader runs, which the controller
|
|
66
|
+
* defers until drawing is actually needed.
|
|
67
|
+
*/
|
|
68
|
+
const createGoogleDrawEngineLoader = (map) => async () => {
|
|
69
|
+
const { TerraDrawGoogleMapsAdapter } = await import('terra-draw-google-maps-adapter');
|
|
70
|
+
return reactMapDraw.loadTerraDrawEngine({
|
|
71
|
+
adapter: new TerraDrawGoogleMapsAdapter({
|
|
72
|
+
lib: google.maps,
|
|
73
|
+
map,
|
|
74
|
+
// Keep drawn features in their own Data layer so nothing else on the map
|
|
75
|
+
// (or a future layer port feature) shares styling or click handling with them.
|
|
76
|
+
isolatedData: true,
|
|
77
|
+
coordinatePrecision: reactMapDraw.DRAW_COORDINATE_PRECISION,
|
|
78
|
+
}),
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
58
82
|
let runtimePromise = null;
|
|
59
83
|
/**
|
|
60
84
|
* Lazily dynamic-imports {@link createDeckGlGoogleMapsOverlayRuntime} and caches the promise.
|
|
@@ -2900,6 +2924,7 @@ class GoogleMapsAdapterInstance {
|
|
|
2900
2924
|
initializationFailed: reactMapAdapterShared.INITIAL_MAP_STATE.initializationFailed,
|
|
2901
2925
|
appearance: reactMapAdapterShared.INITIAL_MAP_STATE.appearance,
|
|
2902
2926
|
tileSize: reactMapAdapterShared.INITIAL_MAP_STATE.tileSize,
|
|
2927
|
+
drawing: reactMapAdapterShared.INITIAL_MAP_STATE.drawing,
|
|
2903
2928
|
};
|
|
2904
2929
|
this.cameraListeners = new Set();
|
|
2905
2930
|
this.statusListeners = new Set();
|
|
@@ -2933,6 +2958,11 @@ class GoogleMapsAdapterInstance {
|
|
|
2933
2958
|
};
|
|
2934
2959
|
this.layers = new GoogleMapsLayerPort();
|
|
2935
2960
|
this.layers.setTheme(this.appearance.theme);
|
|
2961
|
+
// Engine load failures are not surfaced here (same as the deck.gl runtime): the
|
|
2962
|
+
// controller keeps mode and value and loads again on the next connect, setMode
|
|
2963
|
+
// or setValue that needs an engine.
|
|
2964
|
+
this.draw = new reactMapDraw.DrawController();
|
|
2965
|
+
this.draw.subscribe(() => this.syncDrawingStatus());
|
|
2936
2966
|
this.state = reactMapAdapterShared.computeInitialState(this.appearance, config.initialViewport);
|
|
2937
2967
|
this.cachedCameraState = {
|
|
2938
2968
|
center: this.state.center,
|
|
@@ -2945,6 +2975,7 @@ class GoogleMapsAdapterInstance {
|
|
|
2945
2975
|
initializationFailed: this.state.initializationFailed,
|
|
2946
2976
|
appearance: this.state.appearance,
|
|
2947
2977
|
tileSize: this.state.tileSize,
|
|
2978
|
+
drawing: this.state.drawing,
|
|
2948
2979
|
};
|
|
2949
2980
|
}
|
|
2950
2981
|
// ============================================================================
|
|
@@ -2981,11 +3012,13 @@ class GoogleMapsAdapterInstance {
|
|
|
2981
3012
|
// `state` to defaults while `this.appearance` keeps the real values, so a
|
|
2982
3013
|
// StrictMode destroy → revive would otherwise report stale defaults, and the
|
|
2983
3014
|
// appearance controls' sync-back would overwrite persisted preferences with them.
|
|
2984
|
-
this.state = { ...this.state, appearance: this.appearance };
|
|
3015
|
+
this.state = { ...this.state, appearance: this.appearance, drawing: this.draw.getMode() !== "idle" };
|
|
2985
3016
|
this.updateStatusCache();
|
|
2986
3017
|
this.layers.connect(map);
|
|
2987
|
-
// Theme changes recreate the google.maps.Map, so traffic must re-attach on every (re)connect
|
|
3018
|
+
// Theme changes recreate the google.maps.Map, so traffic and drawing must re-attach on every (re)connect.
|
|
3019
|
+
// The draw controller rebuilds its engine from the committed value on the new map (ADR 0030).
|
|
2988
3020
|
this.syncTrafficLayer();
|
|
3021
|
+
this.draw.connect(createGoogleDrawEngineLoader(map));
|
|
2989
3022
|
this.setupEventListeners();
|
|
2990
3023
|
this.layers.setPointerMoveReporter(position => {
|
|
2991
3024
|
this.reportPointerMove(position);
|
|
@@ -3216,6 +3249,7 @@ class GoogleMapsAdapterInstance {
|
|
|
3216
3249
|
this.removeGoogleEventListeners();
|
|
3217
3250
|
this.trafficLayer?.setMap(null);
|
|
3218
3251
|
this.trafficLayer = null;
|
|
3252
|
+
this.draw.disconnect();
|
|
3219
3253
|
this.layers.setPointerMoveReporter(null);
|
|
3220
3254
|
this.layers.destroy();
|
|
3221
3255
|
// Clear our listeners
|
|
@@ -3373,8 +3407,17 @@ class GoogleMapsAdapterInstance {
|
|
|
3373
3407
|
this.cachedCameraState = { center, zoom, bounds, isIdle };
|
|
3374
3408
|
}
|
|
3375
3409
|
updateStatusCache() {
|
|
3376
|
-
const { isReady, initializationFailed, appearance, tileSize } = this.state;
|
|
3377
|
-
this.cachedStatus = { isReady, initializationFailed, appearance, tileSize };
|
|
3410
|
+
const { isReady, initializationFailed, appearance, tileSize, drawing } = this.state;
|
|
3411
|
+
this.cachedStatus = { isReady, initializationFailed, appearance, tileSize, drawing };
|
|
3412
|
+
}
|
|
3413
|
+
/** Mirrors the draw controller's mode into `MapStatus.drawing` (ADR 0030). */
|
|
3414
|
+
syncDrawingStatus() {
|
|
3415
|
+
const drawing = this.draw.getMode() !== "idle";
|
|
3416
|
+
if (this.state.drawing === drawing)
|
|
3417
|
+
return;
|
|
3418
|
+
this.state = { ...this.state, drawing };
|
|
3419
|
+
this.updateStatusCache();
|
|
3420
|
+
this.notifyStatusListeners();
|
|
3378
3421
|
}
|
|
3379
3422
|
notifyCameraListeners() {
|
|
3380
3423
|
this.cameraListeners.forEach(listener => listener());
|
package/index.esm.js
CHANGED
|
@@ -4,6 +4,7 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
4
4
|
import { APIProvider, RenderingType, APIProviderContext, useMap, useApiLoadingStatus, APILoadingStatus, Map as Map$1 } from '@vis.gl/react-google-maps';
|
|
5
5
|
import { useMemo, useCallback, useSyncExternalStore, useId, useContext, useEffect } from 'react';
|
|
6
6
|
import { validateBbox, validatePosition } from '@trackunit/geo-json-utils';
|
|
7
|
+
import { loadTerraDrawEngine, DRAW_COORDINATE_PRECISION, DrawController } from '@trackunit/react-map-draw';
|
|
7
8
|
import { MarkerClusterer, SuperClusterAlgorithm } from '@googlemaps/markerclusterer';
|
|
8
9
|
import { colorWithOpacity } from '@trackunit/react-map-color-utils';
|
|
9
10
|
import { isEqual } from 'es-toolkit';
|
|
@@ -54,6 +55,29 @@ const GoogleApiProvider = ({ apiKey, language, children }) => {
|
|
|
54
55
|
return (jsx(APIProvider, { apiKey: apiKey, language: language, libraries: libraries, version: GOOGLE_MAPS_API_VERSION, children: children }));
|
|
55
56
|
};
|
|
56
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Builds the Google Maps bridge for the shared drawing engine (ADR 0030).
|
|
60
|
+
*
|
|
61
|
+
* One loader per `google.maps.Map` instance: theme switches and traffic toggles
|
|
62
|
+
* recreate the map, and `GoogleMapsAdapterInstance.connect` hands the controller a
|
|
63
|
+
* fresh loader each time so the engine is rebuilt on the live map. Terra Draw and its
|
|
64
|
+
* Google adapter are only downloaded when the loader runs, which the controller
|
|
65
|
+
* defers until drawing is actually needed.
|
|
66
|
+
*/
|
|
67
|
+
const createGoogleDrawEngineLoader = (map) => async () => {
|
|
68
|
+
const { TerraDrawGoogleMapsAdapter } = await import('terra-draw-google-maps-adapter');
|
|
69
|
+
return loadTerraDrawEngine({
|
|
70
|
+
adapter: new TerraDrawGoogleMapsAdapter({
|
|
71
|
+
lib: google.maps,
|
|
72
|
+
map,
|
|
73
|
+
// Keep drawn features in their own Data layer so nothing else on the map
|
|
74
|
+
// (or a future layer port feature) shares styling or click handling with them.
|
|
75
|
+
isolatedData: true,
|
|
76
|
+
coordinatePrecision: DRAW_COORDINATE_PRECISION,
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
57
81
|
let runtimePromise = null;
|
|
58
82
|
/**
|
|
59
83
|
* Lazily dynamic-imports {@link createDeckGlGoogleMapsOverlayRuntime} and caches the promise.
|
|
@@ -2899,6 +2923,7 @@ class GoogleMapsAdapterInstance {
|
|
|
2899
2923
|
initializationFailed: INITIAL_MAP_STATE.initializationFailed,
|
|
2900
2924
|
appearance: INITIAL_MAP_STATE.appearance,
|
|
2901
2925
|
tileSize: INITIAL_MAP_STATE.tileSize,
|
|
2926
|
+
drawing: INITIAL_MAP_STATE.drawing,
|
|
2902
2927
|
};
|
|
2903
2928
|
this.cameraListeners = new Set();
|
|
2904
2929
|
this.statusListeners = new Set();
|
|
@@ -2932,6 +2957,11 @@ class GoogleMapsAdapterInstance {
|
|
|
2932
2957
|
};
|
|
2933
2958
|
this.layers = new GoogleMapsLayerPort();
|
|
2934
2959
|
this.layers.setTheme(this.appearance.theme);
|
|
2960
|
+
// Engine load failures are not surfaced here (same as the deck.gl runtime): the
|
|
2961
|
+
// controller keeps mode and value and loads again on the next connect, setMode
|
|
2962
|
+
// or setValue that needs an engine.
|
|
2963
|
+
this.draw = new DrawController();
|
|
2964
|
+
this.draw.subscribe(() => this.syncDrawingStatus());
|
|
2935
2965
|
this.state = computeInitialState(this.appearance, config.initialViewport);
|
|
2936
2966
|
this.cachedCameraState = {
|
|
2937
2967
|
center: this.state.center,
|
|
@@ -2944,6 +2974,7 @@ class GoogleMapsAdapterInstance {
|
|
|
2944
2974
|
initializationFailed: this.state.initializationFailed,
|
|
2945
2975
|
appearance: this.state.appearance,
|
|
2946
2976
|
tileSize: this.state.tileSize,
|
|
2977
|
+
drawing: this.state.drawing,
|
|
2947
2978
|
};
|
|
2948
2979
|
}
|
|
2949
2980
|
// ============================================================================
|
|
@@ -2980,11 +3011,13 @@ class GoogleMapsAdapterInstance {
|
|
|
2980
3011
|
// `state` to defaults while `this.appearance` keeps the real values, so a
|
|
2981
3012
|
// StrictMode destroy → revive would otherwise report stale defaults, and the
|
|
2982
3013
|
// appearance controls' sync-back would overwrite persisted preferences with them.
|
|
2983
|
-
this.state = { ...this.state, appearance: this.appearance };
|
|
3014
|
+
this.state = { ...this.state, appearance: this.appearance, drawing: this.draw.getMode() !== "idle" };
|
|
2984
3015
|
this.updateStatusCache();
|
|
2985
3016
|
this.layers.connect(map);
|
|
2986
|
-
// Theme changes recreate the google.maps.Map, so traffic must re-attach on every (re)connect
|
|
3017
|
+
// Theme changes recreate the google.maps.Map, so traffic and drawing must re-attach on every (re)connect.
|
|
3018
|
+
// The draw controller rebuilds its engine from the committed value on the new map (ADR 0030).
|
|
2987
3019
|
this.syncTrafficLayer();
|
|
3020
|
+
this.draw.connect(createGoogleDrawEngineLoader(map));
|
|
2988
3021
|
this.setupEventListeners();
|
|
2989
3022
|
this.layers.setPointerMoveReporter(position => {
|
|
2990
3023
|
this.reportPointerMove(position);
|
|
@@ -3215,6 +3248,7 @@ class GoogleMapsAdapterInstance {
|
|
|
3215
3248
|
this.removeGoogleEventListeners();
|
|
3216
3249
|
this.trafficLayer?.setMap(null);
|
|
3217
3250
|
this.trafficLayer = null;
|
|
3251
|
+
this.draw.disconnect();
|
|
3218
3252
|
this.layers.setPointerMoveReporter(null);
|
|
3219
3253
|
this.layers.destroy();
|
|
3220
3254
|
// Clear our listeners
|
|
@@ -3372,8 +3406,17 @@ class GoogleMapsAdapterInstance {
|
|
|
3372
3406
|
this.cachedCameraState = { center, zoom, bounds, isIdle };
|
|
3373
3407
|
}
|
|
3374
3408
|
updateStatusCache() {
|
|
3375
|
-
const { isReady, initializationFailed, appearance, tileSize } = this.state;
|
|
3376
|
-
this.cachedStatus = { isReady, initializationFailed, appearance, tileSize };
|
|
3409
|
+
const { isReady, initializationFailed, appearance, tileSize, drawing } = this.state;
|
|
3410
|
+
this.cachedStatus = { isReady, initializationFailed, appearance, tileSize, drawing };
|
|
3411
|
+
}
|
|
3412
|
+
/** Mirrors the draw controller's mode into `MapStatus.drawing` (ADR 0030). */
|
|
3413
|
+
syncDrawingStatus() {
|
|
3414
|
+
const drawing = this.draw.getMode() !== "idle";
|
|
3415
|
+
if (this.state.drawing === drawing)
|
|
3416
|
+
return;
|
|
3417
|
+
this.state = { ...this.state, drawing };
|
|
3418
|
+
this.updateStatusCache();
|
|
3419
|
+
this.notifyStatusListeners();
|
|
3377
3420
|
}
|
|
3378
3421
|
notifyCameraListeners() {
|
|
3379
3422
|
this.cameraListeners.forEach(listener => listener());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-map-adapter-google",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.154",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -14,14 +14,16 @@
|
|
|
14
14
|
"@loaders.gl/core": "~4.5.2",
|
|
15
15
|
"@luma.gl/core": "^9.4.1",
|
|
16
16
|
"@luma.gl/engine": "^9.4.1",
|
|
17
|
-
"@trackunit/react-map-adapter-shared": "0.0.
|
|
18
|
-
"@trackunit/react-map-color-utils": "0.0.
|
|
19
|
-
"@trackunit/geo-json-utils": "1.
|
|
17
|
+
"@trackunit/react-map-adapter-shared": "0.0.164",
|
|
18
|
+
"@trackunit/react-map-color-utils": "0.0.138",
|
|
19
|
+
"@trackunit/geo-json-utils": "1.19.0",
|
|
20
20
|
"@googlemaps/markerclusterer": "^2.6.2",
|
|
21
21
|
"@vis.gl/react-google-maps": "^1.7.1",
|
|
22
22
|
"es-toolkit": "^1.52.0",
|
|
23
23
|
"react-device-detect": "^2.2.3",
|
|
24
|
-
"zod": "^3.25.76"
|
|
24
|
+
"zod": "^3.25.76",
|
|
25
|
+
"@trackunit/react-map-draw": "0.0.2",
|
|
26
|
+
"terra-draw-google-maps-adapter": "^1.6.2"
|
|
25
27
|
},
|
|
26
28
|
"peerDependencies": {
|
|
27
29
|
"react": "^19.0.0",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type AdapterInstance, type BaseAdapterConfig, type CameraState, type FitBoundsOptions, type GeoJsonBbox, type GeoJsonPosition, type MapEvent, type MapEventHandler, type MapStatus, type MapTheme, type MapType } from "@trackunit/react-map-adapter-shared";
|
|
2
|
+
import { DrawController } from "@trackunit/react-map-draw";
|
|
2
3
|
import { GoogleMapsLayerPort } from "./GoogleMapsLayerPort";
|
|
3
4
|
/**
|
|
4
5
|
* Configuration for Google Maps adapter
|
|
@@ -21,6 +22,11 @@ export declare class GoogleMapsAdapterInstance implements AdapterInstance {
|
|
|
21
22
|
private readonly config;
|
|
22
23
|
/** Layer rendering capabilities, provided via MapLayerContext to <Layers>. */
|
|
23
24
|
readonly layers: GoogleMapsLayerPort;
|
|
25
|
+
/**
|
|
26
|
+
* Drawing capability (ADR 0030). The controller keeps mode and value across map
|
|
27
|
+
* recreations; `connect()` rebinds it to every new `google.maps.Map`.
|
|
28
|
+
*/
|
|
29
|
+
readonly draw: DrawController;
|
|
24
30
|
private map;
|
|
25
31
|
private isDestroyedFlag;
|
|
26
32
|
private state;
|
|
@@ -104,6 +110,8 @@ export declare class GoogleMapsAdapterInstance implements AdapterInstance {
|
|
|
104
110
|
private mapTypeToGoogleMapTypeId;
|
|
105
111
|
private updateCameraCache;
|
|
106
112
|
private updateStatusCache;
|
|
113
|
+
/** Mirrors the draw controller's mode into `MapStatus.drawing` (ADR 0030). */
|
|
114
|
+
private syncDrawingStatus;
|
|
107
115
|
private notifyCameraListeners;
|
|
108
116
|
private notifyStatusListeners;
|
|
109
117
|
private emitEvent;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type DrawEngineLoader } from "@trackunit/react-map-draw";
|
|
2
|
+
/**
|
|
3
|
+
* Builds the Google Maps bridge for the shared drawing engine (ADR 0030).
|
|
4
|
+
*
|
|
5
|
+
* One loader per `google.maps.Map` instance: theme switches and traffic toggles
|
|
6
|
+
* recreate the map, and `GoogleMapsAdapterInstance.connect` hands the controller a
|
|
7
|
+
* fresh loader each time so the engine is rebuilt on the live map. Terra Draw and its
|
|
8
|
+
* Google adapter are only downloaded when the loader runs, which the controller
|
|
9
|
+
* defers until drawing is actually needed.
|
|
10
|
+
*/
|
|
11
|
+
export declare const createGoogleDrawEngineLoader: (map: google.maps.Map) => DrawEngineLoader;
|