@loaders.gl/mvt 4.2.1 → 4.3.0-alpha.2
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 +1784 -847
- package/dist/dist.min.js +1 -1
- package/dist/index.cjs +713 -640
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/parse-mvt.d.ts +2 -1
- package/dist/lib/parse-mvt.d.ts.map +1 -1
- package/dist/lib/parse-mvt.js +15 -45
- package/dist/lib/parse-tilejson.d.ts +4 -4
- package/dist/lib/parse-tilejson.d.ts.map +1 -1
- package/dist/lib/types.d.ts +1 -39
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils/geometry-utils.d.ts +83 -0
- package/dist/lib/utils/geometry-utils.d.ts.map +1 -0
- package/dist/lib/utils/geometry-utils.js +206 -0
- package/dist/lib/vector-tile/vector-tile-feature.d.ts +72 -0
- package/dist/lib/vector-tile/vector-tile-feature.d.ts.map +1 -0
- package/dist/lib/vector-tile/vector-tile-feature.js +342 -0
- package/dist/lib/{mapbox-vector-tile → vector-tile}/vector-tile-layer.d.ts +10 -1
- package/dist/lib/vector-tile/vector-tile-layer.d.ts.map +1 -0
- package/dist/lib/{mapbox-vector-tile → vector-tile}/vector-tile-layer.js +16 -1
- package/dist/lib/vector-tile/vector-tile.d.ts.map +1 -0
- package/dist/lib/{geojson-tiler → vector-tiler}/clip.d.ts +3 -3
- package/dist/lib/vector-tiler/clip.d.ts.map +1 -0
- package/dist/lib/vector-tiler/convert.d.ts +18 -0
- package/dist/lib/vector-tiler/convert.d.ts.map +1 -0
- package/dist/lib/{geojson-tiler → vector-tiler}/convert.js +8 -1
- package/dist/lib/vector-tiler/feature.d.ts +3 -0
- package/dist/lib/vector-tiler/feature.d.ts.map +1 -0
- package/dist/lib/vector-tiler/simplify.d.ts.map +1 -0
- package/dist/lib/{geojson-tiler → vector-tiler}/tile.d.ts +4 -4
- package/dist/lib/vector-tiler/tile.d.ts.map +1 -0
- package/dist/lib/vector-tiler/transform.d.ts +7 -0
- package/dist/lib/vector-tiler/transform.d.ts.map +1 -0
- package/dist/lib/{geojson-tiler → vector-tiler}/wrap.d.ts +2 -2
- package/dist/lib/vector-tiler/wrap.d.ts.map +1 -0
- package/dist/mvt-loader.d.ts +19 -8
- package/dist/mvt-loader.d.ts.map +1 -1
- package/dist/mvt-loader.js +3 -2
- package/dist/mvt-source.d.ts +4 -4
- package/dist/mvt-source.d.ts.map +1 -1
- package/dist/mvt-source.js +7 -7
- package/dist/mvt-worker.js +1244 -762
- package/dist/table-tile-source.d.ts +118 -0
- package/dist/table-tile-source.d.ts.map +1 -0
- package/dist/table-tile-source.js +370 -0
- package/dist/tilejson-loader.js +1 -1
- package/package.json +7 -6
- package/src/index.ts +3 -3
- package/src/lib/parse-mvt.ts +28 -66
- package/src/lib/parse-tilejson.ts +5 -5
- package/src/lib/types.ts +1 -39
- package/src/lib/utils/geometry-utils.ts +234 -0
- package/src/lib/vector-tile/vector-tile-feature.ts +416 -0
- package/src/lib/{mapbox-vector-tile → vector-tile}/vector-tile-layer.ts +28 -2
- package/src/lib/{geojson-tiler → vector-tiler}/clip.ts +4 -4
- package/src/lib/{geojson-tiler → vector-tiler}/convert.ts +19 -9
- package/src/lib/{geojson-tiler → vector-tiler}/feature.ts +3 -3
- package/src/lib/{geojson-tiler → vector-tiler}/tile.ts +10 -10
- package/src/lib/{geojson-tiler → vector-tiler}/transform.ts +2 -2
- package/src/lib/{geojson-tiler → vector-tiler}/wrap.ts +5 -5
- package/src/mvt-loader.ts +14 -6
- package/src/mvt-source.ts +9 -10
- package/src/table-tile-source.ts +508 -0
- package/dist/helpers/binary-util-functions.d.ts +0 -35
- package/dist/helpers/binary-util-functions.d.ts.map +0 -1
- package/dist/helpers/binary-util-functions.js +0 -114
- package/dist/helpers/mapbox-util-functions.d.ts +0 -29
- package/dist/helpers/mapbox-util-functions.d.ts.map +0 -1
- package/dist/helpers/mapbox-util-functions.js +0 -78
- package/dist/lib/binary-vector-tile/vector-tile-feature.d.ts +0 -41
- package/dist/lib/binary-vector-tile/vector-tile-feature.d.ts.map +0 -1
- package/dist/lib/binary-vector-tile/vector-tile-feature.js +0 -163
- package/dist/lib/binary-vector-tile/vector-tile-layer.d.ts +0 -23
- package/dist/lib/binary-vector-tile/vector-tile-layer.d.ts.map +0 -1
- package/dist/lib/binary-vector-tile/vector-tile-layer.js +0 -96
- package/dist/lib/binary-vector-tile/vector-tile.d.ts +0 -9
- package/dist/lib/binary-vector-tile/vector-tile.d.ts.map +0 -1
- package/dist/lib/binary-vector-tile/vector-tile.js +0 -27
- package/dist/lib/geojson-tiler/clip.d.ts.map +0 -1
- package/dist/lib/geojson-tiler/convert.d.ts +0 -10
- package/dist/lib/geojson-tiler/convert.d.ts.map +0 -1
- package/dist/lib/geojson-tiler/feature.d.ts +0 -3
- package/dist/lib/geojson-tiler/feature.d.ts.map +0 -1
- package/dist/lib/geojson-tiler/geojson-tiler.d.ts +0 -44
- package/dist/lib/geojson-tiler/geojson-tiler.d.ts.map +0 -1
- package/dist/lib/geojson-tiler/geojson-tiler.js +0 -209
- package/dist/lib/geojson-tiler/simplify.d.ts.map +0 -1
- package/dist/lib/geojson-tiler/tile.d.ts.map +0 -1
- package/dist/lib/geojson-tiler/transform.d.ts +0 -7
- package/dist/lib/geojson-tiler/transform.d.ts.map +0 -1
- package/dist/lib/geojson-tiler/wrap.d.ts.map +0 -1
- package/dist/lib/mapbox-vector-tile/vector-tile-feature.d.ts +0 -27
- package/dist/lib/mapbox-vector-tile/vector-tile-feature.d.ts.map +0 -1
- package/dist/lib/mapbox-vector-tile/vector-tile-feature.js +0 -178
- package/dist/lib/mapbox-vector-tile/vector-tile-layer.d.ts.map +0 -1
- package/dist/lib/mapbox-vector-tile/vector-tile.d.ts.map +0 -1
- package/src/helpers/binary-util-functions.ts +0 -125
- package/src/helpers/mapbox-util-functions.ts +0 -82
- package/src/lib/binary-vector-tile/vector-tile-feature.ts +0 -203
- package/src/lib/binary-vector-tile/vector-tile-layer.ts +0 -113
- package/src/lib/binary-vector-tile/vector-tile.ts +0 -36
- package/src/lib/geojson-tiler/geojson-tiler.ts +0 -283
- package/src/lib/mapbox-vector-tile/LICENSE.txt +0 -31
- package/src/lib/mapbox-vector-tile/vector-tile-feature.ts +0 -207
- /package/dist/lib/{mapbox-vector-tile → vector-tile}/vector-tile.d.ts +0 -0
- /package/dist/lib/{mapbox-vector-tile → vector-tile}/vector-tile.js +0 -0
- /package/dist/lib/{geojson-tiler → vector-tiler}/clip.js +0 -0
- /package/dist/lib/{geojson-tiler → vector-tiler}/feature.js +0 -0
- /package/dist/lib/{geojson-tiler → vector-tiler}/simplify.d.ts +0 -0
- /package/dist/lib/{geojson-tiler → vector-tiler}/simplify.js +0 -0
- /package/dist/lib/{geojson-tiler → vector-tiler}/tile.js +0 -0
- /package/dist/lib/{geojson-tiler → vector-tiler}/transform.js +0 -0
- /package/dist/lib/{geojson-tiler → vector-tiler}/wrap.js +0 -0
- /package/src/lib/{binary-vector-tile → vector-tile}/LICENSE.txt +0 -0
- /package/src/lib/{mapbox-vector-tile → vector-tile}/vector-tile.ts +0 -0
- /package/src/lib/{geojson-tiler → vector-tiler}/LICENSE +0 -0
- /package/src/lib/{geojson-tiler → vector-tiler}/simplify.ts +0 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// This code is forked from https://github.com/mapbox/vector-tile-js under BSD 3-clause license.
|
|
6
|
+
import {Feature} from '@loaders.gl/schema';
|
|
7
|
+
import {FlatFeature, FlatIndexedGeometry, GeojsonGeometryInfo} from '@loaders.gl/schema';
|
|
8
|
+
import Protobuf from 'pbf';
|
|
9
|
+
import {classifyRings, classifyRingsFlat} from '../utils/geometry-utils';
|
|
10
|
+
import {projectToLngLat, projectToLngLatFlat} from '../utils/geometry-utils';
|
|
11
|
+
import {convertToLocalCoordinates, convertToLocalCoordinatesFlat} from '../utils/geometry-utils';
|
|
12
|
+
|
|
13
|
+
export class VectorTileFeature {
|
|
14
|
+
properties: {[x: string]: string | number | boolean | null};
|
|
15
|
+
extent: any;
|
|
16
|
+
type: number;
|
|
17
|
+
id: number | null;
|
|
18
|
+
_pbf: Protobuf;
|
|
19
|
+
_geometry: number;
|
|
20
|
+
_keys: string[];
|
|
21
|
+
_values: (string | number | boolean | null)[];
|
|
22
|
+
_geometryInfo: GeojsonGeometryInfo;
|
|
23
|
+
|
|
24
|
+
static types: Readonly<string[]> = ['Unknown', 'Point', 'LineString', 'Polygon'];
|
|
25
|
+
|
|
26
|
+
// eslint-disable-next-line max-params
|
|
27
|
+
constructor(
|
|
28
|
+
pbf: Protobuf,
|
|
29
|
+
end: number,
|
|
30
|
+
extent: any,
|
|
31
|
+
keys: string[],
|
|
32
|
+
values: (string | number | boolean | null)[],
|
|
33
|
+
geometryInfo?: GeojsonGeometryInfo
|
|
34
|
+
) {
|
|
35
|
+
// Public
|
|
36
|
+
this.properties = {};
|
|
37
|
+
this.extent = extent;
|
|
38
|
+
this.type = 0;
|
|
39
|
+
this.id = null;
|
|
40
|
+
|
|
41
|
+
// Private
|
|
42
|
+
this._pbf = pbf;
|
|
43
|
+
this._geometry = -1;
|
|
44
|
+
this._keys = keys;
|
|
45
|
+
this._values = values;
|
|
46
|
+
|
|
47
|
+
// Only used by binary tiles
|
|
48
|
+
this._geometryInfo = geometryInfo!;
|
|
49
|
+
|
|
50
|
+
pbf.readFields(readFeature, this, end);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
toGeoJSONFeature(
|
|
54
|
+
coordinates: 'wgs84' | 'local',
|
|
55
|
+
tileIndex?: {x: number; y: number; z: number}
|
|
56
|
+
): Feature {
|
|
57
|
+
const coords = this.loadGeometry();
|
|
58
|
+
|
|
59
|
+
switch (coordinates) {
|
|
60
|
+
case 'wgs84':
|
|
61
|
+
return _toGeoJSONFeature(this, coords, (line: number[][]) =>
|
|
62
|
+
projectToLngLat(line, tileIndex!, this.extent)
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
default:
|
|
66
|
+
return _toGeoJSONFeature(this, coords, convertToLocalCoordinates);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param options
|
|
72
|
+
* @returns
|
|
73
|
+
*/
|
|
74
|
+
toBinaryFeature(
|
|
75
|
+
coordinates: 'wgs84' | 'local',
|
|
76
|
+
tileIndex?: {x: number; y: number; z: number}
|
|
77
|
+
): FlatFeature {
|
|
78
|
+
const geom = this.loadFlatGeometry();
|
|
79
|
+
|
|
80
|
+
switch (coordinates) {
|
|
81
|
+
case 'wgs84':
|
|
82
|
+
return this._toBinaryCoordinates(geom, (coords: number[]) =>
|
|
83
|
+
projectToLngLatFlat(coords, tileIndex!, this.extent)
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
default:
|
|
87
|
+
return this._toBinaryCoordinates(geom, convertToLocalCoordinatesFlat);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Read a bounding box from the feature */
|
|
92
|
+
// eslint-disable-next-line max-statements
|
|
93
|
+
bbox() {
|
|
94
|
+
const pbf = this._pbf;
|
|
95
|
+
pbf.pos = this._geometry;
|
|
96
|
+
|
|
97
|
+
const end = pbf.readVarint() + pbf.pos;
|
|
98
|
+
let cmd = 1;
|
|
99
|
+
let length = 0;
|
|
100
|
+
let x = 0;
|
|
101
|
+
let y = 0;
|
|
102
|
+
let x1 = Infinity;
|
|
103
|
+
let x2 = -Infinity;
|
|
104
|
+
let y1 = Infinity;
|
|
105
|
+
let y2 = -Infinity;
|
|
106
|
+
|
|
107
|
+
while (pbf.pos < end) {
|
|
108
|
+
if (length <= 0) {
|
|
109
|
+
const cmdLen = pbf.readVarint();
|
|
110
|
+
cmd = cmdLen & 0x7;
|
|
111
|
+
length = cmdLen >> 3;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
length--;
|
|
115
|
+
|
|
116
|
+
if (cmd === 1 || cmd === 2) {
|
|
117
|
+
x += pbf.readSVarint();
|
|
118
|
+
y += pbf.readSVarint();
|
|
119
|
+
if (x < x1) x1 = x;
|
|
120
|
+
if (x > x2) x2 = x;
|
|
121
|
+
if (y < y1) y1 = y;
|
|
122
|
+
if (y > y2) y2 = y;
|
|
123
|
+
} else if (cmd !== 7) {
|
|
124
|
+
throw new Error(`unknown command ${cmd}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return [x1, y1, x2, y2];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// BINARY HELPERS
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
*
|
|
135
|
+
* @param transform
|
|
136
|
+
* @returns result
|
|
137
|
+
*/
|
|
138
|
+
_toBinaryCoordinates(
|
|
139
|
+
geom: FlatIndexedGeometry,
|
|
140
|
+
transform: (data: number[], extent: number) => void
|
|
141
|
+
) {
|
|
142
|
+
let geometry;
|
|
143
|
+
|
|
144
|
+
// Apply the supplied transformation to data
|
|
145
|
+
transform(geom.data, this.extent);
|
|
146
|
+
|
|
147
|
+
const coordLength = 2;
|
|
148
|
+
|
|
149
|
+
// eslint-disable-next-line default-case
|
|
150
|
+
switch (this.type) {
|
|
151
|
+
case 1: // Point
|
|
152
|
+
this._geometryInfo.pointFeaturesCount++;
|
|
153
|
+
this._geometryInfo.pointPositionsCount += geom.indices.length;
|
|
154
|
+
geometry = {type: 'Point', ...geom};
|
|
155
|
+
break;
|
|
156
|
+
|
|
157
|
+
case 2: // LineString
|
|
158
|
+
this._geometryInfo.lineFeaturesCount++;
|
|
159
|
+
this._geometryInfo.linePathsCount += geom.indices.length;
|
|
160
|
+
this._geometryInfo.linePositionsCount += geom.data.length / coordLength;
|
|
161
|
+
geometry = {type: 'LineString', ...geom};
|
|
162
|
+
break;
|
|
163
|
+
|
|
164
|
+
case 3: // Polygon
|
|
165
|
+
geometry = classifyRingsFlat(geom);
|
|
166
|
+
|
|
167
|
+
// Unlike Point & LineString geom.indices is a 2D array, thanks
|
|
168
|
+
// to the classifyRings method
|
|
169
|
+
this._geometryInfo.polygonFeaturesCount++;
|
|
170
|
+
this._geometryInfo.polygonObjectsCount += geometry.indices.length;
|
|
171
|
+
|
|
172
|
+
for (const indices of geometry.indices) {
|
|
173
|
+
this._geometryInfo.polygonRingsCount += indices.length;
|
|
174
|
+
}
|
|
175
|
+
this._geometryInfo.polygonPositionsCount += geometry.data.length / coordLength;
|
|
176
|
+
|
|
177
|
+
break;
|
|
178
|
+
default:
|
|
179
|
+
throw new Error(`Invalid geometry type: ${this.type}`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const result: FlatFeature = {type: 'Feature', geometry, properties: this.properties};
|
|
183
|
+
|
|
184
|
+
if (this.id !== null) {
|
|
185
|
+
result.id = this.id;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// GEOJSON HELPER
|
|
192
|
+
|
|
193
|
+
// eslint-disable-next-line complexity, max-statements
|
|
194
|
+
loadGeometry(): number[][][] {
|
|
195
|
+
const pbf = this._pbf;
|
|
196
|
+
pbf.pos = this._geometry;
|
|
197
|
+
|
|
198
|
+
const end = pbf.readVarint() + pbf.pos;
|
|
199
|
+
let cmd = 1;
|
|
200
|
+
let length = 0;
|
|
201
|
+
let x = 0;
|
|
202
|
+
let y = 0;
|
|
203
|
+
const lines: number[][][] = [];
|
|
204
|
+
let line: number[][] | undefined;
|
|
205
|
+
|
|
206
|
+
while (pbf.pos < end) {
|
|
207
|
+
if (length <= 0) {
|
|
208
|
+
const cmdLen = pbf.readVarint();
|
|
209
|
+
cmd = cmdLen & 0x7;
|
|
210
|
+
length = cmdLen >> 3;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
length--;
|
|
214
|
+
|
|
215
|
+
switch (cmd) {
|
|
216
|
+
case 1:
|
|
217
|
+
case 2:
|
|
218
|
+
x += pbf.readSVarint();
|
|
219
|
+
y += pbf.readSVarint();
|
|
220
|
+
|
|
221
|
+
if (cmd === 1) {
|
|
222
|
+
// moveTo
|
|
223
|
+
if (line) lines.push(line);
|
|
224
|
+
line = [];
|
|
225
|
+
}
|
|
226
|
+
if (line) line.push([x, y]);
|
|
227
|
+
break;
|
|
228
|
+
case 7:
|
|
229
|
+
// Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90
|
|
230
|
+
if (line) {
|
|
231
|
+
line.push(line[0].slice()); // closePolygon
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
default:
|
|
235
|
+
throw new Error(`unknown command ${cmd}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (line) lines.push(line);
|
|
240
|
+
|
|
241
|
+
return lines;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Expands the protobuf data to an intermediate Flat GeoJSON
|
|
246
|
+
* data format, which maps closely to the binary data buffers.
|
|
247
|
+
* It is similar to GeoJSON, but rather than storing the coordinates
|
|
248
|
+
* in multidimensional arrays, we have a 1D `data` with all the
|
|
249
|
+
* coordinates, and then index into this using the `indices`
|
|
250
|
+
* parameter, e.g.
|
|
251
|
+
*
|
|
252
|
+
* geometry: {
|
|
253
|
+
* type: 'Point', data: [1,2], indices: [0]
|
|
254
|
+
* }
|
|
255
|
+
* geometry: {
|
|
256
|
+
* type: 'LineString', data: [1,2,3,4,...], indices: [0]
|
|
257
|
+
* }
|
|
258
|
+
* geometry: {
|
|
259
|
+
* type: 'Polygon', data: [1,2,3,4,...], indices: [[0, 2]]
|
|
260
|
+
* }
|
|
261
|
+
* Thus the indices member lets us look up the relevant range
|
|
262
|
+
* from the data array.
|
|
263
|
+
* The Multi* versions of the above types share the same data
|
|
264
|
+
* structure, just with multiple elements in the indices array
|
|
265
|
+
*/
|
|
266
|
+
// eslint-disable-next-line complexity, max-statements
|
|
267
|
+
loadFlatGeometry(): FlatIndexedGeometry {
|
|
268
|
+
const pbf = this._pbf;
|
|
269
|
+
pbf.pos = this._geometry;
|
|
270
|
+
|
|
271
|
+
const endPos = pbf.readVarint() + pbf.pos;
|
|
272
|
+
let cmd = 1;
|
|
273
|
+
let cmdLen: number;
|
|
274
|
+
let length = 0;
|
|
275
|
+
let x = 0;
|
|
276
|
+
let y = 0;
|
|
277
|
+
let i = 0;
|
|
278
|
+
|
|
279
|
+
// Note: I attempted to replace the `data` array with a
|
|
280
|
+
// Float32Array, but performance was worse, both using
|
|
281
|
+
// `set()` and direct index access. Also, we cannot
|
|
282
|
+
// know how large the buffer should be, so it would
|
|
283
|
+
// increase memory usage
|
|
284
|
+
const indices: number[] = []; // Indices where geometries start
|
|
285
|
+
const data: number[] = []; // Flat array of coordinate data
|
|
286
|
+
|
|
287
|
+
while (pbf.pos < endPos) {
|
|
288
|
+
if (length <= 0) {
|
|
289
|
+
cmdLen = pbf.readVarint();
|
|
290
|
+
cmd = cmdLen & 0x7;
|
|
291
|
+
length = cmdLen >> 3;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
length--;
|
|
295
|
+
|
|
296
|
+
if (cmd === 1 || cmd === 2) {
|
|
297
|
+
x += pbf.readSVarint();
|
|
298
|
+
y += pbf.readSVarint();
|
|
299
|
+
|
|
300
|
+
if (cmd === 1) {
|
|
301
|
+
// New line
|
|
302
|
+
indices.push(i);
|
|
303
|
+
}
|
|
304
|
+
data.push(x, y);
|
|
305
|
+
i += 2;
|
|
306
|
+
} else if (cmd === 7) {
|
|
307
|
+
// Workaround for https://github.com/mapbox/mapnik-vector-tile/issues/90
|
|
308
|
+
if (i > 0) {
|
|
309
|
+
const start = indices[indices.length - 1]; // start index of polygon
|
|
310
|
+
data.push(data[start], data[start + 1]); // closePolygon
|
|
311
|
+
i += 2;
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
314
|
+
throw new Error(`unknown command ${cmd}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return {data, indices};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function _toGeoJSONFeature(
|
|
323
|
+
vtFeature: VectorTileFeature,
|
|
324
|
+
coords: number[][][],
|
|
325
|
+
transform: (data: number[][], extent: number) => void
|
|
326
|
+
): Feature {
|
|
327
|
+
let type = VectorTileFeature.types[vtFeature.type];
|
|
328
|
+
let i: number;
|
|
329
|
+
let j: number;
|
|
330
|
+
|
|
331
|
+
let coordinates: number[][] | number[][][] | number[][][][];
|
|
332
|
+
switch (vtFeature.type) {
|
|
333
|
+
case 1:
|
|
334
|
+
const points: number[][] = [];
|
|
335
|
+
for (i = 0; i < coords.length; i++) {
|
|
336
|
+
points[i] = coords[i][0];
|
|
337
|
+
}
|
|
338
|
+
coordinates = points;
|
|
339
|
+
transform(coordinates, vtFeature.extent);
|
|
340
|
+
break;
|
|
341
|
+
|
|
342
|
+
case 2:
|
|
343
|
+
coordinates = coords;
|
|
344
|
+
for (i = 0; i < coordinates.length; i++) {
|
|
345
|
+
transform(coordinates[i], vtFeature.extent);
|
|
346
|
+
}
|
|
347
|
+
break;
|
|
348
|
+
|
|
349
|
+
case 3:
|
|
350
|
+
coordinates = classifyRings(coords);
|
|
351
|
+
for (i = 0; i < coordinates.length; i++) {
|
|
352
|
+
for (j = 0; j < coordinates[i].length; j++) {
|
|
353
|
+
transform(coordinates[i][j], vtFeature.extent);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
break;
|
|
357
|
+
|
|
358
|
+
default:
|
|
359
|
+
throw new Error('illegal vector tile type');
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (coordinates.length === 1) {
|
|
363
|
+
// @ts-expect-error
|
|
364
|
+
coordinates = coordinates[0];
|
|
365
|
+
} else {
|
|
366
|
+
type = `Multi${type}`;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const result: Feature = {
|
|
370
|
+
type: 'Feature',
|
|
371
|
+
geometry: {
|
|
372
|
+
type: type as any,
|
|
373
|
+
coordinates: coordinates as any
|
|
374
|
+
},
|
|
375
|
+
properties: vtFeature.properties
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
if (vtFeature.id !== null) {
|
|
379
|
+
result.properties ||= {};
|
|
380
|
+
result.properties.id = vtFeature.id;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return result;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// PBF READER UTILS
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
*
|
|
390
|
+
* @param tag
|
|
391
|
+
* @param feature
|
|
392
|
+
* @param pbf
|
|
393
|
+
*/
|
|
394
|
+
function readFeature(tag: number, feature?: VectorTileFeature, pbf?: Protobuf): void {
|
|
395
|
+
if (feature && pbf) {
|
|
396
|
+
if (tag === 1) feature.id = pbf.readVarint();
|
|
397
|
+
else if (tag === 2) readTag(pbf, feature);
|
|
398
|
+
else if (tag === 3) feature.type = pbf.readVarint();
|
|
399
|
+
else if (tag === 4) feature._geometry = pbf.pos;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
*
|
|
405
|
+
* @param pbf
|
|
406
|
+
* @param feature
|
|
407
|
+
*/
|
|
408
|
+
function readTag(pbf: Protobuf, feature: VectorTileFeature): void {
|
|
409
|
+
const end = pbf.readVarint() + pbf.pos;
|
|
410
|
+
|
|
411
|
+
while (pbf.pos < end) {
|
|
412
|
+
const key = feature._keys[pbf.readVarint()];
|
|
413
|
+
const value = feature._values[pbf.readVarint()];
|
|
414
|
+
feature.properties[key] = value;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import Protobuf from 'pbf';
|
|
9
9
|
import {VectorTileFeature} from './vector-tile-feature';
|
|
10
|
+
import {GeojsonGeometryInfo} from '@loaders.gl/schema';
|
|
10
11
|
|
|
11
12
|
export class VectorTileLayer {
|
|
12
13
|
version: number;
|
|
@@ -17,6 +18,7 @@ export class VectorTileLayer {
|
|
|
17
18
|
_keys: string[];
|
|
18
19
|
_values: (string | number | boolean | null)[];
|
|
19
20
|
_features: number[];
|
|
21
|
+
|
|
20
22
|
constructor(pbf: Protobuf, end: number) {
|
|
21
23
|
// Public
|
|
22
24
|
this.version = 1;
|
|
@@ -40,8 +42,7 @@ export class VectorTileLayer {
|
|
|
40
42
|
* @param index
|
|
41
43
|
* @returns feature
|
|
42
44
|
*/
|
|
43
|
-
|
|
44
|
-
feature(i: number): VectorTileFeature {
|
|
45
|
+
getGeoJSONFeature(i: number): VectorTileFeature {
|
|
45
46
|
if (i < 0 || i >= this._features.length) {
|
|
46
47
|
throw new Error('feature index out of bounds');
|
|
47
48
|
}
|
|
@@ -51,6 +52,31 @@ export class VectorTileLayer {
|
|
|
51
52
|
const end = this._pbf.readVarint() + this._pbf.pos;
|
|
52
53
|
return new VectorTileFeature(this._pbf, end, this.extent, this._keys, this._values);
|
|
53
54
|
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* return binary feature `i` from this layer as a `VectorTileFeature`
|
|
58
|
+
*
|
|
59
|
+
* @param index
|
|
60
|
+
* @param geometryInfo
|
|
61
|
+
* @returns binary feature
|
|
62
|
+
*/
|
|
63
|
+
getBinaryFeature(i: number, geometryInfo: GeojsonGeometryInfo): VectorTileFeature {
|
|
64
|
+
if (i < 0 || i >= this._features.length) {
|
|
65
|
+
throw new Error('feature index out of bounds');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this._pbf.pos = this._features[i];
|
|
69
|
+
|
|
70
|
+
const end = this._pbf.readVarint() + this._pbf.pos;
|
|
71
|
+
return new VectorTileFeature(
|
|
72
|
+
this._pbf,
|
|
73
|
+
end,
|
|
74
|
+
this.extent,
|
|
75
|
+
this._keys,
|
|
76
|
+
this._values,
|
|
77
|
+
geometryInfo
|
|
78
|
+
);
|
|
79
|
+
}
|
|
54
80
|
}
|
|
55
81
|
|
|
56
82
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
// Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type {TableTileFeature} from './tile';
|
|
7
7
|
import {createFeature} from './feature';
|
|
8
8
|
|
|
9
9
|
/* eslint-disable no-continue */
|
|
@@ -21,7 +21,7 @@ import {createFeature} from './feature';
|
|
|
21
21
|
*/
|
|
22
22
|
// eslint-disable-next-line max-params, complexity, max-statements
|
|
23
23
|
export function clip(
|
|
24
|
-
features:
|
|
24
|
+
features: TableTileFeature[],
|
|
25
25
|
scale: number,
|
|
26
26
|
k1: number,
|
|
27
27
|
k2: number,
|
|
@@ -29,7 +29,7 @@ export function clip(
|
|
|
29
29
|
minAll: number,
|
|
30
30
|
maxAll: number,
|
|
31
31
|
options: {lineMetrics: boolean}
|
|
32
|
-
):
|
|
32
|
+
): TableTileFeature[] | null {
|
|
33
33
|
k1 /= scale;
|
|
34
34
|
k2 /= scale;
|
|
35
35
|
|
|
@@ -41,7 +41,7 @@ export function clip(
|
|
|
41
41
|
return null; // trivial reject
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const clipped:
|
|
44
|
+
const clipped: TableTileFeature[] = [];
|
|
45
45
|
|
|
46
46
|
for (const feature of features) {
|
|
47
47
|
const geometry = feature.geometry;
|
|
@@ -6,15 +6,17 @@
|
|
|
6
6
|
/* eslint-disable */
|
|
7
7
|
// @ts-nocheck
|
|
8
8
|
|
|
9
|
-
import type {Feature} from '@loaders.gl/schema';
|
|
10
|
-
import type {
|
|
9
|
+
import type {Feature, FeatureCollection} from '@loaders.gl/schema';
|
|
10
|
+
import type {TableTileFeature} from './tile';
|
|
11
11
|
|
|
12
12
|
import {simplify} from './simplify';
|
|
13
13
|
import {createFeature} from './feature';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
/**
|
|
16
|
+
* converts a GeoJSON feature into an intermediate projected JSON vector format
|
|
17
|
+
* with simplification data
|
|
18
|
+
*/
|
|
19
|
+
export function convert(data: Feature | FeatureCollection, options): TableTileFeature[] {
|
|
18
20
|
const features = [];
|
|
19
21
|
if (data.type === 'FeatureCollection') {
|
|
20
22
|
for (let i = 0; i < data.features.length; i++) {
|
|
@@ -31,14 +33,22 @@ export function convert(data: Feature, options): GeoJSONTileFeature[] {
|
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
export type ConvertFeatureOptions = {
|
|
36
|
+
/** max zoom to preserve detail on */
|
|
34
37
|
maxZoom?: number;
|
|
35
|
-
tolerance
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
/** simplification tolerance (higher means simpler) */
|
|
39
|
+
tolerance?: number;
|
|
40
|
+
/** tile extent */
|
|
41
|
+
extent?: number;
|
|
42
|
+
/** whether to calculate line metrics */
|
|
43
|
+
lineMetrics?: boolean;
|
|
38
44
|
};
|
|
39
45
|
|
|
46
|
+
/**
|
|
47
|
+
* converts a GeoJSON feature into an intermediate projected JSON vector format
|
|
48
|
+
* with simplification data
|
|
49
|
+
*/
|
|
40
50
|
function convertFeature(
|
|
41
|
-
features:
|
|
51
|
+
features: TableTileFeature[],
|
|
42
52
|
geojson: Feature,
|
|
43
53
|
options: ConvertFeatureOptions,
|
|
44
54
|
index: number
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
// Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {TableTileFeature} from './tile';
|
|
7
7
|
|
|
8
|
-
export function createFeature(id, type, geom, tags):
|
|
9
|
-
const feature:
|
|
8
|
+
export function createFeature(id, type, geom, tags): TableTileFeature {
|
|
9
|
+
const feature: TableTileFeature = {
|
|
10
10
|
// eslint-disable-next-line
|
|
11
11
|
id: id == null ? null : id,
|
|
12
12
|
type,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
// import type {Feature} from '@loaders.gl/schema';
|
|
7
7
|
|
|
8
|
-
export type
|
|
8
|
+
export type TableTileFeature = {
|
|
9
9
|
type: any;
|
|
10
10
|
geometry: any;
|
|
11
11
|
|
|
@@ -20,8 +20,8 @@ export type GeoJSONTileFeature = {
|
|
|
20
20
|
maxY: number;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export type
|
|
24
|
-
features:
|
|
23
|
+
export type TableTile = {
|
|
24
|
+
features: TableTileFeature[]; // Feature[]; Doesn't seem JSON compatible??
|
|
25
25
|
type?: number;
|
|
26
26
|
tags?: Record<string, string>;
|
|
27
27
|
|
|
@@ -53,9 +53,9 @@ export type CreateTileOptions = {
|
|
|
53
53
|
/**
|
|
54
54
|
* Create a tile from features and tile index
|
|
55
55
|
*/
|
|
56
|
-
export function createTile(features: any[], z, tx, ty, options: CreateTileOptions):
|
|
56
|
+
export function createTile(features: any[], z, tx, ty, options: CreateTileOptions): TableTile {
|
|
57
57
|
const tolerance = z === options.maxZoom ? 0 : options.tolerance / ((1 << z) * options.extent);
|
|
58
|
-
const tile:
|
|
58
|
+
const tile: TableTile = {
|
|
59
59
|
features: [],
|
|
60
60
|
numPoints: 0,
|
|
61
61
|
numSimplified: 0,
|
|
@@ -77,7 +77,7 @@ export function createTile(features: any[], z, tx, ty, options: CreateTileOption
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// eslint-disable-next-line complexity, max-statements
|
|
80
|
-
function addFeature(tile:
|
|
80
|
+
function addFeature(tile: TableTile, feature, tolerance: number, options: CreateTileOptions) {
|
|
81
81
|
const geom = feature.geometry;
|
|
82
82
|
const type = feature.type;
|
|
83
83
|
const simplified: number[] = [];
|
|
@@ -121,14 +121,14 @@ function addFeature(tile: GeoJSONTile, feature, tolerance: number, options: Crea
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
// @ts-expect-error TODO - create sub type?
|
|
124
|
-
const tileFeature:
|
|
124
|
+
const tileFeature: TableTileFeature = {
|
|
125
125
|
geometry: simplified,
|
|
126
126
|
type:
|
|
127
127
|
type === 'Polygon' || type === 'MultiPolygon'
|
|
128
128
|
? 3
|
|
129
129
|
: type === 'LineString' || type === 'MultiLineString'
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
? 2
|
|
131
|
+
: 1,
|
|
132
132
|
tags
|
|
133
133
|
};
|
|
134
134
|
if (feature.id !== null) {
|
|
@@ -142,7 +142,7 @@ function addFeature(tile: GeoJSONTile, feature, tolerance: number, options: Crea
|
|
|
142
142
|
function addLine(
|
|
143
143
|
result,
|
|
144
144
|
geom,
|
|
145
|
-
tile:
|
|
145
|
+
tile: TableTile,
|
|
146
146
|
tolerance: number,
|
|
147
147
|
isPolygon: boolean,
|
|
148
148
|
isOuter: boolean
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
// Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type {TableTile} from './tile';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Transforms the coordinates of each feature in the given tile from
|
|
10
10
|
* mercator-projected space into (extent x extent) tile space.
|
|
11
11
|
*/
|
|
12
|
-
export function transformTile(tile:
|
|
12
|
+
export function transformTile(tile: TableTile, extent: number): TableTile {
|
|
13
13
|
if (tile.transformed) {
|
|
14
14
|
return tile;
|
|
15
15
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
// Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type {TableTileFeature} from './tile';
|
|
7
7
|
import {clip} from './clip';
|
|
8
8
|
import {createFeature} from './feature';
|
|
9
9
|
|
|
@@ -22,9 +22,9 @@ export type WrapOptions = {
|
|
|
22
22
|
* @param options buffer and extent
|
|
23
23
|
* @returns
|
|
24
24
|
*/
|
|
25
|
-
export function wrap(features:
|
|
25
|
+
export function wrap(features: TableTileFeature[], options: WrapOptions) {
|
|
26
26
|
const buffer = options.buffer / options.extent;
|
|
27
|
-
let merged:
|
|
27
|
+
let merged: TableTileFeature[] = features;
|
|
28
28
|
const left = clip(features, 1, -1 - buffer, buffer, 0, -1, 2, options); // left world copy
|
|
29
29
|
const right = clip(features, 1, 1 - buffer, 2 + buffer, 0, -1, 2, options); // right world copy
|
|
30
30
|
|
|
@@ -48,8 +48,8 @@ export function wrap(features: GeoJSONTileFeature[], options: WrapOptions) {
|
|
|
48
48
|
* @param offset
|
|
49
49
|
* @returns
|
|
50
50
|
*/
|
|
51
|
-
function shiftFeatureCoords(features:
|
|
52
|
-
const newFeatures:
|
|
51
|
+
function shiftFeatureCoords(features: TableTileFeature[], offset: number): TableTileFeature[] {
|
|
52
|
+
const newFeatures: TableTileFeature[] = [];
|
|
53
53
|
|
|
54
54
|
for (let i = 0; i < features.length; i++) {
|
|
55
55
|
const feature = features[i];
|