@treasuryspatial/map-react 0.1.8 → 0.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"MapModeViewport.d.ts","sourceRoot":"","sources":["../src/MapModeViewport.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA6F,MAAM,OAAO,CAAC;AAElH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EASL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,qBAAqB,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC;IACxB,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iBAAiB,EAAE,MAAM,MAAM,CAAC;CACjC,CAAC;AAIF,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;AACjH,MAAM,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AAEpF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAClD,gBAAgB,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3C,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;IACpC,iBAAiB,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAMF,eAAO,MAAM,eAAe,oGA8W1B,CAAC"}
1
+ {"version":3,"file":"MapModeViewport.d.ts","sourceRoot":"","sources":["../src/MapModeViewport.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA6F,MAAM,OAAO,CAAC;AAElH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EASL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC3B,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,qBAAqB,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC;IACxB,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iBAAiB,EAAE,MAAM,MAAM,CAAC;CACjC,CAAC;AAIF,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;AACjH,MAAM,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AAEpF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAClD,gBAAgB,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3C,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;IACpC,iBAAiB,EAAE,CAAC,SAAS,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAMF,eAAO,MAAM,eAAe,oGAmc1B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
3
+ import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
4
4
  import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
5
5
  import * as THREE from 'three';
6
6
  import { buildGeoJsonPolygon, computeCentroid, computeFootprintStats, createMapThreeLayer, ensureFootprintLayers, getOuterRing, toLocalMeters, toPolygonFeature, } from '@treasuryspatial/map-kit';
@@ -23,8 +23,20 @@ export const MapModeViewport = forwardRef(function MapModeViewport({ active, geo
23
23
  const onCandidateClearRef = useRef(onCandidateClear);
24
24
  const lastGeocodeLabelRef = useRef(null);
25
25
  const reverseGeocodeRequestRef = useRef(0);
26
+ const resizeObserverRef = useRef(null);
26
27
  const [mapReady, setMapReady] = useState(false);
27
28
  const [mapError, setMapError] = useState('');
29
+ const debug = useMemo(() => {
30
+ if (typeof window === 'undefined')
31
+ return false;
32
+ const params = new URLSearchParams(window.location.search);
33
+ return params.has('mapDebug') || process.env.NODE_ENV !== 'production';
34
+ }, []);
35
+ const log = useCallback((...args) => {
36
+ if (!debug)
37
+ return;
38
+ console.info('[map-react]', ...args);
39
+ }, [debug]);
28
40
  useEffect(() => {
29
41
  lightingPresetRef.current = lightingPreset;
30
42
  }, [lightingPreset]);
@@ -71,6 +83,8 @@ export const MapModeViewport = forwardRef(function MapModeViewport({ active, geo
71
83
  return;
72
84
  }
73
85
  let cancelled = false;
86
+ let cleanupCanvasEvents = null;
87
+ let cleanupMapEvents = null;
74
88
  const boot = async () => {
75
89
  try {
76
90
  const module = await import('mapbox-gl');
@@ -95,6 +109,13 @@ export const MapModeViewport = forwardRef(function MapModeViewport({ active, geo
95
109
  preserveDrawingBuffer: true,
96
110
  attributionControl: false,
97
111
  });
112
+ log('map init', {
113
+ style: mapStyle,
114
+ center: [startCenter.lng, startCenter.lat],
115
+ zoom: startZoom,
116
+ bearing: startBearing,
117
+ pitch: startPitch,
118
+ });
98
119
  map.addControl(new mapboxgl.NavigationControl({ visualizePitch: true }), 'bottom-right');
99
120
  const geocoder = new MapboxGeocoder({
100
121
  accessToken,
@@ -106,6 +127,48 @@ export const MapModeViewport = forwardRef(function MapModeViewport({ active, geo
106
127
  });
107
128
  map.addControl(geocoder, 'top-left');
108
129
  mapRef.current = map;
130
+ const onMapError = (event) => {
131
+ const err = event?.error ?? event;
132
+ console.error('[map-react] Mapbox error', err);
133
+ };
134
+ map.on('error', onMapError);
135
+ cleanupMapEvents = () => {
136
+ map.off('error', onMapError);
137
+ };
138
+ const canvas = map.getCanvas();
139
+ const onContextLost = (event) => {
140
+ event.preventDefault();
141
+ console.error('[map-react] WebGL context lost');
142
+ setMapError('WebGL context lost.');
143
+ };
144
+ const onContextRestored = () => {
145
+ console.info('[map-react] WebGL context restored');
146
+ setMapError('');
147
+ };
148
+ canvas.addEventListener('webglcontextlost', onContextLost, { passive: false });
149
+ canvas.addEventListener('webglcontextrestored', onContextRestored);
150
+ cleanupCanvasEvents = () => {
151
+ canvas.removeEventListener('webglcontextlost', onContextLost);
152
+ canvas.removeEventListener('webglcontextrestored', onContextRestored);
153
+ };
154
+ const container = containerRef.current;
155
+ if (container && typeof ResizeObserver !== 'undefined') {
156
+ const observer = new ResizeObserver(() => {
157
+ if (!mapRef.current)
158
+ return;
159
+ mapRef.current.resize();
160
+ if (debug) {
161
+ const mapCanvas = mapRef.current.getCanvas();
162
+ log('map resize', {
163
+ canvasSize: { width: mapCanvas.width, height: mapCanvas.height },
164
+ canvasRect: mapCanvas.getBoundingClientRect(),
165
+ containerRect: container.getBoundingClientRect(),
166
+ });
167
+ }
168
+ });
169
+ observer.observe(container);
170
+ resizeObserverRef.current = observer;
171
+ }
109
172
  map.on('style.load', () => {
110
173
  if (!map.isStyleLoaded())
111
174
  return;
@@ -125,6 +188,17 @@ export const MapModeViewport = forwardRef(function MapModeViewport({ active, geo
125
188
  applyMapVisibility(map, mapVisibility, opacityCacheRef);
126
189
  setMapReady(true);
127
190
  bindFootprintHandlers(map);
191
+ requestAnimationFrame(() => {
192
+ map.resize();
193
+ if (debug) {
194
+ const mapCanvas = map.getCanvas();
195
+ log('map load', {
196
+ canvasSize: { width: mapCanvas.width, height: mapCanvas.height },
197
+ canvasRect: mapCanvas.getBoundingClientRect(),
198
+ containerRect: map.getContainer().getBoundingClientRect(),
199
+ });
200
+ }
201
+ });
128
202
  });
129
203
  geocoder.on('result', (event) => {
130
204
  const center = event?.result?.center;
@@ -153,6 +227,10 @@ export const MapModeViewport = forwardRef(function MapModeViewport({ active, geo
153
227
  threeLayerRef.current = null;
154
228
  setMapReady(false);
155
229
  handlersBoundRef.current = false;
230
+ resizeObserverRef.current?.disconnect();
231
+ resizeObserverRef.current = null;
232
+ cleanupCanvasEvents?.();
233
+ cleanupMapEvents?.();
156
234
  };
157
235
  }, [active, accessToken, mapStyle, mapVisibility]);
158
236
  useEffect(() => {
@@ -223,6 +301,7 @@ export const MapModeViewport = forwardRef(function MapModeViewport({ active, geo
223
301
  threeLayerRef.current = createMapThreeLayer({
224
302
  id: 'courtyard-mesh',
225
303
  zOffsetMeters: 0.05,
304
+ debug,
226
305
  onInit: (scene, renderer) => {
227
306
  sceneRef.current = scene;
228
307
  rendererRef.current = renderer;
@@ -339,6 +418,8 @@ const ensureGeometryUvs = (geometry) => {
339
418
  geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));
340
419
  };
341
420
  function applyMaterialOverrides(group, settings) {
421
+ if (!group || typeof group.traverse !== 'function')
422
+ return;
342
423
  const color = new THREE.Color(settings?.color ?? '#ffffff');
343
424
  const textureUrl = settings?.textureUrl;
344
425
  const repeat = settings?.textureRepeat ?? 2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treasuryspatial/map-react",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",
@@ -18,7 +18,7 @@
18
18
  "access": "public"
19
19
  },
20
20
  "dependencies": {
21
- "@treasuryspatial/map-kit": "^0.1.1"
21
+ "@treasuryspatial/map-kit": "^0.1.4"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": ">=18",