@maplibre/geojson-vt 6.0.4 → 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 +87 -58
- package/dist/geojson-vt.js +1 -1
- package/dist/geojson-vt.mjs +87 -58
- 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
|
-
newPoints.start = points.start;
|
|
661
|
-
newPoints.end = points.end;
|
|
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]);
|
|
662
679
|
}
|
|
663
|
-
|
|
664
|
-
|
|
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;
|
|
665
690
|
}
|
|
666
|
-
|
|
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]);
|
|
693
|
+
}
|
|
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;
|
|
@@ -1374,14 +1403,14 @@ function addMultiPolygonTileFeature(tile, feature, tolerance) {
|
|
|
1374
1403
|
function addLine(result, geom, tile, tolerance, isPolygon, isOuter) {
|
|
1375
1404
|
const sqTolerance = tolerance * tolerance;
|
|
1376
1405
|
if (tolerance > 0 && (geom.size < (isPolygon ? sqTolerance : tolerance))) {
|
|
1377
|
-
tile.numPoints += geom.length / 3;
|
|
1406
|
+
tile.numPoints += geom.points.length / 3;
|
|
1378
1407
|
return;
|
|
1379
1408
|
}
|
|
1380
1409
|
const ring = [];
|
|
1381
|
-
for (let i = 0; i < geom.length; i += 3) {
|
|
1382
|
-
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) {
|
|
1383
1412
|
tile.numSimplified++;
|
|
1384
|
-
ring.push(geom[i], geom[i + 1]);
|
|
1413
|
+
ring.push(geom.points[i], geom.points[i + 1]);
|
|
1385
1414
|
}
|
|
1386
1415
|
tile.numPoints++;
|
|
1387
1416
|
}
|