@maplibre/geojson-vt 6.0.3 → 6.0.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.
- package/dist/clip.d.ts.map +1 -1
- package/dist/convert.d.ts.map +1 -1
- package/dist/deconvert.d.ts +1 -1
- package/dist/deconvert.d.ts.map +1 -1
- package/dist/definitions.d.ts +12 -5
- package/dist/definitions.d.ts.map +1 -1
- package/dist/difference.d.ts +1 -1
- package/dist/difference.d.ts.map +1 -1
- package/dist/feature.d.ts +2 -1
- package/dist/feature.d.ts.map +1 -1
- package/dist/geojson-vt-dev.js +91 -74
- package/dist/geojson-vt.js +1 -1
- package/dist/geojson-vt.mjs +91 -74
- package/dist/geojson-vt.mjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/tile.d.ts.map +1 -1
- package/dist/wrap.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/clip.test.ts +21 -22
- package/src/clip.ts +37 -35
- package/src/convert.ts +17 -16
- package/src/deconvert.test.ts +7 -7
- package/src/deconvert.ts +8 -4
- package/src/definitions.ts +7 -5
- package/src/difference.test.ts +2 -2
- package/src/difference.ts +3 -3
- package/src/feature.ts +16 -6
- package/src/index.ts +3 -2
- package/src/tile.ts +6 -6
- package/src/wrap.ts +38 -18
package/dist/geojson-vt.mjs
CHANGED
|
@@ -95,27 +95,35 @@ function createFeature(id, type, geom, tags) {
|
|
|
95
95
|
switch (data.type) {
|
|
96
96
|
case 'Point':
|
|
97
97
|
case 'MultiPoint':
|
|
98
|
-
case 'LineString':
|
|
99
98
|
calcLineBBox(feature, data.geom);
|
|
100
99
|
break;
|
|
100
|
+
case 'LineString':
|
|
101
|
+
calcLineBBox(feature, data.geom.points);
|
|
102
|
+
break;
|
|
101
103
|
case 'Polygon':
|
|
102
104
|
// the outer ring (ie [0]) contains all inner rings
|
|
103
|
-
calcLineBBox(feature, data.geom[0]);
|
|
105
|
+
calcLineBBox(feature, data.geom[0].points);
|
|
104
106
|
break;
|
|
105
107
|
case 'MultiLineString':
|
|
106
108
|
for (const line of data.geom) {
|
|
107
|
-
calcLineBBox(feature, line);
|
|
109
|
+
calcLineBBox(feature, line.points);
|
|
108
110
|
}
|
|
109
111
|
break;
|
|
110
112
|
case 'MultiPolygon':
|
|
111
113
|
for (const polygon of data.geom) {
|
|
112
114
|
// the outer ring (ie [0]) contains all inner rings
|
|
113
|
-
calcLineBBox(feature, polygon[0]);
|
|
115
|
+
calcLineBBox(feature, polygon[0].points);
|
|
114
116
|
}
|
|
115
117
|
break;
|
|
116
118
|
}
|
|
117
119
|
return feature;
|
|
118
120
|
}
|
|
121
|
+
function optimizeLineMemory(line) {
|
|
122
|
+
const lineImmutable = line;
|
|
123
|
+
if (line.points.length > 64) {
|
|
124
|
+
lineImmutable.points = new Float64Array(line.points);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
119
127
|
function calcLineBBox(feature, geom) {
|
|
120
128
|
for (let i = 0; i < geom.length; i += 3) {
|
|
121
129
|
feature.minX = Math.min(feature.minX, geom[i]);
|
|
@@ -213,7 +221,7 @@ function convertMultiPointFeature(features, id, geom, properties) {
|
|
|
213
221
|
features.push(createFeature(id, 'MultiPoint', out, properties));
|
|
214
222
|
}
|
|
215
223
|
function convertLineStringFeature(features, id, geom, tolerance, properties) {
|
|
216
|
-
const out = [];
|
|
224
|
+
const out = { points: [] };
|
|
217
225
|
convertLine(geom.coordinates, out, tolerance, false);
|
|
218
226
|
features.push(createFeature(id, 'LineString', out, properties));
|
|
219
227
|
}
|
|
@@ -221,7 +229,7 @@ function convertMultiLineStringFeature(features, id, geom, tolerance, options, p
|
|
|
221
229
|
if (options.lineMetrics) {
|
|
222
230
|
// explode into linestrings to be able to track metrics
|
|
223
231
|
for (const line of geom.coordinates) {
|
|
224
|
-
const out = [];
|
|
232
|
+
const out = { points: [] };
|
|
225
233
|
convertLine(line, out, tolerance, false);
|
|
226
234
|
features.push(createFeature(id, 'LineString', out, properties));
|
|
227
235
|
}
|
|
@@ -252,7 +260,7 @@ function convertLine(ring, out, tolerance, isPolygon) {
|
|
|
252
260
|
for (let j = 0; j < ring.length; j++) {
|
|
253
261
|
const x = projectX(ring[j][0]);
|
|
254
262
|
const y = projectY(ring[j][1]);
|
|
255
|
-
out.push(x, y, 0);
|
|
263
|
+
out.points.push(x, y, 0);
|
|
256
264
|
if (j > 0) {
|
|
257
265
|
if (isPolygon) {
|
|
258
266
|
size += (x0 * y - x * y0) / 2; // area
|
|
@@ -264,18 +272,19 @@ function convertLine(ring, out, tolerance, isPolygon) {
|
|
|
264
272
|
x0 = x;
|
|
265
273
|
y0 = y;
|
|
266
274
|
}
|
|
267
|
-
const last = out.length - 3;
|
|
268
|
-
out[2] = 1;
|
|
275
|
+
const last = out.points.length - 3;
|
|
276
|
+
out.points[2] = 1;
|
|
269
277
|
if (tolerance > 0)
|
|
270
|
-
simplify(out, 0, last, tolerance);
|
|
271
|
-
out[last + 2] = 1;
|
|
278
|
+
simplify(out.points, 0, last, tolerance);
|
|
279
|
+
out.points[last + 2] = 1;
|
|
280
|
+
optimizeLineMemory(out);
|
|
272
281
|
out.size = Math.abs(size);
|
|
273
282
|
out.start = 0;
|
|
274
283
|
out.end = out.size;
|
|
275
284
|
}
|
|
276
285
|
function convertLines(rings, out, tolerance, isPolygon) {
|
|
277
286
|
for (let i = 0; i < rings.length; i++) {
|
|
278
|
-
const geom = [];
|
|
287
|
+
const geom = { points: [] };
|
|
279
288
|
convertLine(rings[i], geom, tolerance, isPolygon);
|
|
280
289
|
out.push(geom);
|
|
281
290
|
}
|
|
@@ -331,21 +340,25 @@ function geometryToGeoJSON(feature) {
|
|
|
331
340
|
coordinates: unprojectPoint(geometry[0], geometry[1])
|
|
332
341
|
};
|
|
333
342
|
case 'MultiPoint':
|
|
334
|
-
case 'LineString':
|
|
335
343
|
return {
|
|
336
344
|
type: type,
|
|
337
345
|
coordinates: unprojectPoints(geometry)
|
|
338
346
|
};
|
|
347
|
+
case 'LineString':
|
|
348
|
+
return {
|
|
349
|
+
type: type,
|
|
350
|
+
coordinates: unprojectPoints(geometry.points)
|
|
351
|
+
};
|
|
339
352
|
case 'MultiLineString':
|
|
340
353
|
case 'Polygon':
|
|
341
354
|
return {
|
|
342
355
|
type: type,
|
|
343
|
-
coordinates: geometry.map(ring => unprojectPoints(ring))
|
|
356
|
+
coordinates: geometry.map(ring => unprojectPoints(ring.points))
|
|
344
357
|
};
|
|
345
358
|
case 'MultiPolygon':
|
|
346
359
|
return {
|
|
347
360
|
type: type,
|
|
348
|
-
coordinates: geometry.map(polygon => polygon.map(ring => unprojectPoints(ring)))
|
|
361
|
+
coordinates: geometry.map(polygon => polygon.map(ring => unprojectPoints(ring.points)))
|
|
349
362
|
};
|
|
350
363
|
}
|
|
351
364
|
}
|
|
@@ -510,12 +523,12 @@ function clipLine(geom, newGeom, start, end, axis, isPolygon, trackMetrics) {
|
|
|
510
523
|
const intersect = axis === AxisType.X ? intersectX : intersectY;
|
|
511
524
|
let len = geom.start;
|
|
512
525
|
let segLen, t;
|
|
513
|
-
for (let i = 0; i < geom.length - 3; i += 3) {
|
|
514
|
-
const ax = geom[i];
|
|
515
|
-
const ay = geom[i + 1];
|
|
516
|
-
const az = geom[i + 2];
|
|
517
|
-
const bx = geom[i + 3];
|
|
518
|
-
const by = geom[i + 4];
|
|
526
|
+
for (let i = 0; i < geom.points.length - 3; i += 3) {
|
|
527
|
+
const ax = geom.points[i];
|
|
528
|
+
const ay = geom.points[i + 1];
|
|
529
|
+
const az = geom.points[i + 2];
|
|
530
|
+
const bx = geom.points[i + 3];
|
|
531
|
+
const by = geom.points[i + 4];
|
|
519
532
|
const a = axis === AxisType.X ? ax : ay;
|
|
520
533
|
const b = axis === AxisType.X ? bx : by;
|
|
521
534
|
let exited = false;
|
|
@@ -538,7 +551,7 @@ function clipLine(geom, newGeom, start, end, axis, isPolygon, trackMetrics) {
|
|
|
538
551
|
}
|
|
539
552
|
}
|
|
540
553
|
else {
|
|
541
|
-
addPoint(slice, ax, ay, az);
|
|
554
|
+
addPoint(slice.points, ax, ay, az);
|
|
542
555
|
}
|
|
543
556
|
if (b < start && a >= start) {
|
|
544
557
|
// <--|--- | or <--|-----|--- (line exits the clip region on the left)
|
|
@@ -560,29 +573,31 @@ function clipLine(geom, newGeom, start, end, axis, isPolygon, trackMetrics) {
|
|
|
560
573
|
len += segLen;
|
|
561
574
|
}
|
|
562
575
|
// add the last point
|
|
563
|
-
let last = geom.length - 3;
|
|
564
|
-
const ax = geom[last];
|
|
565
|
-
const ay = geom[last + 1];
|
|
566
|
-
const az = geom[last + 2];
|
|
576
|
+
let last = geom.points.length - 3;
|
|
577
|
+
const ax = geom.points[last];
|
|
578
|
+
const ay = geom.points[last + 1];
|
|
579
|
+
const az = geom.points[last + 2];
|
|
567
580
|
const a = axis === AxisType.X ? ax : ay;
|
|
568
581
|
if (a >= start && a <= end)
|
|
569
|
-
addPoint(slice, ax, ay, az);
|
|
582
|
+
addPoint(slice.points, ax, ay, az);
|
|
570
583
|
// close the polygon if its endpoints are not the same after clipping
|
|
571
|
-
last = slice.length - 3;
|
|
572
|
-
if (isPolygon && last >= 3 && (slice[last] !== slice[0] || slice[last + 1] !== slice[1])) {
|
|
573
|
-
addPoint(slice, slice[0], slice[1], slice[2]);
|
|
584
|
+
last = slice.points.length - 3;
|
|
585
|
+
if (isPolygon && last >= 3 && (slice.points[last] !== slice.points[0] || slice.points[last + 1] !== slice.points[1])) {
|
|
586
|
+
addPoint(slice.points, slice.points[0], slice.points[1], slice.points[2]);
|
|
574
587
|
}
|
|
575
588
|
// add the final slice
|
|
576
|
-
if (slice.length) {
|
|
589
|
+
if (slice.points.length) {
|
|
590
|
+
optimizeLineMemory(slice);
|
|
577
591
|
newGeom.push(slice);
|
|
578
592
|
}
|
|
579
593
|
}
|
|
580
594
|
function newSlice(line) {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
595
|
+
return {
|
|
596
|
+
points: [],
|
|
597
|
+
size: line.size,
|
|
598
|
+
start: line.start,
|
|
599
|
+
end: line.end
|
|
600
|
+
};
|
|
586
601
|
}
|
|
587
602
|
function clipLines(geom, newGeom, start, end, axis, isPolygon) {
|
|
588
603
|
for (const line of geom) {
|
|
@@ -594,12 +609,12 @@ function addPoint(out, x, y, z) {
|
|
|
594
609
|
}
|
|
595
610
|
function intersectX(out, ax, ay, bx, by, x) {
|
|
596
611
|
const t = (x - ax) / (bx - ax);
|
|
597
|
-
addPoint(out, x, ay + (by - ay) * t, 1);
|
|
612
|
+
addPoint(out.points, x, ay + (by - ay) * t, 1);
|
|
598
613
|
return t;
|
|
599
614
|
}
|
|
600
615
|
function intersectY(out, ax, ay, bx, by, y) {
|
|
601
616
|
const t = (y - ay) / (by - ay);
|
|
602
|
-
addPoint(out, ax + (bx - ax) * t, y, 1);
|
|
617
|
+
addPoint(out.points, ax + (bx - ax) * t, y, 1);
|
|
603
618
|
return t;
|
|
604
619
|
}
|
|
605
620
|
|
|
@@ -622,9 +637,13 @@ function shiftFeatureCoords(features, offset) {
|
|
|
622
637
|
for (const feature of features) {
|
|
623
638
|
switch (feature.type) {
|
|
624
639
|
case 'Point':
|
|
625
|
-
case 'MultiPoint':
|
|
640
|
+
case 'MultiPoint': {
|
|
641
|
+
const newGeometry = shiftPointCoords(feature.geometry, offset);
|
|
642
|
+
newFeatures.push(createFeature(feature.id, feature.type, newGeometry, feature.tags));
|
|
643
|
+
continue;
|
|
644
|
+
}
|
|
626
645
|
case 'LineString': {
|
|
627
|
-
const newGeometry =
|
|
646
|
+
const newGeometry = shiftLineCoords(feature.geometry, offset);
|
|
628
647
|
newFeatures.push(createFeature(feature.id, feature.type, newGeometry, feature.tags));
|
|
629
648
|
continue;
|
|
630
649
|
}
|
|
@@ -632,7 +651,7 @@ function shiftFeatureCoords(features, offset) {
|
|
|
632
651
|
case 'Polygon': {
|
|
633
652
|
const newGeometry = [];
|
|
634
653
|
for (const line of feature.geometry) {
|
|
635
|
-
newGeometry.push(
|
|
654
|
+
newGeometry.push(shiftLineCoords(line, offset));
|
|
636
655
|
}
|
|
637
656
|
newFeatures.push(createFeature(feature.id, feature.type, newGeometry, feature.tags));
|
|
638
657
|
continue;
|
|
@@ -642,7 +661,7 @@ function shiftFeatureCoords(features, offset) {
|
|
|
642
661
|
for (const polygon of feature.geometry) {
|
|
643
662
|
const newPolygon = [];
|
|
644
663
|
for (const line of polygon) {
|
|
645
|
-
newPolygon.push(
|
|
664
|
+
newPolygon.push(shiftLineCoords(line, offset));
|
|
646
665
|
}
|
|
647
666
|
newGeometry.push(newPolygon);
|
|
648
667
|
}
|
|
@@ -653,17 +672,27 @@ function shiftFeatureCoords(features, offset) {
|
|
|
653
672
|
}
|
|
654
673
|
return newFeatures;
|
|
655
674
|
}
|
|
656
|
-
function
|
|
657
|
-
const
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
675
|
+
function shiftPointCoords(coords, offset) {
|
|
676
|
+
const newCoords = [];
|
|
677
|
+
for (let i = 0; i < coords.length; i += 3) {
|
|
678
|
+
newCoords.push(coords[i] + offset, coords[i + 1], coords[i + 2]);
|
|
679
|
+
}
|
|
680
|
+
return newCoords;
|
|
681
|
+
}
|
|
682
|
+
function shiftLineCoords(line, offset) {
|
|
683
|
+
const newLine = {
|
|
684
|
+
points: [],
|
|
685
|
+
size: line.size
|
|
686
|
+
};
|
|
687
|
+
if (line.start !== undefined) {
|
|
688
|
+
newLine.start = line.start;
|
|
689
|
+
newLine.end = line.end;
|
|
662
690
|
}
|
|
663
|
-
for (let i = 0; i < points.length; i += 3) {
|
|
664
|
-
|
|
691
|
+
for (let i = 0; i < line.points.length; i += 3) {
|
|
692
|
+
newLine.points.push(line.points[i] + offset, line.points[i + 1], line.points[i + 2]);
|
|
665
693
|
}
|
|
666
|
-
|
|
694
|
+
optimizeLineMemory(newLine);
|
|
695
|
+
return newLine;
|
|
667
696
|
}
|
|
668
697
|
|
|
669
698
|
/**
|
|
@@ -675,7 +704,7 @@ function shiftCoords(points, offset) {
|
|
|
675
704
|
*/
|
|
676
705
|
function applySourceDiff(source, dataDiff, options) {
|
|
677
706
|
// convert diff to sets/maps for o(1) lookups
|
|
678
|
-
const diff = diffToHashed(dataDiff);
|
|
707
|
+
const diff = diffToHashed(dataDiff, options);
|
|
679
708
|
// collection for features that will be affected by this update and used to invalidate tiles
|
|
680
709
|
let affected = [];
|
|
681
710
|
if (diff.removeAll) {
|
|
@@ -786,7 +815,7 @@ function applyPropertyUpdates(tags, update) {
|
|
|
786
815
|
/**
|
|
787
816
|
* Convert a GeoJSON Source Diff to an idempotent hashed representation using Sets and Maps
|
|
788
817
|
*/
|
|
789
|
-
function diffToHashed(diff) {
|
|
818
|
+
function diffToHashed(diff, options) {
|
|
790
819
|
if (!diff)
|
|
791
820
|
return {
|
|
792
821
|
remove: new Set(),
|
|
@@ -796,7 +825,7 @@ function diffToHashed(diff) {
|
|
|
796
825
|
const hashed = {
|
|
797
826
|
removeAll: diff.removeAll,
|
|
798
827
|
remove: new Set(diff.remove || []),
|
|
799
|
-
add: new Map(diff.add?.map(feature => [feature.id, feature])),
|
|
828
|
+
add: new Map(diff.add?.map(feature => [options.promoteId ? feature.properties[options.promoteId] : feature.id, feature])),
|
|
800
829
|
update: new Map(diff.update?.map(update => [update.id, update]))
|
|
801
830
|
};
|
|
802
831
|
return hashed;
|
|
@@ -823,11 +852,6 @@ const OFFSET_PROP = 6;
|
|
|
823
852
|
* This class allow clustering of geojson points.
|
|
824
853
|
*/
|
|
825
854
|
class ClusterTileIndex {
|
|
826
|
-
options;
|
|
827
|
-
trees;
|
|
828
|
-
stride;
|
|
829
|
-
clusterProps;
|
|
830
|
-
points;
|
|
831
855
|
constructor(options) {
|
|
832
856
|
this.options = Object.assign(Object.create(defaultClusterOptions), options);
|
|
833
857
|
this.trees = new Array(this.options.maxZoom + 1);
|
|
@@ -1379,14 +1403,14 @@ function addMultiPolygonTileFeature(tile, feature, tolerance) {
|
|
|
1379
1403
|
function addLine(result, geom, tile, tolerance, isPolygon, isOuter) {
|
|
1380
1404
|
const sqTolerance = tolerance * tolerance;
|
|
1381
1405
|
if (tolerance > 0 && (geom.size < (isPolygon ? sqTolerance : tolerance))) {
|
|
1382
|
-
tile.numPoints += geom.length / 3;
|
|
1406
|
+
tile.numPoints += geom.points.length / 3;
|
|
1383
1407
|
return;
|
|
1384
1408
|
}
|
|
1385
1409
|
const ring = [];
|
|
1386
|
-
for (let i = 0; i < geom.length; i += 3) {
|
|
1387
|
-
if (tolerance === 0 || geom[i + 2] > sqTolerance) {
|
|
1410
|
+
for (let i = 0; i < geom.points.length; i += 3) {
|
|
1411
|
+
if (tolerance === 0 || geom.points[i + 2] > sqTolerance) {
|
|
1388
1412
|
tile.numSimplified++;
|
|
1389
|
-
ring.push(geom[i], geom[i + 1]);
|
|
1413
|
+
ring.push(geom.points[i], geom.points[i + 1]);
|
|
1390
1414
|
}
|
|
1391
1415
|
tile.numPoints++;
|
|
1392
1416
|
}
|
|
@@ -1474,16 +1498,12 @@ function transformPoint(x, y, extent, z2, tx, ty) {
|
|
|
1474
1498
|
}
|
|
1475
1499
|
|
|
1476
1500
|
class TileIndex {
|
|
1477
|
-
options;
|
|
1478
|
-
tileCoords;
|
|
1479
|
-
/** @internal */
|
|
1480
|
-
tiles;
|
|
1481
|
-
/** @internal */
|
|
1482
|
-
stats = {};
|
|
1483
|
-
/** @internal */
|
|
1484
|
-
total = 0;
|
|
1485
1501
|
constructor(options) {
|
|
1486
1502
|
this.options = options;
|
|
1503
|
+
/** @internal */
|
|
1504
|
+
this.stats = {};
|
|
1505
|
+
/** @internal */
|
|
1506
|
+
this.total = 0;
|
|
1487
1507
|
this.tiles = {};
|
|
1488
1508
|
this.tileCoords = [];
|
|
1489
1509
|
this.stats = {};
|
|
@@ -1782,9 +1802,6 @@ class GeoJSONVT {
|
|
|
1782
1802
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1783
1803
|
return this.tileIndex.total;
|
|
1784
1804
|
}
|
|
1785
|
-
options;
|
|
1786
|
-
source;
|
|
1787
|
-
tileIndex;
|
|
1788
1805
|
constructor(data, options) {
|
|
1789
1806
|
options = this.options = Object.assign({}, defaultOptions, options);
|
|
1790
1807
|
const debug = options.debug;
|