@deck.gl/geo-layers 8.8.0-beta.2 → 8.8.0-beta.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 +1892 -1657
- package/dist/es5/geohash-layer/geohash-layer.js +71 -0
- package/dist/es5/geohash-layer/geohash-layer.js.map +1 -0
- package/dist/es5/geohash-layer/geohash-utils.js +77 -0
- package/dist/es5/geohash-layer/geohash-utils.js.map +1 -0
- package/dist/es5/h3-layers/h3-cluster-layer.js +7 -0
- package/dist/es5/h3-layers/h3-cluster-layer.js.map +1 -1
- package/dist/es5/h3-layers/h3-hexagon-layer.js +3 -0
- package/dist/es5/h3-layers/h3-hexagon-layer.js.map +1 -1
- package/dist/es5/index.js +16 -0
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/mvt-layer/mvt-layer.js.map +1 -1
- package/dist/es5/quadkey-layer/quadkey-layer.js.map +1 -1
- package/dist/es5/s2-layer/s2-layer.js.map +1 -1
- package/dist/es5/terrain-layer/terrain-layer.js +57 -34
- package/dist/es5/terrain-layer/terrain-layer.js.map +1 -1
- package/dist/es5/tile-3d-layer/tile-3d-layer.js.map +1 -1
- package/dist/es5/tile-layer/tile-layer.js +4 -2
- package/dist/es5/tile-layer/tile-layer.js.map +1 -1
- package/dist/es5/tile-layer/tileset-2d.js +38 -1
- package/dist/es5/tile-layer/tileset-2d.js.map +1 -1
- package/dist/es5/tile-layer/utils.js +46 -12
- package/dist/es5/tile-layer/utils.js.map +1 -1
- package/dist/es5/trips-layer/trips-layer.js.map +1 -1
- package/dist/esm/geohash-layer/geohash-layer.js +29 -0
- package/dist/esm/geohash-layer/geohash-layer.js.map +1 -0
- package/dist/esm/geohash-layer/geohash-utils.js +56 -0
- package/dist/esm/geohash-layer/geohash-utils.js.map +1 -0
- package/dist/esm/h3-layers/h3-cluster-layer.js +5 -0
- package/dist/esm/h3-layers/h3-cluster-layer.js.map +1 -1
- package/dist/esm/h3-layers/h3-hexagon-layer.js +4 -0
- package/dist/esm/h3-layers/h3-hexagon-layer.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mvt-layer/mvt-layer.js.map +1 -1
- package/dist/esm/quadkey-layer/quadkey-layer.js.map +1 -1
- package/dist/esm/s2-layer/s2-layer.js.map +1 -1
- package/dist/esm/terrain-layer/terrain-layer.js +35 -13
- package/dist/esm/terrain-layer/terrain-layer.js.map +1 -1
- package/dist/esm/tile-3d-layer/tile-3d-layer.js.map +1 -1
- package/dist/esm/tile-layer/tile-layer.js +6 -2
- package/dist/esm/tile-layer/tile-layer.js.map +1 -1
- package/dist/esm/tile-layer/tileset-2d.js +36 -3
- package/dist/esm/tile-layer/tileset-2d.js.map +1 -1
- package/dist/esm/tile-layer/utils.js +36 -0
- package/dist/esm/tile-layer/utils.js.map +1 -1
- package/dist/esm/trips-layer/trips-layer.js.map +1 -1
- package/dist.min.js +2 -2
- package/package.json +2 -2
- package/src/geohash-layer/geohash-layer.ts +39 -0
- package/src/geohash-layer/geohash-utils.ts +54 -0
- package/src/h3-layers/h3-cluster-layer.ts +5 -0
- package/src/h3-layers/h3-hexagon-layer.ts +5 -9
- package/src/index.ts +5 -0
- package/src/mvt-layer/mvt-layer.ts +1 -0
- package/src/quadkey-layer/quadkey-layer.ts +1 -0
- package/src/s2-layer/s2-layer.ts +1 -0
- package/src/terrain-layer/{terrain-layer.js → terrain-layer.ts} +120 -37
- package/src/tile-3d-layer/tile-3d-layer.ts +5 -4
- package/src/tile-layer/tile-layer.ts +4 -2
- package/src/tile-layer/tileset-2d.ts +41 -5
- package/src/tile-layer/utils.ts +44 -0
- package/src/trips-layer/trips-layer.ts +1 -0
- package/typed/geohash-layer/geohash-layer.d.ts +21 -0
- package/typed/geohash-layer/geohash-layer.d.ts.map +1 -0
- package/typed/geohash-layer/geohash-utils.d.ts +3 -0
- package/typed/geohash-layer/geohash-utils.d.ts.map +1 -0
- package/typed/h3-layers/h3-cluster-layer.d.ts +1 -0
- package/typed/h3-layers/h3-cluster-layer.d.ts.map +1 -1
- package/typed/h3-layers/h3-hexagon-layer.d.ts +2 -9
- package/typed/h3-layers/h3-hexagon-layer.d.ts.map +1 -1
- package/typed/index.d.ts +5 -0
- package/typed/index.d.ts.map +1 -1
- package/typed/mvt-layer/mvt-layer.d.ts +1 -0
- package/typed/mvt-layer/mvt-layer.d.ts.map +1 -1
- package/typed/quadkey-layer/quadkey-layer.d.ts +1 -0
- package/typed/quadkey-layer/quadkey-layer.d.ts.map +1 -1
- package/typed/s2-layer/s2-layer.d.ts +1 -0
- package/typed/s2-layer/s2-layer.d.ts.map +1 -1
- package/typed/terrain-layer/terrain-layer.d.ts +62 -26
- package/typed/terrain-layer/terrain-layer.d.ts.map +1 -1
- package/typed/tile-3d-layer/tile-3d-layer.d.ts +4 -3
- package/typed/tile-3d-layer/tile-3d-layer.d.ts.map +1 -1
- package/typed/tile-layer/tile-layer.d.ts +2 -4
- package/typed/tile-layer/tile-layer.d.ts.map +1 -1
- package/typed/tile-layer/tileset-2d.d.ts +10 -2
- package/typed/tile-layer/tileset-2d.d.ts.map +1 -1
- package/typed/tile-layer/utils.d.ts +14 -0
- package/typed/tile-layer/utils.d.ts.map +1 -1
- package/typed/trips-layer/trips-layer.d.ts +1 -0
- package/typed/trips-layer/trips-layer.d.ts.map +1 -1
- package/typed/geo-cell-layer/GeoCellLayer.js +0 -49
- package/typed/great-circle-layer/great-circle-layer.js +0 -29
- package/typed/h3-layers/h3-cluster-layer.js +0 -33
- package/typed/h3-layers/h3-hexagon-layer.js +0 -251
- package/typed/index.js +0 -33
- package/typed/mesh-layer/mesh-layer-fragment.glsl.js +0 -55
- package/typed/mesh-layer/mesh-layer-vertex.glsl.js +0 -80
- package/typed/mesh-layer/mesh-layer.js +0 -110
- package/typed/mvt-layer/coordinate-transform.js +0 -41
- package/typed/mvt-layer/find-index-binary.js +0 -96
- package/typed/mvt-layer/mvt-layer.js +0 -297
- package/typed/quadkey-layer/quadkey-layer.js +0 -18
- package/typed/quadkey-layer/quadkey-utils.js +0 -26
- package/typed/s2-layer/s2-geometry.js +0 -123
- package/typed/s2-layer/s2-layer.js +0 -37
- package/typed/s2-layer/s2-utils.js +0 -88
- package/typed/terrain-layer/terrain-layer.js +0 -226
- package/typed/tile-3d-layer/tile-3d-layer.js +0 -294
- package/typed/tile-layer/tile-2d-header.js +0 -113
- package/typed/tile-layer/tile-2d-traversal.js +0 -181
- package/typed/tile-layer/tile-layer.js +0 -192
- package/typed/tile-layer/tileset-2d.js +0 -399
- package/typed/tile-layer/types.js +0 -1
- package/typed/tile-layer/utils.js +0 -197
- 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.
|
|
5
|
+
"version": "8.8.0-beta.5",
|
|
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": "
|
|
57
|
+
"gitHead": "20b7becdb467aa917c17c9517461bf62ecc48b12"
|
|
58
58
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
/** Render filled and/or stroked polygons based on the [Geohash](https://en.wikipedia.org/wiki/Geohash) geospatial indexing system. */
|
|
22
|
+
export default class GeohashLayer<DataT = any, ExtraProps = {}> extends GeoCellLayer<
|
|
23
|
+
DataT,
|
|
24
|
+
Required<GeohashLayerProps> & ExtraProps
|
|
25
|
+
> {
|
|
26
|
+
static layerName = 'GeohashLayer';
|
|
27
|
+
static defaultProps: any = defaultProps;
|
|
28
|
+
|
|
29
|
+
indexToBounds(): Partial<GeoCellLayer['props']> | null {
|
|
30
|
+
const {data, getGeohash} = this.props;
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
data,
|
|
34
|
+
_normalize: false,
|
|
35
|
+
positionFormat: 'XY',
|
|
36
|
+
getPolygon: (x: DataT, objectInfo) => getGeohashPolygon(getGeohash(x, objectInfo))
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {h3SetToMultiPolygon, H3IndexInput} from 'h3-js';
|
|
2
2
|
|
|
3
3
|
import {AccessorFunction, createIterable, UpdateParameters, DefaultProps} from '@deck.gl/core';
|
|
4
|
+
import {H3HexagonLayer} from '@deck.gl/geo-layers';
|
|
4
5
|
import GeoCellLayer, {GeoCellLayerProps} from '../geo-cell-layer/GeoCellLayer';
|
|
5
6
|
|
|
6
7
|
const defaultProps: DefaultProps<H3ClusterLayerProps> = {
|
|
@@ -28,6 +29,10 @@ export default class H3ClusterLayer<DataT = any, ExtraProps = {}> extends GeoCel
|
|
|
28
29
|
static layerName = 'H3ClusterLayer';
|
|
29
30
|
static defaultProps = defaultProps;
|
|
30
31
|
|
|
32
|
+
initializeState(): void {
|
|
33
|
+
H3HexagonLayer._checkH3Lib();
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
updateState({props, changeFlags}: UpdateParameters<this>): void {
|
|
32
37
|
if (
|
|
33
38
|
changeFlags.dataChanged ||
|
|
@@ -143,15 +143,7 @@ type _H3HexagonLayerProps<DataT> = {
|
|
|
143
143
|
};
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
|
-
*
|
|
147
|
-
* rather than centroid lat/longs. The shape of each hexagon is determined
|
|
148
|
-
* based on a single "center" hexagon, which can be selected by passing in
|
|
149
|
-
* a center lat/lon pair. If not provided, the map center will be used.
|
|
150
|
-
*
|
|
151
|
-
* Also sets the `hexagonId` field in the onHover/onClick callback's info
|
|
152
|
-
* objects. Since this is calculated using math, hexagonId will be present
|
|
153
|
-
* even when no corresponding hexagon is in the data set. You can check
|
|
154
|
-
* index !== -1 to see if picking matches an actual object.
|
|
146
|
+
* Render hexagons from the [H3](https://h3geo.org/) geospatial indexing system.
|
|
155
147
|
*/
|
|
156
148
|
export default class H3HexagonLayer<DataT = any, ExtraPropsT = {}> extends CompositeLayer<
|
|
157
149
|
ExtraPropsT & Required<_H3HexagonLayerProps<DataT> & Required<PolygonLayerProps<DataT>>>
|
|
@@ -159,7 +151,11 @@ export default class H3HexagonLayer<DataT = any, ExtraPropsT = {}> extends Compo
|
|
|
159
151
|
static defaultProps = defaultProps;
|
|
160
152
|
static layerName = 'H3HexagonLayer';
|
|
161
153
|
|
|
154
|
+
// See `main/bundle.ts`
|
|
155
|
+
static _checkH3Lib = () => {};
|
|
156
|
+
|
|
162
157
|
initializeState() {
|
|
158
|
+
H3HexagonLayer._checkH3Lib();
|
|
163
159
|
this.state = {
|
|
164
160
|
edgeLengthKM: 0,
|
|
165
161
|
resolution: -1
|
package/src/index.ts
CHANGED
|
@@ -29,7 +29,9 @@ 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
|
|
|
34
|
+
export {default as _GeoCellLayer} from './geo-cell-layer/GeoCellLayer';
|
|
33
35
|
export {getURLFromTemplate as _getURLFromTemplate} from './tile-layer/utils';
|
|
34
36
|
export {default as _Tileset2D} from './tile-layer/tileset-2d';
|
|
35
37
|
export {default as _Tile2DHeader} from './tile-layer/tile-2d-header';
|
|
@@ -43,4 +45,7 @@ export type {TileLayerProps} from './tile-layer/tile-layer';
|
|
|
43
45
|
export type {GeoBoundingBox} from './tile-layer/types';
|
|
44
46
|
export type {QuadkeyLayerProps} from './quadkey-layer/quadkey-layer';
|
|
45
47
|
export type {TileLoadProps as _TileLoadProps} from './tile-layer/types';
|
|
48
|
+
export type {TerrainLayerProps} from './terrain-layer/terrain-layer';
|
|
49
|
+
export type {Tile3DLayerProps} from './tile-3d-layer/tile-3d-layer';
|
|
46
50
|
export type {MVTLayerProps} from './mvt-layer/mvt-layer';
|
|
51
|
+
export type {GeoCellLayerProps as _GeoCellLayerProps} from './geo-cell-layer/GeoCellLayer';
|
|
@@ -85,6 +85,7 @@ export type _MVTLayerProps = {
|
|
|
85
85
|
|
|
86
86
|
type ContentWGS84Cache = {_contentWGS84?: Feature[]};
|
|
87
87
|
|
|
88
|
+
/** Render data formatted as [Mapbox Vector Tiles](https://docs.mapbox.com/vector-tiles/specification/). */
|
|
88
89
|
export default class MVTLayer<DataT extends Feature = Feature, ExtraProps = {}> extends TileLayer<
|
|
89
90
|
ParsedMvtTile,
|
|
90
91
|
Required<_MVTLayerProps> & ExtraProps
|
|
@@ -19,6 +19,7 @@ type _QuadkeyLayerProps<DataT> = {
|
|
|
19
19
|
getQuadkey?: AccessorFunction<DataT, string>;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
/** Render filled and/or stroked polygons based on the [Quadkey](https://towardsdatascience.com/geospatial-indexing-with-quadkeys-d933dff01496) geospatial indexing system. */
|
|
22
23
|
export default class QuadkeyLayer<DataT = any, ExtraProps = {}> extends GeoCellLayer<
|
|
23
24
|
DataT,
|
|
24
25
|
Required<_QuadkeyLayerProps<DataT>> & ExtraProps
|
package/src/s2-layer/s2-layer.ts
CHANGED
|
@@ -39,6 +39,7 @@ type _S2LayerProps<DataT> = {
|
|
|
39
39
|
getS2Token?: AccessorFunction<DataT, string>;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
+
/** Render filled and/or stroked polygons based on the [S2](http://s2geometry.io/) geospatial indexing system. */
|
|
42
43
|
export default class S2Layer<DataT = any, ExtraProps = {}> extends GeoCellLayer<
|
|
43
44
|
DataT,
|
|
44
45
|
Required<_S2LayerProps<DataT>> & ExtraProps
|
|
@@ -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 {
|
|
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,73 @@ 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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
+
/** Render mesh surfaces from height map images. */
|
|
129
|
+
export default class TerrainLayer<ExtraPropsT = {}> extends CompositeLayer<
|
|
130
|
+
ExtraPropsT & Required<_TerrainLayerProps & Required<TileLayerProps<MeshAndTexture>>>
|
|
131
|
+
> {
|
|
132
|
+
static defaultProps = defaultProps;
|
|
133
|
+
static layerName = 'TerrainLayer';
|
|
134
|
+
|
|
135
|
+
state!: {
|
|
136
|
+
isTiled?: boolean;
|
|
137
|
+
terrain: MeshAttributes;
|
|
138
|
+
zRange?: ZRange | null;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
updateState({props, oldProps}: UpdateParameters<this>): void {
|
|
77
142
|
const elevationDataChanged = props.elevationData !== oldProps.elevationData;
|
|
78
143
|
if (elevationDataChanged) {
|
|
79
144
|
const {elevationData} = props;
|
|
@@ -92,17 +157,25 @@ export default class TerrainLayer extends CompositeLayer {
|
|
|
92
157
|
props.bounds !== oldProps.bounds;
|
|
93
158
|
|
|
94
159
|
if (!this.state.isTiled && shouldReload) {
|
|
95
|
-
|
|
160
|
+
// When state.isTiled, elevationData cannot be an array
|
|
161
|
+
const terrain = this.loadTerrain(props as TerrainLoadProps);
|
|
96
162
|
this.setState({terrain});
|
|
97
163
|
}
|
|
98
164
|
|
|
99
165
|
// TODO - remove in v9
|
|
166
|
+
// @ts-ignore
|
|
100
167
|
if (props.workerUrl) {
|
|
101
168
|
log.removed('workerUrl', 'loadOptions.terrain.workerUrl')();
|
|
102
169
|
}
|
|
103
170
|
}
|
|
104
171
|
|
|
105
|
-
loadTerrain({
|
|
172
|
+
loadTerrain({
|
|
173
|
+
elevationData,
|
|
174
|
+
bounds,
|
|
175
|
+
elevationDecoder,
|
|
176
|
+
meshMaxError,
|
|
177
|
+
signal
|
|
178
|
+
}: TerrainLoadProps): Promise<MeshAttributes> | null {
|
|
106
179
|
if (!elevationData) {
|
|
107
180
|
return null;
|
|
108
181
|
}
|
|
@@ -121,20 +194,25 @@ export default class TerrainLayer extends CompositeLayer {
|
|
|
121
194
|
return fetch(elevationData, {propName: 'elevationData', layer: this, loadOptions, signal});
|
|
122
195
|
}
|
|
123
196
|
|
|
124
|
-
getTiledTerrainData(tile) {
|
|
197
|
+
getTiledTerrainData(tile: TileLoadProps): Promise<MeshAndTexture> {
|
|
125
198
|
const {elevationData, fetch, texture, elevationDecoder, meshMaxError} = this.props;
|
|
126
199
|
const {viewport} = this.context;
|
|
127
200
|
const dataUrl = getURLFromTemplate(elevationData, tile);
|
|
128
|
-
const textureUrl = getURLFromTemplate(texture, tile);
|
|
201
|
+
const textureUrl = texture && getURLFromTemplate(texture, tile);
|
|
129
202
|
|
|
130
|
-
const {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
203
|
+
const {signal} = tile;
|
|
204
|
+
let bottomLeft = [0, 0] as [number, number];
|
|
205
|
+
let topRight = [0, 0] as [number, number];
|
|
206
|
+
if (viewport.isGeospatial) {
|
|
207
|
+
const bbox = tile.bbox as GeoBoundingBox;
|
|
208
|
+
bottomLeft = viewport.projectFlat([bbox.west, bbox.south]);
|
|
209
|
+
topRight = viewport.projectFlat([bbox.east, bbox.north]);
|
|
210
|
+
} else {
|
|
211
|
+
const bbox = tile.bbox as Exclude<TileBoundingBox, GeoBoundingBox>;
|
|
212
|
+
bottomLeft = [bbox.left, bbox.bottom];
|
|
213
|
+
topRight = [bbox.right, bbox.top];
|
|
214
|
+
}
|
|
215
|
+
const bounds: Bounds = [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]];
|
|
138
216
|
|
|
139
217
|
const terrain = this.loadTerrain({
|
|
140
218
|
elevationData: dataUrl,
|
|
@@ -151,9 +229,17 @@ export default class TerrainLayer extends CompositeLayer {
|
|
|
151
229
|
return Promise.all([terrain, surface]);
|
|
152
230
|
}
|
|
153
231
|
|
|
154
|
-
renderSubLayers(
|
|
232
|
+
renderSubLayers(
|
|
233
|
+
props: TileLayerProps<MeshAndTexture> & {
|
|
234
|
+
id: string;
|
|
235
|
+
data: MeshAndTexture;
|
|
236
|
+
tile: Tile2DHeader<MeshAndTexture>;
|
|
237
|
+
}
|
|
238
|
+
) {
|
|
155
239
|
const SubLayerClass = this.getSubLayerClass('mesh', SimpleMeshLayer);
|
|
156
|
-
|
|
240
|
+
|
|
241
|
+
const {color, wireframe, material} = this.props;
|
|
242
|
+
const {data} = props;
|
|
157
243
|
|
|
158
244
|
if (!data) {
|
|
159
245
|
return null;
|
|
@@ -168,12 +254,14 @@ export default class TerrainLayer extends CompositeLayer {
|
|
|
168
254
|
_instanced: false,
|
|
169
255
|
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
170
256
|
getPosition: d => [0, 0, 0],
|
|
171
|
-
getColor: color
|
|
257
|
+
getColor: color,
|
|
258
|
+
wireframe,
|
|
259
|
+
material
|
|
172
260
|
});
|
|
173
261
|
}
|
|
174
262
|
|
|
175
263
|
// Update zRange of viewport
|
|
176
|
-
onViewportLoad(tiles) {
|
|
264
|
+
onViewportLoad(tiles?: Tile2DHeader<MeshAndTexture>[]): void {
|
|
177
265
|
if (!tiles) {
|
|
178
266
|
return;
|
|
179
267
|
}
|
|
@@ -183,6 +271,7 @@ export default class TerrainLayer extends CompositeLayer {
|
|
|
183
271
|
.map(tile => tile.content)
|
|
184
272
|
.filter(Boolean)
|
|
185
273
|
.map(arr => {
|
|
274
|
+
// @ts-ignore
|
|
186
275
|
const bounds = arr[0].header.boundingBox;
|
|
187
276
|
return bounds.map(bound => bound[2]);
|
|
188
277
|
});
|
|
@@ -197,7 +286,7 @@ export default class TerrainLayer extends CompositeLayer {
|
|
|
197
286
|
}
|
|
198
287
|
}
|
|
199
288
|
|
|
200
|
-
renderLayers() {
|
|
289
|
+
renderLayers(): Layer | null | LayersList {
|
|
201
290
|
const {
|
|
202
291
|
color,
|
|
203
292
|
material,
|
|
@@ -220,14 +309,11 @@ export default class TerrainLayer extends CompositeLayer {
|
|
|
220
309
|
} = this.props;
|
|
221
310
|
|
|
222
311
|
if (this.state.isTiled) {
|
|
223
|
-
return new TileLayer(
|
|
312
|
+
return new TileLayer<MeshAndTexture>(
|
|
224
313
|
this.getSubLayerProps({
|
|
225
314
|
id: 'tiles'
|
|
226
315
|
}),
|
|
227
316
|
{
|
|
228
|
-
wireframe,
|
|
229
|
-
color,
|
|
230
|
-
material,
|
|
231
317
|
getTileData: this.getTiledTerrainData.bind(this),
|
|
232
318
|
renderSubLayers: this.renderSubLayers.bind(this),
|
|
233
319
|
updateTriggers: {
|
|
@@ -273,6 +359,3 @@ export default class TerrainLayer extends CompositeLayer {
|
|
|
273
359
|
);
|
|
274
360
|
}
|
|
275
361
|
}
|
|
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<
|
|
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
|
|
47
|
+
export type Tile3DLayerProps<DataT = any> = _Tile3DLayerProps<DataT> & CompositeLayerProps<DataT>;
|
|
48
48
|
|
|
49
49
|
/** Props added by the Tile3DLayer */
|
|
50
|
-
type
|
|
50
|
+
type _Tile3DLayerProps<DataT> = {
|
|
51
51
|
/** Color Accessor for point clouds. **/
|
|
52
52
|
getPointColor?: Accessor<DataT, Color>;
|
|
53
53
|
|
|
@@ -75,8 +75,9 @@ type _Tile3dLayerProps<DataT> = {
|
|
|
75
75
|
_getMeshColor?: (tile: Tile3D) => Color;
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
+
/** Render 3d tiles data formatted according to the [3D Tiles Specification](https://www.opengeospatial.org/standards/3DTiles) and [`ESRI I3S`](https://github.com/Esri/i3s-spec) */
|
|
78
79
|
export default class Tile3DLayer<DataT = any, ExtraPropsT = {}> extends CompositeLayer<
|
|
79
|
-
ExtraPropsT & Required<
|
|
80
|
+
ExtraPropsT & Required<_Tile3DLayerProps<DataT>>
|
|
80
81
|
> {
|
|
81
82
|
static defaultProps = defaultProps as any;
|
|
82
83
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
package/src/tile-layer/utils.ts
CHANGED
|
@@ -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(
|
|
@@ -55,6 +55,7 @@ type _TripsLayerProps<DataT = any> = {
|
|
|
55
55
|
getTimestamps?: AccessorFunction<DataT, NumericArray>;
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
/** Render animated paths that represent vehicle trips. */
|
|
58
59
|
export default class TripsLayer<DataT = any, ExtraProps = {}> extends PathLayer<
|
|
59
60
|
DataT,
|
|
60
61
|
Required<_TripsLayerProps> & ExtraProps
|