@deck.gl/geo-layers 8.8.0-alpha.2 → 8.8.0-alpha.5
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/dist.dev.js +2286 -2542
- package/dist/es5/geo-cell-layer/GeoCellLayer.js +3 -3
- package/dist/es5/geo-cell-layer/GeoCellLayer.js.map +1 -1
- package/dist/es5/index.js +8 -0
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/mvt-layer/coordinate-transform.js.map +1 -1
- package/dist/es5/mvt-layer/find-index-binary.js +7 -5
- package/dist/es5/mvt-layer/find-index-binary.js.map +1 -1
- package/dist/es5/mvt-layer/mvt-layer.js +45 -32
- package/dist/es5/mvt-layer/mvt-layer.js.map +1 -1
- package/dist/es5/quadkey-layer/quadkey-layer.js +4 -2
- package/dist/es5/quadkey-layer/quadkey-layer.js.map +1 -1
- package/dist/es5/quadkey-layer/quadkey-utils.js.map +1 -1
- package/dist/es5/tile-layer/tile-2d-header.js.map +1 -1
- package/dist/es5/tile-layer/tile-layer.js +21 -25
- package/dist/es5/tile-layer/tile-layer.js.map +1 -1
- package/dist/es5/tile-layer/tileset-2d.js +1 -6
- package/dist/es5/tile-layer/tileset-2d.js.map +1 -1
- package/dist/es5/tile-layer/utils.js +5 -0
- package/dist/es5/tile-layer/utils.js.map +1 -1
- package/dist/esm/geo-cell-layer/GeoCellLayer.js +6 -3
- package/dist/esm/geo-cell-layer/GeoCellLayer.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mvt-layer/coordinate-transform.js.map +1 -1
- package/dist/esm/mvt-layer/find-index-binary.js +1 -1
- package/dist/esm/mvt-layer/find-index-binary.js.map +1 -1
- package/dist/esm/mvt-layer/mvt-layer.js +47 -36
- package/dist/esm/mvt-layer/mvt-layer.js.map +1 -1
- package/dist/esm/quadkey-layer/quadkey-layer.js +5 -2
- package/dist/esm/quadkey-layer/quadkey-layer.js.map +1 -1
- package/dist/esm/quadkey-layer/quadkey-utils.js.map +1 -1
- package/dist/esm/tile-layer/tile-2d-header.js.map +1 -1
- package/dist/esm/tile-layer/tile-layer.js +5 -10
- package/dist/esm/tile-layer/tile-layer.js.map +1 -1
- package/dist/esm/tile-layer/tileset-2d.js +1 -5
- package/dist/esm/tile-layer/tileset-2d.js.map +1 -1
- package/dist/esm/tile-layer/utils.js +3 -0
- package/dist/esm/tile-layer/utils.js.map +1 -1
- package/dist.min.js +2 -2
- package/package.json +6 -3
- package/src/geo-cell-layer/{GeoCellLayer.js → GeoCellLayer.ts} +14 -10
- package/src/index.ts +4 -1
- package/src/mvt-layer/{coordinate-transform.js → coordinate-transform.ts} +10 -8
- package/src/mvt-layer/{find-index-binary.js → find-index-binary.ts} +41 -10
- package/src/mvt-layer/{mvt-layer.js → mvt-layer.ts} +145 -59
- package/src/quadkey-layer/quadkey-layer.ts +39 -0
- package/src/quadkey-layer/{quadkey-utils.js → quadkey-utils.ts} +2 -2
- package/src/tile-layer/tile-2d-header.ts +15 -14
- package/src/tile-layer/tile-layer.ts +64 -62
- package/src/tile-layer/tileset-2d.ts +13 -13
- package/src/tile-layer/types.ts +5 -1
- package/src/tile-layer/utils.ts +17 -3
- package/src/quadkey-layer/quadkey-layer.js +0 -22
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@deck.gl/geo-layers",
|
|
3
3
|
"description": "deck.gl layers supporting geospatial use cases and GIS formats",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "8.8.0-alpha.
|
|
5
|
+
"version": "8.8.0-alpha.5",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
23
|
"src",
|
|
24
|
+
"typed",
|
|
24
25
|
"dist.min.js"
|
|
25
26
|
],
|
|
26
27
|
"sideEffects": false,
|
|
@@ -33,12 +34,14 @@
|
|
|
33
34
|
"@loaders.gl/gis": "^3.2.0-alpha.4",
|
|
34
35
|
"@loaders.gl/loader-utils": "^3.2.0-alpha.4",
|
|
35
36
|
"@loaders.gl/mvt": "^3.2.0-alpha.4",
|
|
37
|
+
"@loaders.gl/schema": "^3.2.0-alpha.4",
|
|
36
38
|
"@loaders.gl/terrain": "^3.2.0-alpha.4",
|
|
37
39
|
"@loaders.gl/tiles": "^3.2.0-alpha.4",
|
|
38
|
-
"@luma.gl/experimental": "^8.5.
|
|
40
|
+
"@luma.gl/experimental": "^8.5.13",
|
|
39
41
|
"@math.gl/core": "3.6.0-alpha.5",
|
|
40
42
|
"@math.gl/culling": "3.6.0-alpha.5",
|
|
41
43
|
"@math.gl/web-mercator": "3.6.0-alpha.5",
|
|
44
|
+
"@types/geojson": "^7946.0.8",
|
|
42
45
|
"h3-js": "^3.6.0",
|
|
43
46
|
"long": "^3.2.0"
|
|
44
47
|
},
|
|
@@ -49,5 +52,5 @@
|
|
|
49
52
|
"@deck.gl/mesh-layers": "^8.0.0",
|
|
50
53
|
"@loaders.gl/core": "^3.0.0"
|
|
51
54
|
},
|
|
52
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "a5e210f62321ab78b7cacbcd0614e0ffcdf6bca7"
|
|
53
56
|
}
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import {CompositeLayer} from '@deck.gl/core';
|
|
2
|
-
import {PolygonLayer} from '@deck.gl/layers';
|
|
1
|
+
import {CompositeLayer, Layer, LayersList} from '@deck.gl/core';
|
|
2
|
+
import {PolygonLayer, PolygonLayerProps} from '@deck.gl/layers';
|
|
3
3
|
|
|
4
4
|
const defaultProps = {
|
|
5
5
|
...PolygonLayer.defaultProps
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export type GeoCellLayerProps<DataT = any> = PolygonLayerProps<DataT>;
|
|
9
|
+
|
|
10
|
+
export default class GeoCellLayer<DataT = any, ExtraProps = {}> extends CompositeLayer<
|
|
11
|
+
Required<GeoCellLayerProps<DataT>> & ExtraProps
|
|
12
|
+
> {
|
|
13
|
+
static layerName = 'GeoCellLayer';
|
|
14
|
+
static defaultProps = defaultProps;
|
|
15
|
+
|
|
16
|
+
/** Implement to generate props to create geometry. */
|
|
17
|
+
indexToBounds(): Partial<GeoCellLayer['props']> | null {
|
|
11
18
|
return null;
|
|
12
19
|
}
|
|
13
20
|
|
|
14
|
-
renderLayers() {
|
|
21
|
+
renderLayers(): Layer | null | LayersList {
|
|
15
22
|
// Rendering props underlying layer
|
|
16
23
|
const {
|
|
17
24
|
elevationScale,
|
|
@@ -64,7 +71,7 @@ export default class GeoCellLayer extends CompositeLayer {
|
|
|
64
71
|
},
|
|
65
72
|
this.getSubLayerProps({
|
|
66
73
|
id: 'cell',
|
|
67
|
-
updateTriggers: {
|
|
74
|
+
updateTriggers: updateTriggers && {
|
|
68
75
|
getElevation: updateTriggers.getElevation,
|
|
69
76
|
getFillColor: updateTriggers.getFillColor,
|
|
70
77
|
getLineColor: updateTriggers.getLineColor,
|
|
@@ -75,6 +82,3 @@ export default class GeoCellLayer extends CompositeLayer {
|
|
|
75
82
|
);
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
|
-
|
|
79
|
-
GeoCellLayer.layerName = 'GeoCellLayer';
|
|
80
|
-
GeoCellLayer.defaultProps = defaultProps;
|
package/src/index.ts
CHANGED
|
@@ -32,7 +32,10 @@ export {default as MVTLayer} from './mvt-layer/mvt-layer';
|
|
|
32
32
|
|
|
33
33
|
export {getURLFromTemplate as _getURLFromTemplate} from './tile-layer/utils';
|
|
34
34
|
export {default as _Tileset2D} from './tile-layer/tileset-2d';
|
|
35
|
+
export {default as _Tile2DHeader} from './tile-layer/tile-2d-header';
|
|
35
36
|
|
|
36
37
|
// Types
|
|
37
|
-
|
|
38
38
|
export type {TileLayerProps} from './tile-layer/tile-layer';
|
|
39
|
+
export type {QuadkeyLayerProps} from './quadkey-layer/quadkey-layer';
|
|
40
|
+
export type {TileLoadProps as _TileLoadProps} from './tile-layer/types';
|
|
41
|
+
export type {MVTLayerProps} from './mvt-layer/mvt-layer';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import {Viewport} from '@deck.gl/core';
|
|
1
2
|
import {lerp} from '@math.gl/core';
|
|
3
|
+
import {GeoBoundingBox} from '../tile-layer/types';
|
|
2
4
|
|
|
3
5
|
const availableTransformations = {
|
|
4
6
|
Point,
|
|
@@ -9,38 +11,38 @@ const availableTransformations = {
|
|
|
9
11
|
MultiPolygon
|
|
10
12
|
};
|
|
11
13
|
|
|
12
|
-
function Point([pointX, pointY], [nw, se], viewport) {
|
|
14
|
+
function Point([pointX, pointY]: [number, number], [nw, se]: number[][], viewport: Viewport) {
|
|
13
15
|
const x = lerp(nw[0], se[0], pointX);
|
|
14
16
|
const y = lerp(nw[1], se[1], pointY);
|
|
15
17
|
|
|
16
18
|
return viewport.unprojectFlat([x, y]);
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
function getPoints(geometry, bbox, viewport) {
|
|
21
|
+
function getPoints(geometry, bbox: number[][], viewport: Viewport) {
|
|
20
22
|
return geometry.map(g => Point(g, bbox, viewport));
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
function MultiPoint(multiPoint, bbox, viewport) {
|
|
25
|
+
function MultiPoint(multiPoint, bbox: number[][], viewport: Viewport) {
|
|
24
26
|
return getPoints(multiPoint, bbox, viewport);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
function LineString(line, bbox, viewport) {
|
|
29
|
+
function LineString(line, bbox: number[][], viewport: Viewport) {
|
|
28
30
|
return getPoints(line, bbox, viewport);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
function MultiLineString(multiLineString, bbox, viewport) {
|
|
33
|
+
function MultiLineString(multiLineString, bbox: number[][], viewport: Viewport) {
|
|
32
34
|
return multiLineString.map(lineString => LineString(lineString, bbox, viewport));
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
function Polygon(polygon, bbox, viewport) {
|
|
37
|
+
function Polygon(polygon, bbox: number[][], viewport: Viewport) {
|
|
36
38
|
return polygon.map(polygonRing => getPoints(polygonRing, bbox, viewport));
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
function MultiPolygon(multiPolygon, bbox, viewport) {
|
|
41
|
+
function MultiPolygon(multiPolygon, bbox: number[][], viewport: Viewport) {
|
|
40
42
|
return multiPolygon.map(polygon => Polygon(polygon, bbox, viewport));
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
export function transform(geometry, bbox, viewport) {
|
|
45
|
+
export function transform(geometry, bbox: GeoBoundingBox, viewport: Viewport) {
|
|
44
46
|
const nw = viewport.projectFlat([bbox.west, bbox.north]);
|
|
45
47
|
const se = viewport.projectFlat([bbox.east, bbox.south]);
|
|
46
48
|
const projectedBbox = [nw, se];
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BinaryFeatures,
|
|
3
|
+
BinaryLineFeatures,
|
|
4
|
+
BinaryPointFeatures,
|
|
5
|
+
BinaryPolygonFeatures
|
|
6
|
+
} from '@loaders.gl/schema';
|
|
7
|
+
|
|
8
|
+
type FeatureTypes = BinaryPointFeatures | BinaryLineFeatures | BinaryPolygonFeatures;
|
|
9
|
+
|
|
1
10
|
const GEOM_TYPES = ['points', 'lines', 'polygons'];
|
|
2
11
|
/**
|
|
3
12
|
* Return the index of feature (numericProps or featureIds) for given feature id
|
|
@@ -8,7 +17,12 @@ const GEOM_TYPES = ['points', 'lines', 'polygons'];
|
|
|
8
17
|
* @param {Number|String} featureId - feature id to find
|
|
9
18
|
* @param {String} layerName - the layer to search in
|
|
10
19
|
*/
|
|
11
|
-
export default function findIndexBinary(
|
|
20
|
+
export default function findIndexBinary(
|
|
21
|
+
data: BinaryFeatures,
|
|
22
|
+
uniqueIdProperty: string,
|
|
23
|
+
featureId: string | number,
|
|
24
|
+
layerName: string
|
|
25
|
+
): number {
|
|
12
26
|
for (const gt of GEOM_TYPES) {
|
|
13
27
|
const index = data[gt] && findIndexByType(data[gt], uniqueIdProperty, featureId, layerName);
|
|
14
28
|
if (index >= 0) {
|
|
@@ -19,7 +33,12 @@ export default function findIndexBinary(data, uniqueIdProperty, featureId, layer
|
|
|
19
33
|
return -1;
|
|
20
34
|
}
|
|
21
35
|
|
|
22
|
-
function findIndexByType(
|
|
36
|
+
function findIndexByType(
|
|
37
|
+
geomData: FeatureTypes,
|
|
38
|
+
uniqueIdProperty: string,
|
|
39
|
+
featureId: string | number,
|
|
40
|
+
layerName: string
|
|
41
|
+
): number {
|
|
23
42
|
const featureIds = geomData.featureIds.value;
|
|
24
43
|
|
|
25
44
|
if (!featureIds.length) {
|
|
@@ -53,10 +72,10 @@ function findIndexByType(geomData, uniqueIdProperty, featureId, layerName) {
|
|
|
53
72
|
startFeatureIndex,
|
|
54
73
|
endFeatureIndex
|
|
55
74
|
);
|
|
56
|
-
} else {
|
|
75
|
+
} else if (geomData.fields) {
|
|
57
76
|
featureIndex = findIndex(
|
|
58
77
|
geomData.fields,
|
|
59
|
-
elem => elem.id === featureId,
|
|
78
|
+
(elem: any) => elem.id === featureId,
|
|
60
79
|
startFeatureIndex,
|
|
61
80
|
endFeatureIndex
|
|
62
81
|
);
|
|
@@ -64,15 +83,22 @@ function findIndexByType(geomData, uniqueIdProperty, featureId, layerName) {
|
|
|
64
83
|
return featureIndex >= 0 ? getGlobalFeatureId(geomData, featureIndex) : -1;
|
|
65
84
|
}
|
|
66
85
|
|
|
86
|
+
type LayerRange = [firstFeatureIndex: number, lastFeatureIndex: number];
|
|
87
|
+
|
|
67
88
|
// Returns [firstFeatureIndex, lastFeatureIndex]
|
|
68
89
|
// MVTLoader parses tiles layer-by-layer, so each layer is a continuous range
|
|
69
|
-
function getLayerRange(
|
|
90
|
+
function getLayerRange(
|
|
91
|
+
geomData: FeatureTypes & {
|
|
92
|
+
__layers?: Record<string, LayerRange>;
|
|
93
|
+
},
|
|
94
|
+
layerName: string
|
|
95
|
+
): LayerRange | undefined {
|
|
70
96
|
if (!geomData.__layers) {
|
|
71
97
|
// Cache a map from properties.layerName to index ranges
|
|
72
|
-
const layerNames = {};
|
|
98
|
+
const layerNames: Record<string, LayerRange> = {};
|
|
73
99
|
const {properties} = geomData;
|
|
74
100
|
for (let i = 0; i < properties.length; i++) {
|
|
75
|
-
const {layerName: key} = properties[i]
|
|
101
|
+
const {layerName: key} = properties[i] as Record<string, any>;
|
|
76
102
|
if (!key) {
|
|
77
103
|
// ignore
|
|
78
104
|
} else if (layerNames[key]) {
|
|
@@ -87,10 +113,10 @@ function getLayerRange(geomData, layerName) {
|
|
|
87
113
|
}
|
|
88
114
|
|
|
89
115
|
// Returns global feature id
|
|
90
|
-
function getGlobalFeatureId(geomData, featureIndex) {
|
|
116
|
+
function getGlobalFeatureId(geomData, featureIndex: number) {
|
|
91
117
|
if (!geomData.__ids) {
|
|
92
118
|
// Cache a map from featureId to globalFeatureId
|
|
93
|
-
const result = [];
|
|
119
|
+
const result: string[] = [];
|
|
94
120
|
const featureIds = geomData.featureIds.value;
|
|
95
121
|
const globalFeatureIds = geomData.globalFeatureIds.value;
|
|
96
122
|
for (let i = 0; i < featureIds.length; i++) {
|
|
@@ -102,7 +128,12 @@ function getGlobalFeatureId(geomData, featureIndex) {
|
|
|
102
128
|
}
|
|
103
129
|
|
|
104
130
|
// Like array.findIndex, but only search within a range
|
|
105
|
-
function findIndex(
|
|
131
|
+
function findIndex<T>(
|
|
132
|
+
array: T[],
|
|
133
|
+
predicate: (v: T, index: number) => boolean,
|
|
134
|
+
startIndex: number,
|
|
135
|
+
endIndex: number
|
|
136
|
+
): number {
|
|
106
137
|
for (let i = startIndex; i < endIndex; i++) {
|
|
107
138
|
if (predicate(array[i], i)) {
|
|
108
139
|
return i;
|
|
@@ -1,17 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Layer,
|
|
3
|
+
LayersList,
|
|
4
|
+
log,
|
|
5
|
+
PickingInfo,
|
|
6
|
+
UpdateParameters,
|
|
7
|
+
GetPickingInfoParams,
|
|
8
|
+
Viewport,
|
|
9
|
+
COORDINATE_SYSTEM
|
|
10
|
+
} from '@deck.gl/core';
|
|
11
|
+
import {GeoJsonLayer, GeoJsonLayerProps} from '@deck.gl/layers';
|
|
2
12
|
import {Matrix4} from '@math.gl/core';
|
|
3
13
|
import {MVTWorkerLoader} from '@loaders.gl/mvt';
|
|
4
14
|
import {binaryToGeojson} from '@loaders.gl/gis';
|
|
5
|
-
import {COORDINATE_SYSTEM} from '@deck.gl/core';
|
|
6
15
|
import {ClipExtension} from '@deck.gl/extensions';
|
|
7
16
|
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
17
|
+
import type {Loader} from '@loaders.gl/loader-utils';
|
|
18
|
+
import type {BinaryFeatures} from '@loaders.gl/schema';
|
|
19
|
+
import type {Feature} from 'geojson';
|
|
20
|
+
|
|
21
|
+
import TileLayer, {TiledPickingInfo, TileLayerProps} from '../tile-layer/tile-layer';
|
|
22
|
+
import Tileset2D, {Tileset2DProps} from '../tile-layer/tileset-2d';
|
|
23
|
+
import {getURLFromTemplate, isGeoBoundingBox, isURLTemplate} from '../tile-layer/utils';
|
|
24
|
+
import {GeoBoundingBox, TileLoadProps} from '../tile-layer/types';
|
|
25
|
+
import Tile2DHeader from '../tile-layer/tile-2d-header';
|
|
10
26
|
import {transform} from './coordinate-transform';
|
|
11
27
|
import findIndexBinary from './find-index-binary';
|
|
12
28
|
|
|
13
|
-
import {GeoJsonLayer} from '@deck.gl/layers';
|
|
14
|
-
|
|
15
29
|
const WORLD_SIZE = 512;
|
|
16
30
|
|
|
17
31
|
const defaultProps = {
|
|
@@ -22,8 +36,61 @@ const defaultProps = {
|
|
|
22
36
|
binary: true
|
|
23
37
|
};
|
|
24
38
|
|
|
25
|
-
export
|
|
26
|
-
|
|
39
|
+
export type TileJson = {
|
|
40
|
+
tilejson: string;
|
|
41
|
+
tiles: string[];
|
|
42
|
+
// eslint-disable-next-line camelcase
|
|
43
|
+
vector_layers: any[];
|
|
44
|
+
attribution?: string;
|
|
45
|
+
scheme?: string;
|
|
46
|
+
maxzoom?: number;
|
|
47
|
+
minzoom?: number;
|
|
48
|
+
version?: string;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type ParsedMvtTile = Feature[] | BinaryFeatures;
|
|
52
|
+
|
|
53
|
+
/** All props supported by the MVTLayer */
|
|
54
|
+
export type MVTLayerProps<DataT extends Feature = Feature> = _MVTLayerProps &
|
|
55
|
+
GeoJsonLayerProps<DataT> &
|
|
56
|
+
TileLayerProps<ParsedMvtTile>;
|
|
57
|
+
|
|
58
|
+
/** Props added by the MVTLayer */
|
|
59
|
+
export type _MVTLayerProps = {
|
|
60
|
+
/** Called if `data` is a TileJSON URL when it is successfully fetched. */
|
|
61
|
+
onDataLoad?: ((tilejson: TileJson | null) => void) | null;
|
|
62
|
+
|
|
63
|
+
/** Needed for highlighting a feature split across two or more tiles. */
|
|
64
|
+
uniqueIdProperty?: string;
|
|
65
|
+
|
|
66
|
+
/** A feature with ID corresponding to the supplied value will be highlighted. */
|
|
67
|
+
highlightedFeatureId?: string | null;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Use tile data in binary format.
|
|
71
|
+
*
|
|
72
|
+
* @default true
|
|
73
|
+
*/
|
|
74
|
+
binary?: boolean;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Loaders used to transform tiles into `data` property passed to `renderSubLayers`.
|
|
78
|
+
*
|
|
79
|
+
* @default [MVTWorkerLoader] from `@loaders.gl/mvt`
|
|
80
|
+
*/
|
|
81
|
+
loaders?: Loader[];
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
type ContentWGS84Cache = {_contentWGS84?: Feature[]};
|
|
85
|
+
|
|
86
|
+
export default class MVTLayer<DataT extends Feature = Feature, ExtraProps = {}> extends TileLayer<
|
|
87
|
+
ParsedMvtTile,
|
|
88
|
+
Required<_MVTLayerProps> & ExtraProps
|
|
89
|
+
> {
|
|
90
|
+
static layerName = 'MVTLayer';
|
|
91
|
+
static defaultProps = defaultProps;
|
|
92
|
+
|
|
93
|
+
initializeState(): void {
|
|
27
94
|
super.initializeState();
|
|
28
95
|
// GlobeView doesn't work well with binary data
|
|
29
96
|
const binary = this.context.viewport.resolution !== undefined ? false : this.props.binary;
|
|
@@ -34,16 +101,17 @@ export default class MVTLayer extends TileLayer {
|
|
|
34
101
|
});
|
|
35
102
|
}
|
|
36
103
|
|
|
37
|
-
get isLoaded() {
|
|
38
|
-
return this.state.data && this.state.tileset && super.isLoaded;
|
|
104
|
+
get isLoaded(): boolean {
|
|
105
|
+
return this.state && this.state.data && this.state.tileset && super.isLoaded;
|
|
39
106
|
}
|
|
40
107
|
|
|
41
|
-
updateState({props, oldProps, context, changeFlags}) {
|
|
108
|
+
updateState({props, oldProps, context, changeFlags}: UpdateParameters<this>) {
|
|
42
109
|
if (changeFlags.dataChanged) {
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
43
111
|
this._updateTileData();
|
|
44
112
|
}
|
|
45
113
|
|
|
46
|
-
if (this.state
|
|
114
|
+
if (this.state?.data) {
|
|
47
115
|
super.updateState({props, oldProps, context, changeFlags});
|
|
48
116
|
this._setWGS84PropertyForTiles();
|
|
49
117
|
}
|
|
@@ -54,22 +122,22 @@ export default class MVTLayer extends TileLayer {
|
|
|
54
122
|
}
|
|
55
123
|
|
|
56
124
|
/* eslint-disable complexity */
|
|
57
|
-
async _updateTileData() {
|
|
58
|
-
let
|
|
59
|
-
let tileJSON = null;
|
|
125
|
+
private async _updateTileData(): Promise<void> {
|
|
126
|
+
let data: any = this.props.data;
|
|
127
|
+
let tileJSON: any = null;
|
|
60
128
|
|
|
61
129
|
if (typeof data === 'string' && !isURLTemplate(data)) {
|
|
62
130
|
const {onDataLoad, fetch} = this.props;
|
|
63
131
|
this.setState({data: null, tileJSON: null});
|
|
64
132
|
try {
|
|
65
133
|
tileJSON = await fetch(data, {propName: 'data', layer: this, loaders: []});
|
|
66
|
-
} catch (error) {
|
|
134
|
+
} catch (error: any) {
|
|
67
135
|
this.raiseError(error, 'loading TileJSON');
|
|
68
136
|
data = null;
|
|
69
137
|
}
|
|
70
138
|
|
|
71
139
|
if (onDataLoad) {
|
|
72
|
-
onDataLoad(tileJSON);
|
|
140
|
+
onDataLoad(tileJSON, {propName: 'data', layer: this});
|
|
73
141
|
}
|
|
74
142
|
} else if (data.tilejson) {
|
|
75
143
|
tileJSON = data;
|
|
@@ -82,20 +150,21 @@ export default class MVTLayer extends TileLayer {
|
|
|
82
150
|
this.setState({data, tileJSON});
|
|
83
151
|
}
|
|
84
152
|
|
|
85
|
-
_getTilesetOptions(
|
|
86
|
-
const opts = super._getTilesetOptions(
|
|
87
|
-
const
|
|
153
|
+
_getTilesetOptions(): Tileset2DProps {
|
|
154
|
+
const opts = super._getTilesetOptions();
|
|
155
|
+
const tileJSON: TileJson | null | undefined = this.state.tileJSON;
|
|
156
|
+
const {minZoom, maxZoom} = this.props;
|
|
88
157
|
|
|
89
158
|
if (tileJSON) {
|
|
90
|
-
if (Number.isFinite(tileJSON.minzoom) && tileJSON.minzoom >
|
|
91
|
-
opts.minZoom = tileJSON.minzoom;
|
|
159
|
+
if (Number.isFinite(tileJSON.minzoom) && (tileJSON.minzoom as number) > (minZoom as number)) {
|
|
160
|
+
opts.minZoom = tileJSON.minzoom as number;
|
|
92
161
|
}
|
|
93
162
|
|
|
94
163
|
if (
|
|
95
164
|
Number.isFinite(tileJSON.maxzoom) &&
|
|
96
|
-
(!Number.isFinite(
|
|
165
|
+
(!Number.isFinite(maxZoom) || (tileJSON.maxzoom as number) < (maxZoom as number))
|
|
97
166
|
) {
|
|
98
|
-
opts.maxZoom = tileJSON.maxzoom;
|
|
167
|
+
opts.maxZoom = tileJSON.maxzoom as number;
|
|
99
168
|
}
|
|
100
169
|
}
|
|
101
170
|
return opts;
|
|
@@ -103,20 +172,21 @@ export default class MVTLayer extends TileLayer {
|
|
|
103
172
|
|
|
104
173
|
/* eslint-disable complexity */
|
|
105
174
|
|
|
106
|
-
renderLayers() {
|
|
107
|
-
if (!this.state
|
|
175
|
+
renderLayers(): Layer | null | LayersList {
|
|
176
|
+
if (!this.state?.data) return null;
|
|
108
177
|
return super.renderLayers();
|
|
109
178
|
}
|
|
110
179
|
|
|
111
|
-
getTileData(
|
|
112
|
-
const
|
|
180
|
+
getTileData(loadProps: TileLoadProps): Promise<ParsedMvtTile> {
|
|
181
|
+
const {data, binary} = this.state;
|
|
182
|
+
const {index, signal} = loadProps;
|
|
183
|
+
|
|
184
|
+
const url = getURLFromTemplate(data, loadProps);
|
|
113
185
|
if (!url) {
|
|
114
186
|
return Promise.reject('Invalid URL');
|
|
115
187
|
}
|
|
116
188
|
let loadOptions = this.getLoadOptions();
|
|
117
|
-
const {binary} = this.state;
|
|
118
189
|
const {fetch} = this.props;
|
|
119
|
-
const {signal, index} = tile;
|
|
120
190
|
loadOptions = {
|
|
121
191
|
...loadOptions,
|
|
122
192
|
mimeType: 'application/x-protobuf',
|
|
@@ -134,7 +204,14 @@ export default class MVTLayer extends TileLayer {
|
|
|
134
204
|
return fetch(url, {propName: 'data', layer: this, loadOptions, signal});
|
|
135
205
|
}
|
|
136
206
|
|
|
137
|
-
renderSubLayers(
|
|
207
|
+
renderSubLayers(
|
|
208
|
+
props: TileLayer['props'] & {
|
|
209
|
+
id: string;
|
|
210
|
+
data: ParsedMvtTile;
|
|
211
|
+
_offset: number;
|
|
212
|
+
tile: Tile2DHeader<ParsedMvtTile>;
|
|
213
|
+
}
|
|
214
|
+
): Layer | null | LayersList {
|
|
138
215
|
const {x, y, z} = props.tile.index;
|
|
139
216
|
const worldScale = Math.pow(2, z);
|
|
140
217
|
|
|
@@ -164,7 +241,7 @@ export default class MVTLayer extends TileLayer {
|
|
|
164
241
|
return subLayers;
|
|
165
242
|
}
|
|
166
243
|
|
|
167
|
-
_updateAutoHighlight(info) {
|
|
244
|
+
protected _updateAutoHighlight(info: PickingInfo): void {
|
|
168
245
|
const {uniqueIdProperty} = this.props;
|
|
169
246
|
|
|
170
247
|
const {hoveredFeatureId, hoveredFeatureLayerName} = this.state;
|
|
@@ -193,30 +270,34 @@ export default class MVTLayer extends TileLayer {
|
|
|
193
270
|
}
|
|
194
271
|
}
|
|
195
272
|
|
|
196
|
-
getPickingInfo(params) {
|
|
273
|
+
getPickingInfo(params: GetPickingInfoParams): TiledPickingInfo {
|
|
197
274
|
const info = super.getPickingInfo(params);
|
|
198
275
|
|
|
199
|
-
const isWGS84 = this.context.viewport.resolution;
|
|
276
|
+
const isWGS84 = Boolean(this.context.viewport.resolution);
|
|
200
277
|
|
|
201
278
|
if (this.state.binary && info.index !== -1) {
|
|
202
|
-
const {data} = params.sourceLayer
|
|
203
|
-
info.object = binaryToGeojson(data, {globalFeatureId: info.index});
|
|
279
|
+
const {data} = params.sourceLayer!.props;
|
|
280
|
+
info.object = binaryToGeojson(data as BinaryFeatures, {globalFeatureId: info.index}) as DataT;
|
|
204
281
|
}
|
|
205
282
|
if (info.object && !isWGS84) {
|
|
206
|
-
info.object = transformTileCoordsToWGS84(
|
|
283
|
+
info.object = transformTileCoordsToWGS84(
|
|
284
|
+
info.object,
|
|
285
|
+
info.tile!.bbox as GeoBoundingBox,
|
|
286
|
+
this.context.viewport
|
|
287
|
+
);
|
|
207
288
|
}
|
|
208
289
|
|
|
209
290
|
return info;
|
|
210
291
|
}
|
|
211
292
|
|
|
212
|
-
getSubLayerPropsByTile(tile) {
|
|
293
|
+
getSubLayerPropsByTile(tile: Tile2DHeader<ParsedMvtTile>): Record<string, any> {
|
|
213
294
|
return {
|
|
214
295
|
highlightedObjectIndex: this.getHighlightedObjectIndex(tile),
|
|
215
296
|
highlightColor: this.state.highlightColor
|
|
216
297
|
};
|
|
217
298
|
}
|
|
218
299
|
|
|
219
|
-
getHighlightedObjectIndex(tile) {
|
|
300
|
+
private getHighlightedObjectIndex(tile: Tile2DHeader<ParsedMvtTile>): number {
|
|
220
301
|
const {hoveredFeatureId, hoveredFeatureLayerName, binary} = this.state;
|
|
221
302
|
const {uniqueIdProperty, highlightedFeatureId} = this.props;
|
|
222
303
|
const data = tile.content;
|
|
@@ -253,42 +334,44 @@ export default class MVTLayer extends TileLayer {
|
|
|
253
334
|
return -1;
|
|
254
335
|
}
|
|
255
336
|
|
|
256
|
-
_pickObjects(maxObjects) {
|
|
337
|
+
private _pickObjects(maxObjects: number | null): PickingInfo[] {
|
|
257
338
|
const {deck, viewport} = this.context;
|
|
258
339
|
const width = viewport.width;
|
|
259
340
|
const height = viewport.height;
|
|
260
341
|
const x = viewport.x;
|
|
261
342
|
const y = viewport.y;
|
|
262
343
|
const layerIds = [this.id];
|
|
263
|
-
return deck
|
|
344
|
+
return deck!.pickObjects({x, y, width, height, layerIds, maxObjects});
|
|
264
345
|
}
|
|
265
346
|
|
|
266
|
-
|
|
347
|
+
/** Get the rendered features in the current viewport. */
|
|
348
|
+
getRenderedFeatures(maxFeatures: number | null = null): DataT[] {
|
|
267
349
|
const features = this._pickObjects(maxFeatures);
|
|
268
350
|
const featureCache = new Set();
|
|
269
|
-
const renderedFeatures = [];
|
|
351
|
+
const renderedFeatures: DataT[] = [];
|
|
270
352
|
|
|
271
353
|
for (const f of features) {
|
|
272
354
|
const featureId = getFeatureUniqueId(f.object, this.props.uniqueIdProperty);
|
|
273
355
|
|
|
274
356
|
if (featureId === undefined) {
|
|
275
357
|
// we have no id for the feature, we just add to the list
|
|
276
|
-
renderedFeatures.push(f.object);
|
|
358
|
+
renderedFeatures.push(f.object as DataT);
|
|
277
359
|
} else if (!featureCache.has(featureId)) {
|
|
278
360
|
// Add removing duplicates
|
|
279
361
|
featureCache.add(featureId);
|
|
280
|
-
renderedFeatures.push(f.object);
|
|
362
|
+
renderedFeatures.push(f.object as DataT);
|
|
281
363
|
}
|
|
282
364
|
}
|
|
283
365
|
|
|
284
366
|
return renderedFeatures;
|
|
285
367
|
}
|
|
286
368
|
|
|
287
|
-
_setWGS84PropertyForTiles() {
|
|
369
|
+
private _setWGS84PropertyForTiles(): void {
|
|
288
370
|
const propName = 'dataInWGS84';
|
|
289
|
-
const
|
|
371
|
+
const tileset: Tileset2D = this.state.tileset;
|
|
290
372
|
|
|
291
|
-
|
|
373
|
+
// @ts-expect-error selectedTiles are always initialized when tile is being processed
|
|
374
|
+
tileset.selectedTiles.forEach((tile: Tile2DHeader & ContentWGS84Cache) => {
|
|
292
375
|
if (!tile.hasOwnProperty(propName)) {
|
|
293
376
|
// eslint-disable-next-line accessor-pairs
|
|
294
377
|
Object.defineProperty(tile, propName, {
|
|
@@ -304,11 +387,13 @@ export default class MVTLayer extends TileLayer {
|
|
|
304
387
|
return [];
|
|
305
388
|
}
|
|
306
389
|
|
|
307
|
-
|
|
390
|
+
const {bbox} = tile;
|
|
391
|
+
if (tile._contentWGS84 === undefined && isGeoBoundingBox(bbox)) {
|
|
308
392
|
// Create a cache to transform only once
|
|
393
|
+
|
|
309
394
|
const content = this.state.binary ? binaryToGeojson(tile.content) : tile.content;
|
|
310
395
|
tile._contentWGS84 = content.map(feature =>
|
|
311
|
-
transformTileCoordsToWGS84(feature,
|
|
396
|
+
transformTileCoordsToWGS84(feature, bbox, this.context.viewport)
|
|
312
397
|
);
|
|
313
398
|
}
|
|
314
399
|
return tile._contentWGS84;
|
|
@@ -319,8 +404,8 @@ export default class MVTLayer extends TileLayer {
|
|
|
319
404
|
}
|
|
320
405
|
}
|
|
321
406
|
|
|
322
|
-
function getFeatureUniqueId(feature, uniqueIdProperty) {
|
|
323
|
-
if (uniqueIdProperty) {
|
|
407
|
+
function getFeatureUniqueId(feature: Feature, uniqueIdProperty: string | undefined) {
|
|
408
|
+
if (feature.properties && uniqueIdProperty) {
|
|
324
409
|
return feature.properties[uniqueIdProperty];
|
|
325
410
|
}
|
|
326
411
|
|
|
@@ -331,15 +416,19 @@ function getFeatureUniqueId(feature, uniqueIdProperty) {
|
|
|
331
416
|
return undefined;
|
|
332
417
|
}
|
|
333
418
|
|
|
334
|
-
function getFeatureLayerName(feature) {
|
|
419
|
+
function getFeatureLayerName(feature: Feature): string | null {
|
|
335
420
|
return feature.properties?.layerName || null;
|
|
336
421
|
}
|
|
337
422
|
|
|
338
|
-
function isFeatureIdDefined(value) {
|
|
423
|
+
function isFeatureIdDefined(value: unknown): boolean {
|
|
339
424
|
return value !== undefined && value !== null && value !== '';
|
|
340
425
|
}
|
|
341
426
|
|
|
342
|
-
function transformTileCoordsToWGS84(
|
|
427
|
+
function transformTileCoordsToWGS84(
|
|
428
|
+
object: Feature,
|
|
429
|
+
bbox: GeoBoundingBox,
|
|
430
|
+
viewport: Viewport
|
|
431
|
+
): Feature {
|
|
343
432
|
const feature = {
|
|
344
433
|
...object,
|
|
345
434
|
geometry: {
|
|
@@ -355,8 +444,5 @@ function transformTileCoordsToWGS84(object, bbox, viewport) {
|
|
|
355
444
|
}
|
|
356
445
|
});
|
|
357
446
|
|
|
358
|
-
return feature;
|
|
447
|
+
return feature as Feature;
|
|
359
448
|
}
|
|
360
|
-
|
|
361
|
-
MVTLayer.layerName = 'MVTLayer';
|
|
362
|
-
MVTLayer.defaultProps = defaultProps;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {AccessorFunction} from '@deck.gl/core';
|
|
2
|
+
import GeoCellLayer from '../geo-cell-layer/GeoCellLayer';
|
|
3
|
+
import {getQuadkeyPolygon} from './quadkey-utils';
|
|
4
|
+
|
|
5
|
+
const defaultProps = {
|
|
6
|
+
getQuadkey: {type: 'accessor', value: d => d.quadkey}
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Properties of `QuadkeyLayer`.
|
|
11
|
+
*/
|
|
12
|
+
type QuadkeyLayerProps<DataT = any> = {
|
|
13
|
+
/**
|
|
14
|
+
* Called for each data object to retrieve the quadkey string identifier.
|
|
15
|
+
*
|
|
16
|
+
* By default, it reads `quadkey` property of data object.
|
|
17
|
+
*/
|
|
18
|
+
getQuadkey?: AccessorFunction<DataT, string>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default class QuadkeyLayer<DataT = any, ExtraProps = {}> extends GeoCellLayer<
|
|
22
|
+
DataT,
|
|
23
|
+
Required<QuadkeyLayerProps> & ExtraProps
|
|
24
|
+
> {
|
|
25
|
+
static layerName = 'QuadkeyLayer';
|
|
26
|
+
static defaultProps: any = defaultProps;
|
|
27
|
+
|
|
28
|
+
indexToBounds(): Partial<GeoCellLayer['props']> | null {
|
|
29
|
+
const {data, getQuadkey} = this.props;
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
data,
|
|
33
|
+
_normalize: false,
|
|
34
|
+
positionFormat: 'XY',
|
|
35
|
+
|
|
36
|
+
getPolygon: (x: DataT, objectInfo) => getQuadkeyPolygon(getQuadkey(x, objectInfo))
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|