@treasuryspatial/map-kit 0.1.3 → 0.1.4

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.
@@ -13,6 +13,7 @@ export type MapThreeLayerOptions = {
13
13
  id: string;
14
14
  zOffsetMeters?: number;
15
15
  onInit?: (scene: THREE.Scene, renderer: THREE.WebGLRenderer, camera: THREE.Camera) => void;
16
+ debug?: boolean;
16
17
  };
17
18
  export declare function createMapThreeLayer(options: MapThreeLayerOptions): MapThreeLayer;
18
19
  //# sourceMappingURL=mapThreeLayer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mapThreeLayer.d.ts","sourceRoot":"","sources":["../src/mapThreeLayer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,QAAQ,CAAC,oBAAoB,CAAC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,SAAS,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC;CAC5F,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAoJhF"}
1
+ {"version":3,"file":"mapThreeLayer.d.ts","sourceRoot":"","sources":["../src/mapThreeLayer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,QAAQ,CAAC,oBAAoB,CAAC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,SAAS,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC;IAC3F,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAyMhF"}
@@ -1,7 +1,7 @@
1
1
  import mapboxgl from 'mapbox-gl';
2
2
  import * as THREE from 'three';
3
3
  export function createMapThreeLayer(options) {
4
- const { id, zOffsetMeters = 0.02, onInit } = options;
4
+ const { id, zOffsetMeters = 0.02, onInit, debug = false } = options;
5
5
  let mapRef = null;
6
6
  let scene = null;
7
7
  let camera = null;
@@ -18,6 +18,32 @@ export function createMapThreeLayer(options) {
18
18
  let zOffset = zOffsetMeters;
19
19
  let targetWidth = 0;
20
20
  let targetHeight = 0;
21
+ let renderDisabled = false;
22
+ let errorCount = 0;
23
+ const log = (...args) => {
24
+ if (!debug)
25
+ return;
26
+ console.info(`[map-kit:${id}]`, ...args);
27
+ };
28
+ const logError = (message, err) => {
29
+ console.error(`[map-kit:${id}] ${message}`, err);
30
+ };
31
+ const logGlError = (gl, label) => {
32
+ if (!debug)
33
+ return;
34
+ const error = gl.getError();
35
+ if (error !== gl.NO_ERROR) {
36
+ log(`GL error (${label})`, error);
37
+ }
38
+ };
39
+ const checkFramebuffer = (gl, label) => {
40
+ if (!debug)
41
+ return;
42
+ const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
43
+ if (status !== gl.FRAMEBUFFER_COMPLETE) {
44
+ log(`Framebuffer incomplete (${label})`, status);
45
+ }
46
+ };
21
47
  const layer = {
22
48
  id,
23
49
  type: 'custom',
@@ -46,6 +72,7 @@ export function createMapThreeLayer(options) {
46
72
  });
47
73
  renderTarget.texture.colorSpace = THREE.SRGBColorSpace;
48
74
  renderTarget.texture.premultiplyAlpha = true;
75
+ log('renderTarget', { width: targetWidth, height: targetHeight });
49
76
  screenScene = new THREE.Scene();
50
77
  screenCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
51
78
  screenMaterial = new THREE.MeshBasicMaterial({
@@ -66,35 +93,64 @@ export function createMapThreeLayer(options) {
66
93
  onInit(scene, renderer, camera);
67
94
  },
68
95
  prerender: (_gl, matrix) => {
96
+ if (renderDisabled)
97
+ return;
69
98
  if (!renderer || !scene || !camera || !rootGroup || !renderTarget)
70
99
  return;
71
- camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
72
- if (mercatorOrigin) {
73
- const translate = new THREE.Matrix4().makeTranslation(mercatorOrigin.x, mercatorOrigin.y, (mercatorOrigin.z ?? 0) + zOffset * meterScale);
74
- const scale = new THREE.Matrix4().makeScale(meterScale, -meterScale, meterScale);
75
- rootGroup.matrix = new THREE.Matrix4().multiplyMatrices(translate, scale);
76
- rootGroup.matrixWorldNeedsUpdate = true;
100
+ try {
101
+ camera.projectionMatrix = new THREE.Matrix4().fromArray(matrix);
102
+ if (mercatorOrigin) {
103
+ const translate = new THREE.Matrix4().makeTranslation(mercatorOrigin.x, mercatorOrigin.y, (mercatorOrigin.z ?? 0) + zOffset * meterScale);
104
+ const scale = new THREE.Matrix4().makeScale(meterScale, -meterScale, meterScale);
105
+ rootGroup.matrix = new THREE.Matrix4().multiplyMatrices(translate, scale);
106
+ rootGroup.matrixWorldNeedsUpdate = true;
107
+ }
108
+ const canvas = mapRef?.getCanvas();
109
+ if (canvas && (canvas.width !== targetWidth || canvas.height !== targetHeight)) {
110
+ targetWidth = canvas.width;
111
+ targetHeight = canvas.height;
112
+ renderTarget.setSize(targetWidth, targetHeight);
113
+ log('renderTarget resized', { width: targetWidth, height: targetHeight });
114
+ }
115
+ renderer.setRenderTarget(renderTarget);
116
+ renderer.clear(true, true, true);
117
+ const gl = renderer.getContext();
118
+ checkFramebuffer(gl, 'prerender');
119
+ renderer.render(scene, camera);
120
+ logGlError(gl, 'prerender');
121
+ renderer.setRenderTarget(null);
77
122
  }
78
- const canvas = mapRef?.getCanvas();
79
- if (canvas && (canvas.width !== targetWidth || canvas.height !== targetHeight)) {
80
- targetWidth = canvas.width;
81
- targetHeight = canvas.height;
82
- renderTarget.setSize(targetWidth, targetHeight);
123
+ catch (err) {
124
+ errorCount += 1;
125
+ logError('prerender failed', err);
126
+ if (errorCount > 2) {
127
+ renderDisabled = true;
128
+ log('render disabled after repeated errors');
129
+ }
83
130
  }
84
- renderer.setRenderTarget(renderTarget);
85
- renderer.clear(true, true, true);
86
- renderer.render(scene, camera);
87
- renderer.setRenderTarget(null);
88
131
  },
89
132
  render: (gl) => {
133
+ if (renderDisabled)
134
+ return;
90
135
  if (!renderer || !screenScene || !screenCamera)
91
136
  return;
92
- renderer.resetState();
93
- gl.disable(gl.DEPTH_TEST);
94
- gl.enable(gl.BLEND);
95
- gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
96
- renderer.render(screenScene, screenCamera);
97
- mapRef?.triggerRepaint();
137
+ try {
138
+ renderer.resetState();
139
+ gl.disable(gl.DEPTH_TEST);
140
+ gl.enable(gl.BLEND);
141
+ gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
142
+ renderer.render(screenScene, screenCamera);
143
+ logGlError(gl, 'render');
144
+ mapRef?.triggerRepaint();
145
+ }
146
+ catch (err) {
147
+ errorCount += 1;
148
+ logError('render failed', err);
149
+ if (errorCount > 2) {
150
+ renderDisabled = true;
151
+ log('render disabled after repeated errors');
152
+ }
153
+ }
98
154
  },
99
155
  };
100
156
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treasuryspatial/map-kit",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",