@deck.gl-community/layers 9.0.0-alpha.1 → 9.0.3
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/index.cjs +605 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -5
- package/dist/path-marker-layer/arrow-2d-geometry.d.ts +5 -0
- package/dist/path-marker-layer/arrow-2d-geometry.d.ts.map +1 -0
- package/dist/path-marker-layer/arrow-2d-geometry.js +58 -0
- package/dist/path-marker-layer/create-path-markers.d.ts +19 -0
- package/dist/path-marker-layer/create-path-markers.d.ts.map +1 -0
- package/dist/path-marker-layer/create-path-markers.js +78 -0
- package/dist/path-marker-layer/path-marker-layer.d.ts +41 -0
- package/dist/path-marker-layer/path-marker-layer.d.ts.map +1 -0
- package/dist/path-marker-layer/path-marker-layer.js +124 -0
- package/dist/path-marker-layer/polyline.d.ts +19 -0
- package/dist/path-marker-layer/polyline.d.ts.map +1 -0
- package/dist/path-marker-layer/polyline.js +40 -0
- package/dist/path-outline-layer/outline.d.ts +9 -0
- package/dist/path-outline-layer/outline.d.ts.map +1 -0
- package/dist/path-outline-layer/outline.js +100 -0
- package/dist/path-outline-layer/path-outline-layer.d.ts +35 -0
- package/dist/path-outline-layer/path-outline-layer.d.ts.map +1 -0
- package/dist/path-outline-layer/path-outline-layer.js +116 -0
- package/dist/tile-source-layer/tile-source-layer.d.ts +44 -0
- package/dist/tile-source-layer/tile-source-layer.d.ts.map +1 -0
- package/dist/tile-source-layer/tile-source-layer.js +109 -0
- package/package.json +27 -13
- package/src/index.ts +7 -4
- package/src/path-marker-layer/arrow-2d-geometry.ts +65 -0
- package/src/path-marker-layer/create-path-markers.ts +122 -0
- package/src/path-marker-layer/path-marker-layer.ts +183 -0
- package/src/path-marker-layer/polyline.ts +44 -0
- package/src/path-outline-layer/outline.ts +107 -0
- package/src/path-outline-layer/path-outline-layer.ts +159 -0
- package/src/{tile-source-layer.ts → tile-source-layer/tile-source-layer.ts} +30 -22
- package/dist/data-driven-tile-3d-layer/data-driven-tile-3d-layer.js +0 -193
- package/dist/data-driven-tile-3d-layer/data-driven-tile-3d-layer.js.map +0 -1
- package/dist/data-driven-tile-3d-layer/utils/colorize-tile.js +0 -31
- package/dist/data-driven-tile-3d-layer/utils/colorize-tile.js.map +0 -1
- package/dist/data-driven-tile-3d-layer/utils/filter-tile.js +0 -146
- package/dist/data-driven-tile-3d-layer/utils/filter-tile.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/tile-source-layer.js +0 -112
- package/dist/tile-source-layer.js.map +0 -1
- package/src/data-driven-tile-3d-layer/data-driven-tile-3d-layer.ts +0 -261
- package/src/data-driven-tile-3d-layer/utils/colorize-tile.ts +0 -53
- package/src/data-driven-tile-3d-layer/utils/filter-tile.ts +0 -179
|
@@ -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.js";
|
|
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: 5121,
|
|
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: 32776
|
|
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,44 @@
|
|
|
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
|
+
}
|
|
44
|
+
//# sourceMappingURL=tile-source-layer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tile-source-layer.d.ts","sourceRoot":"","sources":["../../src/tile-source-layer/tile-source-layer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,cAAc,EAAQ,MAAM,eAAe,CAAC;AACpD,OAAO,EAAC,SAAS,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,0BAA0B,CAAC;AAKzD,MAAM,MAAM,oBAAoB,GAAG,cAAc,GAAG;IAClD,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,cAAc,CAAC,oBAAoB,CAAC;IACvE,MAAM,CAAC,SAAS,SAAqB;IACrC,MAAM,CAAC,YAAY;;MAGjB;IAEF,KAAK,EAAE;QACL,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;KACpC,CAAc;IAEf,eAAe;IAMf,WAAW,CAAC,EAAC,KAAK,EAAE,WAAW,EAAC;;;KAAA;IAMhC,YAAY;;;;;;;;;;;;yBAsB8B,GAAG;;;;CAQ9C"}
|
|
@@ -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": "9.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "9.0.3",
|
|
4
|
+
"description": "Addon layers for deck.gl",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"layers",
|
|
@@ -11,26 +11,40 @@
|
|
|
11
11
|
],
|
|
12
12
|
"type": "module",
|
|
13
13
|
"sideEffects": false,
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
14
15
|
"main": "./dist/index.cjs",
|
|
15
16
|
"module": "./dist/index.js",
|
|
16
17
|
"exports": {
|
|
17
18
|
".": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"require": "./dist/index.cjs",
|
|
21
|
+
"import": "./dist/index.js"
|
|
20
22
|
}
|
|
21
23
|
},
|
|
22
24
|
"files": [
|
|
23
25
|
"dist",
|
|
24
26
|
"src"
|
|
25
27
|
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test-watch": "vitest"
|
|
31
|
+
},
|
|
26
32
|
"dependencies": {
|
|
27
|
-
"@deck.gl/core": "^9.0.
|
|
28
|
-
"@deck.gl/extensions": "9.0.
|
|
29
|
-
"@deck.gl/geo-layers": "^9.0.
|
|
30
|
-
"@deck.gl/layers": "^9.0.
|
|
31
|
-
"@deck.gl/mesh-layers": "^9.0.
|
|
32
|
-
"@deck.gl/react": "^9.0.
|
|
33
|
-
"@loaders.gl/core": "^4.
|
|
34
|
-
"@loaders.gl/
|
|
35
|
-
|
|
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"
|
|
48
|
+
},
|
|
49
|
+
"gitHead": "8955b0da47771f3524b65360243ee246abeb3660"
|
|
36
50
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
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 {
|
|
9
|
-
export {
|
|
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
|
+
}
|