@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.
Files changed (54) hide show
  1. package/dist/dist.dev.js +2286 -2542
  2. package/dist/es5/geo-cell-layer/GeoCellLayer.js +3 -3
  3. package/dist/es5/geo-cell-layer/GeoCellLayer.js.map +1 -1
  4. package/dist/es5/index.js +8 -0
  5. package/dist/es5/index.js.map +1 -1
  6. package/dist/es5/mvt-layer/coordinate-transform.js.map +1 -1
  7. package/dist/es5/mvt-layer/find-index-binary.js +7 -5
  8. package/dist/es5/mvt-layer/find-index-binary.js.map +1 -1
  9. package/dist/es5/mvt-layer/mvt-layer.js +45 -32
  10. package/dist/es5/mvt-layer/mvt-layer.js.map +1 -1
  11. package/dist/es5/quadkey-layer/quadkey-layer.js +4 -2
  12. package/dist/es5/quadkey-layer/quadkey-layer.js.map +1 -1
  13. package/dist/es5/quadkey-layer/quadkey-utils.js.map +1 -1
  14. package/dist/es5/tile-layer/tile-2d-header.js.map +1 -1
  15. package/dist/es5/tile-layer/tile-layer.js +21 -25
  16. package/dist/es5/tile-layer/tile-layer.js.map +1 -1
  17. package/dist/es5/tile-layer/tileset-2d.js +1 -6
  18. package/dist/es5/tile-layer/tileset-2d.js.map +1 -1
  19. package/dist/es5/tile-layer/utils.js +5 -0
  20. package/dist/es5/tile-layer/utils.js.map +1 -1
  21. package/dist/esm/geo-cell-layer/GeoCellLayer.js +6 -3
  22. package/dist/esm/geo-cell-layer/GeoCellLayer.js.map +1 -1
  23. package/dist/esm/index.js +1 -0
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/mvt-layer/coordinate-transform.js.map +1 -1
  26. package/dist/esm/mvt-layer/find-index-binary.js +1 -1
  27. package/dist/esm/mvt-layer/find-index-binary.js.map +1 -1
  28. package/dist/esm/mvt-layer/mvt-layer.js +47 -36
  29. package/dist/esm/mvt-layer/mvt-layer.js.map +1 -1
  30. package/dist/esm/quadkey-layer/quadkey-layer.js +5 -2
  31. package/dist/esm/quadkey-layer/quadkey-layer.js.map +1 -1
  32. package/dist/esm/quadkey-layer/quadkey-utils.js.map +1 -1
  33. package/dist/esm/tile-layer/tile-2d-header.js.map +1 -1
  34. package/dist/esm/tile-layer/tile-layer.js +5 -10
  35. package/dist/esm/tile-layer/tile-layer.js.map +1 -1
  36. package/dist/esm/tile-layer/tileset-2d.js +1 -5
  37. package/dist/esm/tile-layer/tileset-2d.js.map +1 -1
  38. package/dist/esm/tile-layer/utils.js +3 -0
  39. package/dist/esm/tile-layer/utils.js.map +1 -1
  40. package/dist.min.js +2 -2
  41. package/package.json +6 -3
  42. package/src/geo-cell-layer/{GeoCellLayer.js → GeoCellLayer.ts} +14 -10
  43. package/src/index.ts +4 -1
  44. package/src/mvt-layer/{coordinate-transform.js → coordinate-transform.ts} +10 -8
  45. package/src/mvt-layer/{find-index-binary.js → find-index-binary.ts} +41 -10
  46. package/src/mvt-layer/{mvt-layer.js → mvt-layer.ts} +145 -59
  47. package/src/quadkey-layer/quadkey-layer.ts +39 -0
  48. package/src/quadkey-layer/{quadkey-utils.js → quadkey-utils.ts} +2 -2
  49. package/src/tile-layer/tile-2d-header.ts +15 -14
  50. package/src/tile-layer/tile-layer.ts +64 -62
  51. package/src/tile-layer/tileset-2d.ts +13 -13
  52. package/src/tile-layer/types.ts +5 -1
  53. package/src/tile-layer/utils.ts +17 -3
  54. 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.2",
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.10",
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": "a52215449dff06fb683f5afd6399526353d11f35"
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 default class GeoCellLayer extends CompositeLayer {
9
- // Implement to generate props to create geometry
10
- indexToBounds() {
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(data, uniqueIdProperty, featureId, layerName) {
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(geomData, uniqueIdProperty, featureId, layerName) {
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(geomData, layerName) {
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(array, predicate, startIndex, endIndex) {
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 {log} from '@deck.gl/core';
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 TileLayer from '../tile-layer/tile-layer';
9
- import {getURLFromTemplate, isURLTemplate} from '../tile-layer/utils';
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 default class MVTLayer extends TileLayer {
26
- initializeState() {
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.data) {
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 {data} = this.props;
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(props) {
86
- const opts = super._getTilesetOptions(props);
87
- const {tileJSON} = this.state;
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 > props.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(props.maxZoom) || tileJSON.maxzoom < props.maxZoom)
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.data) return null;
175
+ renderLayers(): Layer | null | LayersList {
176
+ if (!this.state?.data) return null;
108
177
  return super.renderLayers();
109
178
  }
110
179
 
111
- getTileData(tile) {
112
- const url = getURLFromTemplate(this.state.data, tile);
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(props) {
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.props;
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(info.object, info.tile.bbox, this.context.viewport);
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.pickObjects({x, y, width, height, layerIds, maxObjects});
344
+ return deck!.pickObjects({x, y, width, height, layerIds, maxObjects});
264
345
  }
265
346
 
266
- getRenderedFeatures(maxFeatures = null) {
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 {tileset} = this.state;
371
+ const tileset: Tileset2D = this.state.tileset;
290
372
 
291
- tileset.selectedTiles.forEach(tile => {
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
- if (tile._contentWGS84 === undefined) {
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, tile.bbox, this.context.viewport)
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(object, bbox, viewport) {
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
+ }