@treasuryspatial/map-kit 0.1.16 → 0.1.18

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/mapLayers.js CHANGED
@@ -35,9 +35,9 @@ export function ensureFootprintLayers(map) {
35
35
  type: 'line',
36
36
  source: 'footprint-hover',
37
37
  paint: {
38
- 'line-color': '#f8d34a',
39
- 'line-width': 2,
40
- 'line-opacity': 0.9,
38
+ 'line-color': '#2F4A3C',
39
+ 'line-width': 1.2,
40
+ 'line-opacity': 0.8,
41
41
  },
42
42
  });
43
43
  if (!map.getSource('footprint-selected')) {
@@ -51,9 +51,9 @@ export function ensureFootprintLayers(map) {
51
51
  type: 'line',
52
52
  source: 'footprint-selected',
53
53
  paint: {
54
- 'line-color': '#6ee7ff',
55
- 'line-width': 3,
56
- 'line-opacity': 1,
54
+ 'line-color': '#8C3A2B',
55
+ 'line-width': 1.6,
56
+ 'line-opacity': 0.9,
57
57
  },
58
58
  });
59
59
  const setSource = (id, feature) => {
@@ -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;IAC3F,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAsWhF"}
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,CAofhF"}
@@ -2,6 +2,9 @@ import mapboxgl from 'mapbox-gl';
2
2
  import * as THREE from 'three';
3
3
  export function createMapThreeLayer(options) {
4
4
  const { id, zOffsetMeters = 0.02, onInit, debug = false } = options;
5
+ const useOffscreen = true;
6
+ const debugFill = typeof window !== 'undefined' &&
7
+ /(?:mapDebugFill=1|DebugFill=1)/.test(window.location.href);
5
8
  let mapRef = null;
6
9
  let scene = null;
7
10
  let camera = null;
@@ -25,7 +28,14 @@ export function createMapThreeLayer(options) {
25
28
  let didPrerender = false;
26
29
  let lastMatrix = null;
27
30
  let renderTicks = 0;
31
+ let blitProgram = null;
32
+ let blitBuffer = null;
33
+ let blitAttribPos = -1;
34
+ let blitAttribUv = -1;
35
+ let blitUniformTex = null;
28
36
  const renderOffscreen = () => {
37
+ if (!useOffscreen)
38
+ return;
29
39
  if (renderDisabled)
30
40
  return;
31
41
  if (!renderer || !scene || !camera || !rootGroup || !renderTarget)
@@ -75,8 +85,14 @@ export function createMapThreeLayer(options) {
75
85
  gl.colorMask(true, true, true, true);
76
86
  gl.depthMask(true);
77
87
  renderer.setViewport(0, 0, targetWidth, targetHeight);
78
- renderer.setClearColor(0x000000, 0);
79
- renderer.setClearAlpha(0);
88
+ if (debugFill) {
89
+ renderer.setClearColor(0xff00ff, 1);
90
+ renderer.setClearAlpha(1);
91
+ }
92
+ else {
93
+ renderer.setClearColor(0x000000, 0);
94
+ renderer.setClearAlpha(0);
95
+ }
80
96
  renderer.clear(true, true, true);
81
97
  checkFramebuffer(gl, 'prerender');
82
98
  renderer.render(scene, camera);
@@ -159,7 +175,7 @@ export function createMapThreeLayer(options) {
159
175
  antialias: true,
160
176
  logarithmicDepthBuffer: true,
161
177
  alpha: true,
162
- premultipliedAlpha: true,
178
+ premultipliedAlpha: false,
163
179
  });
164
180
  renderer.autoClear = false;
165
181
  renderer.outputColorSpace = THREE.SRGBColorSpace;
@@ -169,24 +185,75 @@ export function createMapThreeLayer(options) {
169
185
  const canvas = map.getCanvas();
170
186
  targetWidth = canvas.width;
171
187
  targetHeight = canvas.height;
172
- renderTarget = new THREE.WebGLRenderTarget(targetWidth, targetHeight, {
173
- depthBuffer: true,
174
- stencilBuffer: false,
175
- });
176
- renderTarget.texture.colorSpace = THREE.SRGBColorSpace;
177
- renderTarget.texture.premultiplyAlpha = true;
178
- log('renderTarget', { width: targetWidth, height: targetHeight });
179
- screenScene = new THREE.Scene();
180
- screenCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
181
- screenMaterial = new THREE.MeshBasicMaterial({
182
- map: renderTarget.texture,
183
- transparent: true,
184
- depthTest: false,
185
- depthWrite: false,
186
- });
187
- screenMaterial.premultipliedAlpha = true;
188
- screenQuad = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), screenMaterial);
189
- screenScene.add(screenQuad);
188
+ if (useOffscreen) {
189
+ renderTarget = new THREE.WebGLRenderTarget(targetWidth, targetHeight, {
190
+ depthBuffer: true,
191
+ stencilBuffer: false,
192
+ });
193
+ renderTarget.texture.colorSpace = THREE.SRGBColorSpace;
194
+ log('renderTarget', { width: targetWidth, height: targetHeight });
195
+ const vsrc = `
196
+ attribute vec2 a_pos;
197
+ attribute vec2 a_uv;
198
+ varying vec2 v_uv;
199
+ void main() {
200
+ v_uv = a_uv;
201
+ gl_Position = vec4(a_pos, 0.0, 1.0);
202
+ }
203
+ `;
204
+ const fsrc = `
205
+ precision mediump float;
206
+ varying vec2 v_uv;
207
+ uniform sampler2D u_tex;
208
+ void main() {
209
+ gl_FragColor = texture2D(u_tex, v_uv);
210
+ }
211
+ `;
212
+ const compile = (type, src) => {
213
+ const shader = gl.createShader(type);
214
+ if (!shader)
215
+ return null;
216
+ gl.shaderSource(shader, src);
217
+ gl.compileShader(shader);
218
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
219
+ logError('blit shader compile failed', gl.getShaderInfoLog(shader));
220
+ gl.deleteShader(shader);
221
+ return null;
222
+ }
223
+ return shader;
224
+ };
225
+ const vs = compile(gl.VERTEX_SHADER, vsrc);
226
+ const fs = compile(gl.FRAGMENT_SHADER, fsrc);
227
+ if (vs && fs) {
228
+ const program = gl.createProgram();
229
+ if (program) {
230
+ gl.attachShader(program, vs);
231
+ gl.attachShader(program, fs);
232
+ gl.linkProgram(program);
233
+ if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
234
+ blitProgram = program;
235
+ blitAttribPos = gl.getAttribLocation(program, 'a_pos');
236
+ blitAttribUv = gl.getAttribLocation(program, 'a_uv');
237
+ blitUniformTex = gl.getUniformLocation(program, 'u_tex');
238
+ blitBuffer = gl.createBuffer();
239
+ gl.bindBuffer(gl.ARRAY_BUFFER, blitBuffer);
240
+ const data = new Float32Array([
241
+ -1, -1, 0, 0,
242
+ 3, -1, 2, 0,
243
+ -1, 3, 0, 2,
244
+ ]);
245
+ gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
246
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
247
+ }
248
+ else {
249
+ logError('blit program link failed', gl.getProgramInfoLog(program));
250
+ gl.deleteProgram(program);
251
+ }
252
+ }
253
+ gl.deleteShader(vs);
254
+ gl.deleteShader(fs);
255
+ }
256
+ }
190
257
  rootGroup = new THREE.Group();
191
258
  rootGroup.matrixAutoUpdate = false;
192
259
  scene.add(rootGroup);
@@ -239,7 +306,7 @@ export function createMapThreeLayer(options) {
239
306
  render: (gl, matrix) => {
240
307
  if (renderDisabled)
241
308
  return;
242
- if (!renderer || !screenScene || !screenCamera)
309
+ if (!renderer)
243
310
  return;
244
311
  if (!hasRenderable)
245
312
  return;
@@ -255,19 +322,96 @@ export function createMapThreeLayer(options) {
255
322
  renderTicks += 1;
256
323
  log('render tick', { hasMatrix: Boolean(lastMatrix) });
257
324
  }
325
+ if (useOffscreen) {
326
+ if (!renderTarget || !blitProgram || !blitBuffer)
327
+ return;
328
+ const prevFbo = gl.getParameter(gl.FRAMEBUFFER_BINDING);
329
+ renderer.resetState();
330
+ renderOffscreen();
331
+ if (prevFbo) {
332
+ gl.bindFramebuffer(gl.FRAMEBUFFER, prevFbo);
333
+ }
334
+ else {
335
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
336
+ }
337
+ gl.disable(gl.DEPTH_TEST);
338
+ gl.depthMask(false);
339
+ gl.disable(gl.STENCIL_TEST);
340
+ gl.disable(gl.SCISSOR_TEST);
341
+ gl.colorMask(true, true, true, true);
342
+ gl.enable(gl.BLEND);
343
+ gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
344
+ const canvas = mapRef?.getCanvas();
345
+ if (canvas) {
346
+ gl.viewport(0, 0, canvas.width, canvas.height);
347
+ }
348
+ gl.useProgram(blitProgram);
349
+ gl.bindBuffer(gl.ARRAY_BUFFER, blitBuffer);
350
+ const stride = 4 * 4;
351
+ if (blitAttribPos >= 0) {
352
+ gl.enableVertexAttribArray(blitAttribPos);
353
+ gl.vertexAttribPointer(blitAttribPos, 2, gl.FLOAT, false, stride, 0);
354
+ }
355
+ if (blitAttribUv >= 0) {
356
+ gl.enableVertexAttribArray(blitAttribUv);
357
+ gl.vertexAttribPointer(blitAttribUv, 2, gl.FLOAT, false, stride, 8);
358
+ }
359
+ const texture = renderer.properties.get(renderTarget.texture)?.__webglTexture;
360
+ if (texture) {
361
+ gl.activeTexture(gl.TEXTURE0);
362
+ gl.bindTexture(gl.TEXTURE_2D, texture);
363
+ if (blitUniformTex)
364
+ gl.uniform1i(blitUniformTex, 0);
365
+ }
366
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
367
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
368
+ gl.useProgram(null);
369
+ logGlError(gl, 'render');
370
+ renderer.resetState();
371
+ mapRef?.triggerRepaint();
372
+ return;
373
+ }
374
+ if (!scene || !camera)
375
+ return;
376
+ if (!mercatorOrigin && mapRef && !originResolved) {
377
+ try {
378
+ const center = mapRef.getCenter();
379
+ mercatorOrigin = mapboxgl.MercatorCoordinate.fromLngLat(center);
380
+ meterScale = mercatorOrigin.meterInMercatorCoordinateUnits();
381
+ originResolved = true;
382
+ if (debug) {
383
+ log('origin fallback', {
384
+ origin: { lng: center.lng, lat: center.lat },
385
+ mercator: { x: mercatorOrigin.x, y: mercatorOrigin.y, z: mercatorOrigin.z },
386
+ meterScale,
387
+ });
388
+ }
389
+ }
390
+ catch (err) {
391
+ logError('origin fallback failed', err);
392
+ }
393
+ }
394
+ if (mercatorOrigin && lastMatrix && camera) {
395
+ const m = new THREE.Matrix4().fromArray(lastMatrix);
396
+ const translate = new THREE.Matrix4().makeTranslation(mercatorOrigin.x, mercatorOrigin.y, (mercatorOrigin.z ?? 0) + zOffset * meterScale);
397
+ const scale = new THREE.Matrix4().makeScale(meterScale, -meterScale, meterScale);
398
+ const l = new THREE.Matrix4().multiplyMatrices(translate, scale);
399
+ camera.projectionMatrix = m.multiply(l);
400
+ if ('projectionMatrixInverse' in camera) {
401
+ camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
402
+ }
403
+ }
258
404
  renderer.resetState();
259
- gl.disable(gl.DEPTH_TEST);
260
- gl.depthMask(false);
261
- gl.disable(gl.STENCIL_TEST);
262
405
  gl.disable(gl.SCISSOR_TEST);
406
+ gl.disable(gl.STENCIL_TEST);
407
+ gl.enable(gl.DEPTH_TEST);
408
+ gl.depthMask(true);
263
409
  gl.colorMask(true, true, true, true);
264
- gl.enable(gl.BLEND);
265
- gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
266
410
  const canvas = mapRef?.getCanvas();
267
411
  if (canvas) {
268
412
  renderer.setViewport(0, 0, canvas.width, canvas.height);
269
413
  }
270
- renderer.render(screenScene, screenCamera);
414
+ renderer.render(scene, camera);
271
415
  logGlError(gl, 'render');
272
416
  renderer.resetState();
273
417
  mapRef?.triggerRepaint();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treasuryspatial/map-kit",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",