@deck.gl/carto 8.7.0-beta.1 → 8.7.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.
Files changed (48) hide show
  1. package/dist/dist.dev.js +1212 -98
  2. package/dist/es5/api/index.js +6 -0
  3. package/dist/es5/api/index.js.map +1 -1
  4. package/dist/es5/api/layer-map.js +65 -40
  5. package/dist/es5/api/layer-map.js.map +1 -1
  6. package/dist/es5/api/maps-api-common.js +7 -1
  7. package/dist/es5/api/maps-api-common.js.map +1 -1
  8. package/dist/es5/api/maps-v3-client.js +10 -8
  9. package/dist/es5/api/maps-v3-client.js.map +1 -1
  10. package/dist/es5/api/parseMap.js +5 -6
  11. package/dist/es5/api/parseMap.js.map +1 -1
  12. package/dist/es5/index.js +14 -0
  13. package/dist/es5/index.js.map +1 -1
  14. package/dist/es5/layers/carto-dynamic-tile-layer.js +59 -12
  15. package/dist/es5/layers/carto-dynamic-tile-layer.js.map +1 -1
  16. package/dist/es5/layers/carto-layer.js +26 -15
  17. package/dist/es5/layers/carto-layer.js.map +1 -1
  18. package/dist/es5/layers/schema/carto-dynamic-tile.js +197 -0
  19. package/dist/es5/layers/schema/carto-dynamic-tile.js.map +1 -0
  20. package/dist/esm/api/index.js +1 -1
  21. package/dist/esm/api/index.js.map +1 -1
  22. package/dist/esm/api/layer-map.js +54 -31
  23. package/dist/esm/api/layer-map.js.map +1 -1
  24. package/dist/esm/api/maps-api-common.js +5 -0
  25. package/dist/esm/api/maps-api-common.js.map +1 -1
  26. package/dist/esm/api/maps-v3-client.js +6 -2
  27. package/dist/esm/api/maps-v3-client.js.map +1 -1
  28. package/dist/esm/api/parseMap.js +6 -7
  29. package/dist/esm/api/parseMap.js.map +1 -1
  30. package/dist/esm/index.js +2 -1
  31. package/dist/esm/index.js.map +1 -1
  32. package/dist/esm/layers/carto-dynamic-tile-layer.js +52 -8
  33. package/dist/esm/layers/carto-dynamic-tile-layer.js.map +1 -1
  34. package/dist/esm/layers/carto-layer.js +24 -12
  35. package/dist/esm/layers/carto-layer.js.map +1 -1
  36. package/dist/esm/layers/schema/carto-dynamic-tile.js +190 -0
  37. package/dist/esm/layers/schema/carto-dynamic-tile.js.map +1 -0
  38. package/dist.min.js +14 -14
  39. package/package.json +5 -4
  40. package/src/api/index.js +1 -1
  41. package/src/api/layer-map.js +50 -25
  42. package/src/api/maps-api-common.js +7 -0
  43. package/src/api/maps-v3-client.js +4 -3
  44. package/src/api/parseMap.js +2 -4
  45. package/src/index.js +2 -0
  46. package/src/layers/carto-dynamic-tile-layer.js +44 -9
  47. package/src/layers/carto-layer.js +29 -18
  48. package/src/layers/schema/carto-dynamic-tile.js +195 -0
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.1",
5
+ "version": "8.7.0-beta.5",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
@@ -35,13 +35,14 @@
35
35
  "@loaders.gl/loader-utils": "^3.1.5",
36
36
  "@loaders.gl/mvt": "^3.1.5",
37
37
  "@loaders.gl/tiles": "^3.1.5",
38
- "@math.gl/web-mercator": "^3.5.6",
38
+ "@math.gl/web-mercator": "^3.5.7",
39
39
  "cartocolor": "^4.0.2",
40
40
  "d3-array": "^2.8.0",
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": "0297ca9d2c85d980b075e2af4cfbeb75e31db55a"
53
+ "gitHead": "02b67ab8085c6283c0cae45e37a9b70b24f4434b"
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';
@@ -11,8 +11,10 @@ import {
11
11
  } from 'd3-scale';
12
12
  import {format as d3Format} from 'd3-format';
13
13
  import moment from 'moment-timezone';
14
+ import {log} from '@deck.gl/core';
14
15
  import {H3HexagonLayer, MVTLayer} from '@deck.gl/geo-layers';
15
16
  import {GeoJsonLayer} from '@deck.gl/layers';
17
+ import {_CartoDynamicTileLayer, TILE_FORMATS} from '@deck.gl/carto';
16
18
 
17
19
  const SCALE_FUNCS = {
18
20
  linear: scaleLinear,
@@ -62,37 +64,60 @@ function mergePropMaps(a, b) {
62
64
  return {...a, ...b, visConfig: {...a.visConfig, ...b.visConfig}};
63
65
  }
64
66
 
65
- export const LAYER_MAP = {
66
- point: {
67
- Layer: GeoJsonLayer,
68
- propMap: mergePropMaps(sharedPropMap, {
69
- visConfig: {outline: 'stroked'}
70
- }),
71
- defaultProps
72
- },
73
- geojson: {
74
- Layer: GeoJsonLayer,
75
- propMap: sharedPropMap,
76
- defaultProps: {...defaultProps, lineWidthScale: 2}
77
- },
78
- hexagonId: {
79
- Layer: H3HexagonLayer,
80
- propMap: mergePropMaps(sharedPropMap, {
81
- visConfig: {coverage: 'coverage', elevationScale: 'elevationScale'}
82
- }),
83
- defaultProps: {...defaultProps, getHexagon: d => d.h3}
84
- },
85
- mvt: {
86
- Layer: MVTLayer,
67
+ export function getLayer(type, config, dataset) {
68
+ if (type === 'mvt' || type === 'tileset') {
69
+ return getTileLayer(dataset);
70
+ }
71
+
72
+ const hexagonId = config.columns?.hex_id;
73
+ const layer = {
74
+ point: {
75
+ Layer: GeoJsonLayer,
76
+ propMap: mergePropMaps(sharedPropMap, {
77
+ visConfig: {outline: 'stroked'}
78
+ }),
79
+ defaultProps
80
+ },
81
+ geojson: {
82
+ Layer: GeoJsonLayer,
83
+ propMap: sharedPropMap,
84
+ defaultProps: {...defaultProps, lineWidthScale: 2}
85
+ },
86
+ hexagonId: {
87
+ Layer: H3HexagonLayer,
88
+ propMap: mergePropMaps(sharedPropMap, {
89
+ visConfig: {coverage: 'coverage', elevationScale: 'elevationScale'}
90
+ }),
91
+ defaultProps: {...defaultProps, getHexagon: d => d[hexagonId]}
92
+ }
93
+ }[type];
94
+
95
+ log.assert(layer, `Unsupported layer type: ${type}`);
96
+
97
+ return layer;
98
+ }
99
+
100
+ function getTileLayer(dataset) {
101
+ const {
102
+ data: {
103
+ tiles: [tileUrl]
104
+ }
105
+ } = dataset;
106
+ /* global URL */
107
+ const formatTiles = new URL(tileUrl).searchParams.get('formatTiles') || TILE_FORMATS.MVT;
108
+
109
+ return {
110
+ Layer: formatTiles === TILE_FORMATS.MVT ? MVTLayer : _CartoDynamicTileLayer,
87
111
  propMap: sharedPropMap,
88
112
  defaultProps: {
89
113
  ...defaultProps,
90
114
  pointRadiusScale: 0.3,
91
115
  lineWidthScale: 2,
92
- uniqueIdProperty: 'geoid'
116
+ uniqueIdProperty: 'geoid',
117
+ formatTiles
93
118
  }
94
- }
95
- };
119
+ };
120
+ }
96
121
 
97
122
  function domainFromAttribute(attribute, scaleType) {
98
123
  if (scaleType === 'ordinal' || scaleType === 'point') {
@@ -26,6 +26,13 @@ export const FORMATS = {
26
26
  JSON: 'json'
27
27
  };
28
28
 
29
+ // AVAILABLE FORMATS FOR TILES
30
+ export const TILE_FORMATS = {
31
+ MVT: 'mvt',
32
+ GEOJSON: 'geojson',
33
+ BINARY: 'binary'
34
+ };
35
+
29
36
  /**
30
37
  * Simple encode parameter
31
38
  */
@@ -255,7 +255,7 @@ export async function getData({
255
255
  return layerData.data;
256
256
  }
257
257
 
258
- /* global clearInterval, setInterval, URLSearchParams */
258
+ /* global clearInterval, setInterval, URL */
259
259
  async function _fetchMapDataset(dataset, accessToken, credentials, clientId) {
260
260
  // First fetch metadata
261
261
  const {connectionName: connection, source, type} = dataset;
@@ -268,7 +268,7 @@ async function _fetchMapDataset(dataset, accessToken, credentials, clientId) {
268
268
  });
269
269
 
270
270
  // Extract the last time the data changed
271
- const cache = parseInt(new URLSearchParams(url).get('cache'), 10);
271
+ const cache = parseInt(new URL(url).searchParams.get('cache'), 10);
272
272
  if (cache && dataset.cache === cache) {
273
273
  return false;
274
274
  }
@@ -291,6 +291,7 @@ export async function fetchMap({cartoMapId, clientId, credentials, autoRefresh,
291
291
  ...(defaultCredentials.apiVersion === API_VERSIONS.V3 && defaultCredentials),
292
292
  ...credentials
293
293
  };
294
+ const {accessToken} = localCreds;
294
295
 
295
296
  log.assert(cartoMapId, `Must define CARTO map id: fetchMap({cartoMapId: 'XXXX-XXXX-XXXX'})`);
296
297
 
@@ -307,7 +308,7 @@ export async function fetchMap({cartoMapId, clientId, credentials, autoRefresh,
307
308
  }
308
309
 
309
310
  const url = `${localCreds.mapsUrl}/public/${cartoMapId}`;
310
- const map = await request({url});
311
+ const map = await request({url, accessToken});
311
312
 
312
313
  // Periodically check if the data has changed. Note that this
313
314
  // will not update when a map is published.
@@ -1,6 +1,6 @@
1
1
  import GL from '@luma.gl/constants';
2
2
  import {
3
- LAYER_MAP,
3
+ getLayer,
4
4
  getColorAccessor,
5
5
  getSizeAccessor,
6
6
  getTextAccessor,
@@ -24,14 +24,12 @@ export function parseMap(json) {
24
24
  mapStyle,
25
25
  layers: extractTextLayers(layers.reverse()).map(({id, type, config, visualChannels}) => {
26
26
  try {
27
- log.assert(type in LAYER_MAP, `Unsupported layer type: ${type}`);
28
- const {Layer, propMap, defaultProps} = LAYER_MAP[type];
29
-
30
27
  const {dataId} = config;
31
28
  const dataset = datasets.find(d => d.id === dataId);
32
29
  log.assert(dataset, `No dataset matching dataId: ${dataId}`);
33
30
  const {data} = dataset;
34
31
  log.assert(data, `No data loaded for dataId: ${dataId}`);
32
+ const {Layer, propMap, defaultProps} = getLayer(type, config, dataset);
35
33
  return new Layer({
36
34
  id,
37
35
  data,
package/src/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  export {getDefaultCredentials, setDefaultCredentials} from './config.js';
2
2
  export {default as CartoLayer} from './layers/carto-layer';
3
+ export {default as _CartoDynamicTileLayer} from './layers/carto-dynamic-tile-layer';
3
4
  export {default as BASEMAP} from './basemap';
4
5
  export {default as colorBins} from './style/color-bins-style';
5
6
  export {default as colorCategories} from './style/color-categories-style';
6
7
  export {default as colorContinuous} from './style/color-continuous-style';
7
8
  export {
8
9
  FORMATS,
10
+ TILE_FORMATS,
9
11
  MAP_TYPES,
10
12
  API_VERSIONS,
11
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 {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,8 @@ const CartoDynamicTileLoader = {
29
60
  parseSync: parseCartoDynamicTile,
30
61
  options: {
31
62
  cartoDynamicTile: {
32
- formatTiles: 'geojson'
63
+ // TODO change to BINARY for 8.7 prod release
64
+ formatTiles: TILE_FORMATS.GEOJSON
33
65
  }
34
66
  }
35
67
  };
@@ -52,11 +84,14 @@ export default class CartoDynamicTileLayer extends MVTLayer {
52
84
 
53
85
  if (formatTiles) {
54
86
  log.assert(
55
- ['geojson'].includes(formatTiles),
56
- `Invalid value for formatTiles: ${formatTiles}`
87
+ Object.values(TILE_FORMATS).includes(formatTiles),
88
+ `Invalid value for formatTiles: ${formatTiles}. Use value from TILE_FORMATS`
57
89
  );
58
- url += `&${encodeParameter('formatTiles', formatTiles)}`;
59
- loadOptions.cartoBinaryTile = {formatTiles};
90
+ // eslint-disable-next-line no-undef
91
+ const newUrl = new URL(url);
92
+ newUrl.searchParams.set('formatTiles', formatTiles);
93
+ url = newUrl.toString();
94
+ loadOptions.cartoDynamicTile = {formatTiles};
60
95
  }
61
96
 
62
97
  return fetch(url, {propName: 'data', layer: this, loadOptions, signal});
@@ -72,7 +107,7 @@ export default class CartoDynamicTileLayer extends MVTLayer {
72
107
  const {
73
108
  bbox: {west, south, east, north}
74
109
  } = props.tile;
75
- props.extensions = [new ClipExtension()];
110
+ props.extensions = [new ClipExtension(), ...(props.extensions || [])];
76
111
  props.clipBounds = [west, south, east, north];
77
112
 
78
113
  const subLayer = new GeoJsonLayer({
@@ -3,7 +3,7 @@ import CartoDynamicTileLayer from './carto-dynamic-tile-layer';
3
3
  import {MVTLayer} from '@deck.gl/geo-layers';
4
4
  import {GeoJsonLayer} from '@deck.gl/layers';
5
5
  import {fetchLayerData, getDataV2, API_VERSIONS} from '../api';
6
- import {FORMATS, MAP_TYPES} from '../api/maps-api-common';
6
+ import {FORMATS, MAP_TYPES, TILE_FORMATS} from '../api/maps-api-common';
7
7
  import {getDefaultCredentials} from '../config';
8
8
 
9
9
  const defaultProps = {
@@ -27,6 +27,9 @@ const defaultProps = {
27
27
  // (String, optional): format of data
28
28
  format: null,
29
29
 
30
+ // (String, optional): force format of data for tiles
31
+ formatTiles: null,
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
 
@@ -123,29 +126,37 @@ export default class CartoLayer extends CompositeLayer {
123
126
  }
124
127
  }
125
128
 
126
- renderLayers() {
129
+ _getRenderLayer() {
127
130
  const {data, format, apiVersion} = this.state;
128
131
 
129
- if (!data) return null;
132
+ if (apiVersion === API_VERSIONS.V1 || apiVersion === API_VERSIONS.V2) {
133
+ return MVTLayer;
134
+ }
130
135
 
131
- const {type, updateTriggers} = this.props;
136
+ if (format === FORMATS.TILEJSON) {
137
+ /* global URL */
138
+ const formatTiles =
139
+ this.props.formatTiles ||
140
+ new URL(data.tiles[0]).searchParams.get('formatTiles') ||
141
+ TILE_FORMATS.MVT;
142
+ return formatTiles === TILE_FORMATS.MVT ? MVTLayer : CartoDynamicTileLayer;
143
+ }
132
144
 
133
- let layer;
145
+ // It's a geojson layer
146
+ return GeoJsonLayer;
147
+ }
134
148
 
135
- if (apiVersion === API_VERSIONS.V3 && type === MAP_TYPES.TABLE && format === FORMATS.TILEJSON) {
136
- layer = CartoDynamicTileLayer;
137
- } else if (
138
- apiVersion === API_VERSIONS.V1 ||
139
- apiVersion === API_VERSIONS.V2 ||
140
- format === FORMATS.TILEJSON
141
- ) {
142
- layer = MVTLayer;
143
- } else {
144
- layer = GeoJsonLayer;
145
- }
149
+ renderLayers() {
150
+ const {data} = this.state;
151
+
152
+ if (!data) return null;
153
+
154
+ const {updateTriggers} = this.props;
155
+
156
+ const layer = this._getRenderLayer();
146
157
 
147
- const {uniqueIdProperty} = defaultProps;
148
- const props = {uniqueIdProperty, ...this.props};
158
+ const {formatTiles, uniqueIdProperty} = defaultProps;
159
+ const props = {formatTiles, uniqueIdProperty, ...this.props};
149
160
  delete props.data;
150
161
 
151
162
  // 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
+ };