@maplibre/geojson-vt 5.0.3 → 6.0.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.
Files changed (65) hide show
  1. package/README.md +3 -13
  2. package/dist/clip.d.ts +22 -0
  3. package/dist/clip.d.ts.map +1 -0
  4. package/dist/clip.test.d.ts +2 -0
  5. package/dist/clip.test.d.ts.map +1 -0
  6. package/dist/cluster-tile-index.d.ts +76 -0
  7. package/dist/cluster-tile-index.d.ts.map +1 -0
  8. package/dist/cluster-tile-index.test.d.ts +2 -0
  9. package/dist/cluster-tile-index.test.d.ts.map +1 -0
  10. package/dist/convert.d.ts +17 -0
  11. package/dist/convert.d.ts.map +1 -0
  12. package/dist/deconvert.d.ts +19 -0
  13. package/dist/deconvert.d.ts.map +1 -0
  14. package/dist/deconvert.test.d.ts +2 -0
  15. package/dist/deconvert.test.d.ts.map +1 -0
  16. package/dist/definitions.d.ts +241 -0
  17. package/dist/definitions.d.ts.map +1 -0
  18. package/dist/difference.d.ts +67 -0
  19. package/dist/difference.d.ts.map +1 -0
  20. package/dist/difference.test.d.ts +2 -0
  21. package/dist/difference.test.d.ts.map +1 -0
  22. package/dist/feature.d.ts +20 -0
  23. package/dist/feature.d.ts.map +1 -0
  24. package/dist/geojson-to-tile.d.ts +35 -0
  25. package/dist/geojson-to-tile.d.ts.map +1 -0
  26. package/dist/geojson-vt-dev.js +1582 -478
  27. package/dist/geojson-vt.js +1 -1
  28. package/dist/geojson-vt.mjs +1250 -473
  29. package/dist/geojson-vt.mjs.map +1 -1
  30. package/dist/geojsonvt.d.ts +76 -0
  31. package/dist/geojsonvt.d.ts.map +1 -0
  32. package/dist/geojsonvt.test.d.ts +2 -0
  33. package/dist/geojsonvt.test.d.ts.map +1 -0
  34. package/dist/index.d.ts +9 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/simplify.d.ts +9 -0
  37. package/dist/simplify.d.ts.map +1 -0
  38. package/dist/simplify.test.d.ts +2 -0
  39. package/dist/simplify.test.d.ts.map +1 -0
  40. package/dist/tile-index.d.ts +51 -0
  41. package/dist/tile-index.d.ts.map +1 -0
  42. package/dist/tile.d.ts +12 -0
  43. package/dist/tile.d.ts.map +1 -0
  44. package/dist/transform.d.ts +10 -0
  45. package/dist/transform.d.ts.map +1 -0
  46. package/dist/wrap.d.ts +3 -0
  47. package/dist/wrap.d.ts.map +1 -0
  48. package/package.json +26 -12
  49. package/src/clip.ts +119 -81
  50. package/src/cluster-tile-index.test.ts +205 -0
  51. package/src/cluster-tile-index.ts +513 -0
  52. package/src/convert.ts +97 -75
  53. package/src/deconvert.test.ts +153 -0
  54. package/src/deconvert.ts +92 -0
  55. package/src/definitions.ts +196 -18
  56. package/src/difference.ts +3 -3
  57. package/src/feature.ts +11 -4
  58. package/src/geojson-to-tile.ts +58 -0
  59. package/src/geojsonvt.test.ts +39 -0
  60. package/src/geojsonvt.ts +209 -0
  61. package/src/index.ts +27 -378
  62. package/src/tile-index.ts +310 -0
  63. package/src/tile.ts +92 -103
  64. package/src/transform.ts +41 -39
  65. package/src/wrap.ts +4 -4
@@ -0,0 +1,76 @@
1
+ import { type GeoJSONVTSourceDiff } from './difference';
2
+ import type { ClusterOrPointFeature, GeoJSONVTOptions, GeoJSONVTTile, SuperclusterOptions } from './definitions';
3
+ export declare const defaultOptions: GeoJSONVTOptions;
4
+ /**
5
+ * Main class for creating and managing a vector tile index from GeoJSON data.
6
+ */
7
+ export declare class GeoJSONVT {
8
+ /**
9
+ * @internal
10
+ * This is for the tests
11
+ */
12
+ get tiles(): any;
13
+ /**
14
+ * @internal
15
+ * This is for the tests
16
+ */
17
+ get stats(): any;
18
+ /**
19
+ * @internal
20
+ * This is for the tests
21
+ */
22
+ get total(): any;
23
+ private options;
24
+ private source?;
25
+ private tileIndex;
26
+ constructor(data: GeoJSON.GeoJSON, options?: GeoJSONVTOptions);
27
+ private initializeIndex;
28
+ /**
29
+ * Given z, x, and y tile coordinates, returns the corresponding tile with geometries in tile coordinates, much like MVT data is stored.
30
+ * @param z - tile zoom level
31
+ * @param x - tile x coordinate
32
+ * @param y - tile y coordinate
33
+ * @returns the transformed tile or null if not found
34
+ */
35
+ getTile(z: number | string, x: number | string, y: number | string): GeoJSONVTTile | null;
36
+ /**
37
+ * Updates the source data feature set using a {@link GeoJSONVTSourceDiff}
38
+ * @param diff - the source diff object
39
+ */
40
+ updateData(diff: GeoJSONVTSourceDiff, filter?: (feature: GeoJSON.Feature) => boolean): void;
41
+ /**
42
+ * Filter an update using a predicate function. Returns the affected and updated source features.
43
+ */
44
+ private filterUpdate;
45
+ /**
46
+ * Returns source data as GeoJSON - only available when `updateable` option is set to true.
47
+ */
48
+ getData(): GeoJSON.GeoJSON;
49
+ /**
50
+ * Update supercluster options and regenerate the index.
51
+ * @param cluster - whether to enable clustering
52
+ * @param clusterOptions - {@link SuperclusterOptions}
53
+ */
54
+ updateClusterOptions(cluster: boolean, clusterOptions: SuperclusterOptions): void;
55
+ /**
56
+ * Returns the zoom level at which a cluster expands into multiple children.
57
+ * @param clusterId - The target cluster id.
58
+ * @returns the expansion zoom or null in case of non-clustered source
59
+ */
60
+ getClusterExpansionZoom(clusterId: number): number | null;
61
+ /**
62
+ * Returns the immediate children (clusters or points) of a cluster as GeoJSON.
63
+ * @param clusterId - The target cluster id.
64
+ * @returns the immediate children or null in case of non-clustered source
65
+ */
66
+ getClusterChildren(clusterId: number): ClusterOrPointFeature[] | null;
67
+ /**
68
+ * Returns leaf point features under a cluster, paginated by `limit` and `offset`.
69
+ * @param clusterId - The target cluster id.
70
+ * @param limit - Maximum number of points to return (defaults to `10`).
71
+ * @param offset - Number of points to skip before collecting results (defaults to `0`).
72
+ * @returns leaf point features under a cluster or null in case of non-clustered source
73
+ */
74
+ getClusterLeaves(clusterId: number, limit: number, offset: number): GeoJSON.Feature<GeoJSON.Point>[] | null;
75
+ }
76
+ //# sourceMappingURL=geojsonvt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geojsonvt.d.ts","sourceRoot":"","sources":["../src/geojsonvt.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,mBAAmB,EAAC,MAAM,cAAc,CAAC;AAGvE,OAAO,KAAK,EAAC,qBAAqB,EAAgD,gBAAgB,EAAE,aAAa,EAAE,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAE7J,eAAO,MAAM,cAAc,EAAE,gBAc5B,CAAC;AAEF;;GAEG;AACH,qBAAa,SAAS;IAElB;;;OAGG;IACH,IAAW,KAAK,QAGf;IACD;;;OAGG;IACH,IAAW,KAAK,QAGf;IACA;;;MAGE;IACH,IAAW,KAAK,QAGf;IAED,OAAO,CAAC,OAAO,CAAmB;IAElC,OAAO,CAAC,MAAM,CAAC,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAqB;gBAE1B,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,gBAAgB;IA8B7D,OAAO,CAAC,eAAe;IAMvB;;;;;;OAMG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,IAAI;IAUzF;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO;IAqBpF;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,OAAO;IAK1B;;;;OAIG;IACH,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,mBAAmB;IAa1E;;;;OAIG;IACH,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIzD;;;;OAIG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,qBAAqB,EAAE,GAAG,IAAI;IAIrE;;;;;;OAMG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI;CAG9G"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=geojsonvt.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geojsonvt.test.d.ts","sourceRoot":"","sources":["../src/geojsonvt.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { GeoJSONVTFeatureDiff, GeoJSONVTSourceDiff } from './difference';
2
+ import type { GeoJSONVTInternalFeature, GeoJSONVTInternalLineStringFeature, GeoJSONVTInternalMultiLineStringFeature, GeoJSONVTInternalMultiPointFeature, GeoJSONVTInternalMultiPolygonFeature, GeoJSONVTInternalPointFeature, GeoJSONVTInternalPolygonFeature, GeoJSONVTOptions, GeoJSONToTileOptions, PartialGeoJSONVTFeature, StartEndSizeArray, ClusterProperties, ClusterFeature, ClusterOrPointFeature, GeoJSONVTTile, GeoJSONVTFeature, GeoJSONVTFeaturePoint, GeoJSONVTFeatureNonPoint, GeoJSONVTInternalTileFeaturePoint, GeoJSONVTInternalTileFeatureNonPoint, GeoJSONVTInternalTile, GeoJSONVTInternalTileFeature, GeoJSONVTTileIndex, SuperclusterOptions } from './definitions';
3
+ import type { KDBushWithData } from './cluster-tile-index';
4
+ import { GeoJSONVT } from './geojsonvt';
5
+ import { ClusterTileIndex } from './cluster-tile-index';
6
+ import { geoJSONToTile } from './geojson-to-tile';
7
+ export { GeoJSONVT, ClusterTileIndex as Supercluster, geoJSONToTile };
8
+ export type { GeoJSONVTInternalFeature, GeoJSONVTOptions, GeoJSONToTileOptions, GeoJSONVTInternalTile, GeoJSONVTInternalTileFeature, PartialGeoJSONVTFeature, StartEndSizeArray, GeoJSONVTTile, GeoJSONVTFeature, GeoJSONVTSourceDiff, GeoJSONVTFeatureDiff, GeoJSONVTFeaturePoint, GeoJSONVTFeatureNonPoint, GeoJSONVTInternalTileFeaturePoint, GeoJSONVTInternalTileFeatureNonPoint, GeoJSONVTInternalPointFeature, GeoJSONVTInternalMultiPointFeature, GeoJSONVTInternalLineStringFeature, GeoJSONVTInternalMultiLineStringFeature, GeoJSONVTInternalPolygonFeature, GeoJSONVTInternalMultiPolygonFeature, SuperclusterOptions, ClusterProperties, ClusterFeature, ClusterOrPointFeature, KDBushWithData, GeoJSONVTTileIndex };
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,oBAAoB,EAAE,mBAAmB,EAAC,MAAM,cAAc,CAAC;AAC5E,OAAO,KAAK,EAAC,wBAAwB,EAAE,kCAAkC,EAAE,uCAAuC,EAAE,kCAAkC,EAAE,oCAAoC,EAAE,6BAA6B,EAAE,+BAA+B,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,iCAAiC,EAAE,oCAAoC,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,kBAAkB,EAAE,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAC1pB,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EACH,SAAS,EACT,gBAAgB,IAAI,YAAY,EAChC,aAAa,EAChB,CAAA;AAED,YAAY,EACR,wBAAwB,EACxB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,4BAA4B,EAC5B,uBAAuB,EACvB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,iCAAiC,EACjC,oCAAoC,EACpC,6BAA6B,EAC7B,kCAAkC,EAClC,kCAAkC,EAClC,uCAAuC,EACvC,+BAA+B,EAC/B,oCAAoC,EACpC,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EACrB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * calculate simplification data using optimized Douglas-Peucker algorithm
3
+ * @param coords - flat array of coordinates
4
+ * @param first - index of the first coordinate in the segment
5
+ * @param last - index of the last coordinate in the segment
6
+ * @param sqTolerance - square tolerance value
7
+ */
8
+ export declare function simplify(coords: number[], first: number, last: number, sqTolerance: number): void;
9
+ //# sourceMappingURL=simplify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simplify.d.ts","sourceRoot":"","sources":["../src/simplify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAqC1F"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=simplify.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simplify.test.d.ts","sourceRoot":"","sources":["../src/simplify.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ import type { GeoJSONVTInternalFeature, GeoJSONVTOptions, ClusterOrPointFeature, GeoJSONVTTileIndex, GeoJSONVTInternalTile, GeoJSONVTTile } from "./definitions";
2
+ export declare class TileIndex implements GeoJSONVTTileIndex {
3
+ private options;
4
+ private tileCoords;
5
+ /** @internal */
6
+ tiles: {
7
+ [key: string]: GeoJSONVTInternalTile;
8
+ };
9
+ /** @internal */
10
+ stats: {
11
+ [key: string]: number;
12
+ };
13
+ /** @internal */
14
+ total: number;
15
+ constructor(options: GeoJSONVTOptions);
16
+ initialize(features: GeoJSONVTInternalFeature[]): void;
17
+ /** {@inheritdoc} */
18
+ updateIndex(source: GeoJSONVTInternalFeature[], affected: GeoJSONVTInternalFeature[], options: GeoJSONVTOptions): void;
19
+ /** {@inheritdoc} */
20
+ getClusterExpansionZoom(_clusterId: number): number | null;
21
+ /** {@inheritdoc} */
22
+ getChildren(_clusterId: number): ClusterOrPointFeature[] | null;
23
+ /** {@inheritdoc} */
24
+ getLeaves(_clusterId: number, _limit?: number, _offset?: number): GeoJSON.Feature<GeoJSON.Point>[] | null;
25
+ /** {@inheritdoc} */
26
+ getTile(z: number, x: number, y: number): GeoJSONVTTile | null;
27
+ /**
28
+ * splits features from a parent tile to sub-tiles.
29
+ * z, x, and y are the coordinates of the parent tile
30
+ * cz, cx, and cy are the coordinates of the target tile
31
+ *
32
+ * If no target tile is specified, splitting stops when we reach the maximum
33
+ * zoom or the number of points is low as specified in the options.
34
+ * @internal
35
+ * @param features - features to split
36
+ * @param z - tile zoom level
37
+ * @param x - tile x coordinate
38
+ * @param y - tile y coordinate
39
+ * @param cz - target tile zoom level
40
+ * @param cx - target tile x coordinate
41
+ * @param cy - target tile y coordinate
42
+ */
43
+ private splitTile;
44
+ /**
45
+ * Invalidates (removes) tiles affected by the provided features
46
+ * @internal
47
+ * @param features
48
+ */
49
+ private invalidateTiles;
50
+ }
51
+ //# sourceMappingURL=tile-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile-index.d.ts","sourceRoot":"","sources":["../src/tile-index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEjK,qBAAa,SAAU,YAAW,kBAAkB;IAWpC,OAAO,CAAC,OAAO;IAT3B,OAAO,CAAC,UAAU,CAAkD;IAEpE,gBAAgB;IACT,KAAK,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAAA;KAAC,CAAC;IACrD,gBAAgB;IACT,KAAK,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAM;IAC3C,gBAAgB;IACT,KAAK,EAAE,MAAM,CAAK;gBAEL,OAAO,EAAE,gBAAgB;IAO7C,UAAU,CAAC,QAAQ,EAAE,wBAAwB,EAAE,GAAG,IAAI;IAWtD,oBAAoB;IACpB,WAAW,CAAC,MAAM,EAAE,wBAAwB,EAAE,EAAE,QAAQ,EAAE,wBAAwB,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI;IA2BtH,oBAAoB;IAEpB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI1D,oBAAoB;IAEpB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,qBAAqB,EAAE,GAAG,IAAI;IAI/D,oBAAoB;IAEpB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI;IAIzG,oBAAoB;IACpB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAwC9D;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,SAAS;IA4FjB;;;;OAIG;IACH,OAAO,CAAC,eAAe;CAuE1B"}
package/dist/tile.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { GeoJSONVTInternalFeature, GeoJSONVTInternalTile, GeoJSONVTOptions } from "./definitions";
2
+ /**
3
+ * Creates a tile object from the given features
4
+ * @param features - the features to include in the tile
5
+ * @param z
6
+ * @param tx
7
+ * @param ty
8
+ * @param options - the options object
9
+ * @returns the created tile
10
+ */
11
+ export declare function createTile(features: GeoJSONVTInternalFeature[], z: number, tx: number, ty: number, options: GeoJSONVTOptions): GeoJSONVTInternalTile;
12
+ //# sourceMappingURL=tile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile.d.ts","sourceRoot":"","sources":["../src/tile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAyN,qBAAqB,EAAgC,gBAAgB,EAAqB,MAAM,eAAe,CAAC;AAI/W;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,wBAAwB,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,qBAAqB,CAwBpJ"}
@@ -0,0 +1,10 @@
1
+ import type { GeoJSONVTInternalTile, GeoJSONVTTile } from "./definitions";
2
+ /**
3
+ * Transforms the coordinates of each feature in the given tile from
4
+ * mercator-projected space into (extent x extent) tile space.
5
+ * @param tile - the tile to transform, this gets modified in place
6
+ * @param extent - the tile extent (usually 4096)
7
+ * @returns the transformed tile
8
+ */
9
+ export declare function transformTile(tile: GeoJSONVTInternalTile, extent: number): GeoJSONVTTile;
10
+ //# sourceMappingURL=transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmD,qBAAqB,EAA2E,aAAa,EAAE,MAAM,eAAe,CAAC;AAEpM;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAmBxF"}
package/dist/wrap.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { GeoJSONVTInternalFeature, GeoJSONVTOptions } from './definitions';
2
+ export declare function wrap(features: GeoJSONVTInternalFeature[], options: GeoJSONVTOptions): GeoJSONVTInternalFeature[];
3
+ //# sourceMappingURL=wrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAqB,MAAM,eAAe,CAAC;AAGnG,wBAAgB,IAAI,CAAC,QAAQ,EAAE,wBAAwB,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,wBAAwB,EAAE,CAehH"}
package/package.json CHANGED
@@ -1,9 +1,15 @@
1
1
  {
2
2
  "name": "@maplibre/geojson-vt",
3
- "version": "5.0.3",
3
+ "version": "6.0.0",
4
4
  "description": "Slice GeoJSON data into vector tiles efficiently",
5
5
  "type": "module",
6
- "exports": "./src/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/geojson-vt.mjs",
10
+ "default": "./dist/geojson-vt.js"
11
+ }
12
+ },
7
13
  "sideEffects": false,
8
14
  "keywords": [
9
15
  "spatial",
@@ -13,33 +19,38 @@
13
19
  ],
14
20
  "author": "Vladimir Agafonkin",
15
21
  "module": "dist/geojson-vt.mjs",
16
- "main": "dist/geojson-vt-dev.js",
22
+ "main": "dist/geojson-vt.js",
17
23
  "typings": "dist/index.d.ts",
18
24
  "jsdelivr": "dist/geojson-vt.js",
19
25
  "unpkg": "dist/geojson-vt.js",
20
26
  "devDependencies": {
21
- "@eslint/js": "^9.39.2",
27
+ "@eslint/js": "^10.0.1",
28
+ "@rollup/plugin-node-resolve": "^16.0.3",
22
29
  "@rollup/plugin-terser": "^0.4.4",
23
30
  "@rollup/plugin-typescript": "^12.3.0",
31
+ "@types/benchmark": "^2.1.5",
24
32
  "@types/geojson": "^7946.0.16",
25
- "@types/node": "^25.0.9",
26
- "@vitest/coverage-v8": "^4.0.17",
33
+ "@types/node": "^25.3.0",
34
+ "@vitest/coverage-v8": "^4.0.18",
27
35
  "benchmark": "^2.1.4",
28
- "eslint": "^9.39.2",
29
- "rollup": "^4.55.2",
36
+ "eslint": "^10.0.2",
37
+ "rollup": "^4.59.0",
30
38
  "tslib": "^2.8.1",
31
- "typedoc": "^0.28.16",
39
+ "tsx": "^4.21.0",
40
+ "typedoc": "^0.28.17",
32
41
  "typescript": "^5.9.3",
33
- "typescript-eslint": "^8.53.1",
42
+ "typescript-eslint": "^8.56.1",
34
43
  "vitest": "^4.0.17"
35
44
  },
36
45
  "license": "ISC",
37
46
  "scripts": {
38
- "lint": "eslint **/*.ts",
47
+ "lint": "eslint",
39
48
  "test": "vitest",
49
+ "coverage": "vitest run --coverage",
40
50
  "build": "rollup -c && tsc -p tsconfig.declaration.json",
41
51
  "watch": "rollup -cw",
42
- "bench": "node bench/benchmark.js",
52
+ "start": "npm run watch",
53
+ "bench": "tsx bench/benchmark.ts",
43
54
  "docs": "typedoc && mkdir -p docs/debug && cp -r debug/* docs/debug && find docs/debug -name '*.html' -exec sed -i 's|../dist/geojson-vt-dev.js|https://unpkg.com/@maplibre/geojson-vt@latest/dist/geojson-vt.js|g' {} +",
44
55
  "prepublishOnly": "npm run test && npm run build"
45
56
  },
@@ -50,5 +61,8 @@
50
61
  "repository": {
51
62
  "type": "git",
52
63
  "url": "https://github.com/maplibre/geojson-vt"
64
+ },
65
+ "dependencies": {
66
+ "kdbush": "^4.0.2"
53
67
  }
54
68
  }
package/src/clip.ts CHANGED
@@ -1,110 +1,78 @@
1
1
 
2
2
  import {createFeature} from './feature';
3
- import type { GeoJSONVTInternalFeature, GeoJSONVTOptions, StartEndSizeArray } from './definitions';
3
+ import type { GeoJSONVTInternalFeature, GeoJSONVTInternalLineStringFeature, GeoJSONVTInternalMultiLineStringFeature, GeoJSONVTInternalMultiPointFeature, GeoJSONVTInternalMultiPolygonFeature, GeoJSONVTInternalPointFeature, GeoJSONVTInternalPolygonFeature, GeoJSONVTOptions, StartEndSizeArray } from './definitions';
4
4
 
5
- /* clip features between two vertical or horizontal axis-parallel lines:
5
+ export const enum AxisType {
6
+ X = 0,
7
+ Y = 1
8
+ }
9
+
10
+ /**
11
+ * clip features between two vertical or horizontal axis-parallel lines:
6
12
  * | |
7
13
  * ___|___ | /
8
14
  * / | \____|____/
9
15
  * | |
10
16
  *
11
- * k1 and k2 are the line coordinates
12
- * axis: 0 for x, 1 for y
13
- * minAll and maxAll: minimum and maximum coordinate value for all features
17
+ * @param features - the features to clip
18
+ * @param scale - the scale to divide start and end inputs
19
+ * @param start - the start of the clip range
20
+ * @param end - the end of the clip range
21
+ * @param axis - which axis to clip against
22
+ * @param minAll - the minimum for all features in the relevant axis
23
+ * @param maxAll - the maximum for all features in the relevant axis
14
24
  */
15
- export function clip(features: GeoJSONVTInternalFeature[], scale: number, k1: number, k2: number, axis: number, minAll: number, maxAll: number, options: GeoJSONVTOptions): GeoJSONVTInternalFeature[] | null {
16
- k1 /= scale;
17
- k2 /= scale;
25
+ export function clip(features: GeoJSONVTInternalFeature[], scale: number, start: number, end: number, axis: AxisType, minAll: number, maxAll: number, options: GeoJSONVTOptions): GeoJSONVTInternalFeature[] | null {
26
+ start /= scale;
27
+ end /= scale;
18
28
 
19
- if (minAll >= k1 && maxAll < k2) { // trivial accept
29
+ if (minAll >= start && maxAll < end) { // trivial accept
20
30
  return features;
21
31
  }
22
32
 
23
- if (maxAll < k1 || minAll >= k2) { // trivial reject
33
+ if (maxAll < start || minAll >= end) { // trivial reject
24
34
  return null;
25
35
  }
26
36
 
27
37
  const clipped: GeoJSONVTInternalFeature[] = [];
28
38
 
29
39
  for (const feature of features) {
30
- const min = axis === 0 ? feature.minX : feature.minY;
31
- const max = axis === 0 ? feature.maxX : feature.maxY;
40
+ const min = axis === AxisType.X ? feature.minX : feature.minY;
41
+ const max = axis === AxisType.X ? feature.maxX : feature.maxY;
32
42
 
33
- if (min >= k1 && max < k2) { // trivial accept
43
+ if (min >= start && max < end) { // trivial accept
34
44
  clipped.push(feature);
35
45
  continue;
36
46
  }
37
47
 
38
- if (max < k1 || min >= k2) { // trivial reject
48
+ if (max < start || min >= end) { // trivial reject
39
49
  continue;
40
50
  }
41
51
 
42
52
  switch (feature.type) {
43
53
  case 'Point':
44
54
  case 'MultiPoint': {
45
- const pointGeometry: number[] = [];
46
- clipPoints(feature.geometry, pointGeometry, k1, k2, axis);
47
- if (!pointGeometry.length) continue;
48
-
49
- const type = pointGeometry.length === 3 ? 'Point' : 'MultiPoint';
50
- clipped.push(createFeature(feature.id, type, pointGeometry, feature.tags));
55
+ clipPointFeature(feature, clipped, start, end, axis);
51
56
  continue;
52
57
  }
53
58
 
54
59
  case 'LineString': {
55
- const lineGeometry: StartEndSizeArray[] = [];
56
- clipLine(feature.geometry, lineGeometry, k1, k2, axis, false, options.lineMetrics);
57
- if (!lineGeometry.length) continue;
58
-
59
- if (options.lineMetrics) {
60
- for (const line of lineGeometry) {
61
- clipped.push(createFeature(feature.id, feature.type, line, feature.tags));
62
- }
63
- continue;
64
- }
65
-
66
- if (lineGeometry.length > 1) {
67
- clipped.push(createFeature(feature.id, "MultiLineString", lineGeometry, feature.tags));
68
- continue;
69
- }
70
-
71
- clipped.push(createFeature(feature.id, feature.type, lineGeometry[0], feature.tags));
60
+ clipLineStringFeature(feature, clipped, start, end, axis, options);
72
61
  continue;
73
62
  }
74
63
 
75
64
  case 'MultiLineString': {
76
- const multiLineGeometry: StartEndSizeArray[] = [];
77
- clipLines(feature.geometry, multiLineGeometry, k1, k2, axis, false);
78
- if (!multiLineGeometry.length) continue;
79
-
80
- if (multiLineGeometry.length === 1) {
81
- clipped.push(createFeature(feature.id, "LineString", multiLineGeometry[0], feature.tags));
82
- continue;
83
- }
84
-
85
- clipped.push(createFeature(feature.id, feature.type, multiLineGeometry, feature.tags));
65
+ clipMultiLineStringFeature(feature, clipped, start, end, axis);
86
66
  continue;
87
67
  }
88
68
 
89
69
  case 'Polygon': {
90
- const polygonGeometry: StartEndSizeArray[] = [];
91
- clipLines(feature.geometry, polygonGeometry, k1, k2, axis, true);
92
- if (!polygonGeometry.length) continue;
93
-
94
- clipped.push(createFeature(feature.id, feature.type, polygonGeometry, feature.tags));
70
+ clipPolygonFeature(feature, clipped, start, end, axis);
95
71
  continue;
96
72
  }
97
73
 
98
74
  case 'MultiPolygon': {
99
- const multiPolygonGeometry: StartEndSizeArray[][] = [];
100
- for (const polygon of feature.geometry) {
101
- const newPolygon: StartEndSizeArray[] = [];
102
- clipLines(polygon, newPolygon, k1, k2, axis, true);
103
- if (newPolygon.length) multiPolygonGeometry.push(newPolygon);
104
- }
105
- if (!multiPolygonGeometry.length) continue;
106
-
107
- clipped.push(createFeature(feature.id, feature.type, multiPolygonGeometry, feature.tags));
75
+ clipMultiPolygonFeature(feature, clipped, start, end, axis);
108
76
  continue;
109
77
  }
110
78
  }
@@ -115,20 +83,90 @@ export function clip(features: GeoJSONVTInternalFeature[], scale: number, k1: nu
115
83
  return clipped;
116
84
  }
117
85
 
118
- function clipPoints(geom: number[], newGeom: number[], k1: number, k2: number, axis: number) {
86
+ function clipPointFeature(feature: GeoJSONVTInternalPointFeature | GeoJSONVTInternalMultiPointFeature, clipped: GeoJSONVTInternalFeature[], start: number, end: number, axis: AxisType) {
87
+ const geom: number[] = [];
88
+
89
+ clipPoints(feature.geometry, geom, start, end, axis);
90
+ if (!geom.length) return;
91
+
92
+ const type = geom.length === 3 ? 'Point' : 'MultiPoint';
93
+ clipped.push(createFeature(feature.id, type, geom, feature.tags));
94
+ }
95
+
96
+ function clipLineStringFeature(feature: GeoJSONVTInternalLineStringFeature, clipped: GeoJSONVTInternalFeature[], start: number, end: number, axis: AxisType, options: GeoJSONVTOptions) {
97
+ const geom: StartEndSizeArray[] = [];
98
+
99
+ clipLine(feature.geometry, geom, start, end, axis, false, options.lineMetrics);
100
+ if (!geom.length) return;
101
+
102
+ if (options.lineMetrics) {
103
+ for (const line of geom) {
104
+ clipped.push(createFeature(feature.id, 'LineString', line, feature.tags));
105
+ }
106
+ return;
107
+ }
108
+
109
+ if (geom.length > 1) {
110
+ clipped.push(createFeature(feature.id, 'MultiLineString', geom, feature.tags));
111
+ return;
112
+ }
113
+
114
+ clipped.push(createFeature(feature.id, 'LineString', geom[0], feature.tags));
115
+ }
116
+
117
+ function clipMultiLineStringFeature(feature: GeoJSONVTInternalMultiLineStringFeature, clipped: GeoJSONVTInternalFeature[], start: number, end: number, axis: AxisType) {
118
+ const geom: StartEndSizeArray[] = [];
119
+
120
+ clipLines(feature.geometry, geom, start, end, axis, false);
121
+ if (!geom.length) return;
122
+
123
+ if (geom.length === 1) {
124
+ clipped.push(createFeature(feature.id, 'LineString', geom[0], feature.tags));
125
+ return;
126
+ }
127
+
128
+ clipped.push(createFeature(feature.id,'MultiLineString', geom, feature.tags));
129
+ }
130
+
131
+ function clipPolygonFeature(feature: GeoJSONVTInternalPolygonFeature, clipped: GeoJSONVTInternalFeature[], start: number, end: number, axis: AxisType) {
132
+ const geom: StartEndSizeArray[] = [];
133
+
134
+ clipLines(feature.geometry, geom, start, end, axis, true);
135
+ if (!geom.length) return;
136
+
137
+ clipped.push(createFeature(feature.id, 'Polygon', geom, feature.tags));
138
+ }
139
+
140
+ function clipMultiPolygonFeature(feature: GeoJSONVTInternalMultiPolygonFeature, clipped: GeoJSONVTInternalFeature[], start: number, end: number, axis: AxisType) {
141
+ const geom: StartEndSizeArray[][] = [];
142
+
143
+ for (const polygon of feature.geometry) {
144
+ const newPolygon: StartEndSizeArray[] = [];
145
+
146
+ clipLines(polygon, newPolygon, start, end, axis, true);
147
+ if (!newPolygon.length) continue;
148
+
149
+ geom.push(newPolygon);
150
+ }
151
+ if (!geom.length) return;
152
+
153
+ clipped.push(createFeature(feature.id, 'MultiPolygon', geom, feature.tags));
154
+ }
155
+
156
+ function clipPoints(geom: number[], newGeom: number[], start: number, end: number, axis: AxisType) {
119
157
  for (let i = 0; i < geom.length; i += 3) {
120
158
  const a = geom[i + axis];
121
159
 
122
- if (a >= k1 && a <= k2) {
160
+ if (a >= start && a <= end) {
123
161
  addPoint(newGeom, geom[i], geom[i + 1], geom[i + 2]);
124
162
  }
125
163
  }
126
164
  }
127
165
 
128
- function clipLine(geom: StartEndSizeArray, newGeom: StartEndSizeArray[], k1: number, k2: number, axis: number, isPolygon: boolean, trackMetrics: boolean) {
166
+ function clipLine(geom: StartEndSizeArray, newGeom: StartEndSizeArray[], start: number, end: number, axis: AxisType, isPolygon: boolean, trackMetrics: boolean) {
129
167
 
130
168
  let slice = newSlice(geom);
131
- const intersect = axis === 0 ? intersectX : intersectY;
169
+ const intersect = axis === AxisType.X ? intersectX : intersectY;
132
170
  let len = geom.start;
133
171
  let segLen, t;
134
172
 
@@ -138,37 +176,37 @@ function clipLine(geom: StartEndSizeArray, newGeom: StartEndSizeArray[], k1: num
138
176
  const az = geom[i + 2];
139
177
  const bx = geom[i + 3];
140
178
  const by = geom[i + 4];
141
- const a = axis === 0 ? ax : ay;
142
- const b = axis === 0 ? bx : by;
179
+ const a = axis === AxisType.X ? ax : ay;
180
+ const b = axis === AxisType.X ? bx : by;
143
181
  let exited = false;
144
182
 
145
183
  if (trackMetrics) segLen = Math.sqrt(Math.pow(ax - bx, 2) + Math.pow(ay - by, 2));
146
184
 
147
- if (a < k1) {
185
+ if (a < start) {
148
186
  // ---|--> | (line enters the clip region from the left)
149
- if (b > k1) {
150
- t = intersect(slice, ax, ay, bx, by, k1);
187
+ if (b > start) {
188
+ t = intersect(slice, ax, ay, bx, by, start);
151
189
  if (trackMetrics) slice.start = len + segLen * t;
152
190
  }
153
- } else if (a > k2) {
191
+ } else if (a > end) {
154
192
  // | <--|--- (line enters the clip region from the right)
155
- if (b < k2) {
156
- t = intersect(slice, ax, ay, bx, by, k2);
193
+ if (b < end) {
194
+ t = intersect(slice, ax, ay, bx, by, end);
157
195
  if (trackMetrics) slice.start = len + segLen * t;
158
196
  }
159
197
  } else {
160
198
  addPoint(slice, ax, ay, az);
161
199
  }
162
200
 
163
- if (b < k1 && a >= k1) {
201
+ if (b < start && a >= start) {
164
202
  // <--|--- | or <--|-----|--- (line exits the clip region on the left)
165
- t = intersect(slice, ax, ay, bx, by, k1);
203
+ t = intersect(slice, ax, ay, bx, by, start);
166
204
  exited = true;
167
205
  }
168
206
 
169
- if (b > k2 && a <= k2) {
207
+ if (b > end && a <= end) {
170
208
  // | ---|--> or ---|-----|--> (line exits the clip region on the right)
171
- t = intersect(slice, ax, ay, bx, by, k2);
209
+ t = intersect(slice, ax, ay, bx, by, end);
172
210
  exited = true;
173
211
  }
174
212
 
@@ -186,8 +224,8 @@ function clipLine(geom: StartEndSizeArray, newGeom: StartEndSizeArray[], k1: num
186
224
  const ax = geom[last];
187
225
  const ay = geom[last + 1];
188
226
  const az = geom[last + 2];
189
- const a = axis === 0 ? ax : ay;
190
- if (a >= k1 && a <= k2) addPoint(slice, ax, ay, az);
227
+ const a = axis === AxisType.X ? ax : ay;
228
+ if (a >= start && a <= end) addPoint(slice, ax, ay, az);
191
229
 
192
230
  // close the polygon if its endpoints are not the same after clipping
193
231
  last = slice.length - 3;
@@ -209,9 +247,9 @@ function newSlice(line: StartEndSizeArray): StartEndSizeArray {
209
247
  return slice;
210
248
  }
211
249
 
212
- function clipLines(geom: StartEndSizeArray[], newGeom: StartEndSizeArray[], k1: number, k2: number, axis: number, isPolygon: boolean) {
250
+ function clipLines(geom: StartEndSizeArray[], newGeom: StartEndSizeArray[], start: number, end: number, axis: AxisType, isPolygon: boolean) {
213
251
  for (const line of geom) {
214
- clipLine(line, newGeom, k1, k2, axis, isPolygon, false);
252
+ clipLine(line, newGeom, start, end, axis, isPolygon, false);
215
253
  }
216
254
  }
217
255