@maplibre/geojson-vt 5.0.2 → 5.0.4
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 +5 -5
- package/dist/clip.d.ts +3 -0
- package/dist/clip.d.ts.map +1 -0
- package/dist/clip.test.d.ts +2 -0
- package/dist/clip.test.d.ts.map +1 -0
- package/dist/convert.d.ts +9 -0
- package/dist/convert.d.ts.map +1 -0
- package/dist/definitions.d.ts +85 -0
- package/dist/definitions.d.ts.map +1 -0
- package/dist/difference.d.ts +67 -0
- package/dist/difference.d.ts.map +1 -0
- package/dist/difference.test.d.ts +2 -0
- package/dist/difference.test.d.ts.map +1 -0
- package/dist/feature.d.ts +12 -0
- package/dist/feature.d.ts.map +1 -0
- package/dist/geojson-vt-dev.js +63 -34
- package/dist/geojson-vt.js +1 -1
- package/dist/geojson-vt.mjs +63 -34
- package/dist/geojson-vt.mjs.map +1 -1
- package/dist/index.d.ts +63 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/simplify.d.ts +9 -0
- package/dist/simplify.d.ts.map +1 -0
- package/dist/simplify.test.d.ts +2 -0
- package/dist/simplify.test.d.ts.map +1 -0
- package/dist/tile.d.ts +40 -0
- package/dist/tile.d.ts.map +1 -0
- package/dist/transform.d.ts +27 -0
- package/dist/transform.d.ts.map +1 -0
- package/dist/wrap.d.ts +3 -0
- package/dist/wrap.d.ts.map +1 -0
- package/package.json +9 -3
- package/src/clip.ts +3 -3
- package/src/convert.ts +4 -4
- package/src/definitions.ts +1 -1
- package/src/difference.ts +4 -4
- package/src/feature.ts +4 -4
- package/src/index.ts +19 -14
- package/src/tile.ts +71 -43
- package/src/transform.ts +31 -16
- package/src/wrap.ts +3 -3
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ dynamically loading a 100Mb US zip codes GeoJSON with 5.4 million points:
|
|
|
30
30
|
|
|
31
31
|

|
|
32
32
|
|
|
33
|
-
There's a convenient [debug page](http://maplibre.
|
|
33
|
+
There's a convenient [debug page](http://maplibre.org/geojson-vt/debug/) to test out **geojson-vt** on different data.
|
|
34
34
|
Just drag any GeoJSON on the page, watching the console.
|
|
35
35
|
|
|
36
36
|

|
|
@@ -107,20 +107,20 @@ To use `updateData`, the index must be created with the `updateable: true` optio
|
|
|
107
107
|
|
|
108
108
|
### Install
|
|
109
109
|
|
|
110
|
-
Install using NPM (`npm install geojson-vt`), then:
|
|
110
|
+
Install using NPM (`npm install @maplibre/geojson-vt`), then:
|
|
111
111
|
|
|
112
112
|
```js
|
|
113
113
|
// import as a ES module
|
|
114
|
-
import geojsonvt from 'geojson-vt';
|
|
114
|
+
import geojsonvt from '@maplibre/geojson-vt';
|
|
115
115
|
|
|
116
116
|
// import from a CDN in the browser:
|
|
117
|
-
import geojsonvt from 'https://esm.run/geojson-vt';
|
|
117
|
+
import geojsonvt from 'https://esm.run/@maplibre/geojson-vt';
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
Or use a browser build directly:
|
|
121
121
|
|
|
122
122
|
```html
|
|
123
|
-
<script src="https://unpkg.com/geojson-vt/geojson-vt.js"></script>
|
|
123
|
+
<script src="https://unpkg.com/@maplibre/geojson-vt/geojson-vt.js"></script>
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
### Getting Involved
|
package/dist/clip.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { GeoJSONVTInternalFeature, GeoJSONVTOptions } from './definitions';
|
|
2
|
+
export declare function clip(features: GeoJSONVTInternalFeature[], scale: number, k1: number, k2: number, axis: number, minAll: number, maxAll: number, options: GeoJSONVTOptions): GeoJSONVTInternalFeature[] | null;
|
|
3
|
+
//# sourceMappingURL=clip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clip.d.ts","sourceRoot":"","sources":["../src/clip.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAqB,MAAM,eAAe,CAAC;AAYnG,wBAAgB,IAAI,CAAC,QAAQ,EAAE,wBAAwB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,wBAAwB,EAAE,GAAG,IAAI,CAqG5M"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clip.test.d.ts","sourceRoot":"","sources":["../src/clip.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GeoJSONVTInternalFeature, GeoJSONVTOptions } from './definitions';
|
|
2
|
+
/**
|
|
3
|
+
* converts GeoJSON feature into an intermediate projected JSON vector format with simplification data
|
|
4
|
+
* @param data
|
|
5
|
+
* @param options
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export declare function convert(data: GeoJSON.GeoJSON, options: GeoJSONVTOptions): GeoJSONVTInternalFeature[];
|
|
9
|
+
//# sourceMappingURL=convert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../src/convert.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAqB,MAAM,eAAe,CAAC;AAEnG;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,gBAAgB,GAAG,wBAAwB,EAAE,CAiBpG"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type GeoJSONVTOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* Max zoom to preserve detail on
|
|
4
|
+
* @default 14
|
|
5
|
+
*/
|
|
6
|
+
maxZoom?: number;
|
|
7
|
+
/**
|
|
8
|
+
* Max zoom in the tile index
|
|
9
|
+
* @default 5
|
|
10
|
+
*/
|
|
11
|
+
indexMaxZoom?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Max number of points per tile in the tile index
|
|
14
|
+
* @default 100000
|
|
15
|
+
*/
|
|
16
|
+
indexMaxPoints?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Simplification tolerance (higher means simpler)
|
|
19
|
+
* @default 3
|
|
20
|
+
*/
|
|
21
|
+
tolerance?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Tile extent
|
|
24
|
+
* @default 4096
|
|
25
|
+
*/
|
|
26
|
+
extent?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Tile buffer on each side
|
|
29
|
+
* @default 64
|
|
30
|
+
*/
|
|
31
|
+
buffer?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Whether to calculate line metrics
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
lineMetrics?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Name of a feature property to be promoted to feature.id
|
|
39
|
+
*/
|
|
40
|
+
promoteId?: string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Whether to generate feature ids. Cannot be used with promoteId
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
generateId?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Whether geojson can be updated (with caveat of a stored simplified copy)
|
|
48
|
+
* @default false
|
|
49
|
+
*/
|
|
50
|
+
updateable?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Logging level (0, 1 or 2)
|
|
53
|
+
* @default 0
|
|
54
|
+
*/
|
|
55
|
+
debug?: number;
|
|
56
|
+
};
|
|
57
|
+
export type StartEndSizeArray = number[] & {
|
|
58
|
+
start?: number;
|
|
59
|
+
end?: number;
|
|
60
|
+
size?: number;
|
|
61
|
+
};
|
|
62
|
+
export type PartialGeoJSONVTFeature = {
|
|
63
|
+
id?: number | string | undefined;
|
|
64
|
+
tags: GeoJSON.GeoJsonProperties;
|
|
65
|
+
minX: number;
|
|
66
|
+
minY: number;
|
|
67
|
+
maxX: number;
|
|
68
|
+
maxY: number;
|
|
69
|
+
};
|
|
70
|
+
export type GeometryTypeMap = {
|
|
71
|
+
Point: number[];
|
|
72
|
+
MultiPoint: number[];
|
|
73
|
+
LineString: StartEndSizeArray;
|
|
74
|
+
MultiLineString: StartEndSizeArray[];
|
|
75
|
+
Polygon: StartEndSizeArray[];
|
|
76
|
+
MultiPolygon: StartEndSizeArray[][];
|
|
77
|
+
};
|
|
78
|
+
export type GeometryType = "Point" | "MultiPoint" | "LineString" | "MultiLineString" | "Polygon" | "MultiPolygon";
|
|
79
|
+
export type GeoJSONVTInternalFeature = {
|
|
80
|
+
[K in GeometryType]: PartialGeoJSONVTFeature & {
|
|
81
|
+
type: K;
|
|
82
|
+
geometry: GeometryTypeMap[K];
|
|
83
|
+
};
|
|
84
|
+
}[GeometryType];
|
|
85
|
+
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAGF,MAAM,MAAM,iBAAiB,GAAG,MAAM,EAAE,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3F,MAAM,MAAM,uBAAuB,GAAG;IAClC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,eAAe,EAAE,iBAAiB,EAAE,CAAC;IACrC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,YAAY,EAAE,iBAAiB,EAAE,EAAE,CAAC;CACvC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,iBAAiB,GAAG,SAAS,GAAG,cAAc,CAAC;AAElH,MAAM,MAAM,wBAAwB,GAAG;KAClC,CAAC,IAAI,YAAY,GAAG,uBAAuB,GAAG;QAC3C,IAAI,EAAE,CAAC,CAAC;QACR,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;KAChC;CACJ,CAAC,YAAY,CAAC,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { GeoJSONVTInternalFeature, GeoJSONVTOptions } from './definitions';
|
|
2
|
+
export type GeoJSONVTSourceDiff = {
|
|
3
|
+
/**
|
|
4
|
+
* If true, clear all existing features
|
|
5
|
+
*/
|
|
6
|
+
removeAll?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Array of feature IDs to remove
|
|
9
|
+
*/
|
|
10
|
+
remove?: (string | number)[];
|
|
11
|
+
/**
|
|
12
|
+
* Array of GeoJSON features to add
|
|
13
|
+
*/
|
|
14
|
+
add?: GeoJSON.Feature[];
|
|
15
|
+
/**
|
|
16
|
+
* Array of per-feature updates
|
|
17
|
+
*/
|
|
18
|
+
update?: GeoJSONVTFeatureDiff[];
|
|
19
|
+
};
|
|
20
|
+
export type GeoJSONVTFeatureDiff = {
|
|
21
|
+
/**
|
|
22
|
+
* ID of the feature being updated
|
|
23
|
+
*/
|
|
24
|
+
id: string | number;
|
|
25
|
+
/**
|
|
26
|
+
* Optional new geometry
|
|
27
|
+
*/
|
|
28
|
+
newGeometry?: GeoJSON.Geometry;
|
|
29
|
+
/**
|
|
30
|
+
* Remove all properties if true
|
|
31
|
+
*/
|
|
32
|
+
removeAllProperties?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Specific properties to delete
|
|
35
|
+
*/
|
|
36
|
+
removeProperties?: string[];
|
|
37
|
+
/**
|
|
38
|
+
* Properties to add or update
|
|
39
|
+
*/
|
|
40
|
+
addOrUpdateProperties?: {
|
|
41
|
+
key: string;
|
|
42
|
+
value: unknown;
|
|
43
|
+
}[];
|
|
44
|
+
};
|
|
45
|
+
type HashedGeoJSONVTSourceDiff = {
|
|
46
|
+
removeAll?: boolean | undefined;
|
|
47
|
+
remove: Set<string | number>;
|
|
48
|
+
add: Map<string | number | undefined, GeoJSON.Feature>;
|
|
49
|
+
update: Map<string | number, GeoJSONVTFeatureDiff>;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Applies a GeoJSON Source Diff to an existing set of simplified features
|
|
53
|
+
* @param source
|
|
54
|
+
* @param dataDiff
|
|
55
|
+
* @param options
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
export declare function applySourceDiff(source: GeoJSONVTInternalFeature[], dataDiff: GeoJSONVTSourceDiff, options: GeoJSONVTOptions): {
|
|
59
|
+
affected: GeoJSONVTInternalFeature[];
|
|
60
|
+
source: GeoJSONVTInternalFeature[];
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Convert a GeoJSON Source Diff to an idempotent hashed representation using Sets and Maps
|
|
64
|
+
*/
|
|
65
|
+
export declare function diffToHashed(diff: GeoJSONVTSourceDiff): HashedGeoJSONVTSourceDiff;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=difference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"difference.d.ts","sourceRoot":"","sources":["../src/difference.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEhF,MAAM,MAAM,mBAAmB,GAAG;IAC9B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC7B;;OAEG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;IACxB;;OAEG;IACH,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAC/B;;OAEG;IACH,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC;IAC/B;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;OAEG;IACH,qBAAqB,CAAC,EAAE;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,OAAO,CAAC;KAClB,EAAE,CAAC;CACP,CAAC;AAEF,KAAK,yBAAyB,GAAG;IAC7B,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAC7B,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACtD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,wBAAwB,EAAE,EAAE,QAAQ,EAAE,mBAAmB,EAAE,OAAO,EAAE,gBAAgB;;;EAwE3H;AAgED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,yBAAyB,CAejF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"difference.test.d.ts","sourceRoot":"","sources":["../src/difference.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GeoJSONVTInternalFeature, GeometryType, GeometryTypeMap } from "./definitions";
|
|
2
|
+
export type SupportedGeometries = GeoJSON.Point | GeoJSON.MultiPoint | GeoJSON.LineString | GeoJSON.MultiLineString | GeoJSON.Polygon | GeoJSON.MultiPolygon;
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param id - the feature's ID
|
|
6
|
+
* @param type - the feature's type
|
|
7
|
+
* @param geom - the feature's geometry
|
|
8
|
+
* @param tags - the feature's properties
|
|
9
|
+
* @returns the created feature
|
|
10
|
+
*/
|
|
11
|
+
export declare function createFeature<T extends GeometryType>(id: number | string | undefined, type: T, geom: GeometryTypeMap[T], tags: GeoJSON.GeoJsonProperties): GeoJSONVTInternalFeature;
|
|
12
|
+
//# sourceMappingURL=feature.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../src/feature.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAE7F,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,eAAe,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;AAE7J;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,YAAY,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,iBAAiB,GAAG,wBAAwB,CA0CnL"}
|
package/dist/geojson-vt-dev.js
CHANGED
|
@@ -559,22 +559,23 @@ function transformTile(tile, extent) {
|
|
|
559
559
|
const tx = tile.x;
|
|
560
560
|
const ty = tile.y;
|
|
561
561
|
for (const feature of tile.features) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
for (let j = 0; j < geom.length; j += 2) {
|
|
567
|
-
feature.geometry.push(transformPoint(geom[j], geom[j + 1], extent, z2, tx, ty));
|
|
562
|
+
if (feature.type === 1) {
|
|
563
|
+
const pointGeometry = [];
|
|
564
|
+
for (let j = 0; j < feature.geometry.length; j += 2) {
|
|
565
|
+
pointGeometry.push(transformPoint(feature.geometry[j], feature.geometry[j + 1], extent, z2, tx, ty));
|
|
568
566
|
}
|
|
567
|
+
feature.geometry = pointGeometry;
|
|
569
568
|
continue;
|
|
570
569
|
}
|
|
571
|
-
|
|
570
|
+
const geometry = [];
|
|
571
|
+
for (const singleGeom of feature.geometry) {
|
|
572
572
|
const ring = [];
|
|
573
573
|
for (let k = 0; k < singleGeom.length; k += 2) {
|
|
574
574
|
ring.push(transformPoint(singleGeom[k], singleGeom[k + 1], extent, z2, tx, ty));
|
|
575
575
|
}
|
|
576
|
-
|
|
576
|
+
geometry.push(ring);
|
|
577
577
|
}
|
|
578
|
+
feature.geometry = geometry;
|
|
578
579
|
}
|
|
579
580
|
tile.transformed = true;
|
|
580
581
|
return tile;
|
|
@@ -618,55 +619,83 @@ function createTile(features, z, tx, ty, options) {
|
|
|
618
619
|
return tile;
|
|
619
620
|
}
|
|
620
621
|
function addFeature(tile, feature, tolerance, options) {
|
|
621
|
-
const simplified = [];
|
|
622
622
|
tile.minX = Math.min(tile.minX, feature.minX);
|
|
623
623
|
tile.minY = Math.min(tile.minY, feature.minY);
|
|
624
624
|
tile.maxX = Math.max(tile.maxX, feature.maxX);
|
|
625
625
|
tile.maxY = Math.max(tile.maxY, feature.maxY);
|
|
626
|
+
let tags = feature.tags || null;
|
|
627
|
+
let tileFeature;
|
|
626
628
|
switch (feature.type) {
|
|
627
629
|
case 'Point':
|
|
628
|
-
case 'MultiPoint':
|
|
630
|
+
case 'MultiPoint': {
|
|
631
|
+
const geometry = [];
|
|
629
632
|
for (let i = 0; i < feature.geometry.length; i += 3) {
|
|
630
|
-
|
|
633
|
+
geometry.push(feature.geometry[i], feature.geometry[i + 1]);
|
|
631
634
|
tile.numPoints++;
|
|
632
635
|
tile.numSimplified++;
|
|
633
636
|
}
|
|
637
|
+
if (!geometry.length)
|
|
638
|
+
return;
|
|
639
|
+
tileFeature = {
|
|
640
|
+
type: 1,
|
|
641
|
+
tags: tags,
|
|
642
|
+
geometry: geometry
|
|
643
|
+
};
|
|
634
644
|
break;
|
|
635
|
-
|
|
636
|
-
|
|
645
|
+
}
|
|
646
|
+
case 'LineString': {
|
|
647
|
+
const geometry = [];
|
|
648
|
+
addLine(geometry, feature.geometry, tile, tolerance, false, false);
|
|
649
|
+
if (!geometry.length)
|
|
650
|
+
return;
|
|
651
|
+
if (options.lineMetrics) {
|
|
652
|
+
tags = {};
|
|
653
|
+
for (const key in feature.tags)
|
|
654
|
+
tags[key] = feature.tags[key];
|
|
655
|
+
// HM TODO: replace with geojsonvt
|
|
656
|
+
tags['mapbox_clip_start'] = feature.geometry.start / feature.geometry.size;
|
|
657
|
+
tags['mapbox_clip_end'] = feature.geometry.end / feature.geometry.size;
|
|
658
|
+
}
|
|
659
|
+
tileFeature = {
|
|
660
|
+
type: 2,
|
|
661
|
+
tags: tags,
|
|
662
|
+
geometry: geometry
|
|
663
|
+
};
|
|
637
664
|
break;
|
|
665
|
+
}
|
|
638
666
|
case 'MultiLineString':
|
|
639
|
-
case 'Polygon':
|
|
667
|
+
case 'Polygon': {
|
|
668
|
+
const geometry = [];
|
|
640
669
|
for (let i = 0; i < feature.geometry.length; i++) {
|
|
641
|
-
addLine(
|
|
670
|
+
addLine(geometry, feature.geometry[i], tile, tolerance, feature.type === 'Polygon', i === 0);
|
|
642
671
|
}
|
|
672
|
+
if (!geometry.length)
|
|
673
|
+
return;
|
|
674
|
+
tileFeature = {
|
|
675
|
+
type: feature.type === 'Polygon' ? 3 : 2,
|
|
676
|
+
tags: tags,
|
|
677
|
+
geometry: geometry
|
|
678
|
+
};
|
|
643
679
|
break;
|
|
644
|
-
|
|
680
|
+
}
|
|
681
|
+
case 'MultiPolygon': {
|
|
682
|
+
const geometry = [];
|
|
645
683
|
for (let k = 0; k < feature.geometry.length; k++) {
|
|
646
684
|
const polygon = feature.geometry[k];
|
|
647
685
|
for (let i = 0; i < polygon.length; i++) {
|
|
648
|
-
addLine(
|
|
686
|
+
addLine(geometry, polygon[i], tile, tolerance, true, i === 0);
|
|
649
687
|
}
|
|
650
688
|
}
|
|
689
|
+
if (!geometry.length)
|
|
690
|
+
return;
|
|
691
|
+
tileFeature = {
|
|
692
|
+
type: 3,
|
|
693
|
+
tags: tags,
|
|
694
|
+
geometry: geometry
|
|
695
|
+
};
|
|
651
696
|
break;
|
|
697
|
+
}
|
|
652
698
|
}
|
|
653
|
-
if (!simplified.length)
|
|
654
|
-
return;
|
|
655
|
-
let tags = feature.tags || null;
|
|
656
|
-
if (feature.type === 'LineString' && options.lineMetrics) {
|
|
657
|
-
tags = {};
|
|
658
|
-
for (const key in feature.tags)
|
|
659
|
-
tags[key] = feature.tags[key];
|
|
660
|
-
// HM TODO: replace with geojsonvt
|
|
661
|
-
tags['mapbox_clip_start'] = feature.geometry.start / feature.geometry.size;
|
|
662
|
-
tags['mapbox_clip_end'] = feature.geometry.end / feature.geometry.size;
|
|
663
|
-
}
|
|
664
|
-
const tileFeature = {
|
|
665
|
-
geometry: simplified,
|
|
666
|
-
type: feature.type === 'Polygon' || feature.type === 'MultiPolygon' ? 3 :
|
|
667
|
-
(feature.type === 'LineString' || feature.type === 'MultiLineString' ? 2 : 1),
|
|
668
|
-
tags
|
|
669
|
-
};
|
|
670
699
|
if (feature.id !== null) {
|
|
671
700
|
tileFeature.id = feature.id;
|
|
672
701
|
}
|
package/dist/geojson-vt.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).geojsonvt=e()}(this,(function(){"use strict";function t(n,o,i,s){let r=s;const l=o+(i-o>>1);let a,c=i-o;const u=n[o],f=n[o+1],m=n[i],d=n[i+1];for(let t=o+3;t<i;t+=3){const o=e(n[t],n[t+1],u,f,m,d);if(o>r)a=t,r=o;else if(o===r){const e=Math.abs(t-l);e<c&&(a=t,c=e)}}r>s&&(a-o>3&&t(n,o,a,s),n[a+2]=r,i-a>3&&t(n,a,i,s))}function e(t,e,n,o,i,s){let r=i-n,l=s-o;if(0!==r||0!==l){const a=((t-n)*r+(e-o)*l)/(r*r+l*l);a>1?(n=i,o=s):a>0&&(n+=r*a,o+=l*a)}return r=t-n,l=e-o,r*r+l*l}function n(t,e,n,i){const s={type:e,geom:n},r={id:null==t?null:t,type:s.type,geometry:s.geom,tags:i,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};switch(s.type){case"Point":case"MultiPoint":case"LineString":o(r,s.geom);break;case"Polygon":o(r,s.geom[0]);break;case"MultiLineString":for(const t of s.geom)o(r,t);break;case"MultiPolygon":for(const t of s.geom)o(r,t[0])}return r}function o(t,e){for(let n=0;n<e.length;n+=3)t.minX=Math.min(t.minX,e[n]),t.minY=Math.min(t.minY,e[n+1]),t.maxX=Math.max(t.maxX,e[n]),t.maxY=Math.max(t.maxY,e[n+1])}function i(t,e){const n=[];switch(t.type){case"FeatureCollection":for(let o=0;o<t.features.length;o++)s(n,t.features[o],e,o);break;case"Feature":s(n,t,e);break;default:s(n,{geometry:t,properties:void 0},e)}return n}function s(t,e,o,i){if(!e.geometry)return;if("GeometryCollection"===e.geometry.type){for(const n of e.geometry.geometries)s(t,{id:e.id,geometry:n,properties:e.properties},o,i);return}const c=e.geometry.coordinates;if(!c?.length)return;const u=Math.pow(o.tolerance/((1<<o.maxZoom)*o.extent),2);let f=e.id;switch(o.promoteId?f=e.properties?.[o.promoteId]:o.generateId&&(f=i||0),e.geometry.type){case"Point":{const o=[];return r(e.geometry.coordinates,o),void t.push(n(f,e.geometry.type,o,e.properties))}case"MultiPoint":{const o=[];for(const t of e.geometry.coordinates)r(t,o);return void t.push(n(f,e.geometry.type,o,e.properties))}case"LineString":{const o=[];return l(e.geometry.coordinates,o,u,!1),void t.push(n(f,e.geometry.type,o,e.properties))}case"MultiLineString":{if(o.lineMetrics){for(const o of e.geometry.coordinates){const i=[];l(o,i,u,!1),t.push(n(f,"LineString",i,e.properties))}return}const i=[];return a(e.geometry.coordinates,i,u,!1),void t.push(n(f,e.geometry.type,i,e.properties))}case"Polygon":{const o=[];return a(e.geometry.coordinates,o,u,!0),void t.push(n(f,e.geometry.type,o,e.properties))}case"MultiPolygon":{const o=[];for(const t of e.geometry.coordinates){const e=[];a(t,e,u,!0),o.push(e)}return void t.push(n(f,e.geometry.type,o,e.properties))}default:throw new Error("Input data is not a valid GeoJSON object.")}}function r(t,e){e.push(c(t[0]),u(t[1]),0)}function l(e,n,o,i){let s,r,l=0;for(let t=0;t<e.length;t++){const o=c(e[t][0]),a=u(e[t][1]);n.push(o,a,0),t>0&&(l+=i?(s*a-o*r)/2:Math.sqrt(Math.pow(o-s,2)+Math.pow(a-r,2))),s=o,r=a}const a=n.length-3;n[2]=1,o>0&&t(n,0,a,o),n[a+2]=1,n.size=Math.abs(l),n.start=0,n.end=n.size}function a(t,e,n,o){for(let i=0;i<t.length;i++){const s=[];l(t[i],s,n,o),e.push(s)}}function c(t){return t/360+.5}function u(t){const e=Math.sin(t*Math.PI/180),n=.5-.25*Math.log((1+e)/(1-e))/Math.PI;return n<0?0:n>1?1:n}function f(t,e,o,i,s,r,l,a){if(i/=e,r>=(o/=e)&&l<i)return t;if(l<o||r>=i)return null;const c=[];for(const e of t){const t=0===s?e.minX:e.minY,r=0===s?e.maxX:e.maxY;if(t>=o&&r<i)c.push(e);else if(!(r<o||t>=i))switch(e.type){case"Point":case"MultiPoint":{const t=[];if(m(e.geometry,t,o,i,s),!t.length)continue;const r=3===t.length?"Point":"MultiPoint";c.push(n(e.id,r,t,e.tags));continue}case"LineString":{const t=[];if(d(e.geometry,t,o,i,s,!1,a.lineMetrics),!t.length)continue;if(a.lineMetrics){for(const o of t)c.push(n(e.id,e.type,o,e.tags));continue}if(t.length>1){c.push(n(e.id,"MultiLineString",t,e.tags));continue}c.push(n(e.id,e.type,t[0],e.tags));continue}case"MultiLineString":{const t=[];if(g(e.geometry,t,o,i,s,!1),!t.length)continue;if(1===t.length){c.push(n(e.id,"LineString",t[0],e.tags));continue}c.push(n(e.id,e.type,t,e.tags));continue}case"Polygon":{const t=[];if(g(e.geometry,t,o,i,s,!0),!t.length)continue;c.push(n(e.id,e.type,t,e.tags));continue}case"MultiPolygon":{const t=[];for(const n of e.geometry){const e=[];g(n,e,o,i,s,!0),e.length&&t.push(e)}if(!t.length)continue;c.push(n(e.id,e.type,t,e.tags));continue}}}return c.length?c:null}function m(t,e,n,o,i){for(let s=0;s<t.length;s+=3){const r=t[s+i];r>=n&&r<=o&&h(e,t[s],t[s+1],t[s+2])}}function d(t,e,n,o,i,s,r){let l=p(t);const a=0===i?y:x;let c,u,f=t.start;for(let m=0;m<t.length-3;m+=3){const d=t[m],g=t[m+1],y=t[m+2],x=t[m+3],M=t[m+4],P=0===i?d:g,b=0===i?x:M;let w=!1;r&&(c=Math.sqrt(Math.pow(d-x,2)+Math.pow(g-M,2))),P<n?b>n&&(u=a(l,d,g,x,M,n),r&&(l.start=f+c*u)):P>o?b<o&&(u=a(l,d,g,x,M,o),r&&(l.start=f+c*u)):h(l,d,g,y),b<n&&P>=n&&(u=a(l,d,g,x,M,n),w=!0),b>o&&P<=o&&(u=a(l,d,g,x,M,o),w=!0),!s&&w&&(r&&(l.end=f+c*u),e.push(l),l=p(t)),r&&(f+=c)}let m=t.length-3;const d=t[m],g=t[m+1],M=t[m+2],P=0===i?d:g;P>=n&&P<=o&&h(l,d,g,M),m=l.length-3,s&&m>=3&&(l[m]!==l[0]||l[m+1]!==l[1])&&h(l,l[0],l[1],l[2]),l.length&&e.push(l)}function p(t){const e=[];return e.size=t.size,e.start=t.start,e.end=t.end,e}function g(t,e,n,o,i,s){for(const r of t)d(r,e,n,o,i,s,!1)}function h(t,e,n,o){t.push(e,n,o)}function y(t,e,n,o,i,s){const r=(s-e)/(o-e);return h(t,s,n+(i-n)*r,1),r}function x(t,e,n,o,i,s){const r=(s-n)/(i-n);return h(t,e+(o-e)*r,s,1),r}function M(t,e){const n=e.buffer/e.extent;let o=t;const i=f(t,1,-1-n,n,0,-1,2,e),s=f(t,1,1-n,2+n,0,-1,2,e);return i||s?(o=f(t,1,-n,1+n,0,-1,2,e)||[],i&&(o=P(i,1).concat(o)),s&&(o=o.concat(P(s,-1))),o):o}function P(t,e){const o=[];for(const i of t)switch(i.type){case"Point":case"MultiPoint":case"LineString":{const t=b(i.geometry,e);o.push(n(i.id,i.type,t,i.tags));continue}case"MultiLineString":case"Polygon":{const t=[];for(const n of i.geometry)t.push(b(n,e));o.push(n(i.id,i.type,t,i.tags));continue}case"MultiPolygon":{const t=[];for(const n of i.geometry){const o=[];for(const t of n)o.push(b(t,e));t.push(o)}o.push(n(i.id,i.type,t,i.tags));continue}}return o}function b(t,e){const n=[];n.size=t.size,void 0!==t.start&&(n.start=t.start,n.end=t.end);for(let o=0;o<t.length;o+=3)n.push(t[o]+e,t[o+1],t[o+2]);return n}function w(t,e){if(t.transformed)return t;const n=1<<t.z,o=t.x,i=t.y;for(const s of t.features){const t=s.geometry,r=s.type;if(s.geometry=[],1!==r)for(const r of t){const t=[];for(let s=0;s<r.length;s+=2)t.push(v(r[s],r[s+1],e,n,o,i));s.geometry.push(t)}else for(let r=0;r<t.length;r+=2)s.geometry.push(v(t[r],t[r+1],e,n,o,i))}return t.transformed=!0,t}function v(t,e,n,o,i,s){return[Math.round(n*(t*o-i)),Math.round(n*(e*o-s))]}function z(t,e,n,o,i){const s=e===i.maxZoom?0:i.tolerance/((1<<e)*i.extent),r={features:[],numPoints:0,numSimplified:0,numFeatures:t.length,source:null,x:n,y:o,z:e,transformed:!1,minX:2,minY:1,maxX:-1,maxY:0};for(const e of t)Y(r,e,s,i);return r}function Y(t,e,n,o){const i=[];switch(t.minX=Math.min(t.minX,e.minX),t.minY=Math.min(t.minY,e.minY),t.maxX=Math.max(t.maxX,e.maxX),t.maxY=Math.max(t.maxY,e.maxY),e.type){case"Point":case"MultiPoint":for(let n=0;n<e.geometry.length;n+=3)i.push(e.geometry[n],e.geometry[n+1]),t.numPoints++,t.numSimplified++;break;case"LineString":S(i,e.geometry,t,n,!1,!1);break;case"MultiLineString":case"Polygon":for(let o=0;o<e.geometry.length;o++)S(i,e.geometry[o],t,n,"Polygon"===e.type,0===o);break;case"MultiPolygon":for(let o=0;o<e.geometry.length;o++){const s=e.geometry[o];for(let e=0;e<s.length;e++)S(i,s[e],t,n,!0,0===e)}}if(!i.length)return;let s=e.tags||null;if("LineString"===e.type&&o.lineMetrics){s={};for(const t in e.tags)s[t]=e.tags[t];s.mapbox_clip_start=e.geometry.start/e.geometry.size,s.mapbox_clip_end=e.geometry.end/e.geometry.size}const r={geometry:i,type:"Polygon"===e.type||"MultiPolygon"===e.type?3:"LineString"===e.type||"MultiLineString"===e.type?2:1,tags:s};null!==e.id&&(r.id=e.id),t.features.push(r)}function S(t,e,n,o,i,s){const r=o*o;if(o>0&&e.size<(i?r:o))return void(n.numPoints+=e.length/3);const l=[];for(let t=0;t<e.length;t+=3)(0===o||e[t+2]>r)&&(n.numSimplified++,l.push(e[t],e[t+1])),n.numPoints++;i&&function(t,e){let n=0;for(let e=0,o=t.length,i=o-2;e<o;i=e,e+=2)n+=(t[e]-t[i])*(t[e+1]+t[i+1]);if(n>0!==e)return;for(let e=0,n=t.length;e<n/2;e+=2){const o=t[e],i=t[e+1];t[e]=t[n-2-e],t[e+1]=t[n-1-e],t[n-2-e]=o,t[n-1-e]=i}}(l,s),t.push(l)}function X(t,e,n){const o=function(t){if(!t)return{remove:new Set,add:new Map,update:new Map};const e={removeAll:t.removeAll,remove:new Set(t.remove||[]),add:new Map(t.add?.map((t=>[t.id,t]))),update:new Map(t.update?.map((t=>[t.id,t])))};return e}(e);let s=[];if(o.removeAll&&(s=t,t=[]),o.remove.size||o.add.size){const e=[];for(const n of t){const{id:t}=n;(o.remove.has(t)||o.add.has(t))&&e.push(n)}if(e.length){s.push(...e);const n=new Set(e.map((t=>t.id)));t=t.filter((t=>!n.has(t.id)))}if(o.add.size){let e=i({type:"FeatureCollection",features:Array.from(o.add.values())},n);e=M(e,n),s.push(...e),t.push(...e)}}if(o.update.size)for(const[e,i]of o.update){const o=t.findIndex((t=>t.id===e));if(-1===o)continue;const r=t[o],l=L(r,i,n);l&&(s.push(r,l),t[o]=l)}return{affected:s,source:t}}function L(t,e,n){const o=!!e.newGeometry,s=e.removeAllProperties||e.removeProperties?.length>0||e.addOrUpdateProperties?.length>0;if(o){let o=i({type:"FeatureCollection",features:[{type:"Feature",id:t.id,geometry:e.newGeometry,properties:s?I(t.tags,e):t.tags}]},n);return o=M(o,n),o[0]}if(s){const n={...t};return n.tags=I(n.tags,e),n}return null}function I(t,e){if(e.removeAllProperties)return{};const n={...t||{}};if(e.removeProperties)for(const t of e.removeProperties)delete n[t];if(e.addOrUpdateProperties)for(const{key:t,value:o}of e.addOrUpdateProperties)n[t]=o;return n}const Z={maxZoom:14,indexMaxZoom:5,indexMaxPoints:1e5,tolerance:3,extent:4096,buffer:64,lineMetrics:!1,promoteId:null,generateId:!1,updateable:!1,debug:0};class k{options;tiles;tileCoords;stats={};total=0;source;constructor(t,e){const n=(e=this.options=Object.assign({},Z,e)).debug;if(n&&console.time("preprocess data"),e.maxZoom<0||e.maxZoom>24)throw new Error("maxZoom should be in the 0-24 range");if(e.promoteId&&e.generateId)throw new Error("promoteId and generateId cannot be used together.");let o=i(t,e);this.tiles={},this.tileCoords=[],n&&(console.timeEnd("preprocess data"),console.log("index: maxZoom: %d, maxPoints: %d",e.indexMaxZoom,e.indexMaxPoints),console.time("generate tiles"),this.stats={},this.total=0),o=M(o,e),o.length&&this.splitTile(o,0,0,0),e.updateable&&(this.source=o),n&&(o.length&&console.log("features: %d, points: %d",this.tiles[0].numFeatures,this.tiles[0].numPoints),console.timeEnd("generate tiles"),console.log("tiles generated:",this.total,JSON.stringify(this.stats)))}splitTile(t,e,n,o,i,s,r){const l=[t,e,n,o],a=this.options,c=a.debug;for(;l.length;){o=l.pop(),n=l.pop(),e=l.pop(),t=l.pop();const u=1<<e,m=C(e,n,o);let d=this.tiles[m];if(!d&&(c>1&&console.time("creation"),d=this.tiles[m]=z(t,e,n,o,a),this.tileCoords.push({z:e,x:n,y:o,id:m}),c)){c>1&&(console.log("tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",e,n,o,d.numFeatures,d.numPoints,d.numSimplified),console.timeEnd("creation"));const t=`z${e}`;this.stats[t]=(this.stats[t]||0)+1,this.total++}if(d.source=t,null==i){if(e===a.indexMaxZoom||d.numPoints<=a.indexMaxPoints)continue}else{if(e===a.maxZoom||e===i)continue;if(null!=i){const t=i-e;if(n!==s>>t||o!==r>>t)continue}}if(d.source=null,!t.length)continue;c>1&&console.time("clipping");const p=.5*a.buffer/a.extent,g=.5-p,h=.5+p,y=1+p;let x=null,M=null,P=null,b=null;const w=f(t,u,n-p,n+h,0,d.minX,d.maxX,a),v=f(t,u,n+g,n+y,0,d.minX,d.maxX,a);w&&(x=f(w,u,o-p,o+h,1,d.minY,d.maxY,a),M=f(w,u,o+g,o+y,1,d.minY,d.maxY,a)),v&&(P=f(v,u,o-p,o+h,1,d.minY,d.maxY,a),b=f(v,u,o+g,o+y,1,d.minY,d.maxY,a)),c>1&&console.timeEnd("clipping"),l.push(x||[],e+1,2*n,2*o),l.push(M||[],e+1,2*n,2*o+1),l.push(P||[],e+1,2*n+1,2*o),l.push(b||[],e+1,2*n+1,2*o+1)}}getTile(t,e,n){t=+t,e=+e,n=+n;const o=this.options,{extent:i,debug:s}=o;if(t<0||t>24)return null;const r=1<<t,l=C(t,e=e+r&r-1,n);if(this.tiles[l])return w(this.tiles[l],i);s>1&&console.log("drilling down to z%d-%d-%d",t,e,n);let a,c=t,u=e,f=n;for(;!a&&c>0;)c--,u>>=1,f>>=1,a=this.tiles[C(c,u,f)];return a?.source?(s>1&&(console.log("found parent tile z%d-%d-%d",c,u,f),console.time("drilling down")),this.splitTile(a.source,c,u,f,t,e,n),s>1&&console.timeEnd("drilling down"),this.tiles[l]?w(this.tiles[l],i):null):null}invalidateTiles(t){const e=this.options,{debug:n}=e;let o=1/0,i=-1/0,s=1/0,r=-1/0;for(const e of t)o=Math.min(o,e.minX),i=Math.max(i,e.maxX),s=Math.min(s,e.minY),r=Math.max(r,e.maxY);const l=e.buffer/e.extent,a=new Set;for(const e in this.tiles){const c=this.tiles[e],u=1<<c.z,f=(c.x-l)/u,m=(c.x+1+l)/u,d=(c.y-l)/u,p=(c.y+1+l)/u;if(i<f||o>=m||r<d||s>=p)continue;let g=!1;for(const e of t)if(e.maxX>=f&&e.minX<m&&e.maxY>=d&&e.minY<p){g=!0;break}if(g){if(n){n>1&&console.log("invalidate tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",c.z,c.x,c.y,c.numFeatures,c.numPoints,c.numSimplified);const t=`z${c.z}`;this.stats[t]=(this.stats[t]||0)-1,this.total--}delete this.tiles[e],a.add(e)}}a.size&&(this.tileCoords=this.tileCoords.filter((t=>!a.has(t.id))))}updateData(t){const e=this.options,n=e.debug;if(!e.updateable)throw new Error("to update tile geojson `updateable` option must be set to true");const{affected:o,source:i}=X(this.source,t,e);if(!o.length)return;this.source=i,n>1&&(console.log("invalidating tiles"),console.time("invalidating")),this.invalidateTiles(o),n>1&&console.timeEnd("invalidating");const[s,r,l]=[0,0,0],a=z(this.source,s,r,l,this.options);a.source=this.source;const c=C(s,r,l);if(this.tiles[c]=a,this.tileCoords.push({z:s,x:r,y:l,id:c}),n){const t=`z${s}`;this.stats[t]=(this.stats[t]||0)+1,this.total++}}}function C(t,e,n){return 32*((1<<t)*n+e)+t}return function(t,e){return new k(t,e)}}));
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).geojsonvt=e()}(this,(function(){"use strict";function t(o,n,i,s){let r=s;const l=n+(i-n>>1);let a,c=i-n;const u=o[n],m=o[n+1],f=o[i],d=o[i+1];for(let t=n+3;t<i;t+=3){const n=e(o[t],o[t+1],u,m,f,d);if(n>r)a=t,r=n;else if(n===r){const e=Math.abs(t-l);e<c&&(a=t,c=e)}}r>s&&(a-n>3&&t(o,n,a,s),o[a+2]=r,i-a>3&&t(o,a,i,s))}function e(t,e,o,n,i,s){let r=i-o,l=s-n;if(0!==r||0!==l){const a=((t-o)*r+(e-n)*l)/(r*r+l*l);a>1?(o=i,n=s):a>0&&(o+=r*a,n+=l*a)}return r=t-o,l=e-n,r*r+l*l}function o(t,e,o,i){const s={type:e,geom:o},r={id:null==t?null:t,type:s.type,geometry:s.geom,tags:i,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};switch(s.type){case"Point":case"MultiPoint":case"LineString":n(r,s.geom);break;case"Polygon":n(r,s.geom[0]);break;case"MultiLineString":for(const t of s.geom)n(r,t);break;case"MultiPolygon":for(const t of s.geom)n(r,t[0])}return r}function n(t,e){for(let o=0;o<e.length;o+=3)t.minX=Math.min(t.minX,e[o]),t.minY=Math.min(t.minY,e[o+1]),t.maxX=Math.max(t.maxX,e[o]),t.maxY=Math.max(t.maxY,e[o+1])}function i(t,e){const o=[];switch(t.type){case"FeatureCollection":for(let n=0;n<t.features.length;n++)s(o,t.features[n],e,n);break;case"Feature":s(o,t,e);break;default:s(o,{geometry:t,properties:void 0},e)}return o}function s(t,e,n,i){if(!e.geometry)return;if("GeometryCollection"===e.geometry.type){for(const o of e.geometry.geometries)s(t,{id:e.id,geometry:o,properties:e.properties},n,i);return}const c=e.geometry.coordinates;if(!c?.length)return;const u=Math.pow(n.tolerance/((1<<n.maxZoom)*n.extent),2);let m=e.id;switch(n.promoteId?m=e.properties?.[n.promoteId]:n.generateId&&(m=i||0),e.geometry.type){case"Point":{const n=[];return r(e.geometry.coordinates,n),void t.push(o(m,e.geometry.type,n,e.properties))}case"MultiPoint":{const n=[];for(const t of e.geometry.coordinates)r(t,n);return void t.push(o(m,e.geometry.type,n,e.properties))}case"LineString":{const n=[];return l(e.geometry.coordinates,n,u,!1),void t.push(o(m,e.geometry.type,n,e.properties))}case"MultiLineString":{if(n.lineMetrics){for(const n of e.geometry.coordinates){const i=[];l(n,i,u,!1),t.push(o(m,"LineString",i,e.properties))}return}const i=[];return a(e.geometry.coordinates,i,u,!1),void t.push(o(m,e.geometry.type,i,e.properties))}case"Polygon":{const n=[];return a(e.geometry.coordinates,n,u,!0),void t.push(o(m,e.geometry.type,n,e.properties))}case"MultiPolygon":{const n=[];for(const t of e.geometry.coordinates){const e=[];a(t,e,u,!0),n.push(e)}return void t.push(o(m,e.geometry.type,n,e.properties))}default:throw new Error("Input data is not a valid GeoJSON object.")}}function r(t,e){e.push(c(t[0]),u(t[1]),0)}function l(e,o,n,i){let s,r,l=0;for(let t=0;t<e.length;t++){const n=c(e[t][0]),a=u(e[t][1]);o.push(n,a,0),t>0&&(l+=i?(s*a-n*r)/2:Math.sqrt(Math.pow(n-s,2)+Math.pow(a-r,2))),s=n,r=a}const a=o.length-3;o[2]=1,n>0&&t(o,0,a,n),o[a+2]=1,o.size=Math.abs(l),o.start=0,o.end=o.size}function a(t,e,o,n){for(let i=0;i<t.length;i++){const s=[];l(t[i],s,o,n),e.push(s)}}function c(t){return t/360+.5}function u(t){const e=Math.sin(t*Math.PI/180),o=.5-.25*Math.log((1+e)/(1-e))/Math.PI;return o<0?0:o>1?1:o}function m(t,e,n,i,s,r,l,a){if(i/=e,r>=(n/=e)&&l<i)return t;if(l<n||r>=i)return null;const c=[];for(const e of t){const t=0===s?e.minX:e.minY,r=0===s?e.maxX:e.maxY;if(t>=n&&r<i)c.push(e);else if(!(r<n||t>=i))switch(e.type){case"Point":case"MultiPoint":{const t=[];if(f(e.geometry,t,n,i,s),!t.length)continue;const r=3===t.length?"Point":"MultiPoint";c.push(o(e.id,r,t,e.tags));continue}case"LineString":{const t=[];if(d(e.geometry,t,n,i,s,!1,a.lineMetrics),!t.length)continue;if(a.lineMetrics){for(const n of t)c.push(o(e.id,e.type,n,e.tags));continue}if(t.length>1){c.push(o(e.id,"MultiLineString",t,e.tags));continue}c.push(o(e.id,e.type,t[0],e.tags));continue}case"MultiLineString":{const t=[];if(g(e.geometry,t,n,i,s,!1),!t.length)continue;if(1===t.length){c.push(o(e.id,"LineString",t[0],e.tags));continue}c.push(o(e.id,e.type,t,e.tags));continue}case"Polygon":{const t=[];if(g(e.geometry,t,n,i,s,!0),!t.length)continue;c.push(o(e.id,e.type,t,e.tags));continue}case"MultiPolygon":{const t=[];for(const o of e.geometry){const e=[];g(o,e,n,i,s,!0),e.length&&t.push(e)}if(!t.length)continue;c.push(o(e.id,e.type,t,e.tags));continue}}}return c.length?c:null}function f(t,e,o,n,i){for(let s=0;s<t.length;s+=3){const r=t[s+i];r>=o&&r<=n&&h(e,t[s],t[s+1],t[s+2])}}function d(t,e,o,n,i,s,r){let l=p(t);const a=0===i?y:x;let c,u,m=t.start;for(let f=0;f<t.length-3;f+=3){const d=t[f],g=t[f+1],y=t[f+2],x=t[f+3],M=t[f+4],P=0===i?d:g,b=0===i?x:M;let w=!1;r&&(c=Math.sqrt(Math.pow(d-x,2)+Math.pow(g-M,2))),P<o?b>o&&(u=a(l,d,g,x,M,o),r&&(l.start=m+c*u)):P>n?b<n&&(u=a(l,d,g,x,M,n),r&&(l.start=m+c*u)):h(l,d,g,y),b<o&&P>=o&&(u=a(l,d,g,x,M,o),w=!0),b>n&&P<=n&&(u=a(l,d,g,x,M,n),w=!0),!s&&w&&(r&&(l.end=m+c*u),e.push(l),l=p(t)),r&&(m+=c)}let f=t.length-3;const d=t[f],g=t[f+1],M=t[f+2],P=0===i?d:g;P>=o&&P<=n&&h(l,d,g,M),f=l.length-3,s&&f>=3&&(l[f]!==l[0]||l[f+1]!==l[1])&&h(l,l[0],l[1],l[2]),l.length&&e.push(l)}function p(t){const e=[];return e.size=t.size,e.start=t.start,e.end=t.end,e}function g(t,e,o,n,i,s){for(const r of t)d(r,e,o,n,i,s,!1)}function h(t,e,o,n){t.push(e,o,n)}function y(t,e,o,n,i,s){const r=(s-e)/(n-e);return h(t,s,o+(i-o)*r,1),r}function x(t,e,o,n,i,s){const r=(s-o)/(i-o);return h(t,e+(n-e)*r,s,1),r}function M(t,e){const o=e.buffer/e.extent;let n=t;const i=m(t,1,-1-o,o,0,-1,2,e),s=m(t,1,1-o,2+o,0,-1,2,e);return i||s?(n=m(t,1,-o,1+o,0,-1,2,e)||[],i&&(n=P(i,1).concat(n)),s&&(n=n.concat(P(s,-1))),n):n}function P(t,e){const n=[];for(const i of t)switch(i.type){case"Point":case"MultiPoint":case"LineString":{const t=b(i.geometry,e);n.push(o(i.id,i.type,t,i.tags));continue}case"MultiLineString":case"Polygon":{const t=[];for(const o of i.geometry)t.push(b(o,e));n.push(o(i.id,i.type,t,i.tags));continue}case"MultiPolygon":{const t=[];for(const o of i.geometry){const n=[];for(const t of o)n.push(b(t,e));t.push(n)}n.push(o(i.id,i.type,t,i.tags));continue}}return n}function b(t,e){const o=[];o.size=t.size,void 0!==t.start&&(o.start=t.start,o.end=t.end);for(let n=0;n<t.length;n+=3)o.push(t[n]+e,t[n+1],t[n+2]);return o}function w(t,e){if(t.transformed)return t;const o=1<<t.z,n=t.x,i=t.y;for(const s of t.features){if(1===s.type){const t=[];for(let r=0;r<s.geometry.length;r+=2)t.push(v(s.geometry[r],s.geometry[r+1],e,o,n,i));s.geometry=t;continue}const t=[];for(const r of s.geometry){const s=[];for(let t=0;t<r.length;t+=2)s.push(v(r[t],r[t+1],e,o,n,i));t.push(s)}s.geometry=t}return t.transformed=!0,t}function v(t,e,o,n,i,s){return[Math.round(o*(t*n-i)),Math.round(o*(e*n-s))]}function z(t,e,o,n,i){const s=e===i.maxZoom?0:i.tolerance/((1<<e)*i.extent),r={features:[],numPoints:0,numSimplified:0,numFeatures:t.length,source:null,x:o,y:n,z:e,transformed:!1,minX:2,minY:1,maxX:-1,maxY:0};for(const e of t)Y(r,e,s,i);return r}function Y(t,e,o,n){t.minX=Math.min(t.minX,e.minX),t.minY=Math.min(t.minY,e.minY),t.maxX=Math.max(t.maxX,e.maxX),t.maxY=Math.max(t.maxY,e.maxY);let i,s=e.tags||null;switch(e.type){case"Point":case"MultiPoint":{const o=[];for(let n=0;n<e.geometry.length;n+=3)o.push(e.geometry[n],e.geometry[n+1]),t.numPoints++,t.numSimplified++;if(!o.length)return;i={type:1,tags:s,geometry:o};break}case"LineString":{const r=[];if(S(r,e.geometry,t,o,!1,!1),!r.length)return;if(n.lineMetrics){s={};for(const t in e.tags)s[t]=e.tags[t];s.mapbox_clip_start=e.geometry.start/e.geometry.size,s.mapbox_clip_end=e.geometry.end/e.geometry.size}i={type:2,tags:s,geometry:r};break}case"MultiLineString":case"Polygon":{const n=[];for(let i=0;i<e.geometry.length;i++)S(n,e.geometry[i],t,o,"Polygon"===e.type,0===i);if(!n.length)return;i={type:"Polygon"===e.type?3:2,tags:s,geometry:n};break}case"MultiPolygon":{const n=[];for(let i=0;i<e.geometry.length;i++){const s=e.geometry[i];for(let e=0;e<s.length;e++)S(n,s[e],t,o,!0,0===e)}if(!n.length)return;i={type:3,tags:s,geometry:n};break}}null!==e.id&&(i.id=e.id),t.features.push(i)}function S(t,e,o,n,i,s){const r=n*n;if(n>0&&e.size<(i?r:n))return void(o.numPoints+=e.length/3);const l=[];for(let t=0;t<e.length;t+=3)(0===n||e[t+2]>r)&&(o.numSimplified++,l.push(e[t],e[t+1])),o.numPoints++;i&&function(t,e){let o=0;for(let e=0,n=t.length,i=n-2;e<n;i=e,e+=2)o+=(t[e]-t[i])*(t[e+1]+t[i+1]);if(o>0!==e)return;for(let e=0,o=t.length;e<o/2;e+=2){const n=t[e],i=t[e+1];t[e]=t[o-2-e],t[e+1]=t[o-1-e],t[o-2-e]=n,t[o-1-e]=i}}(l,s),t.push(l)}function X(t,e,o){const n=function(t){if(!t)return{remove:new Set,add:new Map,update:new Map};const e={removeAll:t.removeAll,remove:new Set(t.remove||[]),add:new Map(t.add?.map((t=>[t.id,t]))),update:new Map(t.update?.map((t=>[t.id,t])))};return e}(e);let s=[];if(n.removeAll&&(s=t,t=[]),n.remove.size||n.add.size){const e=[];for(const o of t){const{id:t}=o;(n.remove.has(t)||n.add.has(t))&&e.push(o)}if(e.length){s.push(...e);const o=new Set(e.map((t=>t.id)));t=t.filter((t=>!o.has(t.id)))}if(n.add.size){let e=i({type:"FeatureCollection",features:Array.from(n.add.values())},o);e=M(e,o),s.push(...e),t.push(...e)}}if(n.update.size)for(const[e,i]of n.update){const n=t.findIndex((t=>t.id===e));if(-1===n)continue;const r=t[n],l=I(r,i,o);l&&(s.push(r,l),t[n]=l)}return{affected:s,source:t}}function I(t,e,o){const n=!!e.newGeometry,s=e.removeAllProperties||e.removeProperties?.length>0||e.addOrUpdateProperties?.length>0;if(n){let n=i({type:"FeatureCollection",features:[{type:"Feature",id:t.id,geometry:e.newGeometry,properties:s?L(t.tags,e):t.tags}]},o);return n=M(n,o),n[0]}if(s){const o={...t};return o.tags=L(o.tags,e),o}return null}function L(t,e){if(e.removeAllProperties)return{};const o={...t||{}};if(e.removeProperties)for(const t of e.removeProperties)delete o[t];if(e.addOrUpdateProperties)for(const{key:t,value:n}of e.addOrUpdateProperties)o[t]=n;return o}const k={maxZoom:14,indexMaxZoom:5,indexMaxPoints:1e5,tolerance:3,extent:4096,buffer:64,lineMetrics:!1,promoteId:null,generateId:!1,updateable:!1,debug:0};class Z{options;tiles;tileCoords;stats={};total=0;source;constructor(t,e){const o=(e=this.options=Object.assign({},k,e)).debug;if(o&&console.time("preprocess data"),e.maxZoom<0||e.maxZoom>24)throw new Error("maxZoom should be in the 0-24 range");if(e.promoteId&&e.generateId)throw new Error("promoteId and generateId cannot be used together.");let n=i(t,e);this.tiles={},this.tileCoords=[],o&&(console.timeEnd("preprocess data"),console.log("index: maxZoom: %d, maxPoints: %d",e.indexMaxZoom,e.indexMaxPoints),console.time("generate tiles"),this.stats={},this.total=0),n=M(n,e),n.length&&this.splitTile(n,0,0,0),e.updateable&&(this.source=n),o&&(n.length&&console.log("features: %d, points: %d",this.tiles[0].numFeatures,this.tiles[0].numPoints),console.timeEnd("generate tiles"),console.log("tiles generated:",this.total,JSON.stringify(this.stats)))}splitTile(t,e,o,n,i,s,r){const l=[t,e,o,n],a=this.options,c=a.debug;for(;l.length;){n=l.pop(),o=l.pop(),e=l.pop(),t=l.pop();const u=1<<e,f=C(e,o,n);let d=this.tiles[f];if(!d&&(c>1&&console.time("creation"),d=this.tiles[f]=z(t,e,o,n,a),this.tileCoords.push({z:e,x:o,y:n,id:f}),c)){c>1&&(console.log("tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",e,o,n,d.numFeatures,d.numPoints,d.numSimplified),console.timeEnd("creation"));const t=`z${e}`;this.stats[t]=(this.stats[t]||0)+1,this.total++}if(d.source=t,null==i){if(e===a.indexMaxZoom||d.numPoints<=a.indexMaxPoints)continue}else{if(e===a.maxZoom||e===i)continue;if(null!=i){const t=i-e;if(o!==s>>t||n!==r>>t)continue}}if(d.source=null,!t.length)continue;c>1&&console.time("clipping");const p=.5*a.buffer/a.extent,g=.5-p,h=.5+p,y=1+p;let x=null,M=null,P=null,b=null;const w=m(t,u,o-p,o+h,0,d.minX,d.maxX,a),v=m(t,u,o+g,o+y,0,d.minX,d.maxX,a);w&&(x=m(w,u,n-p,n+h,1,d.minY,d.maxY,a),M=m(w,u,n+g,n+y,1,d.minY,d.maxY,a)),v&&(P=m(v,u,n-p,n+h,1,d.minY,d.maxY,a),b=m(v,u,n+g,n+y,1,d.minY,d.maxY,a)),c>1&&console.timeEnd("clipping"),l.push(x||[],e+1,2*o,2*n),l.push(M||[],e+1,2*o,2*n+1),l.push(P||[],e+1,2*o+1,2*n),l.push(b||[],e+1,2*o+1,2*n+1)}}getTile(t,e,o){t=+t,e=+e,o=+o;const n=this.options,{extent:i,debug:s}=n;if(t<0||t>24)return null;const r=1<<t,l=C(t,e=e+r&r-1,o);if(this.tiles[l])return w(this.tiles[l],i);s>1&&console.log("drilling down to z%d-%d-%d",t,e,o);let a,c=t,u=e,m=o;for(;!a&&c>0;)c--,u>>=1,m>>=1,a=this.tiles[C(c,u,m)];return a?.source?(s>1&&(console.log("found parent tile z%d-%d-%d",c,u,m),console.time("drilling down")),this.splitTile(a.source,c,u,m,t,e,o),s>1&&console.timeEnd("drilling down"),this.tiles[l]?w(this.tiles[l],i):null):null}invalidateTiles(t){const e=this.options,{debug:o}=e;let n=1/0,i=-1/0,s=1/0,r=-1/0;for(const e of t)n=Math.min(n,e.minX),i=Math.max(i,e.maxX),s=Math.min(s,e.minY),r=Math.max(r,e.maxY);const l=e.buffer/e.extent,a=new Set;for(const e in this.tiles){const c=this.tiles[e],u=1<<c.z,m=(c.x-l)/u,f=(c.x+1+l)/u,d=(c.y-l)/u,p=(c.y+1+l)/u;if(i<m||n>=f||r<d||s>=p)continue;let g=!1;for(const e of t)if(e.maxX>=m&&e.minX<f&&e.maxY>=d&&e.minY<p){g=!0;break}if(g){if(o){o>1&&console.log("invalidate tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",c.z,c.x,c.y,c.numFeatures,c.numPoints,c.numSimplified);const t=`z${c.z}`;this.stats[t]=(this.stats[t]||0)-1,this.total--}delete this.tiles[e],a.add(e)}}a.size&&(this.tileCoords=this.tileCoords.filter((t=>!a.has(t.id))))}updateData(t){const e=this.options,o=e.debug;if(!e.updateable)throw new Error("to update tile geojson `updateable` option must be set to true");const{affected:n,source:i}=X(this.source,t,e);if(!n.length)return;this.source=i,o>1&&(console.log("invalidating tiles"),console.time("invalidating")),this.invalidateTiles(n),o>1&&console.timeEnd("invalidating");const[s,r,l]=[0,0,0],a=z(this.source,s,r,l,this.options);a.source=this.source;const c=C(s,r,l);if(this.tiles[c]=a,this.tileCoords.push({z:s,x:r,y:l,id:c}),o){const t=`z${s}`;this.stats[t]=(this.stats[t]||0)+1,this.total++}}}function C(t,e,o){return 32*((1<<t)*o+e)+t}return function(t,e){return new Z(t,e)}}));
|
package/dist/geojson-vt.mjs
CHANGED
|
@@ -553,22 +553,23 @@ function transformTile(tile, extent) {
|
|
|
553
553
|
const tx = tile.x;
|
|
554
554
|
const ty = tile.y;
|
|
555
555
|
for (const feature of tile.features) {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
for (let j = 0; j < geom.length; j += 2) {
|
|
561
|
-
feature.geometry.push(transformPoint(geom[j], geom[j + 1], extent, z2, tx, ty));
|
|
556
|
+
if (feature.type === 1) {
|
|
557
|
+
const pointGeometry = [];
|
|
558
|
+
for (let j = 0; j < feature.geometry.length; j += 2) {
|
|
559
|
+
pointGeometry.push(transformPoint(feature.geometry[j], feature.geometry[j + 1], extent, z2, tx, ty));
|
|
562
560
|
}
|
|
561
|
+
feature.geometry = pointGeometry;
|
|
563
562
|
continue;
|
|
564
563
|
}
|
|
565
|
-
|
|
564
|
+
const geometry = [];
|
|
565
|
+
for (const singleGeom of feature.geometry) {
|
|
566
566
|
const ring = [];
|
|
567
567
|
for (let k = 0; k < singleGeom.length; k += 2) {
|
|
568
568
|
ring.push(transformPoint(singleGeom[k], singleGeom[k + 1], extent, z2, tx, ty));
|
|
569
569
|
}
|
|
570
|
-
|
|
570
|
+
geometry.push(ring);
|
|
571
571
|
}
|
|
572
|
+
feature.geometry = geometry;
|
|
572
573
|
}
|
|
573
574
|
tile.transformed = true;
|
|
574
575
|
return tile;
|
|
@@ -612,55 +613,83 @@ function createTile(features, z, tx, ty, options) {
|
|
|
612
613
|
return tile;
|
|
613
614
|
}
|
|
614
615
|
function addFeature(tile, feature, tolerance, options) {
|
|
615
|
-
const simplified = [];
|
|
616
616
|
tile.minX = Math.min(tile.minX, feature.minX);
|
|
617
617
|
tile.minY = Math.min(tile.minY, feature.minY);
|
|
618
618
|
tile.maxX = Math.max(tile.maxX, feature.maxX);
|
|
619
619
|
tile.maxY = Math.max(tile.maxY, feature.maxY);
|
|
620
|
+
let tags = feature.tags || null;
|
|
621
|
+
let tileFeature;
|
|
620
622
|
switch (feature.type) {
|
|
621
623
|
case 'Point':
|
|
622
|
-
case 'MultiPoint':
|
|
624
|
+
case 'MultiPoint': {
|
|
625
|
+
const geometry = [];
|
|
623
626
|
for (let i = 0; i < feature.geometry.length; i += 3) {
|
|
624
|
-
|
|
627
|
+
geometry.push(feature.geometry[i], feature.geometry[i + 1]);
|
|
625
628
|
tile.numPoints++;
|
|
626
629
|
tile.numSimplified++;
|
|
627
630
|
}
|
|
631
|
+
if (!geometry.length)
|
|
632
|
+
return;
|
|
633
|
+
tileFeature = {
|
|
634
|
+
type: 1,
|
|
635
|
+
tags: tags,
|
|
636
|
+
geometry: geometry
|
|
637
|
+
};
|
|
628
638
|
break;
|
|
629
|
-
|
|
630
|
-
|
|
639
|
+
}
|
|
640
|
+
case 'LineString': {
|
|
641
|
+
const geometry = [];
|
|
642
|
+
addLine(geometry, feature.geometry, tile, tolerance, false, false);
|
|
643
|
+
if (!geometry.length)
|
|
644
|
+
return;
|
|
645
|
+
if (options.lineMetrics) {
|
|
646
|
+
tags = {};
|
|
647
|
+
for (const key in feature.tags)
|
|
648
|
+
tags[key] = feature.tags[key];
|
|
649
|
+
// HM TODO: replace with geojsonvt
|
|
650
|
+
tags['mapbox_clip_start'] = feature.geometry.start / feature.geometry.size;
|
|
651
|
+
tags['mapbox_clip_end'] = feature.geometry.end / feature.geometry.size;
|
|
652
|
+
}
|
|
653
|
+
tileFeature = {
|
|
654
|
+
type: 2,
|
|
655
|
+
tags: tags,
|
|
656
|
+
geometry: geometry
|
|
657
|
+
};
|
|
631
658
|
break;
|
|
659
|
+
}
|
|
632
660
|
case 'MultiLineString':
|
|
633
|
-
case 'Polygon':
|
|
661
|
+
case 'Polygon': {
|
|
662
|
+
const geometry = [];
|
|
634
663
|
for (let i = 0; i < feature.geometry.length; i++) {
|
|
635
|
-
addLine(
|
|
664
|
+
addLine(geometry, feature.geometry[i], tile, tolerance, feature.type === 'Polygon', i === 0);
|
|
636
665
|
}
|
|
666
|
+
if (!geometry.length)
|
|
667
|
+
return;
|
|
668
|
+
tileFeature = {
|
|
669
|
+
type: feature.type === 'Polygon' ? 3 : 2,
|
|
670
|
+
tags: tags,
|
|
671
|
+
geometry: geometry
|
|
672
|
+
};
|
|
637
673
|
break;
|
|
638
|
-
|
|
674
|
+
}
|
|
675
|
+
case 'MultiPolygon': {
|
|
676
|
+
const geometry = [];
|
|
639
677
|
for (let k = 0; k < feature.geometry.length; k++) {
|
|
640
678
|
const polygon = feature.geometry[k];
|
|
641
679
|
for (let i = 0; i < polygon.length; i++) {
|
|
642
|
-
addLine(
|
|
680
|
+
addLine(geometry, polygon[i], tile, tolerance, true, i === 0);
|
|
643
681
|
}
|
|
644
682
|
}
|
|
683
|
+
if (!geometry.length)
|
|
684
|
+
return;
|
|
685
|
+
tileFeature = {
|
|
686
|
+
type: 3,
|
|
687
|
+
tags: tags,
|
|
688
|
+
geometry: geometry
|
|
689
|
+
};
|
|
645
690
|
break;
|
|
691
|
+
}
|
|
646
692
|
}
|
|
647
|
-
if (!simplified.length)
|
|
648
|
-
return;
|
|
649
|
-
let tags = feature.tags || null;
|
|
650
|
-
if (feature.type === 'LineString' && options.lineMetrics) {
|
|
651
|
-
tags = {};
|
|
652
|
-
for (const key in feature.tags)
|
|
653
|
-
tags[key] = feature.tags[key];
|
|
654
|
-
// HM TODO: replace with geojsonvt
|
|
655
|
-
tags['mapbox_clip_start'] = feature.geometry.start / feature.geometry.size;
|
|
656
|
-
tags['mapbox_clip_end'] = feature.geometry.end / feature.geometry.size;
|
|
657
|
-
}
|
|
658
|
-
const tileFeature = {
|
|
659
|
-
geometry: simplified,
|
|
660
|
-
type: feature.type === 'Polygon' || feature.type === 'MultiPolygon' ? 3 :
|
|
661
|
-
(feature.type === 'LineString' || feature.type === 'MultiLineString' ? 2 : 1),
|
|
662
|
-
tags
|
|
663
|
-
};
|
|
664
693
|
if (feature.id !== null) {
|
|
665
694
|
tileFeature.id = feature.id;
|
|
666
695
|
}
|