@deck.gl/carto 8.9.0-alpha.2 → 8.9.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +1927 -1675
- package/dist/es5/api/layer-map.js +104 -9
- package/dist/es5/api/layer-map.js.map +1 -1
- package/dist/es5/api/maps-v3-client.js +10 -8
- package/dist/es5/api/maps-v3-client.js.map +1 -1
- package/dist/es5/api/parseMap.js +55 -7
- package/dist/es5/api/parseMap.js.map +1 -1
- package/dist/es5/api/types.js +2 -0
- package/dist/es5/api/types.js.map +1 -0
- package/dist/es5/index.js +0 -20
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/layers/carto-layer.js +19 -2
- package/dist/es5/layers/carto-layer.js.map +1 -1
- package/dist/es5/layers/carto-tile-layer.js +33 -107
- package/dist/es5/layers/carto-tile-layer.js.map +1 -1
- package/dist/es5/layers/h3-tile-layer.js +10 -1
- package/dist/es5/layers/h3-tile-layer.js.map +1 -1
- package/dist/es5/layers/quadbin-layer.js.map +1 -1
- package/dist/es5/layers/quadbin-tile-layer.js +10 -1
- package/dist/es5/layers/quadbin-tile-layer.js.map +1 -1
- package/dist/es5/layers/quadbin-tileset-2d.js +13 -11
- package/dist/es5/layers/quadbin-tileset-2d.js.map +1 -1
- package/dist/es5/layers/quadbin-utils.js +6 -82
- package/dist/es5/layers/quadbin-utils.js.map +1 -1
- package/dist/es5/layers/schema/carto-spatial-tile-loader.js +16 -32
- package/dist/es5/layers/schema/carto-spatial-tile-loader.js.map +1 -1
- package/dist/es5/layers/schema/carto-tile.js +30 -6
- package/dist/es5/layers/schema/carto-tile.js.map +1 -1
- package/dist/es5/layers/schema/carto-vector-tile-loader.js +81 -0
- package/dist/es5/layers/schema/carto-vector-tile-loader.js.map +1 -0
- package/dist/es5/layers/schema/spatialjson-utils.js +4 -3
- package/dist/es5/layers/schema/spatialjson-utils.js.map +1 -1
- package/dist/es5/layers/schema/tile-loader-utils.js +34 -0
- package/dist/es5/layers/schema/tile-loader-utils.js.map +1 -0
- package/dist/es5/layers/spatial-index-tile-layer.js +40 -0
- package/dist/es5/layers/spatial-index-tile-layer.js.map +1 -1
- package/dist/esm/api/layer-map.js +85 -9
- package/dist/esm/api/layer-map.js.map +1 -1
- package/dist/esm/api/maps-v3-client.js +5 -2
- package/dist/esm/api/maps-v3-client.js.map +1 -1
- package/dist/esm/api/parseMap.js +58 -7
- package/dist/esm/api/parseMap.js.map +1 -1
- package/dist/esm/api/types.js +2 -0
- package/dist/esm/api/types.js.map +1 -0
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/layers/carto-layer.js +18 -0
- package/dist/esm/layers/carto-layer.js.map +1 -1
- package/dist/esm/layers/carto-tile-layer.js +31 -82
- package/dist/esm/layers/carto-tile-layer.js.map +1 -1
- package/dist/esm/layers/h3-tile-layer.js +6 -1
- package/dist/esm/layers/h3-tile-layer.js.map +1 -1
- package/dist/esm/layers/quadbin-layer.js.map +1 -1
- package/dist/esm/layers/quadbin-tile-layer.js +6 -1
- package/dist/esm/layers/quadbin-tile-layer.js.map +1 -1
- package/dist/esm/layers/quadbin-tileset-2d.js +12 -10
- package/dist/esm/layers/quadbin-tileset-2d.js.map +1 -1
- package/dist/esm/layers/quadbin-utils.js +2 -67
- package/dist/esm/layers/quadbin-utils.js.map +1 -1
- package/dist/esm/layers/schema/carto-spatial-tile-loader.js +14 -29
- package/dist/esm/layers/schema/carto-spatial-tile-loader.js.map +1 -1
- package/dist/esm/layers/schema/carto-tile.js +22 -6
- package/dist/esm/layers/schema/carto-tile.js.map +1 -1
- package/dist/esm/layers/schema/carto-vector-tile-loader.js +40 -0
- package/dist/esm/layers/schema/carto-vector-tile-loader.js.map +1 -0
- package/dist/esm/layers/schema/spatialjson-utils.js +4 -3
- package/dist/esm/layers/schema/spatialjson-utils.js.map +1 -1
- package/dist/esm/layers/schema/tile-loader-utils.js +23 -0
- package/dist/esm/layers/schema/tile-loader-utils.js.map +1 -0
- package/dist/esm/layers/spatial-index-tile-layer.js +40 -1
- package/dist/esm/layers/spatial-index-tile-layer.js.map +1 -1
- package/dist.min.js +4 -4
- package/package.json +4 -3
- package/src/api/layer-map.ts +103 -17
- package/src/api/maps-v3-client.ts +5 -3
- package/src/api/parseMap.ts +90 -17
- package/src/api/types.ts +108 -0
- package/src/index.ts +0 -5
- package/src/layers/carto-layer.ts +9 -2
- package/src/layers/carto-tile-layer.ts +32 -82
- package/src/layers/h3-tile-layer.ts +7 -1
- package/src/layers/quadbin-layer.ts +1 -1
- package/src/layers/quadbin-tile-layer.ts +7 -1
- package/src/layers/quadbin-tileset-2d.ts +14 -12
- package/src/layers/quadbin-utils.ts +4 -85
- package/src/layers/schema/carto-spatial-tile-loader.ts +12 -29
- package/src/layers/schema/carto-tile.ts +31 -6
- package/src/layers/schema/carto-vector-tile-loader.ts +39 -0
- package/src/layers/schema/spatialjson-utils.ts +4 -4
- package/src/layers/schema/tile-loader-utils.ts +22 -0
- package/src/layers/spatial-index-tile-layer.ts +37 -1
- package/typed/api/layer-map.d.ts +10 -13
- package/typed/api/layer-map.d.ts.map +1 -1
- package/typed/api/maps-v3-client.d.ts +1 -0
- package/typed/api/maps-v3-client.d.ts.map +1 -1
- package/typed/api/parseMap.d.ts +1 -0
- package/typed/api/parseMap.d.ts.map +1 -1
- package/typed/api/types.d.ts +87 -0
- package/typed/api/types.d.ts.map +1 -0
- package/typed/index.d.ts +0 -1
- package/typed/index.d.ts.map +1 -1
- package/typed/layers/carto-layer.d.ts.map +1 -1
- package/typed/layers/carto-tile-layer.d.ts +2 -0
- package/typed/layers/carto-tile-layer.d.ts.map +1 -1
- package/typed/layers/h3-tile-layer.d.ts.map +1 -1
- package/typed/layers/quadbin-layer.d.ts +1 -1
- package/typed/layers/quadbin-tile-layer.d.ts.map +1 -1
- package/typed/layers/quadbin-tileset-2d.d.ts +6 -5
- package/typed/layers/quadbin-tileset-2d.d.ts.map +1 -1
- package/typed/layers/quadbin-utils.d.ts +2 -12
- package/typed/layers/quadbin-utils.d.ts.map +1 -1
- package/typed/layers/schema/carto-spatial-tile-loader.d.ts.map +1 -1
- package/typed/layers/schema/carto-tile.d.ts +4 -0
- package/typed/layers/schema/carto-tile.d.ts.map +1 -1
- package/typed/layers/schema/carto-vector-tile-loader.d.ts +4 -0
- package/typed/layers/schema/carto-vector-tile-loader.d.ts.map +1 -0
- package/typed/layers/schema/spatialjson-utils.d.ts +1 -1
- package/typed/layers/schema/spatialjson-utils.d.ts.map +1 -1
- package/typed/layers/schema/tile-loader-utils.d.ts +5 -0
- package/typed/layers/schema/tile-loader-utils.d.ts.map +1 -0
- package/typed/layers/spatial-index-tile-layer.d.ts +2 -1
- package/typed/layers/spatial-index-tile-layer.d.ts.map +1 -1
- package/typed/api/index.js +0 -3
- package/typed/api/layer-map.js +0 -264
- package/typed/api/maps-api-common.js +0 -50
- package/typed/api/maps-client.js +0 -125
- package/typed/api/maps-v3-client.js +0 -304
- package/typed/api/parseMap.js +0 -178
- package/typed/basemap.js +0 -9
- package/typed/config.js +0 -35
- package/typed/index.js +0 -10
- package/typed/layers/carto-layer.js +0 -173
- package/typed/layers/carto-tile-layer.js +0 -105
- package/typed/layers/h3-tile-layer.js +0 -47
- package/typed/layers/h3-tileset-2d.js +0 -85
- package/typed/layers/quadkey-tile-layer.d.ts +0 -21
- package/typed/layers/quadkey-tile-layer.d.ts.map +0 -1
- package/typed/layers/quadkey-tile-layer.js +0 -42
- package/typed/layers/quadkey-tileset-2d.d.ts +0 -15
- package/typed/layers/quadkey-tileset-2d.d.ts.map +0 -1
- package/typed/layers/quadkey-tileset-2d.js +0 -36
- package/typed/layers/schema/carto-tile.js +0 -161
- package/typed/layers/spatial-index-tile-layer.js +0 -40
- package/typed/style/color-bins-style.js +0 -12
- package/typed/style/color-categories-style.js +0 -16
- package/typed/style/color-continuous-style.js +0 -12
- package/typed/style/palette.js +0 -62
- package/typed/style/utils.js +0 -15
- package/typed/utils.js +0 -4
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import {registerLoaders} from '@loaders.gl/core';
|
|
2
|
+
import CartoVectorTileLoader from './schema/carto-vector-tile-loader';
|
|
3
|
+
registerLoaders([CartoVectorTileLoader]);
|
|
4
|
+
|
|
5
|
+
import {DefaultProps} from '@deck.gl/core';
|
|
4
6
|
import {ClipExtension} from '@deck.gl/extensions';
|
|
5
7
|
import {
|
|
6
8
|
MVTLayer,
|
|
@@ -11,81 +13,16 @@ import {
|
|
|
11
13
|
_TileLoadProps as TileLoadProps
|
|
12
14
|
} from '@deck.gl/geo-layers';
|
|
13
15
|
import {GeoJsonLayer} from '@deck.gl/layers';
|
|
14
|
-
import {geojsonToBinary} from '@loaders.gl/gis';
|
|
15
|
-
import {KeyValueProperties, Tile, TileReader} from './schema/carto-tile';
|
|
16
|
-
import {TileFormat, TILE_FORMATS} from '../api/maps-api-common';
|
|
17
|
-
import {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
16
|
+
import {binaryToGeojson, geojsonToBinary} from '@loaders.gl/gis';
|
|
18
17
|
import type {BinaryFeatures} from '@loaders.gl/schema';
|
|
18
|
+
import {TileFormat, TILE_FORMATS} from '../api/maps-api-common';
|
|
19
19
|
import type {Feature} from 'geojson';
|
|
20
20
|
|
|
21
|
-
function parseJSON(arrayBuffer: ArrayBuffer): any {
|
|
22
|
-
return JSON.parse(new TextDecoder().decode(arrayBuffer));
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function parsePbf(buffer: ArrayBuffer): Tile {
|
|
26
|
-
const pbf = new Protobuf(buffer);
|
|
27
|
-
const tile = TileReader.read(pbf);
|
|
28
|
-
return tile;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function unpackProperties(properties: KeyValueProperties[]) {
|
|
32
|
-
if (!properties || !properties.length) {
|
|
33
|
-
return [];
|
|
34
|
-
}
|
|
35
|
-
return properties.map(item => {
|
|
36
|
-
const currentRecord: Record<string, unknown> = {};
|
|
37
|
-
item.data.forEach(({key, value}) => {
|
|
38
|
-
currentRecord[key] = value;
|
|
39
|
-
});
|
|
40
|
-
return currentRecord;
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function parseCartoTile(arrayBuffer: ArrayBuffer, options?: LoaderOptions): BinaryFeatures | null {
|
|
45
|
-
if (!arrayBuffer) return null;
|
|
46
|
-
const formatTiles = options && options.cartoTile && options.cartoTile.formatTiles;
|
|
47
|
-
if (formatTiles === TILE_FORMATS.GEOJSON) return geojsonToBinary(parseJSON(arrayBuffer).features);
|
|
48
|
-
|
|
49
|
-
const tile = parsePbf(arrayBuffer);
|
|
50
|
-
|
|
51
|
-
const {points, lines, polygons} = tile;
|
|
52
|
-
const data = {
|
|
53
|
-
points: {...points, properties: unpackProperties(points.properties)},
|
|
54
|
-
lines: {...lines, properties: unpackProperties(lines.properties)},
|
|
55
|
-
polygons: {...polygons, properties: unpackProperties(polygons.properties)}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// Note: there is slight, difference in `numericProps` type, however geojson/mvtlayer can cope with this
|
|
59
|
-
return data as unknown as BinaryFeatures;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
21
|
const defaultTileFormat = TILE_FORMATS.BINARY;
|
|
63
22
|
|
|
64
|
-
const CartoTileLoader: LoaderWithParser = {
|
|
65
|
-
name: 'CARTO Tile',
|
|
66
|
-
version: '1',
|
|
67
|
-
id: 'cartoTile',
|
|
68
|
-
module: 'carto',
|
|
69
|
-
extensions: ['pbf'],
|
|
70
|
-
mimeTypes: [
|
|
71
|
-
'application/vnd.carto-vector-tile',
|
|
72
|
-
'application/x-protobuf' // Back-compatibility
|
|
73
|
-
],
|
|
74
|
-
category: 'geometry',
|
|
75
|
-
worker: false,
|
|
76
|
-
parse: async (arrayBuffer, options) => parseCartoTile(arrayBuffer, options),
|
|
77
|
-
parseSync: parseCartoTile,
|
|
78
|
-
options: {
|
|
79
|
-
cartoTile: {
|
|
80
|
-
formatTiles: defaultTileFormat
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
23
|
const defaultProps: DefaultProps<CartoTileLayerProps> = {
|
|
86
24
|
...MVTLayer.defaultProps,
|
|
87
|
-
formatTiles: defaultTileFormat
|
|
88
|
-
loaders: [CartoTileLoader]
|
|
25
|
+
formatTiles: defaultTileFormat
|
|
89
26
|
};
|
|
90
27
|
|
|
91
28
|
/** All properties supported by CartoTileLayer. */
|
|
@@ -110,6 +47,12 @@ export default class CartoTileLayer<
|
|
|
110
47
|
static layerName = 'CartoTileLayer';
|
|
111
48
|
static defaultProps = defaultProps;
|
|
112
49
|
|
|
50
|
+
initializeState(): void {
|
|
51
|
+
super.initializeState();
|
|
52
|
+
const binary = this.props.formatTiles === TILE_FORMATS.BINARY;
|
|
53
|
+
this.setState({binary});
|
|
54
|
+
}
|
|
55
|
+
|
|
113
56
|
getTileData(tile: TileLoadProps) {
|
|
114
57
|
const url = _getURLFromTemplate(this.state.data, tile);
|
|
115
58
|
if (!url) {
|
|
@@ -120,17 +63,13 @@ export default class CartoTileLayer<
|
|
|
120
63
|
const {fetch, formatTiles} = this.props;
|
|
121
64
|
const {signal} = tile;
|
|
122
65
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
Object.values(TILE_FORMATS).includes(formatTiles),
|
|
131
|
-
`Invalid value for formatTiles: ${formatTiles}. Use value from TILE_FORMATS`
|
|
132
|
-
);
|
|
133
|
-
loadOptions.cartoTile = {formatTiles};
|
|
66
|
+
// The backend doesn't yet support our custom mime-type, so force it here
|
|
67
|
+
// TODO remove once backend sends the correct mime-type
|
|
68
|
+
if (formatTiles === TILE_FORMATS.BINARY) {
|
|
69
|
+
loadOptions = {
|
|
70
|
+
...loadOptions,
|
|
71
|
+
mimeType: 'application/vnd.carto-vector-tile'
|
|
72
|
+
};
|
|
134
73
|
}
|
|
135
74
|
|
|
136
75
|
return fetch(url, {propName: 'data', layer: this, loadOptions, signal});
|
|
@@ -161,4 +100,15 @@ export default class CartoTileLayer<
|
|
|
161
100
|
const subLayer = new GeoJsonLayer(subLayerProps);
|
|
162
101
|
return subLayer;
|
|
163
102
|
}
|
|
103
|
+
|
|
104
|
+
getPickingInfo(params) {
|
|
105
|
+
const info = super.getPickingInfo(params);
|
|
106
|
+
|
|
107
|
+
if (this.state.binary && info.index !== -1) {
|
|
108
|
+
const {data} = params.sourceLayer!.props;
|
|
109
|
+
info.object = binaryToGeojson(data as BinaryFeatures, {globalFeatureId: info.index}) as DataT;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return info;
|
|
113
|
+
}
|
|
164
114
|
}
|
|
@@ -94,7 +94,13 @@ export default class H3TileLayer<DataT = any, ExtraPropsT = {}> extends Composit
|
|
|
94
94
|
renderSubLayers,
|
|
95
95
|
// minZoom and maxZoom are H3 resolutions, however we must use this naming as that is what the Tileset2D class expects
|
|
96
96
|
minZoom: minresolution,
|
|
97
|
-
maxZoom: maxresolution
|
|
97
|
+
maxZoom: maxresolution,
|
|
98
|
+
loadOptions: {
|
|
99
|
+
...this.getLoadOptions(),
|
|
100
|
+
cartoSpatialTile: {
|
|
101
|
+
scheme: 'h3'
|
|
102
|
+
}
|
|
103
|
+
}
|
|
98
104
|
})
|
|
99
105
|
];
|
|
100
106
|
}
|
|
@@ -19,7 +19,7 @@ type _QuadbinLayerProps<DataT> = {
|
|
|
19
19
|
*
|
|
20
20
|
* By default, it reads `quadbin` property of data object.
|
|
21
21
|
*/
|
|
22
|
-
getQuadbin?: AccessorFunction<DataT,
|
|
22
|
+
getQuadbin?: AccessorFunction<DataT, bigint>;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export default class QuadbinLayer<DataT = any, ExtraProps = {}> extends GeoCellLayer<
|
|
@@ -64,7 +64,13 @@ export default class QuadbinTileLayer<DataT = any, ExtraProps = {}> extends Comp
|
|
|
64
64
|
// TODO: Tileset2D should be generic over TileIndex type
|
|
65
65
|
TilesetClass: QuadbinTileset2D as any,
|
|
66
66
|
renderSubLayers,
|
|
67
|
-
maxZoom
|
|
67
|
+
maxZoom,
|
|
68
|
+
loadOptions: {
|
|
69
|
+
...this.getLoadOptions(),
|
|
70
|
+
cartoSpatialTile: {
|
|
71
|
+
scheme: 'quadbin'
|
|
72
|
+
}
|
|
73
|
+
}
|
|
68
74
|
})
|
|
69
75
|
];
|
|
70
76
|
}
|
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
import {_Tileset2D as Tileset2D} from '@deck.gl/geo-layers';
|
|
2
|
-
import {
|
|
2
|
+
import {bigIntToHex, cellToParent, cellToTile, getResolution, tileToCell} from 'quadbin';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// For calculations bigint representation is used, but
|
|
5
|
+
// for constructing URL also provide the hexidecimal value
|
|
6
|
+
type QuadbinTileIndex = {q: bigint; i?: string};
|
|
5
7
|
|
|
6
8
|
export default class QuadbinTileset2D extends Tileset2D {
|
|
7
9
|
// @ts-expect-error for spatial indices, TileSet2d should be parametrized by TileIndexT
|
|
8
10
|
getTileIndices(opts): QuadbinTileIndex[] {
|
|
9
11
|
return super
|
|
10
12
|
.getTileIndices(opts)
|
|
11
|
-
.map(
|
|
12
|
-
.map(
|
|
13
|
+
.map(tileToCell)
|
|
14
|
+
.map(q => ({q, i: bigIntToHex(q)}));
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
// @ts-expect-error TileIndex must be generic
|
|
16
|
-
getTileId({i}: QuadbinTileIndex): string {
|
|
17
|
-
return i;
|
|
18
|
+
getTileId({q, i}: QuadbinTileIndex): string {
|
|
19
|
+
return i || bigIntToHex(q);
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
// @ts-expect-error TileIndex must be generic
|
|
21
|
-
getTileMetadata({
|
|
22
|
-
return super.getTileMetadata(
|
|
23
|
+
getTileMetadata({q}: QuadbinTileIndex) {
|
|
24
|
+
return super.getTileMetadata(cellToTile(q));
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
// @ts-expect-error TileIndex must be generic
|
|
26
|
-
getTileZoom({
|
|
27
|
-
return Number(
|
|
28
|
+
getTileZoom({q}: QuadbinTileIndex): number {
|
|
29
|
+
return Number(getResolution(q));
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
// @ts-expect-error TileIndex must be generic
|
|
31
|
-
getParentIndex({
|
|
32
|
-
return {
|
|
33
|
+
getParentIndex({q}: QuadbinTileIndex): QuadbinTileIndex {
|
|
34
|
+
return {q: cellToParent(q)};
|
|
33
35
|
}
|
|
34
36
|
}
|
|
@@ -1,91 +1,10 @@
|
|
|
1
1
|
import {worldToLngLat} from '@math.gl/web-mercator';
|
|
2
|
+
import {cellToTile} from 'quadbin';
|
|
2
3
|
|
|
3
4
|
const TILE_SIZE = 512;
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
0x3333333333333333n,
|
|
8
|
-
0x0f0f0f0f0f0f0f0fn,
|
|
9
|
-
0x00ff00ff00ff00ffn,
|
|
10
|
-
0x0000ffff0000ffffn,
|
|
11
|
-
0x00000000ffffffffn
|
|
12
|
-
];
|
|
13
|
-
const S = [0n, 1n, 2n, 4n, 8n, 16n];
|
|
14
|
-
|
|
15
|
-
export function indexToBigInt(index: string): bigint {
|
|
16
|
-
return BigInt(`0x${index}`);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function bigIntToIndex(quadbin: bigint): string {
|
|
20
|
-
return quadbin.toString(16);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function tileToQuadbin(tile): string {
|
|
24
|
-
if (tile.z < 0 || tile.z > 26) {
|
|
25
|
-
throw new Error('Wrong zoom');
|
|
26
|
-
}
|
|
27
|
-
const z = BigInt(tile.z);
|
|
28
|
-
let x = BigInt(tile.x) << (32n - z);
|
|
29
|
-
let y = BigInt(tile.y) << (32n - z);
|
|
30
|
-
|
|
31
|
-
for (let i = 0; i < 5; i++) {
|
|
32
|
-
const s = S[5 - i];
|
|
33
|
-
const b = B[4 - i];
|
|
34
|
-
x = (x | (x << s)) & b;
|
|
35
|
-
y = (y | (y << s)) & b;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const quadbin =
|
|
39
|
-
0x4000000000000000n |
|
|
40
|
-
(1n << 59n) | // | (mode << 59) | (mode_dep << 57)
|
|
41
|
-
(z << 52n) |
|
|
42
|
-
((x | (y << 1n)) >> 12n) |
|
|
43
|
-
(0xfffffffffffffn >> (z * 2n));
|
|
44
|
-
return bigIntToIndex(quadbin);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function quadbinToTile(index: string) {
|
|
48
|
-
const quadbin = indexToBigInt(index);
|
|
49
|
-
const mode = (quadbin >> 59n) & 7n;
|
|
50
|
-
const modeDep = (quadbin >> 57n) & 3n;
|
|
51
|
-
const z = (quadbin >> 52n) & 0x1fn;
|
|
52
|
-
const q = (quadbin & 0xfffffffffffffn) << 12n;
|
|
53
|
-
|
|
54
|
-
if (mode !== 1n && modeDep !== 0n) {
|
|
55
|
-
throw new Error('Wrong mode');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
let x = q;
|
|
59
|
-
let y = q >> 1n;
|
|
60
|
-
|
|
61
|
-
for (let i = 0; i < 6; i++) {
|
|
62
|
-
const s = S[i];
|
|
63
|
-
const b = B[i];
|
|
64
|
-
x = (x | (x >> s)) & b;
|
|
65
|
-
y = (y | (y >> s)) & b;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
x = x >> (32n - z);
|
|
69
|
-
y = y >> (32n - z);
|
|
70
|
-
|
|
71
|
-
return {z: Number(z), x: Number(x), y: Number(y)};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function quadbinZoom(index: string) {
|
|
75
|
-
const quadbin = indexToBigInt(index);
|
|
76
|
-
return (quadbin >> 52n) & 0x1fn;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function quadbinParent(index: string) {
|
|
80
|
-
const quadbin = indexToBigInt(index);
|
|
81
|
-
const zparent = quadbinZoom(index) - 1n;
|
|
82
|
-
const parent =
|
|
83
|
-
(quadbin & ~(0x1fn << 52n)) | (zparent << 52n) | (0xfffffffffffffn >> (zparent * 2n));
|
|
84
|
-
return bigIntToIndex(parent);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function quadbinToWorldBounds(quadbin: string): [number[], number[]] {
|
|
88
|
-
const {x, y, z} = quadbinToTile(quadbin);
|
|
6
|
+
export function quadbinToWorldBounds(quadbin: bigint): [number[], number[]] {
|
|
7
|
+
const {x, y, z} = cellToTile(quadbin);
|
|
89
8
|
const mask = 1 << z;
|
|
90
9
|
const scale = mask / TILE_SIZE;
|
|
91
10
|
return [
|
|
@@ -94,7 +13,7 @@ export function quadbinToWorldBounds(quadbin: string): [number[], number[]] {
|
|
|
94
13
|
];
|
|
95
14
|
}
|
|
96
15
|
|
|
97
|
-
export function getQuadbinPolygon(quadbin:
|
|
16
|
+
export function getQuadbinPolygon(quadbin: bigint): number[] {
|
|
98
17
|
const [topLeft, bottomRight] = quadbinToWorldBounds(quadbin);
|
|
99
18
|
const [w, n] = worldToLngLat(topLeft);
|
|
100
19
|
const [e, s] = worldToLngLat(bottomRight);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import Protobuf from 'pbf';
|
|
2
1
|
import {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
3
2
|
|
|
4
|
-
import {KeyValueProperties} from './carto-tile';
|
|
5
|
-
import {binaryToSpatialjson, Properties, SpatialJson} from './spatialjson-utils';
|
|
6
3
|
import {Tile, TileReader} from './carto-spatial-tile';
|
|
4
|
+
import {parsePbf, unpackProperties} from './tile-loader-utils';
|
|
5
|
+
import {IndexScheme, binaryToSpatialjson, SpatialJson} from './spatialjson-utils';
|
|
7
6
|
|
|
8
7
|
const CartoSpatialTileLoader: LoaderWithParser = {
|
|
9
8
|
name: 'CARTO Spatial Tile',
|
|
@@ -11,46 +10,30 @@ const CartoSpatialTileLoader: LoaderWithParser = {
|
|
|
11
10
|
id: 'cartoSpatialTile',
|
|
12
11
|
module: 'carto',
|
|
13
12
|
extensions: ['pbf'],
|
|
14
|
-
mimeTypes: [
|
|
15
|
-
'application/vnd.carto-spatial-tile',
|
|
16
|
-
'application/x-protobuf' // Back-compatibility
|
|
17
|
-
],
|
|
13
|
+
mimeTypes: ['application/vnd.carto-spatial-tile'],
|
|
18
14
|
category: 'geometry',
|
|
19
15
|
worker: false,
|
|
20
16
|
parse: async (arrayBuffer, options) => parseCartoSpatialTile(arrayBuffer, options),
|
|
21
17
|
parseSync: parseCartoSpatialTile,
|
|
22
|
-
options: {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const pbf = new Protobuf(buffer);
|
|
27
|
-
const tile = TileReader.read(pbf);
|
|
28
|
-
return tile;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function unpackProperties(properties: KeyValueProperties[]): Properties[] {
|
|
32
|
-
if (!properties || !properties.length) {
|
|
33
|
-
return [];
|
|
18
|
+
options: {
|
|
19
|
+
cartoSpatialTile: {
|
|
20
|
+
scheme: 'quadbin'
|
|
21
|
+
} as {scheme: IndexScheme}
|
|
34
22
|
}
|
|
35
|
-
|
|
36
|
-
const currentRecord: Properties = {};
|
|
37
|
-
item.data.forEach(({key, value}) => {
|
|
38
|
-
currentRecord[key] = value;
|
|
39
|
-
});
|
|
40
|
-
return currentRecord;
|
|
41
|
-
});
|
|
42
|
-
}
|
|
23
|
+
};
|
|
43
24
|
|
|
44
25
|
function parseCartoSpatialTile(
|
|
45
26
|
arrayBuffer: ArrayBuffer,
|
|
46
27
|
options?: LoaderOptions
|
|
47
28
|
): SpatialJson | null {
|
|
48
29
|
if (!arrayBuffer) return null;
|
|
49
|
-
const tile = parsePbf(arrayBuffer);
|
|
30
|
+
const tile: Tile = parsePbf(arrayBuffer, TileReader);
|
|
50
31
|
|
|
51
32
|
const {cells} = tile;
|
|
33
|
+
const scheme = options?.cartoSpatialTile?.scheme;
|
|
52
34
|
const data = {
|
|
53
|
-
cells: {...cells, properties: unpackProperties(cells.properties)}
|
|
35
|
+
cells: {...cells, properties: unpackProperties(cells.properties)},
|
|
36
|
+
scheme
|
|
54
37
|
};
|
|
55
38
|
|
|
56
39
|
return binaryToSpatialjson(data);
|
|
@@ -67,6 +67,21 @@ class IntsReader {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
// Fields ========================================
|
|
71
|
+
|
|
72
|
+
interface Fields {
|
|
73
|
+
id: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
class FieldsReader {
|
|
77
|
+
static read(pbf, end?: number): Fields {
|
|
78
|
+
return pbf.readFields(FieldsReader._readField, {id: 0}, end);
|
|
79
|
+
}
|
|
80
|
+
static _readField(this: void, tag: number, obj: Fields, pbf) {
|
|
81
|
+
if (tag === 1) obj.id = pbf.readVarint();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
70
85
|
// NumericProp ========================================
|
|
71
86
|
|
|
72
87
|
export interface NumericProp {
|
|
@@ -106,13 +121,21 @@ interface Points {
|
|
|
106
121
|
featureIds: Ints;
|
|
107
122
|
properties: KeyValueProperties[];
|
|
108
123
|
numericProps: Record<string, NumericProp>;
|
|
124
|
+
fields: Fields[];
|
|
109
125
|
}
|
|
110
126
|
|
|
111
127
|
class PointsReader {
|
|
112
128
|
static read(pbf, end?: number): Points {
|
|
113
129
|
return pbf.readFields(
|
|
114
130
|
PointsReader._readField,
|
|
115
|
-
{
|
|
131
|
+
{
|
|
132
|
+
positions: null,
|
|
133
|
+
globalFeatureIds: null,
|
|
134
|
+
featureIds: null,
|
|
135
|
+
properties: [],
|
|
136
|
+
numericProps: {},
|
|
137
|
+
fields: []
|
|
138
|
+
},
|
|
116
139
|
end
|
|
117
140
|
);
|
|
118
141
|
}
|
|
@@ -124,7 +147,7 @@ class PointsReader {
|
|
|
124
147
|
else if (tag === 5) {
|
|
125
148
|
const entry = NumericPropKeyValueReader.read(pbf, pbf.readVarint() + pbf.pos);
|
|
126
149
|
obj.numericProps[entry.key] = entry.value;
|
|
127
|
-
}
|
|
150
|
+
} else if (tag === 6) obj.fields.push(FieldsReader.read(pbf, pbf.readVarint() + pbf.pos));
|
|
128
151
|
}
|
|
129
152
|
}
|
|
130
153
|
|
|
@@ -143,7 +166,8 @@ class LinesReader {
|
|
|
143
166
|
globalFeatureIds: null,
|
|
144
167
|
featureIds: null,
|
|
145
168
|
properties: [],
|
|
146
|
-
numericProps: {}
|
|
169
|
+
numericProps: {},
|
|
170
|
+
fields: []
|
|
147
171
|
},
|
|
148
172
|
end
|
|
149
173
|
);
|
|
@@ -157,7 +181,7 @@ class LinesReader {
|
|
|
157
181
|
else if (tag === 6) {
|
|
158
182
|
const entry = NumericPropKeyValueReader.read(pbf, pbf.readVarint() + pbf.pos);
|
|
159
183
|
obj.numericProps[entry.key] = entry.value;
|
|
160
|
-
}
|
|
184
|
+
} else if (tag === 7) obj.fields.push(FieldsReader.read(pbf, pbf.readVarint() + pbf.pos));
|
|
161
185
|
}
|
|
162
186
|
}
|
|
163
187
|
// Polygons ========================================
|
|
@@ -180,7 +204,8 @@ class PolygonsReader {
|
|
|
180
204
|
primitivePolygonIndices: null,
|
|
181
205
|
triangles: null,
|
|
182
206
|
properties: [],
|
|
183
|
-
numericProps: {}
|
|
207
|
+
numericProps: {},
|
|
208
|
+
fields: []
|
|
184
209
|
},
|
|
185
210
|
end
|
|
186
211
|
);
|
|
@@ -197,7 +222,7 @@ class PolygonsReader {
|
|
|
197
222
|
else if (tag === 8) {
|
|
198
223
|
const entry = NumericPropKeyValueReader.read(pbf, pbf.readVarint() + pbf.pos);
|
|
199
224
|
obj.numericProps[entry.key] = entry.value;
|
|
200
|
-
}
|
|
225
|
+
} else if (tag === 9) obj.fields.push(FieldsReader.read(pbf, pbf.readVarint() + pbf.pos));
|
|
201
226
|
}
|
|
202
227
|
}
|
|
203
228
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
2
|
+
import type {BinaryFeatures} from '@loaders.gl/schema';
|
|
3
|
+
|
|
4
|
+
import {TileReader} from './carto-tile';
|
|
5
|
+
import {parsePbf, unpackProperties} from './tile-loader-utils';
|
|
6
|
+
|
|
7
|
+
const CartoVectorTileLoader: LoaderWithParser = {
|
|
8
|
+
name: 'CARTO Vector Tile',
|
|
9
|
+
version: '1',
|
|
10
|
+
id: 'cartoVectorTile',
|
|
11
|
+
module: 'carto',
|
|
12
|
+
extensions: ['pbf'],
|
|
13
|
+
mimeTypes: ['application/vnd.carto-vector-tile'],
|
|
14
|
+
category: 'geometry',
|
|
15
|
+
worker: false,
|
|
16
|
+
parse: async (arrayBuffer, options) => parseCartoVectorTile(arrayBuffer, options),
|
|
17
|
+
parseSync: parseCartoVectorTile,
|
|
18
|
+
options: {}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function parseCartoVectorTile(
|
|
22
|
+
arrayBuffer: ArrayBuffer,
|
|
23
|
+
options?: LoaderOptions
|
|
24
|
+
): BinaryFeatures | null {
|
|
25
|
+
if (!arrayBuffer) return null;
|
|
26
|
+
const tile = parsePbf(arrayBuffer, TileReader);
|
|
27
|
+
|
|
28
|
+
const {points, lines, polygons} = tile;
|
|
29
|
+
const data = {
|
|
30
|
+
points: {...points, properties: unpackProperties(points.properties)},
|
|
31
|
+
lines: {...lines, properties: unpackProperties(lines.properties)},
|
|
32
|
+
polygons: {...polygons, properties: unpackProperties(polygons.properties)}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Note: there is slight, difference in `numericProps` type, however geojson/mvtlayer can cope with this
|
|
36
|
+
return data as unknown as BinaryFeatures;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default CartoVectorTileLoader;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {bigIntToHex} from 'quadbin';
|
|
2
2
|
|
|
3
3
|
export type IndexScheme = 'h3' | 'quadbin';
|
|
4
4
|
type TypedArray = Float32Array | Float64Array;
|
|
@@ -13,16 +13,16 @@ export type Cells = {
|
|
|
13
13
|
};
|
|
14
14
|
export type SpatialBinary = {scheme?: IndexScheme; cells: Cells};
|
|
15
15
|
export type SpatialJson = {
|
|
16
|
-
id: string;
|
|
16
|
+
id: string | bigint;
|
|
17
17
|
properties: Properties;
|
|
18
18
|
}[];
|
|
19
19
|
|
|
20
20
|
export function binaryToSpatialjson(binary: SpatialBinary): SpatialJson {
|
|
21
|
-
const {cells} = binary;
|
|
21
|
+
const {cells, scheme} = binary;
|
|
22
22
|
const count = cells.indices.value.length;
|
|
23
23
|
const spatial: any[] = [];
|
|
24
24
|
for (let i = 0; i < count; i++) {
|
|
25
|
-
const id =
|
|
25
|
+
const id = scheme === 'h3' ? bigIntToHex(cells.indices.value[i]) : cells.indices.value[i];
|
|
26
26
|
|
|
27
27
|
const properties = {...cells.properties[i]};
|
|
28
28
|
for (const key of Object.keys(cells.numericProps)) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Protobuf from 'pbf';
|
|
2
|
+
import {KeyValueProperties} from './carto-tile';
|
|
3
|
+
import {Properties} from './spatialjson-utils';
|
|
4
|
+
|
|
5
|
+
export function parsePbf(buffer: ArrayBuffer, TileReader) {
|
|
6
|
+
const pbf = new Protobuf(buffer);
|
|
7
|
+
const tile = TileReader.read(pbf);
|
|
8
|
+
return tile;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function unpackProperties(properties: KeyValueProperties[]): Properties[] {
|
|
12
|
+
if (!properties || !properties.length) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
return properties.map(item => {
|
|
16
|
+
const currentRecord: Properties = {};
|
|
17
|
+
item.data.forEach(({key, value}) => {
|
|
18
|
+
currentRecord[key] = value;
|
|
19
|
+
});
|
|
20
|
+
return currentRecord;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -3,7 +3,13 @@ import CartoSpatialTileLoader from './schema/carto-spatial-tile-loader';
|
|
|
3
3
|
registerLoaders([CartoSpatialTileLoader]);
|
|
4
4
|
|
|
5
5
|
import {PickingInfo} from '@deck.gl/core';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
TileLayer,
|
|
8
|
+
_getURLFromTemplate,
|
|
9
|
+
_Tile2DHeader as Tile2DHeader,
|
|
10
|
+
_TileLoadProps as TileLoadProps
|
|
11
|
+
} from '@deck.gl/geo-layers';
|
|
12
|
+
import {TILE_FORMATS} from '../api/maps-api-common';
|
|
7
13
|
|
|
8
14
|
function isFeatureIdDefined(value: unknown): boolean {
|
|
9
15
|
return value !== undefined && value !== null && value !== '';
|
|
@@ -12,6 +18,36 @@ function isFeatureIdDefined(value: unknown): boolean {
|
|
|
12
18
|
export default class SpatialIndexTileLayer<ExtraProps = {}> extends TileLayer<any, ExtraProps> {
|
|
13
19
|
static layerName = 'SpatialIndexTileLayer';
|
|
14
20
|
|
|
21
|
+
getTileData(tile: TileLoadProps) {
|
|
22
|
+
const {data, getTileData, fetch} = this.props;
|
|
23
|
+
const {signal} = tile;
|
|
24
|
+
|
|
25
|
+
tile.url =
|
|
26
|
+
typeof data === 'string' || Array.isArray(data) ? _getURLFromTemplate(data, tile) : null;
|
|
27
|
+
if (!tile.url) {
|
|
28
|
+
return Promise.reject('Invalid URL');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (getTileData) {
|
|
32
|
+
return getTileData(tile);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let loadOptions = this.getLoadOptions();
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
const {formatTiles} = this.props;
|
|
38
|
+
|
|
39
|
+
// The backend doesn't yet support our custom mime-type, so force it here
|
|
40
|
+
// TODO remove entire `getTileData` method once backend sends the correct mime-type
|
|
41
|
+
if (formatTiles === TILE_FORMATS.BINARY) {
|
|
42
|
+
loadOptions = {
|
|
43
|
+
...loadOptions,
|
|
44
|
+
mimeType: 'application/vnd.carto-spatial-tile'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return fetch(tile.url, {propName: 'data', layer: this, loadOptions, signal});
|
|
49
|
+
}
|
|
50
|
+
|
|
15
51
|
protected _updateAutoHighlight(info: PickingInfo): void {
|
|
16
52
|
const {hoveredFeatureId} = this.state;
|
|
17
53
|
const hoveredFeature = info.object;
|