This repository has been archived by the owner on Mar 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 197
/
GeoJsonTiler.ts
103 lines (90 loc) · 3.34 KB
/
GeoJsonTiler.ts
1
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
/*
* Copyright (C) 2017-2019 HERE Europe B.V.
* Licensed under Apache 2.0, see full license in LICENSE
* SPDX-License-Identifier: Apache-2.0
*/
import { GeoJson, ITiler } from "@here/harp-datasource-protocol";
import { TileKey } from "@here/harp-geoutils";
// tslint:disable-next-line:no-var-requires
const geojsonvtExport = require("geojson-vt");
// to be able to run tests on nodejs
const geojsonvt = geojsonvtExport.default || geojsonvtExport;
interface GeoJsonVtIndex {
geojson: GeoJson;
getTile(level: number, column: number, row: number): any;
}
export class GeoJsonTiler implements ITiler {
indexes: Map<string, GeoJsonVtIndex>;
constructor() {
this.indexes = new Map();
}
dispose() {
/* */
}
async connect(): Promise<void> {
return Promise.resolve();
}
async registerIndex(indexId: string, input: URL | GeoJson): Promise<void> {
if (this.indexes.has(indexId)) {
return;
}
return this.updateIndex(indexId, input);
}
async updateIndex(indexId: string, input: URL | GeoJson): Promise<void> {
if (input instanceof URL) {
const response = await fetch(input.href);
if (!response.ok) {
throw new Error(
`GeoJsonTiler: Unable to fetch ${input.href}: ${response.statusText}`
);
}
input = await response.json();
} else {
input = input as GeoJson;
}
const index = geojsonvt(input, {
maxZoom: 20, // max zoom to preserve detail on
indexMaxZoom: 5, // max zoom in the tile index
indexMaxPoints: 100000, // max number of points per tile in the tile index
tolerance: 3, // simplification tolerance (higher means simpler)
extent: 4096, // tile extent
buffer: 0, // tile buffer on each side
lineMetrics: false, // whether to calculate line metrics
promoteId: null, // name of a feature property to be promoted to feature.id
generateId: true, // whether to generate feature ids. Cannot be used with promoteId
debug: 0 // logging level (0, 1 or 2)
});
index.geojson = input;
this.indexes.set(indexId, index);
}
async getTile(indexId: string, tileKey: TileKey): Promise<{}> {
const index = this.indexes.get(indexId);
if (index === undefined) {
throw new Error("Tile not found");
}
const tile = index.getTile(tileKey.level, tileKey.column, tileKey.row);
if (tile !== null) {
tile.layer = indexId;
for (const feature of tile.features) {
feature.originalGeometry = this.getOriginalGeometry(feature, index.geojson);
}
}
return tile || {};
}
private getOriginalGeometry(feature: any, geojson: GeoJson): any {
switch (geojson.type) {
case "Point":
case "MultiPoint":
case "LineString":
case "MultiLineString":
case "Polygon":
case "MultiPolygon":
case "GeometryCollection":
return geojson;
case "Feature":
return geojson.geometry;
case "FeatureCollection":
return geojson.features[feature.id].geometry;
}
}
}