@maplibre/geojson-vt 6.0.2 → 6.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/dist/difference.d.ts +11 -4
- package/dist/difference.d.ts.map +1 -1
- package/dist/geojson-vt-dev.js +43 -52
- package/dist/geojson-vt.js +1 -1
- package/dist/geojson-vt.mjs +43 -52
- package/dist/geojson-vt.mjs.map +1 -1
- package/package.json +3 -3
- package/src/difference.ts +51 -46
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maplibre/geojson-vt",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.4",
|
|
4
4
|
"description": "Slice GeoJSON data into vector tiles efficiently",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@types/benchmark": "^2.1.5",
|
|
32
32
|
"@types/geojson": "^7946.0.16",
|
|
33
33
|
"@types/node": "^25.5.0",
|
|
34
|
-
"@vitest/coverage-v8": "^4.0
|
|
34
|
+
"@vitest/coverage-v8": "^4.1.0",
|
|
35
35
|
"benchmark": "^2.1.4",
|
|
36
36
|
"eslint": "^10.0.3",
|
|
37
37
|
"rollup": "^4.59.0",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"tsx": "^4.21.0",
|
|
40
40
|
"typedoc": "^0.28.17",
|
|
41
41
|
"typescript": "^5.9.3",
|
|
42
|
-
"typescript-eslint": "^8.57.
|
|
42
|
+
"typescript-eslint": "^8.57.1",
|
|
43
43
|
"vitest": "^4.0.17"
|
|
44
44
|
},
|
|
45
45
|
"license": "ISC",
|
package/src/difference.ts
CHANGED
|
@@ -47,6 +47,17 @@ export type GeoJSONVTFeatureDiff = {
|
|
|
47
47
|
}[];
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
export type ApplySourceDiffResult = {
|
|
51
|
+
/**
|
|
52
|
+
* The features affected by this update, which should be used to invalidate tiles
|
|
53
|
+
*/
|
|
54
|
+
affected: GeoJSONVTInternalFeature[];
|
|
55
|
+
/**
|
|
56
|
+
* The updated source data, which should replace the existing source data in the index
|
|
57
|
+
*/
|
|
58
|
+
source: GeoJSONVTInternalFeature[];
|
|
59
|
+
};
|
|
60
|
+
|
|
50
61
|
type HashedGeoJSONVTSourceDiff = {
|
|
51
62
|
removeAll?: boolean | undefined;
|
|
52
63
|
remove: Set<string | number>;
|
|
@@ -61,91 +72,86 @@ type HashedGeoJSONVTSourceDiff = {
|
|
|
61
72
|
* @param options
|
|
62
73
|
* @returns
|
|
63
74
|
*/
|
|
64
|
-
export function applySourceDiff(source: GeoJSONVTInternalFeature[], dataDiff: GeoJSONVTSourceDiff, options: GeoJSONVTOptions) {
|
|
65
|
-
|
|
75
|
+
export function applySourceDiff(source: GeoJSONVTInternalFeature[], dataDiff: GeoJSONVTSourceDiff, options: GeoJSONVTOptions): ApplySourceDiffResult {
|
|
66
76
|
// convert diff to sets/maps for o(1) lookups
|
|
67
77
|
const diff = diffToHashed(dataDiff);
|
|
68
78
|
|
|
69
|
-
// collection for features that will be affected by this update
|
|
79
|
+
// collection for features that will be affected by this update and used to invalidate tiles
|
|
70
80
|
let affected: GeoJSONVTInternalFeature[] = [];
|
|
71
81
|
|
|
72
|
-
// full removal - clear everything before applying diff
|
|
73
82
|
if (diff.removeAll) {
|
|
74
83
|
affected = source;
|
|
75
84
|
source = [];
|
|
76
85
|
}
|
|
77
86
|
|
|
78
|
-
// remove/add features and collect affected ones
|
|
79
87
|
if (diff.remove.size || diff.add.size) {
|
|
80
88
|
const removeFeatures = [];
|
|
81
89
|
|
|
82
|
-
//
|
|
90
|
+
// Collect features to remove (explicit removals + replacements via add)
|
|
83
91
|
for (const feature of source) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// explicit feature removal
|
|
87
|
-
if (diff.remove.has(id)) {
|
|
88
|
-
removeFeatures.push(feature);
|
|
89
|
-
// feature with duplicate id being added
|
|
90
|
-
} else if (diff.add.has(id)) {
|
|
92
|
+
if (diff.remove.has(feature.id) || diff.add.has(feature.id)) {
|
|
91
93
|
removeFeatures.push(feature);
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
// collect affected and remove from source
|
|
96
97
|
if (removeFeatures.length) {
|
|
97
98
|
affected.push(...removeFeatures);
|
|
98
|
-
|
|
99
99
|
const removeIds = new Set(removeFeatures.map(f => f.id));
|
|
100
100
|
source = source.filter(f => !removeIds.has(f.id));
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
// convert and add new features
|
|
104
103
|
if (diff.add.size) {
|
|
105
|
-
// projects and adds simplification info
|
|
106
104
|
let addFeatures = convertToInternal({type: 'FeatureCollection', features: Array.from(diff.add.values())}, options);
|
|
107
|
-
|
|
108
|
-
// wraps features (ie extreme west and extreme east)
|
|
109
105
|
addFeatures = wrap(addFeatures, options);
|
|
110
|
-
|
|
111
106
|
affected.push(...addFeatures);
|
|
112
107
|
source.push(...addFeatures);
|
|
113
108
|
}
|
|
114
109
|
}
|
|
115
110
|
|
|
116
111
|
if (diff.update.size) {
|
|
112
|
+
// Features can be duplicated across the antimeridian (wrap) in a single tile, so must update all instances with the same id
|
|
117
113
|
for (const [id, update] of diff.update) {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const feature
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
114
|
+
const oldFeatures = [];
|
|
115
|
+
const keepFeatures = [];
|
|
116
|
+
|
|
117
|
+
for (const feature of source) {
|
|
118
|
+
if (feature.id === id) {
|
|
119
|
+
oldFeatures.push(feature);
|
|
120
|
+
} else {
|
|
121
|
+
keepFeatures.push(feature);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (!oldFeatures.length) continue;
|
|
126
125
|
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
const updatedFeatures = getUpdatedFeatures(oldFeatures, update, options);
|
|
127
|
+
if (!updatedFeatures.length) continue;
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
affected.push(...oldFeatures, ...updatedFeatures);
|
|
130
|
+
keepFeatures.push(...updatedFeatures);
|
|
131
|
+
source = keepFeatures;
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
return {affected, source};
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Gets updated simplified feature(s) based on a diff update object.
|
|
140
|
+
* @param vtFeatures - the original features
|
|
141
|
+
* @param update - the update object to apply
|
|
142
|
+
* @param options - the options to use for the wrap method
|
|
143
|
+
* @returns Updated features. If geometry is updated, returns new feature(s) converted from geojson and wrapped. If only properties are updated, returns feature(s) with tags updated.
|
|
144
|
+
*/
|
|
145
|
+
function getUpdatedFeatures(vtFeatures: GeoJSONVTInternalFeature[], update: GeoJSONVTFeatureDiff, options: GeoJSONVTOptions): GeoJSONVTInternalFeature[] {
|
|
140
146
|
const changeGeometry = !!update.newGeometry;
|
|
141
|
-
|
|
142
147
|
const changeProps =
|
|
143
148
|
update.removeAllProperties ||
|
|
144
149
|
update.removeProperties?.length > 0 ||
|
|
145
150
|
update.addOrUpdateProperties?.length > 0;
|
|
146
151
|
|
|
147
|
-
// if geometry changed, need to create new geojson feature and convert to
|
|
152
|
+
// if geometry changed, need to create a new geojson feature and convert to internal format
|
|
148
153
|
if (changeGeometry) {
|
|
154
|
+
const vtFeature = vtFeatures[0];
|
|
149
155
|
const geojsonFeature = {
|
|
150
156
|
type: 'Feature' as const,
|
|
151
157
|
id: vtFeature.id,
|
|
@@ -153,23 +159,22 @@ function getUpdatedFeature(vtFeature: GeoJSONVTInternalFeature, update: GeoJSONV
|
|
|
153
159
|
properties: changeProps ? applyPropertyUpdates(vtFeature.tags, update) : vtFeature.tags
|
|
154
160
|
};
|
|
155
161
|
|
|
156
|
-
// projects and adds simplification info
|
|
157
162
|
let features = convertToInternal({type: 'FeatureCollection', features: [geojsonFeature]}, options);
|
|
158
|
-
|
|
159
|
-
// wraps features (ie extreme west and extreme east)
|
|
160
163
|
features = wrap(features, options);
|
|
161
|
-
|
|
162
|
-
return features[0];
|
|
164
|
+
return features;
|
|
163
165
|
}
|
|
164
166
|
|
|
165
|
-
// only properties changed - update tags directly
|
|
166
167
|
if (changeProps) {
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
const updated = [];
|
|
169
|
+
for (const vtFeature of vtFeatures) {
|
|
170
|
+
const feature = {...vtFeature};
|
|
171
|
+
feature.tags = applyPropertyUpdates(feature.tags, update);
|
|
172
|
+
updated.push(feature);
|
|
173
|
+
}
|
|
174
|
+
return updated;
|
|
170
175
|
}
|
|
171
176
|
|
|
172
|
-
return
|
|
177
|
+
return [];
|
|
173
178
|
}
|
|
174
179
|
|
|
175
180
|
/**
|