@deck.gl-community/layers 0.0.0 → 9.0.2

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.
Files changed (39) hide show
  1. package/dist/index.cjs +493 -403
  2. package/dist/index.cjs.map +7 -0
  3. package/dist/index.d.ts +6 -0
  4. package/dist/index.js +6 -5
  5. package/dist/path-marker-layer/arrow-2d-geometry.d.ts +4 -0
  6. package/dist/path-marker-layer/arrow-2d-geometry.js +58 -0
  7. package/dist/path-marker-layer/create-path-markers.d.ts +18 -0
  8. package/dist/path-marker-layer/create-path-markers.js +78 -0
  9. package/dist/path-marker-layer/path-marker-layer.d.ts +40 -0
  10. package/dist/path-marker-layer/path-marker-layer.js +124 -0
  11. package/dist/path-marker-layer/polyline.d.ts +18 -0
  12. package/dist/path-marker-layer/polyline.js +40 -0
  13. package/dist/path-outline-layer/outline.d.ts +8 -0
  14. package/dist/path-outline-layer/outline.js +100 -0
  15. package/dist/path-outline-layer/path-outline-layer.d.ts +34 -0
  16. package/dist/path-outline-layer/path-outline-layer.js +116 -0
  17. package/dist/tile-source-layer/tile-source-layer.d.ts +43 -0
  18. package/dist/tile-source-layer/tile-source-layer.js +109 -0
  19. package/package.json +33 -20
  20. package/src/index.ts +8 -5
  21. package/src/path-marker-layer/arrow-2d-geometry.ts +65 -0
  22. package/src/path-marker-layer/create-path-markers.ts +122 -0
  23. package/src/path-marker-layer/path-marker-layer.ts +183 -0
  24. package/src/path-marker-layer/polyline.ts +44 -0
  25. package/src/path-outline-layer/outline.ts +107 -0
  26. package/src/path-outline-layer/path-outline-layer.ts +159 -0
  27. package/src/{tile-source-layer.ts → tile-source-layer/tile-source-layer.ts} +34 -26
  28. package/dist/data-driven-tile-3d-layer/data-driven-tile-3d-layer.js +0 -193
  29. package/dist/data-driven-tile-3d-layer/data-driven-tile-3d-layer.js.map +0 -1
  30. package/dist/data-driven-tile-3d-layer/utils/colorize-tile.js +0 -31
  31. package/dist/data-driven-tile-3d-layer/utils/colorize-tile.js.map +0 -1
  32. package/dist/data-driven-tile-3d-layer/utils/filter-tile.js +0 -146
  33. package/dist/data-driven-tile-3d-layer/utils/filter-tile.js.map +0 -1
  34. package/dist/index.js.map +0 -1
  35. package/dist/tile-source-layer.js +0 -112
  36. package/dist/tile-source-layer.js.map +0 -1
  37. package/src/data-driven-tile-3d-layer/data-driven-tile-3d-layer.ts +0 -257
  38. package/src/data-driven-tile-3d-layer/utils/colorize-tile.ts +0 -49
  39. package/src/data-driven-tile-3d-layer/utils/filter-tile.ts +0 -175
@@ -0,0 +1,116 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { PathLayer } from '@deck.gl/layers';
5
+ import { GL } from '@luma.gl/constants';
6
+ import { outline } from './outline';
7
+ /**
8
+ * Unit literal to shader unit number conversion.
9
+ */
10
+ export const UNIT = {
11
+ common: 0,
12
+ meters: 1,
13
+ pixels: 2
14
+ };
15
+ // TODO - this should be built into assembleShaders
16
+ function injectShaderCode({ source, code = '' }) {
17
+ const INJECT_CODE = /}[^{}]*$/;
18
+ return source.replace(INJECT_CODE, code.concat('\n}\n'));
19
+ }
20
+ const VS_CODE = `\
21
+ outline_setUV(gl_Position);
22
+ outline_setZLevel(instanceZLevel);
23
+ `;
24
+ const FS_CODE = `\
25
+ fragColor = outline_filterColor(fragColor);
26
+ `;
27
+ const defaultProps = {
28
+ getZLevel: () => 0
29
+ };
30
+ export class PathOutlineLayer extends PathLayer {
31
+ static layerName = 'PathOutlineLayer';
32
+ static defaultProps = defaultProps;
33
+ state = undefined;
34
+ // Override getShaders to inject the outline module
35
+ getShaders() {
36
+ const shaders = super.getShaders();
37
+ return Object.assign({}, shaders, {
38
+ modules: shaders.modules.concat([outline]),
39
+ vs: injectShaderCode({ source: shaders.vs, code: VS_CODE }),
40
+ fs: injectShaderCode({ source: shaders.fs, code: FS_CODE })
41
+ });
42
+ }
43
+ // @ts-expect-error PathLayer is missing LayerContext arg
44
+ initializeState(context) {
45
+ super.initializeState();
46
+ // Create an outline "shadow" map
47
+ // TODO - we should create a single outlineMap for all layers
48
+ this.setState({
49
+ outlineFramebuffer: context.device.createFramebuffer({}),
50
+ dummyTexture: context.device.createTexture({})
51
+ });
52
+ // Create an attribute manager
53
+ // @ts-expect-error check whether this.getAttributeManager works here
54
+ this.state.attributeManager.addInstanced({
55
+ instanceZLevel: {
56
+ size: 1,
57
+ type: GL.UNSIGNED_BYTE,
58
+ accessor: 'getZLevel'
59
+ }
60
+ });
61
+ }
62
+ // Override draw to add render module
63
+ draw({ moduleParameters = {}, parameters, uniforms, context }) {
64
+ // Need to calculate same uniforms as base layer
65
+ const { jointRounded, capRounded, billboard, miterLimit, widthUnits, widthScale, widthMinPixels, widthMaxPixels } = this.props;
66
+ uniforms = Object.assign({}, uniforms, {
67
+ jointType: Number(jointRounded),
68
+ capType: Number(capRounded),
69
+ billboard,
70
+ widthUnits: UNIT[widthUnits],
71
+ widthScale,
72
+ miterLimit,
73
+ widthMinPixels,
74
+ widthMaxPixels
75
+ });
76
+ // Render the outline shadowmap (based on segment z orders)
77
+ const { outlineFramebuffer, dummyTexture } = this.state;
78
+ // TODO(v9): resize, see 'sf' example.
79
+ // outlineFramebuffer.resize();
80
+ // TODO(v9) clear FBO
81
+ // outlineFramebuffer.clear({ color: true, depth: true, stencil: true });
82
+ this.state.model.updateModuleSettings({
83
+ outlineEnabled: true,
84
+ outlineRenderShadowmap: true,
85
+ outlineShadowmap: dummyTexture
86
+ });
87
+ this.state.model.draw({
88
+ uniforms: Object.assign({}, uniforms, {
89
+ jointType: 0,
90
+ widthScale: this.props.widthScale * 1.3
91
+ }),
92
+ parameters: {
93
+ depthTest: false,
94
+ // Biggest value needs to go into buffer
95
+ blendEquation: GL.MAX
96
+ },
97
+ framebuffer: outlineFramebuffer
98
+ });
99
+ // Now use the outline shadowmap to render the lines (with outlines)
100
+ this.state.model.updateModuleSettings({
101
+ outlineEnabled: true,
102
+ outlineRenderShadowmap: false,
103
+ outlineShadowmap: outlineFramebuffer
104
+ });
105
+ this.state.model.draw({
106
+ uniforms: Object.assign({}, uniforms, {
107
+ jointType: Number(jointRounded),
108
+ capType: Number(capRounded),
109
+ widthScale: this.props.widthScale
110
+ }),
111
+ parameters: {
112
+ depthTest: false
113
+ }
114
+ });
115
+ }
116
+ }
@@ -0,0 +1,43 @@
1
+ import { CompositeLayer } from '@deck.gl/core';
2
+ import { TileLayer, TileLayerProps } from '@deck.gl/geo-layers';
3
+ import type { TileSource } from '@loaders.gl/loader-utils';
4
+ export type TileSourceLayerProps = TileLayerProps & {
5
+ tileSource: TileSource<any>;
6
+ showTileBorders?: boolean;
7
+ };
8
+ /**
9
+ * A Deck.gl layer that renders a tile source
10
+ * Autodiscovers type of content (vector tile, bitmap, ...)
11
+ * Can render debug borders around tiles
12
+ * TODO - Change debug border color based on zoom level
13
+ */
14
+ export declare class TileSourceLayer extends CompositeLayer<TileSourceLayerProps> {
15
+ static layerName: string;
16
+ static defaultProps: {
17
+ showTileBorders: boolean;
18
+ };
19
+ state: {
20
+ tileSource: TileSource<any> | null;
21
+ };
22
+ initializeState(): void;
23
+ updateState({ props, changeFlags }: {
24
+ props: any;
25
+ changeFlags: any;
26
+ }): void;
27
+ renderLayers(): TileLayer<any, {
28
+ id: string;
29
+ getTileData: any;
30
+ maxRequests: 20;
31
+ pickable: true;
32
+ onViewportLoad: any;
33
+ autoHighlight: any;
34
+ highlightColor: number[];
35
+ minZoom: any;
36
+ maxZoom: any;
37
+ tileSize: 256;
38
+ zoomOffset: 0 | -1;
39
+ renderSubLayers: any;
40
+ tileSource: any;
41
+ showTileBorders: any;
42
+ }>[];
43
+ }
@@ -0,0 +1,109 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { CompositeLayer } from '@deck.gl/core';
5
+ import { TileLayer } from '@deck.gl/geo-layers';
6
+ import { BitmapLayer, GeoJsonLayer, PathLayer } from '@deck.gl/layers';
7
+ /* global window */
8
+ const devicePixelRatio = (typeof window !== 'undefined' && window.devicePixelRatio) || 1;
9
+ /**
10
+ * A Deck.gl layer that renders a tile source
11
+ * Autodiscovers type of content (vector tile, bitmap, ...)
12
+ * Can render debug borders around tiles
13
+ * TODO - Change debug border color based on zoom level
14
+ */
15
+ export class TileSourceLayer extends CompositeLayer {
16
+ static layerName = 'TileSourceLayer';
17
+ static defaultProps = {
18
+ ...TileLayer.defaultProps,
19
+ showTileBorders: true
20
+ };
21
+ state = undefined;
22
+ initializeState() {
23
+ this.setState({
24
+ tileSource: null
25
+ });
26
+ }
27
+ updateState({ props, changeFlags }) {
28
+ this.setState({
29
+ tileSource: props.tileSource
30
+ });
31
+ }
32
+ renderLayers() {
33
+ const { tileSource, showTileBorders, metadata, onTilesLoad } = this.props;
34
+ const minZoom = metadata?.minZoom || 0;
35
+ const maxZoom = metadata?.maxZoom || 30;
36
+ return [
37
+ new TileLayer({
38
+ // HACK: Trigger new layer via id prop to force clear tile cache
39
+ id: String(tileSource.url),
40
+ getTileData: tileSource.getTileData,
41
+ // Assume the pmtiles file support HTTP/2, so we aren't limited by the browser to a certain number per domain.
42
+ maxRequests: 20,
43
+ pickable: true,
44
+ onViewportLoad: onTilesLoad,
45
+ autoHighlight: showTileBorders,
46
+ highlightColor: [60, 60, 60, 40],
47
+ minZoom,
48
+ maxZoom,
49
+ tileSize: 256,
50
+ // TOOD - why is this needed?
51
+ zoomOffset: devicePixelRatio === 1 ? -1 : 0,
52
+ renderSubLayers: renderSubLayers,
53
+ // Custom prop
54
+ tileSource,
55
+ showTileBorders
56
+ })
57
+ ];
58
+ }
59
+ }
60
+ function renderSubLayers(props) {
61
+ const { tileSource, showTileBorders, minZoom, maxZoom, tile: { index: { z: zoom }, bbox: { west, south, east, north } } } = props;
62
+ const layers = [];
63
+ const borderColor = zoom <= minZoom || zoom >= maxZoom ? [255, 0, 0, 255] : [0, 0, 255, 255];
64
+ switch (tileSource.mimeType) {
65
+ case 'application/vnd.mapbox-vector-tile':
66
+ layers.push(new GeoJsonLayer({
67
+ id: `${props.id}-geojson`,
68
+ data: props.data,
69
+ pickable: true,
70
+ getFillColor: [0, 190, 80, 255],
71
+ lineWidthScale: 500,
72
+ lineWidthMinPixels: 0.5
73
+ }));
74
+ break;
75
+ case 'image/png':
76
+ case 'image/jpeg':
77
+ case 'image/webp':
78
+ case 'image/avif':
79
+ layers.push(new BitmapLayer(props, {
80
+ data: null,
81
+ image: props.data,
82
+ bounds: [west, south, east, north],
83
+ pickable: true
84
+ }));
85
+ break;
86
+ default:
87
+ // eslint-disable-next-line no-console
88
+ console.error('Unknown tile mimeType', tileSource?.mimeType);
89
+ }
90
+ // Debug tile borders
91
+ if (showTileBorders) {
92
+ layers.push(new PathLayer({
93
+ id: `${props.id}-border`,
94
+ data: [
95
+ [
96
+ [west, north],
97
+ [west, south],
98
+ [east, south],
99
+ [east, north],
100
+ [west, north]
101
+ ]
102
+ ],
103
+ getPath: (d) => d,
104
+ getColor: borderColor,
105
+ widthMinPixels: 4
106
+ }));
107
+ }
108
+ return layers;
109
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deck.gl-community/layers",
3
- "version": "0.0.0",
4
- "description": "Experimental layers for deck.gl",
3
+ "version": "9.0.2",
4
+ "description": "Addon layers for deck.gl",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "layers",
@@ -10,28 +10,41 @@
10
10
  "deck.gl"
11
11
  ],
12
12
  "type": "module",
13
- "main": "dist/index.cjs",
14
- "module": "dist/index.js",
13
+ "sideEffects": false,
14
+ "types": "./dist/index.d.ts",
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.js",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "require": "./dist/index.cjs",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
15
24
  "files": [
16
25
  "dist",
17
26
  "src"
18
27
  ],
28
+ "scripts": {
29
+ "test": "vitest run",
30
+ "test-watch": "vitest"
31
+ },
19
32
  "dependencies": {
20
- "@deck.gl/core": "^8.9.28",
21
- "@deck.gl/extensions": "8.9.28",
22
- "@deck.gl/geo-layers": "^8.9.28",
23
- "@deck.gl/layers": "^8.9.28",
24
- "@deck.gl/mesh-layers": "^8.9.28",
25
- "@deck.gl/react": "^8.9.28",
26
- "@loaders.gl/core": "^4.0.0",
27
- "@loaders.gl/loader-utils": "^4.0.0"
33
+ "@deck.gl/core": "^9.0.12",
34
+ "@deck.gl/extensions": "^9.0.12",
35
+ "@deck.gl/geo-layers": "^9.0.12",
36
+ "@deck.gl/layers": "^9.0.12",
37
+ "@deck.gl/mesh-layers": "^9.0.12",
38
+ "@deck.gl/react": "^9.0.12",
39
+ "@loaders.gl/core": "^4.2.0",
40
+ "@loaders.gl/i3s": "^4.2.0",
41
+ "@loaders.gl/loader-utils": "^4.2.0",
42
+ "@loaders.gl/schema": "^4.2.0",
43
+ "@loaders.gl/tiles": "^4.2.0",
44
+ "@luma.gl/constants": "^9.0.11",
45
+ "@luma.gl/core": "^9.0.11",
46
+ "@luma.gl/engine": "^9.0.11",
47
+ "@math.gl/core": "^4.0.0"
28
48
  },
29
- "devDependencies": {
30
- "@babel/preset-flow": "^7.18.6",
31
- "@testing-library/jest-dom": "^5.16.5",
32
- "babel-jest": "^29.4.3",
33
- "eslint-plugin-jest": "^27.2.1",
34
- "jest": "^29.2.2",
35
- "jest-environment-jsdom": "^29.3.0"
36
- }
49
+ "gitHead": "646f8328d27d67d596f05c9154072051ec5cf4f0"
37
50
  }
package/src/index.ts CHANGED
@@ -1,9 +1,12 @@
1
- //
1
+ // deck.gl-community
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- export {TileSourceLayer} from './tile-source-layer';
6
- export {DataDrivenTile3DLayer} from './data-driven-tile-3d-layer/data-driven-tile-3d-layer';
5
+ export type {TileSourceLayerProps} from './tile-source-layer/tile-source-layer';
6
+ export {TileSourceLayer} from './tile-source-layer/tile-source-layer';
7
7
 
8
- export {colorizeTile} from './data-driven-tile-3d-layer/utils/colorize-tile';
9
- export {filterTile} from './data-driven-tile-3d-layer/utils/filter-tile';
8
+ export type {PathOutlineLayerProps} from './path-outline-layer/path-outline-layer';
9
+ export {PathOutlineLayer} from './path-outline-layer/path-outline-layer';
10
+
11
+ export type {PathMarkerLayerProps} from './path-marker-layer/path-marker-layer';
12
+ export {PathMarkerLayer} from './path-marker-layer/path-marker-layer';
@@ -0,0 +1,65 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {Geometry} from '@luma.gl/engine';
6
+
7
+ export class Arrow2DGeometry extends Geometry {
8
+ constructor(opts = {}) {
9
+ super(
10
+ Object.assign({}, opts, {
11
+ attributes: getArrowAttributes(opts),
12
+ topology: 'triangle-list' as const
13
+ })
14
+ );
15
+ }
16
+ }
17
+
18
+ function getArrowAttributes({length = 1, headSize = 0.2, tailWidth = 0.05, tailStart = 0.05}) {
19
+ const texCoords = [
20
+ // HEAD
21
+ 0.5,
22
+ 1.0,
23
+ 0,
24
+ 0.5 - headSize / 2,
25
+ 1.0 - headSize,
26
+ 0,
27
+ 0.5 + headSize / 2,
28
+ 1.0 - headSize,
29
+ 0,
30
+ 0.5 - tailWidth / 2,
31
+ tailStart,
32
+ 0,
33
+ 0.5 + tailWidth / 2,
34
+ 1.0 - headSize,
35
+ 0,
36
+ 0.5 + tailWidth / 2,
37
+ tailStart,
38
+ 0,
39
+ 0.5 - tailWidth / 2,
40
+ tailStart,
41
+ 0,
42
+ 0.5 - tailWidth / 2,
43
+ 1.0 - headSize,
44
+ 0,
45
+ 0.5 + tailWidth / 2,
46
+ 1.0 - headSize,
47
+ 0
48
+ ];
49
+
50
+ const normals = [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1];
51
+
52
+ // Center and scale
53
+ const positions = new Array(texCoords.length);
54
+ for (let i = 0; i < texCoords.length / 3; i++) {
55
+ const i3 = i * 3;
56
+ positions[i3 + 0] = (texCoords[i3 + 0] - 0.5) * length;
57
+ positions[i3 + 1] = (texCoords[i3 + 1] - 0.5) * length;
58
+ positions[i3 + 2] = 0;
59
+ }
60
+ return {
61
+ positions: {size: 3, value: new Float32Array(positions)},
62
+ normals: {size: 3, value: new Float32Array(normals)},
63
+ texCoords: {size: 2, value: new Float32Array(texCoords)}
64
+ };
65
+ }
@@ -0,0 +1,122 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {Vector2} from '@math.gl/core';
6
+
7
+ /** GeoJSON style position coordinate vector */
8
+ export type Position = [number, number] | [number, number, number];
9
+
10
+ /** [red, green, blue, alpha] in premultiplied alpha format */
11
+ export type Color = [number, number, number, number];
12
+
13
+ export interface PathMarker {
14
+ position: Position;
15
+ angle: number;
16
+ color: Color;
17
+ object: unknown;
18
+ }
19
+
20
+ function getLineLength(vPoints) {
21
+ // calculate total length
22
+ let lineLength = 0;
23
+ for (let i = 0; i < vPoints.length - 1; i++) {
24
+ lineLength += vPoints[i].distance(vPoints[i + 1]);
25
+ }
26
+ return lineLength;
27
+ }
28
+
29
+ const DEFAULT_COLOR = [0, 0, 0, 255];
30
+ const DEFAULT_DIRECTION = {forward: true, backward: false};
31
+
32
+ export function createPathMarkers({
33
+ data,
34
+ getPath = (x, context) => x.path,
35
+ getDirection = (x) => x.direction,
36
+ getColor = (x) => DEFAULT_COLOR,
37
+ getMarkerPercentages = (x, info) => [0.5],
38
+ projectFlat
39
+ }): PathMarker[] {
40
+ const markers: PathMarker[] = [];
41
+
42
+ for (const object of data) {
43
+ const path = getPath(object, null);
44
+ const direction = getDirection(object) || DEFAULT_DIRECTION;
45
+ const color = getColor(object);
46
+
47
+ const vPoints = path.map((p) => new Vector2(p));
48
+ const vPointsReverse = vPoints.slice(0).reverse();
49
+
50
+ // calculate total length
51
+ const lineLength = getLineLength(vPoints);
52
+
53
+ // Ask for where to put markers
54
+ const percentages = getMarkerPercentages(object, {lineLength});
55
+
56
+ // Create the markers
57
+ for (const percentage of percentages) {
58
+ if (direction.forward) {
59
+ const marker = createMarkerAlongPath({
60
+ path: vPoints,
61
+ percentage,
62
+ lineLength,
63
+ color,
64
+ object,
65
+ projectFlat
66
+ });
67
+ markers.push(marker);
68
+ }
69
+
70
+ if (direction.backward) {
71
+ const marker = createMarkerAlongPath({
72
+ path: vPointsReverse,
73
+ percentage,
74
+ lineLength,
75
+ color,
76
+ object,
77
+ projectFlat
78
+ });
79
+ markers.push(marker);
80
+ }
81
+ }
82
+ }
83
+
84
+ return markers;
85
+ }
86
+
87
+ function createMarkerAlongPath({
88
+ path,
89
+ percentage,
90
+ lineLength,
91
+ color,
92
+ object,
93
+ projectFlat
94
+ }): PathMarker {
95
+ const distanceAlong = lineLength * percentage;
96
+ let currentDistance = 0;
97
+ let previousDistance = 0;
98
+ let i = 0;
99
+ for (i = 0; i < path.length - 1; i++) {
100
+ currentDistance += path[i].distance(path[i + 1]);
101
+ if (currentDistance > distanceAlong) {
102
+ break;
103
+ }
104
+ previousDistance = currentDistance;
105
+ }
106
+
107
+ // If reached the end of the loop without exiting early,
108
+ // undo the final increment to avoid a null-pointer exception
109
+ if (i === path.length - 1) {
110
+ i -= 1;
111
+ }
112
+
113
+ const vDirection = path[i + 1].clone().subtract(path[i]).normalize();
114
+ const along = distanceAlong - previousDistance;
115
+ const vCenter = vDirection.clone().multiply(new Vector2(along, along)).add(path[i]);
116
+
117
+ const vDirection2 = new Vector2(projectFlat(path[i + 1])).subtract(projectFlat(path[i]));
118
+
119
+ const angle = (vDirection2.verticalAngle() * 180) / Math.PI;
120
+
121
+ return {position: [vCenter.x, vCenter.y, 0], angle, color, object};
122
+ }