@deck.gl/carto 8.7.0-beta.3 → 8.7.0-beta.4

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@deck.gl/carto",
3
3
  "description": "CARTO official integration with Deck.gl. Build geospatial applications using CARTO and Deck.gl.",
4
4
  "license": "MIT",
5
- "version": "8.7.0-beta.3",
5
+ "version": "8.7.0-beta.4",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
@@ -41,7 +41,8 @@
41
41
  "d3-color": "^2.0.0",
42
42
  "d3-format": "^2.0.0",
43
43
  "d3-scale": "^3.2.3",
44
- "moment-timezone": "^0.5.33"
44
+ "moment-timezone": "^0.5.33",
45
+ "pbf": "^3.2.1"
45
46
  },
46
47
  "peerDependencies": {
47
48
  "@deck.gl/core": "^8.0.0",
@@ -49,5 +50,5 @@
49
50
  "@deck.gl/layers": "^8.0.0",
50
51
  "@loaders.gl/core": "^3.1.5"
51
52
  },
52
- "gitHead": "32879c662f37d4c912cf702c220a75d6cd0a67bc"
53
+ "gitHead": "fc41a854c97a421dec38411fc593bcdf625cdf84"
53
54
  }
package/src/api/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export {FORMATS, MAP_TYPES, API_VERSIONS} from './maps-api-common';
1
+ export {FORMATS, TILE_FORMATS, MAP_TYPES, API_VERSIONS} from './maps-api-common';
2
2
  export {getDataV2, CONNECTIONS} from './maps-client';
3
3
  export {fetchLayerData, fetchMap, getData, mapInstantiation} from './maps-v3-client';
@@ -26,6 +26,7 @@ export const FORMATS = {
26
26
  JSON: 'json'
27
27
  };
28
28
 
29
+ // AVAILABLE FORMATS FOR TILES
29
30
  export const TILE_FORMATS = {
30
31
  MVT: 'mvt',
31
32
  GEOJSON: 'geojson',
package/src/index.js CHANGED
@@ -7,6 +7,7 @@ export {default as colorCategories} from './style/color-categories-style';
7
7
  export {default as colorContinuous} from './style/color-continuous-style';
8
8
  export {
9
9
  FORMATS,
10
+ TILE_FORMATS,
10
11
  MAP_TYPES,
11
12
  API_VERSIONS,
12
13
  fetchLayerData,
@@ -1,20 +1,51 @@
1
1
  /* global TextDecoder */
2
+ import Protobuf from 'pbf';
2
3
  import {log} from '@deck.gl/core';
3
4
  import {ClipExtension} from '@deck.gl/extensions';
4
5
  import {MVTLayer, _getURLFromTemplate} from '@deck.gl/geo-layers';
5
6
  import {GeoJsonLayer} from '@deck.gl/layers';
6
7
  import {geojsonToBinary} from '@loaders.gl/gis';
7
- import {encodeParameter} from '../api/maps-api-common';
8
+ import {Tile} from './schema/carto-dynamic-tile';
9
+ import {encodeParameter, TILE_FORMATS} from '../api/maps-api-common';
8
10
 
9
11
  function parseJSON(arrayBuffer) {
10
12
  return JSON.parse(new TextDecoder().decode(arrayBuffer));
11
13
  }
12
14
 
15
+ function parsePbf(buffer) {
16
+ const pbf = new Protobuf(buffer);
17
+ const tile = Tile.read(pbf);
18
+ return tile;
19
+ }
20
+
21
+ function unpackProperties(properties) {
22
+ if (!properties || !properties.length) {
23
+ return [];
24
+ }
25
+ return properties.map(item => {
26
+ const currentRecord = {};
27
+ item.data.forEach(({key, value}) => {
28
+ currentRecord[key] = value;
29
+ });
30
+ return currentRecord;
31
+ });
32
+ }
33
+
13
34
  function parseCartoDynamicTile(arrayBuffer, options) {
14
35
  if (!arrayBuffer) return null;
15
36
  const formatTiles = options && options.cartoDynamicTile && options.cartoDynamicTile.formatTiles;
16
- if (formatTiles === 'geojson') return geojsonToBinary(parseJSON(arrayBuffer).features);
17
- return null;
37
+ if (formatTiles === TILE_FORMATS.GEOJSON) return geojsonToBinary(parseJSON(arrayBuffer).features);
38
+
39
+ const tile = parsePbf(arrayBuffer);
40
+
41
+ const {points, lines, polygons} = tile;
42
+ const data = {
43
+ points: {...points, properties: unpackProperties(points.properties)},
44
+ lines: {...lines, properties: unpackProperties(lines.properties)},
45
+ polygons: {...polygons, properties: unpackProperties(polygons.properties)}
46
+ };
47
+
48
+ return data;
18
49
  }
19
50
 
20
51
  const CartoDynamicTileLoader = {
@@ -29,7 +60,7 @@ const CartoDynamicTileLoader = {
29
60
  parseSync: parseCartoDynamicTile,
30
61
  options: {
31
62
  cartoDynamicTile: {
32
- formatTiles: 'geojson'
63
+ formatTiles: TILE_FORMATS.BINARY
33
64
  }
34
65
  }
35
66
  };
@@ -52,11 +83,11 @@ export default class CartoDynamicTileLayer extends MVTLayer {
52
83
 
53
84
  if (formatTiles) {
54
85
  log.assert(
55
- ['geojson'].includes(formatTiles),
56
- `Invalid value for formatTiles: ${formatTiles}`
86
+ Object.values(TILE_FORMATS).includes(formatTiles),
87
+ `Invalid value for formatTiles: ${formatTiles}. Use value from TILE_FORMATS`
57
88
  );
58
89
  url += `&${encodeParameter('formatTiles', formatTiles)}`;
59
- loadOptions.cartoBinaryTile = {formatTiles};
90
+ loadOptions.cartoDynamicTile = {formatTiles};
60
91
  }
61
92
 
62
93
  return fetch(url, {propName: 'data', layer: this, loadOptions, signal});
@@ -72,7 +103,7 @@ export default class CartoDynamicTileLayer extends MVTLayer {
72
103
  const {
73
104
  bbox: {west, south, east, north}
74
105
  } = props.tile;
75
- props.extensions = [new ClipExtension()];
106
+ props.extensions = [new ClipExtension(), ...props.extensions];
76
107
  props.clipBounds = [west, south, east, north];
77
108
 
78
109
  const subLayer = new GeoJsonLayer({
@@ -27,6 +27,9 @@ const defaultProps = {
27
27
  // (String, optional): format of data
28
28
  format: null,
29
29
 
30
+ // (String, optional): format of data
31
+ formatTiles: TILE_FORMATS.GEOJSON, // TODO: for 8.7 release switch to BINARY
32
+
30
33
  // (String, optional): clientId identifier used for internal tracing, place here a string to identify the client who is doing the request.
31
34
  clientId: null,
32
35
 
@@ -128,7 +131,7 @@ export default class CartoLayer extends CompositeLayer {
128
131
 
129
132
  if (!data) return null;
130
133
 
131
- const {updateTriggers} = this.props;
134
+ const {type, updateTriggers} = this.props;
132
135
 
133
136
  let layer;
134
137
 
@@ -137,8 +140,12 @@ export default class CartoLayer extends CompositeLayer {
137
140
  apiVersion === API_VERSIONS.V3 &&
138
141
  format === FORMATS.TILEJSON &&
139
142
  new URLSearchParams(data.tiles[0]).get('format');
143
+ const nonMvtTiles = tilesFormat && tilesFormat !== TILE_FORMATS.MVT;
144
+
145
+ const dynamicTiles =
146
+ apiVersion === API_VERSIONS.V3 && type === MAP_TYPES.TABLE && format === FORMATS.TILEJSON;
140
147
 
141
- if (tilesFormat && tilesFormat !== TILE_FORMATS.MVT) {
148
+ if (nonMvtTiles || dynamicTiles) {
142
149
  layer = CartoDynamicTileLayer;
143
150
  } else if (
144
151
  apiVersion === API_VERSIONS.V1 ||
@@ -150,8 +157,8 @@ export default class CartoLayer extends CompositeLayer {
150
157
  layer = GeoJsonLayer;
151
158
  }
152
159
 
153
- const {uniqueIdProperty} = defaultProps;
154
- const props = {uniqueIdProperty, ...this.props};
160
+ const {formatTiles, uniqueIdProperty} = defaultProps;
161
+ const props = {formatTiles, uniqueIdProperty, ...this.props};
155
162
  delete props.data;
156
163
 
157
164
  // eslint-disable-next-line new-cap
@@ -0,0 +1,195 @@
1
+ // KeyValueObject ========================================
2
+
3
+ const KeyValueObject = {};
4
+
5
+ KeyValueObject.read = function (pbf, end) {
6
+ return pbf.readFields(KeyValueObject._readField, {key: '', value: ''}, end);
7
+ };
8
+ KeyValueObject._readField = function (tag, obj, pbf) {
9
+ if (tag === 1) obj.key = pbf.readString();
10
+ else if (tag === 2) obj.value = pbf.readString();
11
+ };
12
+
13
+ // Properties ========================================
14
+
15
+ const Properties = {};
16
+
17
+ Properties.read = function (pbf, end) {
18
+ return pbf.readFields(Properties._readField, {data: []}, end);
19
+ };
20
+ Properties._readField = function (tag, obj, pbf) {
21
+ if (tag === 1) obj.data.push(KeyValueObject.read(pbf, pbf.readVarint() + pbf.pos));
22
+ };
23
+
24
+ // Doubles ========================================
25
+
26
+ const Doubles = {};
27
+
28
+ Doubles.read = function (pbf, end) {
29
+ // TODO perhaps we can do better and directly map from the source
30
+ // ArrayBuffer using ArrayBuffer.slice()
31
+ const {value, size} = pbf.readFields(Doubles._readField, {value: [], size: 0}, end);
32
+ return {value: new Float32Array(value), size};
33
+ };
34
+ Doubles._readField = function (tag, obj, pbf) {
35
+ if (tag === 1) pbf.readPackedDouble(obj.value);
36
+ else if (tag === 2) obj.size = pbf.readVarint(true);
37
+ };
38
+
39
+ // Ints ========================================
40
+
41
+ const Ints = {};
42
+
43
+ Ints.read = function (pbf, end) {
44
+ const {value, size} = pbf.readFields(Ints._readField, {value: [], size: 0}, end);
45
+ return {value: new Uint32Array(value), size};
46
+ };
47
+ Ints._readField = function (tag, obj, pbf) {
48
+ if (tag === 1) pbf.readPackedVarint(obj.value);
49
+ else if (tag === 2) obj.size = pbf.readVarint(true);
50
+ };
51
+
52
+ // NumericProp ========================================
53
+
54
+ const NumericProp = {};
55
+
56
+ NumericProp.read = function (pbf, end) {
57
+ return pbf.readFields(NumericProp._readField, {value: []}, end);
58
+ };
59
+ NumericProp._readField = function (tag, obj, pbf) {
60
+ if (tag === 1) pbf.readPackedDouble(obj.value);
61
+ };
62
+
63
+ // NumericPropKeyValue ========================================
64
+
65
+ const NumericPropKeyValue = {};
66
+
67
+ NumericPropKeyValue.read = function (pbf, end) {
68
+ return pbf.readFields(NumericPropKeyValue._readField, {key: '', value: null}, end);
69
+ };
70
+ NumericPropKeyValue._readField = function (tag, obj, pbf) {
71
+ if (tag === 1) obj.key = pbf.readString();
72
+ else if (tag === 2) obj.value = NumericProp.read(pbf, pbf.readVarint() + pbf.pos);
73
+ };
74
+
75
+ // NumericProp._FieldEntry1 ========================================
76
+
77
+ NumericProp._FieldEntry1 = {};
78
+
79
+ NumericProp._FieldEntry1.read = function (pbf, end) {
80
+ return pbf.readFields(NumericProp._FieldEntry1._readField, {key: '', value: 0}, end);
81
+ };
82
+ NumericProp._FieldEntry1._readField = function (tag, obj, pbf) {
83
+ if (tag === 1) obj.key = pbf.readString();
84
+ else if (tag === 2) obj.value = pbf.readDouble();
85
+ };
86
+
87
+ // StringProp ========================================
88
+
89
+ const StringProp = {};
90
+
91
+ StringProp.read = function (pbf, end) {
92
+ return pbf.readFields(StringProp._readField, {value: []}, end);
93
+ };
94
+ StringProp._readField = function (tag, obj, pbf) {
95
+ if (tag === 1) obj.value.push(pbf.readString());
96
+ };
97
+
98
+ // Points ========================================
99
+
100
+ const Points = {};
101
+
102
+ Points.read = function (pbf, end) {
103
+ return pbf.readFields(
104
+ Points._readField,
105
+ {positions: null, globalFeatureIds: null, featureIds: null, properties: [], numericProps: {}},
106
+ end
107
+ );
108
+ };
109
+ Points._readField = function (tag, obj, pbf) {
110
+ if (tag === 1) obj.positions = Doubles.read(pbf, pbf.readVarint() + pbf.pos);
111
+ else if (tag === 2) obj.globalFeatureIds = Ints.read(pbf, pbf.readVarint() + pbf.pos);
112
+ else if (tag === 3) obj.featureIds = Ints.read(pbf, pbf.readVarint() + pbf.pos);
113
+ else if (tag === 4) obj.properties.push(Properties.read(pbf, pbf.readVarint() + pbf.pos));
114
+ else if (tag === 5) {
115
+ const entry = NumericPropKeyValue.read(pbf, pbf.readVarint() + pbf.pos);
116
+ obj.numericProps[entry.key] = entry.value;
117
+ }
118
+ };
119
+
120
+ // Lines ========================================
121
+
122
+ const Lines = {};
123
+
124
+ Lines.read = function (pbf, end) {
125
+ return pbf.readFields(
126
+ Lines._readField,
127
+ {
128
+ positions: null,
129
+ pathIndices: null,
130
+ globalFeatureIds: null,
131
+ featureIds: null,
132
+ properties: [],
133
+ numericProps: {}
134
+ },
135
+ end
136
+ );
137
+ };
138
+ Lines._readField = function (tag, obj, pbf) {
139
+ if (tag === 1) obj.positions = Doubles.read(pbf, pbf.readVarint() + pbf.pos);
140
+ else if (tag === 2) obj.pathIndices = Ints.read(pbf, pbf.readVarint() + pbf.pos);
141
+ else if (tag === 3) obj.globalFeatureIds = Ints.read(pbf, pbf.readVarint() + pbf.pos);
142
+ else if (tag === 4) obj.featureIds = Ints.read(pbf, pbf.readVarint() + pbf.pos);
143
+ else if (tag === 5) obj.properties.push(Properties.read(pbf, pbf.readVarint() + pbf.pos));
144
+ else if (tag === 6) {
145
+ const entry = NumericPropKeyValue.read(pbf, pbf.readVarint() + pbf.pos);
146
+ obj.numericProps[entry.key] = entry.value;
147
+ }
148
+ };
149
+
150
+ // Polygons ========================================
151
+
152
+ const Polygons = {};
153
+
154
+ Polygons.read = function (pbf, end) {
155
+ return pbf.readFields(
156
+ Polygons._readField,
157
+ {
158
+ positions: null,
159
+ polygonIndices: null,
160
+ globalFeatureIds: null,
161
+ featureIds: null,
162
+ primitivePolygonIndices: null,
163
+ triangles: null,
164
+ properties: [],
165
+ numericProps: {}
166
+ },
167
+ end
168
+ );
169
+ };
170
+ Polygons._readField = function (tag, obj, pbf) {
171
+ if (tag === 1) obj.positions = Doubles.read(pbf, pbf.readVarint() + pbf.pos);
172
+ else if (tag === 2) obj.polygonIndices = Ints.read(pbf, pbf.readVarint() + pbf.pos);
173
+ else if (tag === 3) obj.globalFeatureIds = Ints.read(pbf, pbf.readVarint() + pbf.pos);
174
+ else if (tag === 4) obj.featureIds = Ints.read(pbf, pbf.readVarint() + pbf.pos);
175
+ else if (tag === 5) obj.primitivePolygonIndices = Ints.read(pbf, pbf.readVarint() + pbf.pos);
176
+ else if (tag === 6) obj.triangles = Ints.read(pbf, pbf.readVarint() + pbf.pos);
177
+ else if (tag === 7) obj.properties.push(Properties.read(pbf, pbf.readVarint() + pbf.pos));
178
+ else if (tag === 8) {
179
+ const entry = NumericPropKeyValue.read(pbf, pbf.readVarint() + pbf.pos);
180
+ obj.numericProps[entry.key] = entry.value;
181
+ }
182
+ };
183
+
184
+ // Tile ========================================
185
+
186
+ export const Tile = {};
187
+
188
+ Tile.read = function (pbf, end) {
189
+ return pbf.readFields(Tile._readField, {points: null, lines: null, polygons: null}, end);
190
+ };
191
+ Tile._readField = function (tag, obj, pbf) {
192
+ if (tag === 1) obj.points = Points.read(pbf, pbf.readVarint() + pbf.pos);
193
+ else if (tag === 2) obj.lines = Lines.read(pbf, pbf.readVarint() + pbf.pos);
194
+ else if (tag === 3) obj.polygons = Polygons.read(pbf, pbf.readVarint() + pbf.pos);
195
+ };