@maplibre/geojson-vt 6.1.1 → 6.2.0
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/README.md +3 -0
- package/dist/cluster-tile-index.d.ts +41 -6
- package/dist/cluster-tile-index.d.ts.map +1 -1
- package/dist/convert.d.ts +4 -4
- package/dist/convert.d.ts.map +1 -1
- package/dist/deconvert.d.ts +7 -7
- package/dist/deconvert.d.ts.map +1 -1
- package/dist/definitions.d.ts +17 -5
- package/dist/definitions.d.ts.map +1 -1
- package/dist/geojson-vt-dev.js +315 -154
- package/dist/geojson-vt.js +1 -1
- package/dist/geojson-vt.mjs +305 -146
- package/dist/geojson-vt.mjs.map +1 -1
- package/dist/geojsonvt.d.ts.map +1 -1
- package/dist/simplify.d.ts.map +1 -1
- package/dist/tile-index.d.ts +6 -0
- package/dist/tile-index.d.ts.map +1 -1
- package/dist/wrap.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/clip.ts +2 -2
- package/src/cluster-tile-index.test.ts +103 -0
- package/src/cluster-tile-index.ts +242 -97
- package/src/convert.ts +35 -28
- package/src/deconvert.ts +20 -18
- package/src/definitions.ts +17 -5
- package/src/difference.test.ts +71 -0
- package/src/difference.ts +3 -3
- package/src/geojsonvt.test.ts +236 -1
- package/src/geojsonvt.ts +5 -4
- package/src/simplify.test.ts +18 -0
- package/src/simplify.ts +12 -2
- package/src/tile-index.ts +17 -3
- package/src/wrap.ts +2 -0
package/src/geojsonvt.ts
CHANGED
|
@@ -19,7 +19,8 @@ export const defaultOptions: GeoJSONVTOptions = {
|
|
|
19
19
|
updateable: false,
|
|
20
20
|
cluster: false,
|
|
21
21
|
clusterOptions: defaultClusterOptions,
|
|
22
|
-
debug: 0
|
|
22
|
+
debug: 0,
|
|
23
|
+
worldCoordinates: false
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
/**
|
|
@@ -62,7 +63,7 @@ export class GeoJSONVT {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
private initializeIndex(features: GeoJSONVTInternalFeature[], options: GeoJSONVTOptions) {
|
|
65
|
-
this.tileIndex = options.cluster ? new ClusterTileIndex(options.clusterOptions) : new TileIndex(options);
|
|
66
|
+
this.tileIndex = options.cluster ? new ClusterTileIndex(options.clusterOptions, options.worldCoordinates) : new TileIndex(options);
|
|
66
67
|
if (!features.length) return;
|
|
67
68
|
this.tileIndex.initialize(features);
|
|
68
69
|
}
|
|
@@ -117,7 +118,7 @@ export class GeoJSONVT {
|
|
|
117
118
|
|
|
118
119
|
for (const feature of source) {
|
|
119
120
|
if (feature.id == undefined) continue;
|
|
120
|
-
if (predicate(featureToGeoJSON(feature))) continue;
|
|
121
|
+
if (predicate(featureToGeoJSON(feature, this.options.worldCoordinates))) continue;
|
|
121
122
|
affected.push(feature);
|
|
122
123
|
removeIds.add(feature.id);
|
|
123
124
|
}
|
|
@@ -131,7 +132,7 @@ export class GeoJSONVT {
|
|
|
131
132
|
*/
|
|
132
133
|
getData(): GeoJSON.GeoJSON {
|
|
133
134
|
if (!this.options.updateable) throw new Error('to retrieve data the `updateable` option must be set to true');
|
|
134
|
-
return convertToGeoJSON(this.source);
|
|
135
|
+
return convertToGeoJSON(this.source, this.options.worldCoordinates);
|
|
135
136
|
}
|
|
136
137
|
|
|
137
138
|
/**
|
package/src/simplify.test.ts
CHANGED
|
@@ -71,3 +71,21 @@ test('does not throw max call stack error on bad long input', () => {
|
|
|
71
71
|
simplify(coords, 0, coords.length, 2e-15);
|
|
72
72
|
}).not.toThrow();
|
|
73
73
|
});
|
|
74
|
+
|
|
75
|
+
test('does not throw max call stack error when splitting off one vertex at a time due to zig-zag', () => {
|
|
76
|
+
// the old recursive implementation overflows at ~5000 vertices; the work is quadratic, so keep it small
|
|
77
|
+
const n = 6000;
|
|
78
|
+
const coords: number[] = [];
|
|
79
|
+
for (let i = 0; i < n; i++) {
|
|
80
|
+
coords.push(i / n, 0.5 + (i % 2 ? 1 : -1) * (1 + i * 1e-4) * 1e-3, 0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
expect(() => {
|
|
84
|
+
simplify(coords, 0, coords.length - 3, 1e-12);
|
|
85
|
+
}).not.toThrow();
|
|
86
|
+
let kept = 0;
|
|
87
|
+
for (let i = 5; i < coords.length - 3; i += 3) {
|
|
88
|
+
if (coords[i] > 0) kept++;
|
|
89
|
+
}
|
|
90
|
+
expect(kept).toBe(n - 2);
|
|
91
|
+
});
|
package/src/simplify.ts
CHANGED
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
* @param sqTolerance - square tolerance value
|
|
7
7
|
*/
|
|
8
8
|
export function simplify(coords: number[], first: number, last: number, sqTolerance: number) {
|
|
9
|
+
const stack = [first, last];
|
|
10
|
+
|
|
11
|
+
while (stack.length) {
|
|
12
|
+
last = stack.pop();
|
|
13
|
+
first = stack.pop();
|
|
14
|
+
simplifySegment(coords, first, last, sqTolerance, stack);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function simplifySegment(coords: number[], first: number, last: number, sqTolerance: number, stack: number[]) {
|
|
9
19
|
let maxSqDist = sqTolerance;
|
|
10
20
|
const mid = first + ((last - first) >> 1);
|
|
11
21
|
let minPosToMid = last - first;
|
|
@@ -38,9 +48,9 @@ export function simplify(coords: number[], first: number, last: number, sqTolera
|
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
if (maxSqDist > sqTolerance) {
|
|
41
|
-
if (index - first > 3) simplify(coords, first, index, sqTolerance);
|
|
42
51
|
coords[index + 2] = maxSqDist;
|
|
43
|
-
if (
|
|
52
|
+
if (index - first > 3) stack.push(first, index);
|
|
53
|
+
if (last - index > 3) stack.push(index, last);
|
|
44
54
|
}
|
|
45
55
|
}
|
|
46
56
|
|
package/src/tile-index.ts
CHANGED
|
@@ -23,7 +23,7 @@ export class TileIndex implements GeoJSONVTTileIndex {
|
|
|
23
23
|
|
|
24
24
|
initialize(features: GeoJSONVTInternalFeature[]): void {
|
|
25
25
|
// start slicing from the top tile down
|
|
26
|
-
this.splitTile(features, 0, 0, 0);
|
|
26
|
+
this.splitTile(this.clipToWorld(features), 0, 0, 0);
|
|
27
27
|
|
|
28
28
|
if (this.options.debug) {
|
|
29
29
|
if (features.length) console.log('features: %d, points: %d', this.tiles[0].numFeatures, this.tiles[0].numPoints);
|
|
@@ -45,8 +45,9 @@ export class TileIndex implements GeoJSONVTTileIndex {
|
|
|
45
45
|
|
|
46
46
|
// re-generate root tile with updated feature set
|
|
47
47
|
const [z, x, y] = [0, 0, 0];
|
|
48
|
-
const
|
|
49
|
-
rootTile
|
|
48
|
+
const rootSource = this.clipToWorld(source);
|
|
49
|
+
const rootTile = createTile(rootSource, z, x, y, options);
|
|
50
|
+
rootTile.source = rootSource;
|
|
50
51
|
|
|
51
52
|
// update tile index with new root tile - ready for getTile calls
|
|
52
53
|
const id = toID(z, x, y);
|
|
@@ -83,6 +84,7 @@ export class TileIndex implements GeoJSONVTTileIndex {
|
|
|
83
84
|
const {extent, debug} = this.options;
|
|
84
85
|
|
|
85
86
|
const z2 = 1 << z;
|
|
87
|
+
if (this.options.worldCoordinates && (x < 0 || x >= z2)) return null; // a row outside the world has no tile either
|
|
86
88
|
x = (x + z2) & (z2 - 1); // wrap tile x coordinate
|
|
87
89
|
|
|
88
90
|
const id = toID(z, x, y);
|
|
@@ -119,6 +121,18 @@ export class TileIndex implements GeoJSONVTTileIndex {
|
|
|
119
121
|
return transformTile(this.tiles[id], extent);
|
|
120
122
|
}
|
|
121
123
|
|
|
124
|
+
/**
|
|
125
|
+
* The features the top tile starts from: all of them in a wrapping world, where wrapping already put them inside,
|
|
126
|
+
* and only what lies inside the world square and its buffer with `worldCoordinates`. The index keeps the rest, so
|
|
127
|
+
* an update can still move a feature in from outside.
|
|
128
|
+
*/
|
|
129
|
+
private clipToWorld(features: GeoJSONVTInternalFeature[]): GeoJSONVTInternalFeature[] {
|
|
130
|
+
if (!this.options.worldCoordinates) return features;
|
|
131
|
+
const buffer = this.options.buffer / this.options.extent;
|
|
132
|
+
const inX = clip(features, 1, -buffer, 1 + buffer, AxisType.X, -Infinity, Infinity, this.options) || [];
|
|
133
|
+
return clip(inX, 1, -buffer, 1 + buffer, AxisType.Y, -Infinity, Infinity, this.options) || [];
|
|
134
|
+
}
|
|
135
|
+
|
|
122
136
|
/**
|
|
123
137
|
* splits features from a parent tile to sub-tiles.
|
|
124
138
|
* z, x, and y are the coordinates of the parent tile
|
package/src/wrap.ts
CHANGED
|
@@ -4,6 +4,8 @@ import type { GeoJSONVTInternalFeature, GeoJSONVTOptions, SliceArray, SliceFixed
|
|
|
4
4
|
import {createFeature, optimizeLineMemory} from './feature';
|
|
5
5
|
|
|
6
6
|
export function wrap(features: GeoJSONVTInternalFeature[], options: GeoJSONVTOptions): GeoJSONVTInternalFeature[] {
|
|
7
|
+
if (options.worldCoordinates) return features;
|
|
8
|
+
|
|
7
9
|
const buffer = options.buffer / options.extent;
|
|
8
10
|
let merged = features;
|
|
9
11
|
|