@deck.gl/geo-layers 8.8.0-beta.2 → 8.8.0-beta.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.
Files changed (81) hide show
  1. package/dist/dist.dev.js +1867 -1646
  2. package/dist/es5/geohash-layer/geohash-layer.js +71 -0
  3. package/dist/es5/geohash-layer/geohash-layer.js.map +1 -0
  4. package/dist/es5/geohash-layer/geohash-utils.js +77 -0
  5. package/dist/es5/geohash-layer/geohash-utils.js.map +1 -0
  6. package/dist/es5/index.js +8 -0
  7. package/dist/es5/index.js.map +1 -1
  8. package/dist/es5/terrain-layer/terrain-layer.js +57 -34
  9. package/dist/es5/terrain-layer/terrain-layer.js.map +1 -1
  10. package/dist/es5/tile-3d-layer/tile-3d-layer.js.map +1 -1
  11. package/dist/es5/tile-layer/tile-layer.js +4 -2
  12. package/dist/es5/tile-layer/tile-layer.js.map +1 -1
  13. package/dist/es5/tile-layer/tileset-2d.js +38 -1
  14. package/dist/es5/tile-layer/tileset-2d.js.map +1 -1
  15. package/dist/es5/tile-layer/utils.js +46 -12
  16. package/dist/es5/tile-layer/utils.js.map +1 -1
  17. package/dist/esm/geohash-layer/geohash-layer.js +29 -0
  18. package/dist/esm/geohash-layer/geohash-layer.js.map +1 -0
  19. package/dist/esm/geohash-layer/geohash-utils.js +56 -0
  20. package/dist/esm/geohash-layer/geohash-utils.js.map +1 -0
  21. package/dist/esm/index.js +1 -0
  22. package/dist/esm/index.js.map +1 -1
  23. package/dist/esm/terrain-layer/terrain-layer.js +35 -13
  24. package/dist/esm/terrain-layer/terrain-layer.js.map +1 -1
  25. package/dist/esm/tile-3d-layer/tile-3d-layer.js.map +1 -1
  26. package/dist/esm/tile-layer/tile-layer.js +6 -2
  27. package/dist/esm/tile-layer/tile-layer.js.map +1 -1
  28. package/dist/esm/tile-layer/tileset-2d.js +36 -3
  29. package/dist/esm/tile-layer/tileset-2d.js.map +1 -1
  30. package/dist/esm/tile-layer/utils.js +36 -0
  31. package/dist/esm/tile-layer/utils.js.map +1 -1
  32. package/dist.min.js +2 -2
  33. package/package.json +2 -2
  34. package/src/geohash-layer/geohash-layer.ts +38 -0
  35. package/src/geohash-layer/geohash-utils.ts +54 -0
  36. package/src/index.ts +3 -0
  37. package/src/terrain-layer/{terrain-layer.js → terrain-layer.ts} +119 -37
  38. package/src/tile-3d-layer/tile-3d-layer.ts +4 -4
  39. package/src/tile-layer/tile-layer.ts +4 -2
  40. package/src/tile-layer/tileset-2d.ts +41 -5
  41. package/src/tile-layer/utils.ts +44 -0
  42. package/typed/geohash-layer/geohash-layer.d.ts +20 -0
  43. package/typed/geohash-layer/geohash-layer.d.ts.map +1 -0
  44. package/typed/geohash-layer/geohash-utils.d.ts +3 -0
  45. package/typed/geohash-layer/geohash-utils.d.ts.map +1 -0
  46. package/typed/index.d.ts +3 -0
  47. package/typed/index.d.ts.map +1 -1
  48. package/typed/terrain-layer/terrain-layer.d.ts +61 -26
  49. package/typed/terrain-layer/terrain-layer.d.ts.map +1 -1
  50. package/typed/tile-3d-layer/tile-3d-layer.d.ts +3 -3
  51. package/typed/tile-layer/tile-layer.d.ts +2 -4
  52. package/typed/tile-layer/tile-layer.d.ts.map +1 -1
  53. package/typed/tile-layer/tileset-2d.d.ts +10 -2
  54. package/typed/tile-layer/tileset-2d.d.ts.map +1 -1
  55. package/typed/tile-layer/utils.d.ts +14 -0
  56. package/typed/tile-layer/utils.d.ts.map +1 -1
  57. package/typed/geo-cell-layer/GeoCellLayer.js +0 -49
  58. package/typed/great-circle-layer/great-circle-layer.js +0 -29
  59. package/typed/h3-layers/h3-cluster-layer.js +0 -33
  60. package/typed/h3-layers/h3-hexagon-layer.js +0 -251
  61. package/typed/index.js +0 -33
  62. package/typed/mesh-layer/mesh-layer-fragment.glsl.js +0 -55
  63. package/typed/mesh-layer/mesh-layer-vertex.glsl.js +0 -80
  64. package/typed/mesh-layer/mesh-layer.js +0 -110
  65. package/typed/mvt-layer/coordinate-transform.js +0 -41
  66. package/typed/mvt-layer/find-index-binary.js +0 -96
  67. package/typed/mvt-layer/mvt-layer.js +0 -297
  68. package/typed/quadkey-layer/quadkey-layer.js +0 -18
  69. package/typed/quadkey-layer/quadkey-utils.js +0 -26
  70. package/typed/s2-layer/s2-geometry.js +0 -123
  71. package/typed/s2-layer/s2-layer.js +0 -37
  72. package/typed/s2-layer/s2-utils.js +0 -88
  73. package/typed/terrain-layer/terrain-layer.js +0 -226
  74. package/typed/tile-3d-layer/tile-3d-layer.js +0 -294
  75. package/typed/tile-layer/tile-2d-header.js +0 -113
  76. package/typed/tile-layer/tile-2d-traversal.js +0 -181
  77. package/typed/tile-layer/tile-layer.js +0 -192
  78. package/typed/tile-layer/tileset-2d.js +0 -399
  79. package/typed/tile-layer/types.js +0 -1
  80. package/typed/tile-layer/utils.js +0 -197
  81. package/typed/trips-layer/trips-layer.js +0 -92
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-beta.2",
5
+ "version": "8.8.0-beta.3",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
@@ -54,5 +54,5 @@
54
54
  "@loaders.gl/core": "^3.0.0",
55
55
  "@luma.gl/core": "^8.0.0"
56
56
  },
57
- "gitHead": "d9bae59d015387c547366465d75d80950c60a34e"
57
+ "gitHead": "bb459e1b4a4e3674ee9832d775d39211541d17b4"
58
58
  }
@@ -0,0 +1,38 @@
1
+ import {AccessorFunction} from '@deck.gl/core';
2
+ import GeoCellLayer from '../geo-cell-layer/GeoCellLayer';
3
+ import {getGeohashPolygon} from './geohash-utils';
4
+
5
+ const defaultProps = {
6
+ getGeohash: {type: 'accessor', value: d => d.geohash}
7
+ };
8
+
9
+ /**
10
+ * Properties of `GeohashLayer`.
11
+ */
12
+ type GeohashLayerProps<DataT = any> = {
13
+ /**
14
+ * Called for each data object to retrieve the geohash string identifier.
15
+ *
16
+ * By default, it reads `geohash` property of data object.
17
+ */
18
+ getGeohash?: AccessorFunction<DataT, string>;
19
+ };
20
+
21
+ export default class GeohashLayer<DataT = any, ExtraProps = {}> extends GeoCellLayer<
22
+ DataT,
23
+ Required<GeohashLayerProps> & ExtraProps
24
+ > {
25
+ static layerName = 'GeohashLayer';
26
+ static defaultProps: any = defaultProps;
27
+
28
+ indexToBounds(): Partial<GeoCellLayer['props']> | null {
29
+ const {data, getGeohash} = this.props;
30
+
31
+ return {
32
+ data,
33
+ _normalize: false,
34
+ positionFormat: 'XY',
35
+ getPolygon: (x: DataT, objectInfo) => getGeohashPolygon(getGeohash(x, objectInfo))
36
+ };
37
+ }
38
+ }
@@ -0,0 +1,54 @@
1
+ const BASE32_CODES = '0123456789bcdefghjkmnpqrstuvwxyz';
2
+ const BASE32_CODES_DICT = {};
3
+ for (let i = 0; i < BASE32_CODES.length; i++) {
4
+ BASE32_CODES_DICT[BASE32_CODES.charAt(i)] = i;
5
+ }
6
+
7
+ const MIN_LAT = -90;
8
+ const MAX_LAT = 90;
9
+ const MIN_LON = -180;
10
+ const MAX_LON = 180;
11
+
12
+ // Adapted from ngeohash decode_bbox
13
+ export function getGeohashBounds(geohash: string): number[] {
14
+ let isLon = true;
15
+ let maxLat = MAX_LAT;
16
+ let minLat = MIN_LAT;
17
+ let maxLon = MAX_LON;
18
+ let minLon = MIN_LON;
19
+ let mid: number;
20
+
21
+ let hashValue = 0;
22
+ for (let i = 0, l = geohash.length; i < l; i++) {
23
+ const code = geohash[i].toLowerCase();
24
+ hashValue = BASE32_CODES_DICT[code];
25
+
26
+ for (let bits = 4; bits >= 0; bits--) {
27
+ const bit = (hashValue >> bits) & 1;
28
+ if (isLon) {
29
+ mid = (maxLon + minLon) / 2;
30
+ if (bit === 1) {
31
+ minLon = mid;
32
+ } else {
33
+ maxLon = mid;
34
+ }
35
+ } else {
36
+ mid = (maxLat + minLat) / 2;
37
+ if (bit === 1) {
38
+ minLat = mid;
39
+ } else {
40
+ maxLat = mid;
41
+ }
42
+ }
43
+ isLon = !isLon;
44
+ }
45
+ }
46
+
47
+ return [minLat, minLon, maxLat, maxLon];
48
+ }
49
+
50
+ export function getGeohashPolygon(geohash: string): number[] {
51
+ const [s, w, n, e] = getGeohashBounds(geohash);
52
+
53
+ return [e, n, e, s, w, s, w, n, e, n];
54
+ }
package/src/index.ts CHANGED
@@ -29,6 +29,7 @@ export {default as H3HexagonLayer} from './h3-layers/h3-hexagon-layer';
29
29
  export {default as Tile3DLayer} from './tile-3d-layer/tile-3d-layer';
30
30
  export {default as TerrainLayer} from './terrain-layer/terrain-layer';
31
31
  export {default as MVTLayer} from './mvt-layer/mvt-layer';
32
+ export {default as GeohashLayer} from './geohash-layer/geohash-layer';
32
33
 
33
34
  export {getURLFromTemplate as _getURLFromTemplate} from './tile-layer/utils';
34
35
  export {default as _Tileset2D} from './tile-layer/tileset-2d';
@@ -43,4 +44,6 @@ export type {TileLayerProps} from './tile-layer/tile-layer';
43
44
  export type {GeoBoundingBox} from './tile-layer/types';
44
45
  export type {QuadkeyLayerProps} from './quadkey-layer/quadkey-layer';
45
46
  export type {TileLoadProps as _TileLoadProps} from './tile-layer/types';
47
+ export type {TerrainLayerProps} from './terrain-layer/terrain-layer';
48
+ export type {Tile3DLayerProps} from './tile-3d-layer/tile-3d-layer';
46
49
  export type {MVTLayerProps} from './mvt-layer/mvt-layer';
@@ -18,16 +18,30 @@
18
18
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  // THE SOFTWARE.
20
20
 
21
- import {CompositeLayer, log} from '@deck.gl/core';
21
+ import {
22
+ Color,
23
+ CompositeLayer,
24
+ CompositeLayerProps,
25
+ DefaultProps,
26
+ Layer,
27
+ LayersList,
28
+ log,
29
+ Material,
30
+ Texture,
31
+ UpdateParameters
32
+ } from '@deck.gl/core';
22
33
  import {SimpleMeshLayer} from '@deck.gl/mesh-layers';
23
34
  import {COORDINATE_SYSTEM} from '@deck.gl/core';
35
+ import type {MeshAttributes} from '@loaders.gl/schema';
24
36
  import {TerrainWorkerLoader} from '@loaders.gl/terrain';
25
- import TileLayer from '../tile-layer/tile-layer';
37
+ import TileLayer, {TileLayerProps} from '../tile-layer/tile-layer';
38
+ import Tile2DHeader from '../tile-layer/tile-2d-header';
39
+ import {Bounds, GeoBoundingBox, TileBoundingBox, TileLoadProps, ZRange} from '../tile-layer/types';
26
40
  import {urlType, getURLFromTemplate} from '../tile-layer/utils';
27
41
 
28
42
  const DUMMY_DATA = [1];
29
43
 
30
- const defaultProps = {
44
+ const defaultProps: DefaultProps<TerrainLayerProps> = {
31
45
  ...TileLayer.defaultProps,
32
46
  // Image url that encodes height data
33
47
  elevationData: urlType,
@@ -58,22 +72,72 @@ const defaultProps = {
58
72
  loaders: [TerrainWorkerLoader]
59
73
  };
60
74
 
75
+ type URLTemplate = string | string[];
76
+
61
77
  // Turns array of templates into a single string to work around shallow change
62
- function urlTemplateToUpdateTrigger(template) {
78
+ function urlTemplateToUpdateTrigger(template: URLTemplate | null): string {
63
79
  if (Array.isArray(template)) {
64
80
  return template.join(';');
65
81
  }
66
- return template;
82
+ return template || '';
67
83
  }
68
84
 
69
- /**
70
- * state: {
71
- * isTiled: True renders TileLayer of many SimpleMeshLayers, false renders one SimpleMeshLayer
72
- * terrain: Mesh object. Only defined when isTiled is false.
73
- * }
74
- */
75
- export default class TerrainLayer extends CompositeLayer {
76
- updateState({props, oldProps}) {
85
+ type ElevationDecoder = {rScaler: number; gScaler: number; bScaler: number; offset: number};
86
+ type TerrainLoadProps = {
87
+ bounds: Bounds;
88
+ elevationData: string | null;
89
+ elevationDecoder: ElevationDecoder;
90
+ meshMaxError: number;
91
+ signal?: AbortSignal;
92
+ };
93
+
94
+ type MeshAndTexture = [MeshAttributes | null, Texture | null];
95
+
96
+ /** All properties supported by TerrainLayer */
97
+ export type TerrainLayerProps = _TerrainLayerProps &
98
+ TileLayerProps<MeshAndTexture> &
99
+ CompositeLayerProps;
100
+
101
+ /** Props added by the TerrainLayer */
102
+ type _TerrainLayerProps = {
103
+ /** Image url that encodes height data. **/
104
+ elevationData: URLTemplate;
105
+
106
+ /** Image url to use as texture. **/
107
+ texture?: URLTemplate | null;
108
+
109
+ /** Martini error tolerance in meters, smaller number -> more detailed mesh. **/
110
+ meshMaxError?: number;
111
+
112
+ /** Bounding box of the terrain image, [minX, minY, maxX, maxY] in world coordinates. **/
113
+ bounds?: Bounds | null;
114
+
115
+ /** Color to use if texture is unavailable. **/
116
+ color?: Color;
117
+
118
+ /** Object to decode height data, from (r, g, b) to height in meters. **/
119
+ elevationDecoder?: ElevationDecoder;
120
+
121
+ /** Whether to render the mesh in wireframe mode. **/
122
+ wireframe?: boolean;
123
+
124
+ /** Material props for lighting effect. **/
125
+ material?: Material;
126
+ };
127
+
128
+ export default class TerrainLayer<ExtraPropsT = {}> extends CompositeLayer<
129
+ ExtraPropsT & Required<_TerrainLayerProps & Required<TileLayerProps<MeshAndTexture>>>
130
+ > {
131
+ static defaultProps = defaultProps;
132
+ static layerName = 'TerrainLayer';
133
+
134
+ state!: {
135
+ isTiled?: boolean;
136
+ terrain: MeshAttributes;
137
+ zRange?: ZRange | null;
138
+ };
139
+
140
+ updateState({props, oldProps}: UpdateParameters<this>): void {
77
141
  const elevationDataChanged = props.elevationData !== oldProps.elevationData;
78
142
  if (elevationDataChanged) {
79
143
  const {elevationData} = props;
@@ -92,17 +156,25 @@ export default class TerrainLayer extends CompositeLayer {
92
156
  props.bounds !== oldProps.bounds;
93
157
 
94
158
  if (!this.state.isTiled && shouldReload) {
95
- const terrain = this.loadTerrain(props);
159
+ // When state.isTiled, elevationData cannot be an array
160
+ const terrain = this.loadTerrain(props as TerrainLoadProps);
96
161
  this.setState({terrain});
97
162
  }
98
163
 
99
164
  // TODO - remove in v9
165
+ // @ts-ignore
100
166
  if (props.workerUrl) {
101
167
  log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
102
168
  }
103
169
  }
104
170
 
105
- loadTerrain({elevationData, bounds, elevationDecoder, meshMaxError, signal}) {
171
+ loadTerrain({
172
+ elevationData,
173
+ bounds,
174
+ elevationDecoder,
175
+ meshMaxError,
176
+ signal
177
+ }: TerrainLoadProps): Promise<MeshAttributes> | null {
106
178
  if (!elevationData) {
107
179
  return null;
108
180
  }
@@ -121,20 +193,25 @@ export default class TerrainLayer extends CompositeLayer {
121
193
  return fetch(elevationData, {propName: 'elevationData', layer: this, loadOptions, signal});
122
194
  }
123
195
 
124
- getTiledTerrainData(tile) {
196
+ getTiledTerrainData(tile: TileLoadProps): Promise<MeshAndTexture> {
125
197
  const {elevationData, fetch, texture, elevationDecoder, meshMaxError} = this.props;
126
198
  const {viewport} = this.context;
127
199
  const dataUrl = getURLFromTemplate(elevationData, tile);
128
- const textureUrl = getURLFromTemplate(texture, tile);
200
+ const textureUrl = texture && getURLFromTemplate(texture, tile);
129
201
 
130
- const {bbox, signal} = tile;
131
- const bottomLeft = viewport.isGeospatial
132
- ? viewport.projectFlat([bbox.west, bbox.south])
133
- : [bbox.left, bbox.bottom];
134
- const topRight = viewport.isGeospatial
135
- ? viewport.projectFlat([bbox.east, bbox.north])
136
- : [bbox.right, bbox.top];
137
- const bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
202
+ const {signal} = tile;
203
+ let bottomLeft = [0, 0] as [number, number];
204
+ let topRight = [0, 0] as [number, number];
205
+ if (viewport.isGeospatial) {
206
+ const bbox = tile.bbox as GeoBoundingBox;
207
+ bottomLeft = viewport.projectFlat([bbox.west, bbox.south]);
208
+ topRight = viewport.projectFlat([bbox.east, bbox.north]);
209
+ } else {
210
+ const bbox = tile.bbox as Exclude<TileBoundingBox, GeoBoundingBox>;
211
+ bottomLeft = [bbox.left, bbox.bottom];
212
+ topRight = [bbox.right, bbox.top];
213
+ }
214
+ const bounds: Bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
138
215
 
139
216
  const terrain = this.loadTerrain({
140
217
  elevationData: dataUrl,
@@ -151,9 +228,17 @@ export default class TerrainLayer extends CompositeLayer {
151
228
  return Promise.all([terrain, surface]);
152
229
  }
153
230
 
154
- renderSubLayers(props) {
231
+ renderSubLayers(
232
+ props: TileLayerProps<MeshAndTexture> & {
233
+ id: string;
234
+ data: MeshAndTexture;
235
+ tile: Tile2DHeader<MeshAndTexture>;
236
+ }
237
+ ) {
155
238
  const SubLayerClass = this.getSubLayerClass('mesh', SimpleMeshLayer);
156
- const {data, color} = props;
239
+
240
+ const {color, wireframe, material} = this.props;
241
+ const {data} = props;
157
242
 
158
243
  if (!data) {
159
244
  return null;
@@ -168,12 +253,14 @@ export default class TerrainLayer extends CompositeLayer {
168
253
  _instanced: false,
169
254
  coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
170
255
  getPosition: d => [0, 0, 0],
171
- getColor: color
256
+ getColor: color,
257
+ wireframe,
258
+ material
172
259
  });
173
260
  }
174
261
 
175
262
  // Update zRange of viewport
176
- onViewportLoad(tiles) {
263
+ onViewportLoad(tiles?: Tile2DHeader<MeshAndTexture>[]): void {
177
264
  if (!tiles) {
178
265
  return;
179
266
  }
@@ -183,6 +270,7 @@ export default class TerrainLayer extends CompositeLayer {
183
270
  .map(tile => tile.content)
184
271
  .filter(Boolean)
185
272
  .map(arr => {
273
+ // @ts-ignore
186
274
  const bounds = arr[0].header.boundingBox;
187
275
  return bounds.map(bound => bound[2]);
188
276
  });
@@ -197,7 +285,7 @@ export default class TerrainLayer extends CompositeLayer {
197
285
  }
198
286
  }
199
287
 
200
- renderLayers() {
288
+ renderLayers(): Layer | null | LayersList {
201
289
  const {
202
290
  color,
203
291
  material,
@@ -220,14 +308,11 @@ export default class TerrainLayer extends CompositeLayer {
220
308
  } = this.props;
221
309
 
222
310
  if (this.state.isTiled) {
223
- return new TileLayer(
311
+ return new TileLayer<MeshAndTexture>(
224
312
  this.getSubLayerProps({
225
313
  id: 'tiles'
226
314
  }),
227
315
  {
228
- wireframe,
229
- color,
230
- material,
231
316
  getTileData: this.getTiledTerrainData.bind(this),
232
317
  renderSubLayers: this.renderSubLayers.bind(this),
233
318
  updateTriggers: {
@@ -273,6 +358,3 @@ export default class TerrainLayer extends CompositeLayer {
273
358
  );
274
359
  }
275
360
  }
276
-
277
- TerrainLayer.layerName = 'TerrainLayer';
278
- TerrainLayer.defaultProps = defaultProps;
@@ -28,7 +28,7 @@ import {Tiles3DLoader} from '@loaders.gl/3d-tiles';
28
28
 
29
29
  const SINGLE_DATA = [0];
30
30
 
31
- const defaultProps: DefaultProps<Tile3dLayerProps> = {
31
+ const defaultProps: DefaultProps<Tile3DLayerProps> = {
32
32
  getPointColor: {type: 'accessor', value: [0, 0, 0, 255]},
33
33
  pointSize: 1.0,
34
34
 
@@ -44,10 +44,10 @@ const defaultProps: DefaultProps<Tile3dLayerProps> = {
44
44
  };
45
45
 
46
46
  /** All properties supported by Tile3DLayer */
47
- export type Tile3dLayerProps<DataT = any> = _Tile3dLayerProps<DataT> & CompositeLayerProps<DataT>;
47
+ export type Tile3DLayerProps<DataT = any> = _Tile3DLayerProps<DataT> & CompositeLayerProps<DataT>;
48
48
 
49
49
  /** Props added by the Tile3DLayer */
50
- type _Tile3dLayerProps<DataT> = {
50
+ type _Tile3DLayerProps<DataT> = {
51
51
  /** Color Accessor for point clouds. **/
52
52
  getPointColor?: Accessor<DataT, Color>;
53
53
 
@@ -76,7 +76,7 @@ type _Tile3dLayerProps<DataT> = {
76
76
  };
77
77
 
78
78
  export default class Tile3DLayer<DataT = any, ExtraPropsT = {}> extends CompositeLayer<
79
- ExtraPropsT & Required<_Tile3dLayerProps<DataT>>
79
+ ExtraPropsT & Required<_Tile3DLayerProps<DataT>>
80
80
  > {
81
81
  static defaultProps = defaultProps as any;
82
82
  static layerName = 'Tile3DLayer';
@@ -7,6 +7,7 @@ import {
7
7
  PickingInfo,
8
8
  GetPickingInfoParams,
9
9
  DefaultProps,
10
+ FilterContext,
10
11
  _flatten as flatten
11
12
  } from '@deck.gl/core';
12
13
  import {GeoJsonLayer} from '@deck.gl/layers';
@@ -352,7 +353,8 @@ export default class TileLayer<DataT = any, ExtraPropsT = {}> extends CompositeL
352
353
  });
353
354
  }
354
355
 
355
- filterSubLayer({layer}) {
356
- return layer.props.tile.isVisible;
356
+ filterSubLayer({layer, cullRect}: FilterContext) {
357
+ const {tile} = (layer as Layer<{tile: Tile2DHeader}>).props;
358
+ return this.state.tileset.isTileVisible(tile, cullRect);
357
359
  }
358
360
  }
@@ -1,10 +1,11 @@
1
1
  import Tile2DHeader from './tile-2d-header';
2
- import {getTileIndices, tileToBoundingBox} from './utils';
2
+ import {getTileIndices, tileToBoundingBox, getCullBounds} from './utils';
3
3
  import {RequestScheduler} from '@loaders.gl/loader-utils';
4
- import {Matrix4} from '@math.gl/core';
4
+ import {Matrix4, equals} from '@math.gl/core';
5
5
  import {Viewport} from '@deck.gl/core';
6
6
  import {Bounds, TileIndex, ZRange} from './types';
7
7
  import {TileLayerProps} from './tile-layer';
8
+ import {_memoize as memoize} from '@deck.gl/core';
8
9
 
9
10
  // bit masks
10
11
  const TILE_STATE_VISITED = 1;
@@ -78,6 +79,7 @@ export default class Tileset2D {
78
79
 
79
80
  private _cacheByteSize: number;
80
81
  private _viewport: Viewport | null;
82
+ private _zRange?: ZRange;
81
83
  private _selectedTiles: Tile2DHeader[] | null;
82
84
  private _frameNumber: number;
83
85
  private _modelMatrix: Matrix4;
@@ -184,12 +186,18 @@ export default class Tileset2D {
184
186
  ): number {
185
187
  const modelMatrixAsMatrix4 = new Matrix4(modelMatrix);
186
188
  const isModelMatrixNew = !modelMatrixAsMatrix4.equals(this._modelMatrix);
187
- if (!this._viewport || !viewport.equals(this._viewport) || isModelMatrixNew) {
189
+ if (
190
+ !this._viewport ||
191
+ !viewport.equals(this._viewport) ||
192
+ !equals(this._zRange, zRange) ||
193
+ isModelMatrixNew
194
+ ) {
188
195
  if (isModelMatrixNew) {
189
196
  this._modelMatrixInverse = modelMatrixAsMatrix4.clone().invert();
190
197
  this._modelMatrix = modelMatrixAsMatrix4;
191
198
  }
192
199
  this._viewport = viewport;
200
+ this._zRange = zRange;
193
201
  const tileIndices = this.getTileIndices({
194
202
  viewport,
195
203
  maxZoom: this._maxZoom,
@@ -225,6 +233,32 @@ export default class Tileset2D {
225
233
  return this._frameNumber;
226
234
  }
227
235
 
236
+ isTileVisible(
237
+ tile: Tile2DHeader,
238
+ cullRect?: {x: number; y: number; width: number; height: number}
239
+ ): boolean {
240
+ if (!tile.isVisible) {
241
+ return false;
242
+ }
243
+
244
+ if (cullRect && this._viewport) {
245
+ const [minX, minY, maxX, maxY] = getCullBounds({
246
+ viewport: this._viewport,
247
+ z: this._zRange,
248
+ cullRect
249
+ });
250
+ const {bbox} = tile;
251
+ if ('west' in bbox) {
252
+ return bbox.west < maxX && bbox.east > minX && bbox.south < maxY && bbox.north > minY;
253
+ }
254
+ // top/bottom could be swapped depending on the indexing system
255
+ const y0 = Math.min(bbox.top, bbox.bottom);
256
+ const y1 = Math.max(bbox.top, bbox.bottom);
257
+ return bbox.left < maxX && bbox.right > minX && y0 < maxY && y1 > minY;
258
+ }
259
+ return true;
260
+ }
261
+
228
262
  /* Public interface for subclassing */
229
263
 
230
264
  /** Returns array of tile indices in the current viewport */
@@ -321,7 +355,9 @@ export default class Tileset2D {
321
355
 
322
356
  /* Private methods */
323
357
 
324
- _pruneRequests(): void {
358
+ private _getCullBounds = memoize(getCullBounds);
359
+
360
+ private _pruneRequests(): void {
325
361
  const {maxRequests} = this.opts;
326
362
 
327
363
  const abortCandidates: Tile2DHeader[] = [];
@@ -345,7 +381,7 @@ export default class Tileset2D {
345
381
  }
346
382
 
347
383
  // This needs to be called every time some tiles have been added/removed from cache
348
- _rebuildTree() {
384
+ private _rebuildTree() {
349
385
  const {_cache} = this;
350
386
 
351
387
  // Reset states
@@ -127,6 +127,50 @@ function getBoundingBox(viewport: Viewport, zRange: number[] | null, extent: Bou
127
127
  ];
128
128
  }
129
129
 
130
+ /** Get culling bounds in world space */
131
+ export function getCullBounds({
132
+ viewport,
133
+ z,
134
+ cullRect
135
+ }: {
136
+ /** Current viewport */
137
+ viewport: Viewport;
138
+ /** Current z range */
139
+ z: ZRange | number | undefined;
140
+ /** Culling rectangle in screen space */
141
+ cullRect: {x: number; y: number; width: number; height: number};
142
+ }): [number, number, number, number] {
143
+ const x = cullRect.x - viewport.x;
144
+ const y = cullRect.y - viewport.y;
145
+ const {width, height} = cullRect;
146
+
147
+ if (!Array.isArray(z)) {
148
+ const unprojectOption = {targetZ: z || 0};
149
+
150
+ const topLeft = viewport.unproject([x, y], unprojectOption);
151
+ const topRight = viewport.unproject([x + width, y], unprojectOption);
152
+ const bottomLeft = viewport.unproject([x, y + height], unprojectOption);
153
+ const bottomRight = viewport.unproject([x + width, y + height], unprojectOption);
154
+
155
+ return [
156
+ Math.min(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]),
157
+ Math.min(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]),
158
+ Math.max(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]),
159
+ Math.max(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1])
160
+ ];
161
+ }
162
+
163
+ const bounds0 = getCullBounds({viewport, z: z[0], cullRect});
164
+ const bounds1 = getCullBounds({viewport, z: z[1], cullRect});
165
+
166
+ return [
167
+ Math.min(bounds0[0], bounds1[0]),
168
+ Math.min(bounds0[1], bounds1[1]),
169
+ Math.max(bounds0[2], bounds1[2]),
170
+ Math.max(bounds0[3], bounds1[3])
171
+ ];
172
+ }
173
+
130
174
  function getIndexingCoords(bbox: Bounds, scale: number, modelMatrixInverse?: Matrix4): Bounds {
131
175
  if (modelMatrixInverse) {
132
176
  const transformedTileIndex = transformBox(bbox, modelMatrixInverse).map(
@@ -0,0 +1,20 @@
1
+ import { AccessorFunction } from '@deck.gl/core/typed';
2
+ import GeoCellLayer from '../geo-cell-layer/GeoCellLayer';
3
+ /**
4
+ * Properties of `GeohashLayer`.
5
+ */
6
+ declare type GeohashLayerProps<DataT = any> = {
7
+ /**
8
+ * Called for each data object to retrieve the geohash string identifier.
9
+ *
10
+ * By default, it reads `geohash` property of data object.
11
+ */
12
+ getGeohash?: AccessorFunction<DataT, string>;
13
+ };
14
+ export default class GeohashLayer<DataT = any, ExtraProps = {}> extends GeoCellLayer<DataT, Required<GeohashLayerProps> & ExtraProps> {
15
+ static layerName: string;
16
+ static defaultProps: any;
17
+ indexToBounds(): Partial<GeoCellLayer['props']> | null;
18
+ }
19
+ export {};
20
+ //# sourceMappingURL=geohash-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geohash-layer.d.ts","sourceRoot":"","sources":["../../src/geohash-layer/geohash-layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAC/C,OAAO,YAAY,MAAM,gCAAgC,CAAC;AAO1D;;GAEG;AACH,aAAK,iBAAiB,CAAC,KAAK,GAAG,GAAG,IAAI;IACpC;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,YAAY,CAAC,KAAK,GAAG,GAAG,EAAE,UAAU,GAAG,EAAE,CAAE,SAAQ,YAAY,CAClF,KAAK,EACL,QAAQ,CAAC,iBAAiB,CAAC,GAAG,UAAU,CACzC;IACC,MAAM,CAAC,SAAS,SAAkB;IAClC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAgB;IAExC,aAAa,IAAI,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI;CAUvD"}
@@ -0,0 +1,3 @@
1
+ export declare function getGeohashBounds(geohash: string): number[];
2
+ export declare function getGeohashPolygon(geohash: string): number[];
3
+ //# sourceMappingURL=geohash-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geohash-utils.d.ts","sourceRoot":"","sources":["../../src/geohash-layer/geohash-utils.ts"],"names":[],"mappings":"AAYA,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAmC1D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAI3D"}
package/typed/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export { default as H3HexagonLayer } from './h3-layers/h3-hexagon-layer';
8
8
  export { default as Tile3DLayer } from './tile-3d-layer/tile-3d-layer';
9
9
  export { default as TerrainLayer } from './terrain-layer/terrain-layer';
10
10
  export { default as MVTLayer } from './mvt-layer/mvt-layer';
11
+ export { default as GeohashLayer } from './geohash-layer/geohash-layer';
11
12
  export { getURLFromTemplate as _getURLFromTemplate } from './tile-layer/utils';
12
13
  export { default as _Tileset2D } from './tile-layer/tileset-2d';
13
14
  export { default as _Tile2DHeader } from './tile-layer/tile-2d-header';
@@ -19,5 +20,7 @@ export type { TileLayerProps } from './tile-layer/tile-layer';
19
20
  export type { GeoBoundingBox } from './tile-layer/types';
20
21
  export type { QuadkeyLayerProps } from './quadkey-layer/quadkey-layer';
21
22
  export type { TileLoadProps as _TileLoadProps } from './tile-layer/types';
23
+ export type { TerrainLayerProps } from './terrain-layer/terrain-layer';
24
+ export type { Tile3DLayerProps } from './tile-3d-layer/tile-3d-layer';
22
25
  export type { MVTLayerProps } from './mvt-layer/mvt-layer';
23
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAC,OAAO,IAAI,OAAO,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAC,OAAO,IAAI,UAAU,EAAC,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAC,OAAO,IAAI,WAAW,EAAC,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAC,kBAAkB,IAAI,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAC,OAAO,IAAI,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAC,OAAO,IAAI,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAGrE,YAAY,EAAC,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAC,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAC,qBAAqB,EAAC,MAAM,yCAAyC,CAAC;AACnF,YAAY,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAC,cAAc,EAAC,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAC,iBAAiB,EAAC,MAAM,+BAA+B,CAAC;AACrE,YAAY,EAAC,aAAa,IAAI,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACxE,YAAY,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAC,OAAO,IAAI,gBAAgB,EAAC,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAC,OAAO,IAAI,OAAO,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAC,OAAO,IAAI,UAAU,EAAC,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAC,OAAO,IAAI,cAAc,EAAC,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAC,OAAO,IAAI,WAAW,EAAC,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,+BAA+B,CAAC;AAEtE,OAAO,EAAC,kBAAkB,IAAI,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAC,OAAO,IAAI,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAC,OAAO,IAAI,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAGrE,YAAY,EAAC,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAC,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAC,qBAAqB,EAAC,MAAM,yCAAyC,CAAC;AACnF,YAAY,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAC,cAAc,EAAC,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAC,iBAAiB,EAAC,MAAM,+BAA+B,CAAC;AACrE,YAAY,EAAC,aAAa,IAAI,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACxE,YAAY,EAAC,iBAAiB,EAAC,MAAM,+BAA+B,CAAC;AACrE,YAAY,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AACpE,YAAY,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC"}