@map-colonies/mc-utils 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -67
- package/dist/arrays/index.d.ts +1 -1
- package/dist/arrays/index.d.ts.map +0 -0
- package/dist/arrays/index.js +17 -17
- package/dist/arrays/index.js.map +0 -0
- package/dist/arrays/subGroups.d.ts +8 -8
- package/dist/arrays/subGroups.d.ts.map +0 -0
- package/dist/arrays/subGroups.js +33 -138
- package/dist/arrays/subGroups.js.map +1 -1
- package/dist/communication/http/httpClient.d.ts +29 -29
- package/dist/communication/http/httpClient.d.ts.map +0 -0
- package/dist/communication/http/httpClient.js +317 -434
- package/dist/communication/http/httpClient.js.map +1 -1
- package/dist/communication/http/index.d.ts +1 -1
- package/dist/communication/http/index.d.ts.map +0 -0
- package/dist/communication/http/index.js +17 -17
- package/dist/communication/http/index.js.map +0 -0
- package/dist/communication/index.d.ts +1 -1
- package/dist/communication/index.d.ts.map +0 -0
- package/dist/communication/index.js +17 -17
- package/dist/communication/index.js.map +0 -0
- package/dist/dateTime/getUTCDate.d.ts +1 -1
- package/dist/dateTime/getUTCDate.d.ts.map +0 -0
- package/dist/dateTime/getUTCDate.js +10 -10
- package/dist/dateTime/getUTCDate.js.map +1 -1
- package/dist/dateTime/index.d.ts +1 -1
- package/dist/dateTime/index.d.ts.map +0 -0
- package/dist/dateTime/index.js +17 -17
- package/dist/dateTime/index.js.map +0 -0
- package/dist/geo/bboxUtils.d.ts +23 -23
- package/dist/geo/bboxUtils.d.ts.map +0 -0
- package/dist/geo/bboxUtils.js +89 -89
- package/dist/geo/bboxUtils.js.map +1 -1
- package/dist/geo/geoConvertor.d.ts +18 -18
- package/dist/geo/geoConvertor.d.ts.map +0 -0
- package/dist/geo/geoConvertor.js +49 -51
- package/dist/geo/geoConvertor.js.map +1 -1
- package/dist/geo/geoHash.d.ts +24 -24
- package/dist/geo/geoHash.d.ts.map +0 -0
- package/dist/geo/geoHash.js +134 -274
- package/dist/geo/geoHash.js.map +1 -1
- package/dist/geo/geoIntersection.d.ts +19 -19
- package/dist/geo/geoIntersection.d.ts.map +0 -0
- package/dist/geo/geoIntersection.js +70 -70
- package/dist/geo/geoIntersection.js.map +1 -1
- package/dist/geo/index.d.ts +8 -8
- package/dist/geo/index.d.ts.map +0 -0
- package/dist/geo/index.js +24 -24
- package/dist/geo/index.js.map +0 -0
- package/dist/geo/tileBatcher.d.ts +8 -8
- package/dist/geo/tileBatcher.d.ts.map +0 -0
- package/dist/geo/tileBatcher.js +97 -193
- package/dist/geo/tileBatcher.js.map +1 -1
- package/dist/geo/tileRanger.d.ts +46 -46
- package/dist/geo/tileRanger.d.ts.map +0 -0
- package/dist/geo/tileRanger.js +232 -383
- package/dist/geo/tileRanger.js.map +1 -1
- package/dist/geo/tiles.d.ts +82 -82
- package/dist/geo/tiles.d.ts.map +0 -0
- package/dist/geo/tiles.js +219 -246
- package/dist/geo/tiles.js.map +1 -1
- package/dist/geo/tilesGenerator.d.ts +2 -2
- package/dist/geo/tilesGenerator.d.ts.map +0 -0
- package/dist/geo/tilesGenerator.js +17 -111
- package/dist/geo/tilesGenerator.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -21
- package/dist/index.js.map +1 -1
- package/dist/models/enums/gdal/dataType.d.ts +16 -16
- package/dist/models/enums/gdal/dataType.d.ts.map +0 -0
- package/dist/models/enums/gdal/dataType.js +20 -20
- package/dist/models/enums/gdal/dataType.js.map +0 -0
- package/dist/models/enums/gdal/index.d.ts +2 -2
- package/dist/models/enums/gdal/index.d.ts.map +0 -0
- package/dist/models/enums/gdal/index.js +18 -18
- package/dist/models/enums/gdal/index.js.map +0 -0
- package/dist/models/enums/gdal/resamplingMethod.d.ts +16 -16
- package/dist/models/enums/gdal/resamplingMethod.d.ts.map +0 -0
- package/dist/models/enums/gdal/resamplingMethod.js +20 -20
- package/dist/models/enums/gdal/resamplingMethod.js.map +0 -0
- package/dist/models/enums/geo/index.d.ts +1 -1
- package/dist/models/enums/geo/index.d.ts.map +0 -0
- package/dist/models/enums/geo/index.js +17 -17
- package/dist/models/enums/geo/index.js.map +0 -0
- package/dist/models/enums/geo/tileOrigin.d.ts +7 -7
- package/dist/models/enums/geo/tileOrigin.d.ts.map +0 -0
- package/dist/models/enums/geo/tileOrigin.js +11 -11
- package/dist/models/enums/geo/tileOrigin.js.map +0 -0
- package/dist/models/enums/index.d.ts +2 -2
- package/dist/models/enums/index.d.ts.map +0 -0
- package/dist/models/enums/index.js +18 -18
- package/dist/models/enums/index.js.map +0 -0
- package/dist/models/index.d.ts +2 -2
- package/dist/models/index.d.ts.map +0 -0
- package/dist/models/index.js +18 -18
- package/dist/models/index.js.map +0 -0
- package/dist/models/interfaces/geo/iPoint.d.ts +7 -7
- package/dist/models/interfaces/geo/iPoint.d.ts.map +0 -0
- package/dist/models/interfaces/geo/iPoint.js +2 -2
- package/dist/models/interfaces/geo/iPoint.js.map +0 -0
- package/dist/models/interfaces/geo/iTile.d.ts +15 -15
- package/dist/models/interfaces/geo/iTile.d.ts.map +0 -0
- package/dist/models/interfaces/geo/iTile.js +2 -2
- package/dist/models/interfaces/geo/iTile.js.map +0 -0
- package/dist/models/interfaces/geo/index.d.ts +2 -2
- package/dist/models/interfaces/geo/index.d.ts.map +0 -0
- package/dist/models/interfaces/geo/index.js +18 -18
- package/dist/models/interfaces/geo/index.js.map +0 -0
- package/dist/models/interfaces/index.d.ts +1 -1
- package/dist/models/interfaces/index.d.ts.map +0 -0
- package/dist/models/interfaces/index.js +17 -17
- package/dist/models/interfaces/index.js.map +0 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/timeout.d.ts +4 -1
- package/dist/utils/timeout.d.ts.map +1 -1
- package/dist/utils/timeout.js +22 -47
- package/dist/utils/timeout.js.map +1 -1
- package/package.json +79 -79
package/dist/geo/tileRanger.js
CHANGED
|
@@ -1,384 +1,233 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
dx = boundingRange.maxX - boundingRange.minX;
|
|
235
|
-
dy = boundingRange.maxY - boundingRange.minY;
|
|
236
|
-
minXZoom = Math.max(Math.floor(Math.log2(1 << (zoom + 1)) / dx) - 1, 0);
|
|
237
|
-
minYZoom = Math.max(Math.floor(Math.log2(1 << zoom) / dy), 0);
|
|
238
|
-
minZoom = Math.min(minXZoom, minYZoom);
|
|
239
|
-
if (verbose) {
|
|
240
|
-
console.log("MinZoom: ".concat(minZoom));
|
|
241
|
-
}
|
|
242
|
-
minimalRange = (0, bboxUtils_1.bboxToTileRange)(bbox, minZoom);
|
|
243
|
-
x = minimalRange.minX;
|
|
244
|
-
_a.label = 1;
|
|
245
|
-
case 1:
|
|
246
|
-
if (!(x < minimalRange.maxX)) return [3 /*break*/, 12];
|
|
247
|
-
y = minimalRange.minY;
|
|
248
|
-
_a.label = 2;
|
|
249
|
-
case 2:
|
|
250
|
-
if (!(y < minimalRange.maxY)) return [3 /*break*/, 11];
|
|
251
|
-
tile = { x: x, y: y, zoom: minimalRange.zoom };
|
|
252
|
-
intersection = intersectionFunction(tile, intersectionTarget);
|
|
253
|
-
if (verbose) {
|
|
254
|
-
console.log("Tile X: ".concat(tile.x, ", Y: ").concat(tile.y, " zoom ").concat(tile.zoom, ", intersection: ").concat(intersection));
|
|
255
|
-
}
|
|
256
|
-
if (!(intersection === TileIntersectionState.FULL)) return [3 /*break*/, 6];
|
|
257
|
-
tileRange = this.tileToRange(tile, zoom);
|
|
258
|
-
if (verbose) {
|
|
259
|
-
console.log("return BBOX tile range zoom: ".concat(tileRange.zoom, " : X ").concat(tileRange.minX, " - ").concat(tileRange.maxX, " : Y ").concat(tileRange.minY, " - ").concat(tileRange.maxY));
|
|
260
|
-
}
|
|
261
|
-
return [4 /*yield*/, __await(Promise.resolve(tileRange))];
|
|
262
|
-
case 3: return [4 /*yield*/, __await.apply(void 0, [_a.sent()])];
|
|
263
|
-
case 4: return [4 /*yield*/, _a.sent()];
|
|
264
|
-
case 5:
|
|
265
|
-
_a.sent();
|
|
266
|
-
return [3 /*break*/, 10];
|
|
267
|
-
case 6:
|
|
268
|
-
if (!(intersection === TileIntersectionState.PARTIAL)) return [3 /*break*/, 10];
|
|
269
|
-
return [4 /*yield*/, __await(Promise.resolve(this.optimizeHash(tile, zoom, intersectionTarget, intersectionFunction, verbose)))];
|
|
270
|
-
case 7:
|
|
271
|
-
/// if it partly covered:
|
|
272
|
-
// calculate the sub tiles contained in the current tile (in the next zoom level)
|
|
273
|
-
// for every sub tile recursively run step 6
|
|
274
|
-
//optimize partial base hashes
|
|
275
|
-
return [5 /*yield**/, __values(__asyncDelegator.apply(void 0, [__asyncValues.apply(void 0, [_a.sent()])]))];
|
|
276
|
-
case 8:
|
|
277
|
-
/// if it partly covered:
|
|
278
|
-
// calculate the sub tiles contained in the current tile (in the next zoom level)
|
|
279
|
-
// for every sub tile recursively run step 6
|
|
280
|
-
//optimize partial base hashes
|
|
281
|
-
return [4 /*yield*/, __await.apply(void 0, [_a.sent()])];
|
|
282
|
-
case 9:
|
|
283
|
-
/// if it partly covered:
|
|
284
|
-
// calculate the sub tiles contained in the current tile (in the next zoom level)
|
|
285
|
-
// for every sub tile recursively run step 6
|
|
286
|
-
//optimize partial base hashes
|
|
287
|
-
_a.sent();
|
|
288
|
-
_a.label = 10;
|
|
289
|
-
case 10:
|
|
290
|
-
y++;
|
|
291
|
-
return [3 /*break*/, 2];
|
|
292
|
-
case 11:
|
|
293
|
-
x++;
|
|
294
|
-
return [3 /*break*/, 1];
|
|
295
|
-
case 12: return [2 /*return*/];
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
};
|
|
300
|
-
/**
|
|
301
|
-
* generate tile
|
|
302
|
-
* @param tile tile to get all intersecting tiles from
|
|
303
|
-
* @param targetZoom target tiles zoom level
|
|
304
|
-
* @param intersectionTarget original zoom level and footprint to intersect
|
|
305
|
-
* @param intersectionFunction the intersection function to be called
|
|
306
|
-
*/
|
|
307
|
-
TileRanger.prototype.optimizeHash = function (tile, targetZoom, intersectionTarget, intersectionFunction, verbose) {
|
|
308
|
-
var tiles, tiles_2, tiles_2_1, subTile, intersection, tileRange, e_1_1;
|
|
309
|
-
var e_1, _a;
|
|
310
|
-
if (verbose === void 0) { verbose = false; }
|
|
311
|
-
return __generator(this, function (_b) {
|
|
312
|
-
switch (_b.label) {
|
|
313
|
-
case 0:
|
|
314
|
-
/// generate from a tile the next zoom level tiles that compose the tile
|
|
315
|
-
if (verbose) {
|
|
316
|
-
console.log("optimizeHash: Tile X: ".concat(tile.x, ", Y: ").concat(tile.y, " zoom ").concat(tile.zoom, ", intersectionTarget ").concat(intersectionTarget.maxZoom, ", - generate from a tile the next zoom level tiles that compose the tile"));
|
|
317
|
-
}
|
|
318
|
-
tiles = this.generateSubTiles(tile);
|
|
319
|
-
_b.label = 1;
|
|
320
|
-
case 1:
|
|
321
|
-
_b.trys.push([1, 8, 9, 10]);
|
|
322
|
-
tiles_2 = __values(tiles), tiles_2_1 = tiles_2.next();
|
|
323
|
-
_b.label = 2;
|
|
324
|
-
case 2:
|
|
325
|
-
if (!!tiles_2_1.done) return [3 /*break*/, 7];
|
|
326
|
-
subTile = tiles_2_1.value;
|
|
327
|
-
intersection = intersectionFunction(subTile, intersectionTarget);
|
|
328
|
-
if (verbose) {
|
|
329
|
-
console.log("Tile X: ".concat(subTile.x, ", Y: ").concat(subTile.y, " zoom ").concat(subTile.zoom, ", intersection: ").concat(intersection));
|
|
330
|
-
}
|
|
331
|
-
if (!(intersection === TileIntersectionState.FULL)) return [3 /*break*/, 4];
|
|
332
|
-
tileRange = this.tileToRange(subTile, targetZoom);
|
|
333
|
-
if (verbose) {
|
|
334
|
-
console.log("return BBOX tile range zoom: ".concat(tileRange.zoom, " : X ").concat(tileRange.minX, " - ").concat(tileRange.maxX, " : Y ").concat(tileRange.minY, " - ").concat(tileRange.maxY));
|
|
335
|
-
}
|
|
336
|
-
return [4 /*yield*/, tileRange];
|
|
337
|
-
case 3:
|
|
338
|
-
_b.sent();
|
|
339
|
-
return [3 /*break*/, 6];
|
|
340
|
-
case 4:
|
|
341
|
-
if (!(intersection === TileIntersectionState.PARTIAL)) return [3 /*break*/, 6];
|
|
342
|
-
/// if it partly covered:
|
|
343
|
-
// calculate the sub tiles contained in the current tile (in the next zoom level) - recursive
|
|
344
|
-
return [5 /*yield**/, __values(this.optimizeHash(subTile, targetZoom, intersectionTarget, intersectionFunction, verbose))];
|
|
345
|
-
case 5:
|
|
346
|
-
/// if it partly covered:
|
|
347
|
-
// calculate the sub tiles contained in the current tile (in the next zoom level) - recursive
|
|
348
|
-
_b.sent();
|
|
349
|
-
_b.label = 6;
|
|
350
|
-
case 6:
|
|
351
|
-
tiles_2_1 = tiles_2.next();
|
|
352
|
-
return [3 /*break*/, 2];
|
|
353
|
-
case 7: return [3 /*break*/, 10];
|
|
354
|
-
case 8:
|
|
355
|
-
e_1_1 = _b.sent();
|
|
356
|
-
e_1 = { error: e_1_1 };
|
|
357
|
-
return [3 /*break*/, 10];
|
|
358
|
-
case 9:
|
|
359
|
-
try {
|
|
360
|
-
if (tiles_2_1 && !tiles_2_1.done && (_a = tiles_2.return)) _a.call(tiles_2);
|
|
361
|
-
}
|
|
362
|
-
finally { if (e_1) throw e_1.error; }
|
|
363
|
-
return [7 /*endfinally*/];
|
|
364
|
-
case 10: return [2 /*return*/];
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
};
|
|
368
|
-
TileRanger.prototype.generateSubTiles = function (tile) {
|
|
369
|
-
var tile0 = { x: tile.x << 1, y: tile.y << 1, zoom: tile.zoom + 1 };
|
|
370
|
-
var tile1 = { x: tile0.x + 1, y: tile0.y, zoom: tile0.zoom };
|
|
371
|
-
var tile2 = { x: tile0.x, y: tile0.y + 1, zoom: tile0.zoom };
|
|
372
|
-
var tile3 = { x: tile0.x + 1, y: tile0.y + 1, zoom: tile0.zoom };
|
|
373
|
-
var tiles = [tile0, tile1, tile2, tile3];
|
|
374
|
-
return tiles;
|
|
375
|
-
};
|
|
376
|
-
TileRanger.prototype.isBbox = function (footprint) {
|
|
377
|
-
var bbox = (0, turf_1.bbox)(footprint);
|
|
378
|
-
var bboxPoly = (0, turf_1.bboxPolygon)(bbox);
|
|
379
|
-
return (0, turf_1.booleanEqual)(footprint, bboxPoly);
|
|
380
|
-
};
|
|
381
|
-
return TileRanger;
|
|
382
|
-
}());
|
|
383
|
-
exports.TileRanger = TileRanger;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TileRanger = void 0;
|
|
4
|
+
const turf_1 = require("@turf/turf");
|
|
5
|
+
const bboxUtils_1 = require("./bboxUtils");
|
|
6
|
+
const tiles_1 = require("./tiles");
|
|
7
|
+
const tilesGenerator_1 = require("./tilesGenerator");
|
|
8
|
+
var TileIntersectionState;
|
|
9
|
+
(function (TileIntersectionState) {
|
|
10
|
+
TileIntersectionState["FULL"] = "full";
|
|
11
|
+
TileIntersectionState["PARTIAL"] = "partial";
|
|
12
|
+
TileIntersectionState["NONE"] = "none";
|
|
13
|
+
})(TileIntersectionState || (TileIntersectionState = {}));
|
|
14
|
+
/**
|
|
15
|
+
* class for generating and decoding tile hashes
|
|
16
|
+
*/
|
|
17
|
+
class TileRanger {
|
|
18
|
+
/**
|
|
19
|
+
* converts tile to tile range of specified zoom level
|
|
20
|
+
* @param tile
|
|
21
|
+
* @param zoom target tile range zoom
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
24
|
+
tileToRange(tile, zoom) {
|
|
25
|
+
let minX, minY, maxX, maxY;
|
|
26
|
+
minX = tile.x;
|
|
27
|
+
maxX = tile.x + 1;
|
|
28
|
+
minY = tile.y;
|
|
29
|
+
maxY = tile.y + 1;
|
|
30
|
+
if (tile.zoom < zoom) {
|
|
31
|
+
const dz = zoom - tile.zoom;
|
|
32
|
+
minX = minX << dz;
|
|
33
|
+
maxX = maxX << dz;
|
|
34
|
+
minY = minY << dz;
|
|
35
|
+
maxY = maxY << dz;
|
|
36
|
+
}
|
|
37
|
+
else if (tile.zoom > zoom) {
|
|
38
|
+
const dz = tile.zoom - zoom;
|
|
39
|
+
minX = minX >> dz;
|
|
40
|
+
minY = minY >> dz;
|
|
41
|
+
maxX = minX + 1;
|
|
42
|
+
maxY = minY + 1;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
minX,
|
|
46
|
+
minY,
|
|
47
|
+
maxX,
|
|
48
|
+
maxY,
|
|
49
|
+
zoom,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* generate tile hashes
|
|
54
|
+
* @param footprint footprint to cover with generated tile hashes
|
|
55
|
+
* @param zoom max hash zoom
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
async *encodeFootprint(footprint, zoom, verbose = false) {
|
|
59
|
+
////////////////////////////////
|
|
60
|
+
/// Step 1: check if the footprint is identical to its bbox
|
|
61
|
+
////////////////////////////////
|
|
62
|
+
if (verbose) {
|
|
63
|
+
console.log('encode footprint');
|
|
64
|
+
}
|
|
65
|
+
////////////////////////////////
|
|
66
|
+
/// Step 2: convert footprint to BBOX
|
|
67
|
+
////////////////////////////////
|
|
68
|
+
const bbox = (0, turf_1.bbox)(footprint);
|
|
69
|
+
if (this.isBbox(footprint)) {
|
|
70
|
+
// if it is convert its bbox directly to tile range and return it (bbox to tiles conversion is fast and direct mathematical conversion)
|
|
71
|
+
const tileRange = (0, bboxUtils_1.bboxToTileRange)(bbox, zoom);
|
|
72
|
+
if (verbose) {
|
|
73
|
+
console.log(`footprint is identical to its bbox - return BBOX tile range zoom: ${tileRange.zoom} : X ${tileRange.minX} - ${tileRange.maxX} : Y ${tileRange.minY} - ${tileRange.maxY}`);
|
|
74
|
+
}
|
|
75
|
+
yield await Promise.resolve(tileRange);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const intersectionParams = {
|
|
79
|
+
footprint,
|
|
80
|
+
maxZoom: zoom,
|
|
81
|
+
};
|
|
82
|
+
if (verbose) {
|
|
83
|
+
console.log('footprint is different from its bbox - generateRanges');
|
|
84
|
+
}
|
|
85
|
+
yield* await Promise.resolve(this.generateRanges(bbox, zoom, intersectionParams, this.tileFootprintIntersection, verbose));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
generateTiles(area, zoom) {
|
|
89
|
+
let gen;
|
|
90
|
+
if (Array.isArray(area)) {
|
|
91
|
+
const tileRangeGen = async function* tileRangeGenerator() {
|
|
92
|
+
yield await Promise.resolve((0, bboxUtils_1.bboxToTileRange)(area, zoom));
|
|
93
|
+
};
|
|
94
|
+
gen = tileRangeGen();
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
gen = this.encodeFootprint(area, zoom);
|
|
98
|
+
}
|
|
99
|
+
return (0, tilesGenerator_1.tilesGenerator)(gen);
|
|
100
|
+
}
|
|
101
|
+
async *generateRanges(bbox, zoom, intersectionTarget, intersectionFunction, verbose = false) {
|
|
102
|
+
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
103
|
+
/// Step 3: Convert the bbox to tile range of the requested zoom
|
|
104
|
+
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
105
|
+
if (verbose) {
|
|
106
|
+
console.log('Convert the bbox to tile range of the requested zoom');
|
|
107
|
+
}
|
|
108
|
+
const boundingRange = (0, bboxUtils_1.bboxToTileRange)(bbox, zoom);
|
|
109
|
+
if (verbose) {
|
|
110
|
+
const bboxString = `BBOX[0]: ${bbox[0]}, BBOX[1]: ${bbox[1]}, BBOX[2]: ${bbox[2]}, BBOX[3]: ${bbox[3]}`;
|
|
111
|
+
console.log(`${bboxString}, Zoom: ${zoom}, bounding range: minX: ${boundingRange.minX}, maxX: ${boundingRange.maxX}, minY: ${boundingRange.minY}, maxY: ${boundingRange.maxY}`);
|
|
112
|
+
}
|
|
113
|
+
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
114
|
+
/// Step 4: Use range size to calculate zoom level where the target area is smaller then 1 tile
|
|
115
|
+
/// (use zoom zero in-case there is no such zoom, for example in global bbox).
|
|
116
|
+
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
117
|
+
// find minimal zoom where the the area can be converted by area the size of single tile to skip levels that can't have full hashes
|
|
118
|
+
if (verbose) {
|
|
119
|
+
console.log("find minimal zoom where the the area can be converted by area the size of single tile to skip levels that can't have full hashes");
|
|
120
|
+
}
|
|
121
|
+
const dx = boundingRange.maxX - boundingRange.minX;
|
|
122
|
+
const dy = boundingRange.maxY - boundingRange.minY;
|
|
123
|
+
const minXZoom = Math.max(Math.floor(Math.log2(1 << (zoom + 1)) / dx) - 1, 0);
|
|
124
|
+
const minYZoom = Math.max(Math.floor(Math.log2(1 << zoom) / dy), 0);
|
|
125
|
+
const minZoom = Math.min(minXZoom, minYZoom);
|
|
126
|
+
if (verbose) {
|
|
127
|
+
console.log(`MinZoom: ${minZoom}`);
|
|
128
|
+
}
|
|
129
|
+
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
130
|
+
/// Step 5: convert the requested bbox to to tile range of the zoom level calculated in step 3 (this reduce the iteration required for the calculation)
|
|
131
|
+
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
132
|
+
//find base hashes
|
|
133
|
+
const minimalRange = (0, bboxUtils_1.bboxToTileRange)(bbox, minZoom);
|
|
134
|
+
for (let x = minimalRange.minX; x < minimalRange.maxX; x++) {
|
|
135
|
+
for (let y = minimalRange.minY; y < minimalRange.maxY; y++) {
|
|
136
|
+
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
137
|
+
/// Step 6: for every tile in the current range:
|
|
138
|
+
/// Step 7: check the tile intersection with the footprint
|
|
139
|
+
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
140
|
+
const tile = { x, y, zoom: minimalRange.zoom };
|
|
141
|
+
const intersection = intersectionFunction(tile, intersectionTarget);
|
|
142
|
+
if (verbose) {
|
|
143
|
+
console.log(`Tile X: ${tile.x}, Y: ${tile.y} zoom ${tile.zoom}, intersection: ${intersection}`);
|
|
144
|
+
}
|
|
145
|
+
/// if it is completely covered or the tile is in the requested zoom:
|
|
146
|
+
if (intersection === TileIntersectionState.FULL) {
|
|
147
|
+
/// convert it to tile range of the requested resolution
|
|
148
|
+
/// add the range to the result set (yield is used for lazy calculation to improve memory usage)
|
|
149
|
+
const tileRange = this.tileToRange(tile, zoom);
|
|
150
|
+
if (verbose) {
|
|
151
|
+
console.log(`return BBOX tile range zoom: ${tileRange.zoom} : X ${tileRange.minX} - ${tileRange.maxX} : Y ${tileRange.minY} - ${tileRange.maxY}`);
|
|
152
|
+
}
|
|
153
|
+
yield await Promise.resolve(tileRange);
|
|
154
|
+
}
|
|
155
|
+
else if (intersection === TileIntersectionState.PARTIAL) {
|
|
156
|
+
/// if it partly covered:
|
|
157
|
+
// calculate the sub tiles contained in the current tile (in the next zoom level)
|
|
158
|
+
// for every sub tile recursively run step 6
|
|
159
|
+
//optimize partial base hashes
|
|
160
|
+
yield* await Promise.resolve(this.optimizeHash(tile, zoom, intersectionTarget, intersectionFunction, verbose));
|
|
161
|
+
}
|
|
162
|
+
/// else do nothing as this tiles aren't intersected with the original footprint
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* generate tile
|
|
168
|
+
* @param tile tile to get all intersecting tiles from
|
|
169
|
+
* @param targetZoom target tiles zoom level
|
|
170
|
+
* @param intersectionTarget original zoom level and footprint to intersect
|
|
171
|
+
* @param intersectionFunction the intersection function to be called
|
|
172
|
+
*/
|
|
173
|
+
*optimizeHash(tile, targetZoom, intersectionTarget, intersectionFunction, verbose = false) {
|
|
174
|
+
/// generate from a tile the next zoom level tiles that compose the tile
|
|
175
|
+
if (verbose) {
|
|
176
|
+
console.log(`optimizeHash: Tile X: ${tile.x}, Y: ${tile.y} zoom ${tile.zoom}, intersectionTarget ${intersectionTarget.maxZoom}, - generate from a tile the next zoom level tiles that compose the tile`);
|
|
177
|
+
}
|
|
178
|
+
const tiles = this.generateSubTiles(tile);
|
|
179
|
+
for (const subTile of tiles) {
|
|
180
|
+
const intersection = intersectionFunction(subTile, intersectionTarget);
|
|
181
|
+
if (verbose) {
|
|
182
|
+
console.log(`Tile X: ${subTile.x}, Y: ${subTile.y} zoom ${subTile.zoom}, intersection: ${intersection}`);
|
|
183
|
+
}
|
|
184
|
+
if (intersection === TileIntersectionState.FULL) {
|
|
185
|
+
/// convert it to tile range of the requested resolution
|
|
186
|
+
/// add the range to the result set (yield is used for lazy calculation to improve memory usage)
|
|
187
|
+
const tileRange = this.tileToRange(subTile, targetZoom);
|
|
188
|
+
if (verbose) {
|
|
189
|
+
console.log(`return BBOX tile range zoom: ${tileRange.zoom} : X ${tileRange.minX} - ${tileRange.maxX} : Y ${tileRange.minY} - ${tileRange.maxY}`);
|
|
190
|
+
}
|
|
191
|
+
yield tileRange;
|
|
192
|
+
}
|
|
193
|
+
else if (intersection === TileIntersectionState.PARTIAL) {
|
|
194
|
+
/// if it partly covered:
|
|
195
|
+
// calculate the sub tiles contained in the current tile (in the next zoom level) - recursive
|
|
196
|
+
yield* this.optimizeHash(subTile, targetZoom, intersectionTarget, intersectionFunction, verbose);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
generateSubTiles(tile) {
|
|
201
|
+
const tile0 = { x: tile.x << 1, y: tile.y << 1, zoom: tile.zoom + 1 };
|
|
202
|
+
const tile1 = { x: tile0.x + 1, y: tile0.y, zoom: tile0.zoom };
|
|
203
|
+
const tile2 = { x: tile0.x, y: tile0.y + 1, zoom: tile0.zoom };
|
|
204
|
+
const tile3 = { x: tile0.x + 1, y: tile0.y + 1, zoom: tile0.zoom };
|
|
205
|
+
const tiles = [tile0, tile1, tile2, tile3];
|
|
206
|
+
return tiles;
|
|
207
|
+
}
|
|
208
|
+
tileFootprintIntersection = (tile, intersectionParams) => {
|
|
209
|
+
const tileBbox = (0, tiles_1.tileToBbox)(tile);
|
|
210
|
+
const tilePoly = (0, turf_1.bboxPolygon)(tileBbox);
|
|
211
|
+
const intersection = (0, turf_1.intersect)(intersectionParams.footprint, tilePoly);
|
|
212
|
+
if (intersection === null) {
|
|
213
|
+
return TileIntersectionState.NONE;
|
|
214
|
+
}
|
|
215
|
+
// stop condition
|
|
216
|
+
if (tile.zoom === intersectionParams.maxZoom) {
|
|
217
|
+
return TileIntersectionState.FULL;
|
|
218
|
+
}
|
|
219
|
+
const intArea = (0, turf_1.area)(intersection);
|
|
220
|
+
const hashArea = (0, turf_1.area)(tilePoly);
|
|
221
|
+
if (intArea == hashArea) {
|
|
222
|
+
return TileIntersectionState.FULL;
|
|
223
|
+
}
|
|
224
|
+
return TileIntersectionState.PARTIAL;
|
|
225
|
+
};
|
|
226
|
+
isBbox(footprint) {
|
|
227
|
+
const bbox = (0, turf_1.bbox)(footprint);
|
|
228
|
+
const bboxPoly = (0, turf_1.bboxPolygon)(bbox);
|
|
229
|
+
return (0, turf_1.booleanEqual)(footprint, bboxPoly);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
exports.TileRanger = TileRanger;
|
|
384
233
|
//# sourceMappingURL=tileRanger.js.map
|