@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.
Files changed (149) hide show
  1. package/dist/dist.dev.js +1927 -1675
  2. package/dist/es5/api/layer-map.js +104 -9
  3. package/dist/es5/api/layer-map.js.map +1 -1
  4. package/dist/es5/api/maps-v3-client.js +10 -8
  5. package/dist/es5/api/maps-v3-client.js.map +1 -1
  6. package/dist/es5/api/parseMap.js +55 -7
  7. package/dist/es5/api/parseMap.js.map +1 -1
  8. package/dist/es5/api/types.js +2 -0
  9. package/dist/es5/api/types.js.map +1 -0
  10. package/dist/es5/index.js +0 -20
  11. package/dist/es5/index.js.map +1 -1
  12. package/dist/es5/layers/carto-layer.js +19 -2
  13. package/dist/es5/layers/carto-layer.js.map +1 -1
  14. package/dist/es5/layers/carto-tile-layer.js +33 -107
  15. package/dist/es5/layers/carto-tile-layer.js.map +1 -1
  16. package/dist/es5/layers/h3-tile-layer.js +10 -1
  17. package/dist/es5/layers/h3-tile-layer.js.map +1 -1
  18. package/dist/es5/layers/quadbin-layer.js.map +1 -1
  19. package/dist/es5/layers/quadbin-tile-layer.js +10 -1
  20. package/dist/es5/layers/quadbin-tile-layer.js.map +1 -1
  21. package/dist/es5/layers/quadbin-tileset-2d.js +13 -11
  22. package/dist/es5/layers/quadbin-tileset-2d.js.map +1 -1
  23. package/dist/es5/layers/quadbin-utils.js +6 -82
  24. package/dist/es5/layers/quadbin-utils.js.map +1 -1
  25. package/dist/es5/layers/schema/carto-spatial-tile-loader.js +16 -32
  26. package/dist/es5/layers/schema/carto-spatial-tile-loader.js.map +1 -1
  27. package/dist/es5/layers/schema/carto-tile.js +30 -6
  28. package/dist/es5/layers/schema/carto-tile.js.map +1 -1
  29. package/dist/es5/layers/schema/carto-vector-tile-loader.js +81 -0
  30. package/dist/es5/layers/schema/carto-vector-tile-loader.js.map +1 -0
  31. package/dist/es5/layers/schema/spatialjson-utils.js +4 -3
  32. package/dist/es5/layers/schema/spatialjson-utils.js.map +1 -1
  33. package/dist/es5/layers/schema/tile-loader-utils.js +34 -0
  34. package/dist/es5/layers/schema/tile-loader-utils.js.map +1 -0
  35. package/dist/es5/layers/spatial-index-tile-layer.js +40 -0
  36. package/dist/es5/layers/spatial-index-tile-layer.js.map +1 -1
  37. package/dist/esm/api/layer-map.js +85 -9
  38. package/dist/esm/api/layer-map.js.map +1 -1
  39. package/dist/esm/api/maps-v3-client.js +5 -2
  40. package/dist/esm/api/maps-v3-client.js.map +1 -1
  41. package/dist/esm/api/parseMap.js +58 -7
  42. package/dist/esm/api/parseMap.js.map +1 -1
  43. package/dist/esm/api/types.js +2 -0
  44. package/dist/esm/api/types.js.map +1 -0
  45. package/dist/esm/index.js +0 -1
  46. package/dist/esm/index.js.map +1 -1
  47. package/dist/esm/layers/carto-layer.js +18 -0
  48. package/dist/esm/layers/carto-layer.js.map +1 -1
  49. package/dist/esm/layers/carto-tile-layer.js +31 -82
  50. package/dist/esm/layers/carto-tile-layer.js.map +1 -1
  51. package/dist/esm/layers/h3-tile-layer.js +6 -1
  52. package/dist/esm/layers/h3-tile-layer.js.map +1 -1
  53. package/dist/esm/layers/quadbin-layer.js.map +1 -1
  54. package/dist/esm/layers/quadbin-tile-layer.js +6 -1
  55. package/dist/esm/layers/quadbin-tile-layer.js.map +1 -1
  56. package/dist/esm/layers/quadbin-tileset-2d.js +12 -10
  57. package/dist/esm/layers/quadbin-tileset-2d.js.map +1 -1
  58. package/dist/esm/layers/quadbin-utils.js +2 -67
  59. package/dist/esm/layers/quadbin-utils.js.map +1 -1
  60. package/dist/esm/layers/schema/carto-spatial-tile-loader.js +14 -29
  61. package/dist/esm/layers/schema/carto-spatial-tile-loader.js.map +1 -1
  62. package/dist/esm/layers/schema/carto-tile.js +22 -6
  63. package/dist/esm/layers/schema/carto-tile.js.map +1 -1
  64. package/dist/esm/layers/schema/carto-vector-tile-loader.js +40 -0
  65. package/dist/esm/layers/schema/carto-vector-tile-loader.js.map +1 -0
  66. package/dist/esm/layers/schema/spatialjson-utils.js +4 -3
  67. package/dist/esm/layers/schema/spatialjson-utils.js.map +1 -1
  68. package/dist/esm/layers/schema/tile-loader-utils.js +23 -0
  69. package/dist/esm/layers/schema/tile-loader-utils.js.map +1 -0
  70. package/dist/esm/layers/spatial-index-tile-layer.js +40 -1
  71. package/dist/esm/layers/spatial-index-tile-layer.js.map +1 -1
  72. package/dist.min.js +4 -4
  73. package/package.json +4 -3
  74. package/src/api/layer-map.ts +103 -17
  75. package/src/api/maps-v3-client.ts +5 -3
  76. package/src/api/parseMap.ts +90 -17
  77. package/src/api/types.ts +108 -0
  78. package/src/index.ts +0 -5
  79. package/src/layers/carto-layer.ts +9 -2
  80. package/src/layers/carto-tile-layer.ts +32 -82
  81. package/src/layers/h3-tile-layer.ts +7 -1
  82. package/src/layers/quadbin-layer.ts +1 -1
  83. package/src/layers/quadbin-tile-layer.ts +7 -1
  84. package/src/layers/quadbin-tileset-2d.ts +14 -12
  85. package/src/layers/quadbin-utils.ts +4 -85
  86. package/src/layers/schema/carto-spatial-tile-loader.ts +12 -29
  87. package/src/layers/schema/carto-tile.ts +31 -6
  88. package/src/layers/schema/carto-vector-tile-loader.ts +39 -0
  89. package/src/layers/schema/spatialjson-utils.ts +4 -4
  90. package/src/layers/schema/tile-loader-utils.ts +22 -0
  91. package/src/layers/spatial-index-tile-layer.ts +37 -1
  92. package/typed/api/layer-map.d.ts +10 -13
  93. package/typed/api/layer-map.d.ts.map +1 -1
  94. package/typed/api/maps-v3-client.d.ts +1 -0
  95. package/typed/api/maps-v3-client.d.ts.map +1 -1
  96. package/typed/api/parseMap.d.ts +1 -0
  97. package/typed/api/parseMap.d.ts.map +1 -1
  98. package/typed/api/types.d.ts +87 -0
  99. package/typed/api/types.d.ts.map +1 -0
  100. package/typed/index.d.ts +0 -1
  101. package/typed/index.d.ts.map +1 -1
  102. package/typed/layers/carto-layer.d.ts.map +1 -1
  103. package/typed/layers/carto-tile-layer.d.ts +2 -0
  104. package/typed/layers/carto-tile-layer.d.ts.map +1 -1
  105. package/typed/layers/h3-tile-layer.d.ts.map +1 -1
  106. package/typed/layers/quadbin-layer.d.ts +1 -1
  107. package/typed/layers/quadbin-tile-layer.d.ts.map +1 -1
  108. package/typed/layers/quadbin-tileset-2d.d.ts +6 -5
  109. package/typed/layers/quadbin-tileset-2d.d.ts.map +1 -1
  110. package/typed/layers/quadbin-utils.d.ts +2 -12
  111. package/typed/layers/quadbin-utils.d.ts.map +1 -1
  112. package/typed/layers/schema/carto-spatial-tile-loader.d.ts.map +1 -1
  113. package/typed/layers/schema/carto-tile.d.ts +4 -0
  114. package/typed/layers/schema/carto-tile.d.ts.map +1 -1
  115. package/typed/layers/schema/carto-vector-tile-loader.d.ts +4 -0
  116. package/typed/layers/schema/carto-vector-tile-loader.d.ts.map +1 -0
  117. package/typed/layers/schema/spatialjson-utils.d.ts +1 -1
  118. package/typed/layers/schema/spatialjson-utils.d.ts.map +1 -1
  119. package/typed/layers/schema/tile-loader-utils.d.ts +5 -0
  120. package/typed/layers/schema/tile-loader-utils.d.ts.map +1 -0
  121. package/typed/layers/spatial-index-tile-layer.d.ts +2 -1
  122. package/typed/layers/spatial-index-tile-layer.d.ts.map +1 -1
  123. package/typed/api/index.js +0 -3
  124. package/typed/api/layer-map.js +0 -264
  125. package/typed/api/maps-api-common.js +0 -50
  126. package/typed/api/maps-client.js +0 -125
  127. package/typed/api/maps-v3-client.js +0 -304
  128. package/typed/api/parseMap.js +0 -178
  129. package/typed/basemap.js +0 -9
  130. package/typed/config.js +0 -35
  131. package/typed/index.js +0 -10
  132. package/typed/layers/carto-layer.js +0 -173
  133. package/typed/layers/carto-tile-layer.js +0 -105
  134. package/typed/layers/h3-tile-layer.js +0 -47
  135. package/typed/layers/h3-tileset-2d.js +0 -85
  136. package/typed/layers/quadkey-tile-layer.d.ts +0 -21
  137. package/typed/layers/quadkey-tile-layer.d.ts.map +0 -1
  138. package/typed/layers/quadkey-tile-layer.js +0 -42
  139. package/typed/layers/quadkey-tileset-2d.d.ts +0 -15
  140. package/typed/layers/quadkey-tileset-2d.d.ts.map +0 -1
  141. package/typed/layers/quadkey-tileset-2d.js +0 -36
  142. package/typed/layers/schema/carto-tile.js +0 -161
  143. package/typed/layers/spatial-index-tile-layer.js +0 -40
  144. package/typed/style/color-bins-style.js +0 -12
  145. package/typed/style/color-categories-style.js +0 -16
  146. package/typed/style/color-continuous-style.js +0 -12
  147. package/typed/style/palette.js +0 -62
  148. package/typed/style/utils.js +0 -15
  149. package/typed/utils.js +0 -4
@@ -1,6 +1,8 @@
1
- /* global TextDecoder */
2
- import Protobuf from 'pbf';
3
- import {log, DefaultProps} from '@deck.gl/core';
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
- loadOptions = {
124
- ...loadOptions,
125
- mimeType: 'application/x-protobuf'
126
- };
127
-
128
- if (formatTiles) {
129
- log.assert(
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, string>;
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 {tileToQuadbin, quadbinToTile, quadbinParent, quadbinZoom} from './quadbin-utils';
2
+ import {bigIntToHex, cellToParent, cellToTile, getResolution, tileToCell} from 'quadbin';
3
3
 
4
- type QuadbinTileIndex = {i: string};
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(tileToQuadbin)
12
- .map(i => ({i}));
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({i}: QuadbinTileIndex) {
22
- return super.getTileMetadata(quadbinToTile(i));
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({i}: QuadbinTileIndex): number {
27
- return Number(quadbinZoom(i));
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({i}: QuadbinTileIndex): QuadbinTileIndex {
32
- return {i: quadbinParent(i)};
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
- const B = [
6
- 0x5555555555555555n,
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: string): number[] {
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
- 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[]): Properties[] {
32
- if (!properties || !properties.length) {
33
- return [];
18
+ options: {
19
+ cartoSpatialTile: {
20
+ scheme: 'quadbin'
21
+ } as {scheme: IndexScheme}
34
22
  }
35
- return properties.map(item => {
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
- {positions: null, globalFeatureIds: null, featureIds: null, properties: [], numericProps: {}},
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 {bigIntToIndex} from '../quadbin-utils';
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 = bigIntToIndex(cells.indices.value[i]);
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 {TileLayer, _Tile2DHeader as Tile2DHeader} from '@deck.gl/geo-layers';
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;