@loaders.gl/mvt 4.3.0-alpha.2 → 4.3.0-alpha.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/dist.dev.js +821 -680
- package/dist/dist.min.js +1 -1
- package/dist/index.cjs +795 -656
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/lib/get-schemas-from-tilejson.d.ts +4 -0
- package/dist/lib/get-schemas-from-tilejson.d.ts.map +1 -0
- package/dist/lib/get-schemas-from-tilejson.js +55 -0
- package/dist/lib/parse-tilejson.d.ts +9 -4
- package/dist/lib/parse-tilejson.d.ts.map +1 -1
- package/dist/lib/parse-tilejson.js +6 -6
- package/dist/lib/types.d.ts +39 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +1 -1
- package/dist/lib/utils/geometry-utils.js +1 -1
- package/dist/lib/vector-tiler/{clip.d.ts → features/clip-features.d.ts} +4 -4
- package/dist/lib/vector-tiler/features/clip-features.d.ts.map +1 -0
- package/dist/lib/vector-tiler/{clip.js → features/clip-features.js} +4 -4
- package/dist/lib/vector-tiler/{convert.d.ts → features/convert-feature.d.ts} +7 -7
- package/dist/lib/vector-tiler/features/convert-feature.d.ts.map +1 -0
- package/dist/lib/vector-tiler/features/convert-feature.js +140 -0
- package/dist/lib/vector-tiler/features/proto-feature.d.ts +30 -0
- package/dist/lib/vector-tiler/features/proto-feature.d.ts.map +1 -0
- package/dist/lib/vector-tiler/features/proto-feature.js +52 -0
- package/dist/lib/vector-tiler/{simplify.d.ts → features/simplify-path.d.ts} +2 -2
- package/dist/lib/vector-tiler/features/simplify-path.d.ts.map +1 -0
- package/dist/lib/vector-tiler/{simplify.js → features/simplify-path.js} +3 -3
- package/dist/lib/vector-tiler/{wrap.d.ts → features/wrap-features.d.ts} +5 -5
- package/dist/lib/vector-tiler/features/wrap-features.d.ts.map +1 -0
- package/dist/lib/vector-tiler/{wrap.js → features/wrap-features.js} +33 -26
- package/dist/lib/vector-tiler/proto-tile.d.ts +40 -0
- package/dist/lib/vector-tiler/proto-tile.d.ts.map +1 -0
- package/dist/lib/vector-tiler/proto-tile.js +138 -0
- package/dist/lib/vector-tiler/tile-to-geojson.d.ts +12 -0
- package/dist/lib/vector-tiler/tile-to-geojson.d.ts.map +1 -0
- package/dist/lib/vector-tiler/tile-to-geojson.js +81 -0
- package/dist/lib/vector-tiler/transform-tile.d.ts +7 -0
- package/dist/lib/vector-tiler/transform-tile.d.ts.map +1 -0
- package/dist/lib/vector-tiler/transform-tile.js +41 -0
- package/dist/mvt-loader.d.ts +2 -0
- package/dist/mvt-loader.d.ts.map +1 -1
- package/dist/mvt-loader.js +1 -1
- package/dist/mvt-source.d.ts +31 -14
- package/dist/mvt-source.d.ts.map +1 -1
- package/dist/mvt-source.js +26 -6
- package/dist/mvt-worker.js +4 -4
- package/dist/table-tile-source.d.ts +66 -36
- package/dist/table-tile-source.d.ts.map +1 -1
- package/dist/table-tile-source.js +167 -117
- package/dist/tilejson-loader.js +1 -1
- package/package.json +9 -6
- package/src/index.ts +13 -6
- package/src/lib/get-schemas-from-tilejson.ts +64 -0
- package/src/lib/parse-tilejson.ts +19 -12
- package/src/lib/types.ts +40 -2
- package/src/lib/utils/geometry-utils.ts +1 -1
- package/src/lib/vector-tiler/{clip.ts → features/clip-features.ts} +8 -8
- package/src/lib/vector-tiler/{convert.ts → features/convert-feature.ts} +91 -70
- package/src/lib/vector-tiler/features/proto-feature.ts +104 -0
- package/src/lib/vector-tiler/{simplify.ts → features/simplify-path.ts} +8 -3
- package/src/lib/vector-tiler/{wrap.ts → features/wrap-features.ts} +44 -29
- package/src/lib/vector-tiler/proto-tile.ts +217 -0
- package/src/lib/vector-tiler/tile-to-geojson.ts +105 -0
- package/src/lib/vector-tiler/transform-tile.ts +57 -0
- package/src/mvt-loader.ts +2 -0
- package/src/mvt-source.ts +42 -18
- package/src/table-tile-source.ts +130 -85
- package/src/tilejson-loader.ts +2 -2
- package/dist/lib/vector-tiler/clip.d.ts.map +0 -1
- package/dist/lib/vector-tiler/convert.d.ts.map +0 -1
- package/dist/lib/vector-tiler/convert.js +0 -139
- package/dist/lib/vector-tiler/feature.d.ts +0 -3
- package/dist/lib/vector-tiler/feature.d.ts.map +0 -1
- package/dist/lib/vector-tiler/feature.js +0 -44
- package/dist/lib/vector-tiler/simplify.d.ts.map +0 -1
- package/dist/lib/vector-tiler/tile.d.ts +0 -38
- package/dist/lib/vector-tiler/tile.d.ts.map +0 -1
- package/dist/lib/vector-tiler/tile.js +0 -123
- package/dist/lib/vector-tiler/transform.d.ts +0 -7
- package/dist/lib/vector-tiler/transform.d.ts.map +0 -1
- package/dist/lib/vector-tiler/transform.js +0 -41
- package/dist/lib/vector-tiler/wrap.d.ts.map +0 -1
- package/src/lib/vector-tiler/feature.ts +0 -47
- package/src/lib/vector-tiler/tile.ts +0 -187
- package/src/lib/vector-tiler/transform.ts +0 -57
package/src/index.ts
CHANGED
|
@@ -2,16 +2,23 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
export {MVTLoader, MVTWorkerLoader} from './mvt-loader';
|
|
5
|
+
// TileJSONLoader
|
|
7
6
|
|
|
8
|
-
export type {TileJSON} from './lib/parse-tilejson';
|
|
9
|
-
export type {TileJSONLoaderOptions} from './tilejson-loader';
|
|
10
7
|
export {TileJSONLoader} from './tilejson-loader';
|
|
8
|
+
export type {TileJSONLoaderOptions} from './tilejson-loader';
|
|
9
|
+
export type {TileJSON} from './lib/parse-tilejson';
|
|
10
|
+
|
|
11
|
+
// MVTLoader
|
|
12
|
+
|
|
13
|
+
export {MVTLoader, MVTWorkerLoader} from './mvt-loader';
|
|
14
|
+
export type {MVTLoaderOptions} from './mvt-loader';
|
|
15
|
+
|
|
16
|
+
// MVTSource
|
|
11
17
|
|
|
12
18
|
export {MVTSource} from './mvt-source';
|
|
19
|
+
export type {MVTTileSource, MVTTileSourceProps} from './mvt-source';
|
|
13
20
|
|
|
14
|
-
// TableTileSource
|
|
21
|
+
// TableTileSource (dynamically tiles a table)
|
|
15
22
|
|
|
16
|
-
export type {TableTileSourceProps} from './table-tile-source';
|
|
17
23
|
export {TableTileSource} from './table-tile-source';
|
|
24
|
+
export type {DynamicVectorTileSource, DynamicVectorTileSourceProps} from './table-tile-source';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {Schema, Field, DataType, SchemaMetadata, FieldMetadata} from '@loaders.gl/schema';
|
|
6
|
+
import type {TileJSONLayer, TileJSONField} from './parse-tilejson';
|
|
7
|
+
|
|
8
|
+
// LAYERS
|
|
9
|
+
|
|
10
|
+
export function getSchemaFromTileJSONLayer(layer: TileJSONLayer): Schema {
|
|
11
|
+
const fields: Field[] = [];
|
|
12
|
+
if (layer.fields) {
|
|
13
|
+
for (const field of layer.fields) {
|
|
14
|
+
fields.push({
|
|
15
|
+
name: field.name,
|
|
16
|
+
type: getDataTypeFromTileJSONField(field),
|
|
17
|
+
metadata: getMetadataFromTileJSONField(field)
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
metadata: getMetadataFromTileJSONLayer(layer),
|
|
23
|
+
fields
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getMetadataFromTileJSONLayer(layer: TileJSONLayer): SchemaMetadata {
|
|
28
|
+
const metadata: Record<string, string> = {};
|
|
29
|
+
for (const [key, value] of Object.entries(layer)) {
|
|
30
|
+
if (key !== 'fields' && value) {
|
|
31
|
+
metadata[key] = JSON.stringify(value);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return metadata;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// FIELDS
|
|
38
|
+
|
|
39
|
+
function getDataTypeFromTileJSONField(field: TileJSONField): DataType {
|
|
40
|
+
switch (field.type.toLowerCase()) {
|
|
41
|
+
case 'float32':
|
|
42
|
+
return 'float32';
|
|
43
|
+
case 'number':
|
|
44
|
+
case 'float64':
|
|
45
|
+
return 'float64';
|
|
46
|
+
case 'string':
|
|
47
|
+
case 'utf8':
|
|
48
|
+
return 'utf8';
|
|
49
|
+
case 'boolean':
|
|
50
|
+
return 'bool';
|
|
51
|
+
default:
|
|
52
|
+
return 'null';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getMetadataFromTileJSONField(field: TileJSONField): FieldMetadata {
|
|
57
|
+
const metadata: Record<string, string> = {};
|
|
58
|
+
for (const [key, value] of Object.entries(field)) {
|
|
59
|
+
if (key !== 'name' && value) {
|
|
60
|
+
metadata[key] = JSON.stringify(value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return metadata;
|
|
64
|
+
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
import {Schema} from '@loaders.gl/schema';
|
|
6
|
+
import {getSchemaFromTileJSONLayer} from './get-schemas-from-tilejson';
|
|
7
|
+
|
|
5
8
|
export type TileJSONOptions = {
|
|
6
9
|
/** max number of values. If not provided, include all values in the source tilestats */
|
|
7
10
|
maxValues?: number;
|
|
@@ -9,13 +12,21 @@ export type TileJSONOptions = {
|
|
|
9
12
|
|
|
10
13
|
/** Parsed and typed TileJSON, merges Tilestats information if present */
|
|
11
14
|
export type TileJSON = {
|
|
15
|
+
/** Name of the tileset (for presentation in UI) */
|
|
12
16
|
name?: string;
|
|
17
|
+
/** A description of the contents or purpose of the tileset */
|
|
13
18
|
description?: string;
|
|
19
|
+
/** The version of the tileset */
|
|
14
20
|
version?: string;
|
|
15
21
|
|
|
16
22
|
tileFormat?: string;
|
|
17
23
|
tilesetType?: string;
|
|
18
24
|
|
|
25
|
+
/** Generating application. Tippecanoe adds this. */
|
|
26
|
+
generator?: string;
|
|
27
|
+
/** Generating application options. Tippecanoe adds this. */
|
|
28
|
+
generatorOptions?: string;
|
|
29
|
+
|
|
19
30
|
/** Tile indexing scheme */
|
|
20
31
|
scheme?: 'xyz' | 'tms';
|
|
21
32
|
/** Sharded URLs */
|
|
@@ -33,11 +44,6 @@ export type TileJSON = {
|
|
|
33
44
|
// Combination of tilestats (if present) and tilejson layer information
|
|
34
45
|
layers?: TileJSONLayer[];
|
|
35
46
|
|
|
36
|
-
/** Generating application. Tippecanoe adds this. */
|
|
37
|
-
generator?: string;
|
|
38
|
-
/** Generating application options. Tippecanoe adds this. */
|
|
39
|
-
generatorOptions?: string;
|
|
40
|
-
|
|
41
47
|
/** Any nested JSON metadata */
|
|
42
48
|
metaJson?: any | null;
|
|
43
49
|
};
|
|
@@ -61,6 +67,8 @@ export type TileJSONLayer = {
|
|
|
61
67
|
minZoom?: number;
|
|
62
68
|
maxZoom?: number;
|
|
63
69
|
fields: TileJSONField[];
|
|
70
|
+
|
|
71
|
+
schema?: Schema;
|
|
64
72
|
};
|
|
65
73
|
|
|
66
74
|
export type TileJSONField = {
|
|
@@ -262,17 +270,16 @@ function parseTilestatsForLayer(layer: TilestatsLayer, options: TileJSONOptions)
|
|
|
262
270
|
}
|
|
263
271
|
|
|
264
272
|
function mergeLayers(layers: TileJSONLayer[], tilestatsLayers: TileJSONLayer[]): TileJSONLayer[] {
|
|
265
|
-
return layers.map((layer) => {
|
|
273
|
+
return layers.map((layer: TileJSONLayer): TileJSONLayer => {
|
|
266
274
|
const tilestatsLayer = tilestatsLayers.find((tsLayer) => tsLayer.name === layer.name);
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
delete layer2.fields;
|
|
271
|
-
return {
|
|
272
|
-
...layer2,
|
|
275
|
+
const fields = tilestatsLayer?.fields || layer.fields || [];
|
|
276
|
+
const mergedLayer = {
|
|
277
|
+
...layer,
|
|
273
278
|
...tilestatsLayer,
|
|
274
279
|
fields
|
|
275
280
|
} as TileJSONLayer;
|
|
281
|
+
mergedLayer.schema = getSchemaFromTileJSONLayer(mergedLayer);
|
|
282
|
+
return mergedLayer;
|
|
276
283
|
});
|
|
277
284
|
}
|
|
278
285
|
|
package/src/lib/types.ts
CHANGED
|
@@ -1,8 +1,46 @@
|
|
|
1
1
|
// loaders.gl
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
// Copyright vis.gl contributors
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
/** For local coordinates, the tileIndex is not required */
|
|
6
|
+
type MVTLocalCoordinatesOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* When set to `local`, the parser will return a flat array of GeoJSON objects with local coordinates decoded from tile origin.
|
|
9
|
+
*/
|
|
10
|
+
coordinates: 'local';
|
|
11
|
+
tileIndex: null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/** In WGS84 coordinates, the tileIndex is required */
|
|
15
|
+
type MVTWgs84CoordinatesOptions = {
|
|
16
|
+
/**
|
|
17
|
+
* When set to `wgs84`, the parser will return a flat array of GeoJSON objects with coordinates in longitude, latitude decoded from the provided tile index.
|
|
18
|
+
*/
|
|
19
|
+
coordinates?: 'wgs84';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Mandatory with `wgs84` coordinates option. An object containing tile index values (`x`, `y`,
|
|
23
|
+
* `z`) to reproject features' coordinates into WGS84.
|
|
24
|
+
*/
|
|
25
|
+
tileIndex?: {x: number; y: number; z: number};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type MVTOptions = (MVTLocalCoordinatesOptions | MVTWgs84CoordinatesOptions) & {
|
|
29
|
+
shape?: 'geojson-table' | 'columnar-table' | 'geojson' | 'binary' | 'binary-geometry';
|
|
30
|
+
/**
|
|
31
|
+
* When non-`null`, the layer name of each feature is added to
|
|
32
|
+
* `feature.properties[layerProperty]`. (A `feature.properties` object is created if the feature
|
|
33
|
+
* has no existing properties). If set to `null`, a layer name property will not be added.
|
|
34
|
+
*/
|
|
35
|
+
layerProperty?: string | number;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Optional list of layer names. If not `null`, only features belonging to the named layers will
|
|
39
|
+
* be included in the output. If `null`, features from all layers are returned.
|
|
40
|
+
*/
|
|
41
|
+
layers?: string[];
|
|
42
|
+
};
|
|
4
43
|
|
|
5
|
-
/** TODO where is this used? */
|
|
6
44
|
export type MVTMapboxGeometry = {
|
|
7
45
|
type?: string;
|
|
8
46
|
id?: number;
|
|
@@ -52,7 +52,7 @@ export function convertToLocalCoordinates(
|
|
|
52
52
|
* @param feature
|
|
53
53
|
*/
|
|
54
54
|
export function convertToLocalCoordinatesFlat(data: number[], extent: number): void {
|
|
55
|
-
for (let i = 0
|
|
55
|
+
for (let i = 0; i < data.length; ++i) {
|
|
56
56
|
data[i] /= extent;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
// Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
import {
|
|
6
|
+
import type {ProtoFeature} from './proto-feature';
|
|
7
|
+
import {createProtoFeature} from './proto-feature';
|
|
8
8
|
|
|
9
9
|
/* eslint-disable no-continue */
|
|
10
10
|
|
|
@@ -20,8 +20,8 @@ import {createFeature} from './feature';
|
|
|
20
20
|
* @param minAll and maxAll: minimum and maximum coordinate value for all features
|
|
21
21
|
*/
|
|
22
22
|
// eslint-disable-next-line max-params, complexity, max-statements
|
|
23
|
-
export function
|
|
24
|
-
features:
|
|
23
|
+
export function clipFeatures(
|
|
24
|
+
features: ProtoFeature[],
|
|
25
25
|
scale: number,
|
|
26
26
|
k1: number,
|
|
27
27
|
k2: number,
|
|
@@ -29,7 +29,7 @@ export function clip(
|
|
|
29
29
|
minAll: number,
|
|
30
30
|
maxAll: number,
|
|
31
31
|
options: {lineMetrics: boolean}
|
|
32
|
-
):
|
|
32
|
+
): ProtoFeature[] | null {
|
|
33
33
|
k1 /= scale;
|
|
34
34
|
k2 /= scale;
|
|
35
35
|
|
|
@@ -41,7 +41,7 @@ export function clip(
|
|
|
41
41
|
return null; // trivial reject
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const clipped:
|
|
44
|
+
const clipped: ProtoFeature[] = [];
|
|
45
45
|
|
|
46
46
|
for (const feature of features) {
|
|
47
47
|
const geometry = feature.geometry;
|
|
@@ -82,7 +82,7 @@ export function clip(
|
|
|
82
82
|
if (newGeometry.length) {
|
|
83
83
|
if (options.lineMetrics && type === 'LineString') {
|
|
84
84
|
for (const line of newGeometry) {
|
|
85
|
-
clipped.push(
|
|
85
|
+
clipped.push(createProtoFeature(feature.id, type, line, feature.tags));
|
|
86
86
|
}
|
|
87
87
|
continue;
|
|
88
88
|
}
|
|
@@ -100,7 +100,7 @@ export function clip(
|
|
|
100
100
|
type = newGeometry.length === 3 ? 'Point' : 'MultiPoint';
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
clipped.push(
|
|
103
|
+
clipped.push(createProtoFeature(feature.id, type, newGeometry, feature.tags));
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -7,30 +7,10 @@
|
|
|
7
7
|
// @ts-nocheck
|
|
8
8
|
|
|
9
9
|
import type {Feature, FeatureCollection} from '@loaders.gl/schema';
|
|
10
|
-
import type {
|
|
10
|
+
import type {ProtoFeature} from './proto-feature';
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* converts a GeoJSON feature into an intermediate projected JSON vector format
|
|
17
|
-
* with simplification data
|
|
18
|
-
*/
|
|
19
|
-
export function convert(data: Feature | FeatureCollection, options): TableTileFeature[] {
|
|
20
|
-
const features = [];
|
|
21
|
-
if (data.type === 'FeatureCollection') {
|
|
22
|
-
for (let i = 0; i < data.features.length; i++) {
|
|
23
|
-
convertFeature(features, data.features[i], options, i);
|
|
24
|
-
}
|
|
25
|
-
} else if (data.type === 'Feature') {
|
|
26
|
-
convertFeature(features, data, options);
|
|
27
|
-
} else {
|
|
28
|
-
// single geometry or a geometry collection
|
|
29
|
-
convertFeature(features, {geometry: data}, options);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return features;
|
|
33
|
-
}
|
|
12
|
+
import {createProtoFeature} from './proto-feature';
|
|
13
|
+
import {simplifyPath} from './simplify-path';
|
|
34
14
|
|
|
35
15
|
export type ConvertFeatureOptions = {
|
|
36
16
|
/** max zoom to preserve detail on */
|
|
@@ -43,16 +23,43 @@ export type ConvertFeatureOptions = {
|
|
|
43
23
|
lineMetrics?: boolean;
|
|
44
24
|
};
|
|
45
25
|
|
|
26
|
+
/**
|
|
27
|
+
* converts a GeoJSON feature into an intermediate projected JSON vector format
|
|
28
|
+
* with simplification data
|
|
29
|
+
*/
|
|
30
|
+
export function convertFeaturesToProtoFeature(
|
|
31
|
+
data: Feature | FeatureCollection,
|
|
32
|
+
options: ConvertFeatureOptions
|
|
33
|
+
): ProtoFeature[] {
|
|
34
|
+
const protoFeatures = [];
|
|
35
|
+
switch (data.type) {
|
|
36
|
+
case 'FeatureCollection':
|
|
37
|
+
let i = 0;
|
|
38
|
+
for (const feature of data.features) {
|
|
39
|
+
protoFeatures.push(convertFeature(feature, options, i++));
|
|
40
|
+
}
|
|
41
|
+
break;
|
|
42
|
+
case 'Feature':
|
|
43
|
+
protoFeatures.push(convertFeature(data, options));
|
|
44
|
+
break;
|
|
45
|
+
default:
|
|
46
|
+
// single geometry or a geometry collection
|
|
47
|
+
protoFeatures.push(convertFeature({geometry: data}, options));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return protoFeatures;
|
|
51
|
+
}
|
|
52
|
+
|
|
46
53
|
/**
|
|
47
54
|
* converts a GeoJSON feature into an intermediate projected JSON vector format
|
|
48
55
|
* with simplification data
|
|
49
56
|
*/
|
|
50
57
|
function convertFeature(
|
|
51
|
-
features: TableTileFeature[],
|
|
52
58
|
geojson: Feature,
|
|
53
59
|
options: ConvertFeatureOptions,
|
|
54
60
|
index: number
|
|
55
|
-
):
|
|
61
|
+
): ProtoFeature {
|
|
62
|
+
// GeoJSON geometries can be null, but no vector tile will include them.
|
|
56
63
|
if (!geojson.geometry) {
|
|
57
64
|
return;
|
|
58
65
|
}
|
|
@@ -67,53 +74,67 @@ function convertFeature(
|
|
|
67
74
|
} else if (options.generateId) {
|
|
68
75
|
id = index || 0;
|
|
69
76
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (options.lineMetrics) {
|
|
80
|
-
// explode into linestrings to be able to track metrics
|
|
81
|
-
for (const line of coords) {
|
|
82
|
-
geometry = [];
|
|
83
|
-
convertLine(line, geometry, tolerance, false);
|
|
84
|
-
features.push(createFeature(id, 'LineString', geometry, geojson.properties));
|
|
77
|
+
|
|
78
|
+
switch (type) {
|
|
79
|
+
case 'Point':
|
|
80
|
+
convertPoint(coords, geometry);
|
|
81
|
+
break;
|
|
82
|
+
|
|
83
|
+
case 'MultiPoint':
|
|
84
|
+
for (const p of coords) {
|
|
85
|
+
convertPoint(p, geometry);
|
|
85
86
|
}
|
|
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
|
-
|
|
87
|
+
break;
|
|
88
|
+
|
|
89
|
+
case 'LineString':
|
|
90
|
+
convertLine(coords, geometry, tolerance, false);
|
|
91
|
+
break;
|
|
92
|
+
|
|
93
|
+
case 'MultiLineString':
|
|
94
|
+
if (options.lineMetrics) {
|
|
95
|
+
// explode into linestrings to be able to track metrics
|
|
96
|
+
for (const line of coords) {
|
|
97
|
+
geometry = [];
|
|
98
|
+
convertLine(line, geometry, tolerance, false);
|
|
99
|
+
features.push(createProtoFeature(id, 'LineString', geometry, geojson.properties));
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
convertLines(coords, geometry, tolerance, false);
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
|
|
106
|
+
case 'Polygon':
|
|
107
|
+
convertLines(coords, geometry, tolerance, true);
|
|
108
|
+
break;
|
|
109
|
+
|
|
110
|
+
case 'MultiPolygon':
|
|
111
|
+
for (const polygon of coords) {
|
|
112
|
+
const newPolygon = [];
|
|
113
|
+
convertLines(polygon, newPolygon, tolerance, true);
|
|
114
|
+
geometry.push(newPolygon);
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
|
|
118
|
+
case 'GeometryCollection':
|
|
119
|
+
for (const singleGeometry of geojson.geometry.geometries) {
|
|
120
|
+
convertFeature(
|
|
121
|
+
features,
|
|
122
|
+
{
|
|
123
|
+
id,
|
|
124
|
+
geometry: singleGeometry,
|
|
125
|
+
properties: geojson.properties
|
|
126
|
+
},
|
|
127
|
+
options,
|
|
128
|
+
index
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
|
|
133
|
+
default:
|
|
134
|
+
throw new Error('Input data is not a valid GeoJSON object.');
|
|
114
135
|
}
|
|
115
136
|
|
|
116
|
-
|
|
137
|
+
return createProtoFeature(id, type, geometry, geojson.properties);
|
|
117
138
|
}
|
|
118
139
|
|
|
119
140
|
function convertPoint(coords, out): void {
|
|
@@ -143,7 +164,7 @@ function convertLine(ring: number[], out, tolerance: number, isPolygon: boolean)
|
|
|
143
164
|
|
|
144
165
|
const last = out.length - 3;
|
|
145
166
|
out[2] = 1;
|
|
146
|
-
|
|
167
|
+
simplifyPath(out, 0, last, tolerance);
|
|
147
168
|
out[last + 2] = 1;
|
|
148
169
|
|
|
149
170
|
out.size = Math.abs(size);
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
// Forked from https://github.com/mapbox/geojson-vt under compatible ISC license
|
|
5
|
+
|
|
6
|
+
export type ProtoFeature = {
|
|
7
|
+
type: 'Point' | 'MultiPoint' | 'LineString' | 'MultiLineString' | 'Polygon' | 'MultiPolygon';
|
|
8
|
+
simplifiedType: 1 | 2 | 3;
|
|
9
|
+
geometry: any[];
|
|
10
|
+
|
|
11
|
+
// book keeping
|
|
12
|
+
id?: string;
|
|
13
|
+
tags?: Record<string, unknown>;
|
|
14
|
+
|
|
15
|
+
/** spatial extents */
|
|
16
|
+
minX: number;
|
|
17
|
+
/** spatial extents */
|
|
18
|
+
maxX: number;
|
|
19
|
+
/** spatial extents */
|
|
20
|
+
minY: number;
|
|
21
|
+
/** spatial extents */
|
|
22
|
+
maxY: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type GeoJSONTileGeometry =
|
|
26
|
+
| GeoJSONTilePointGeometry
|
|
27
|
+
| GeoJSONTileLineGeometry
|
|
28
|
+
| GeoJSONTilePolygonGeometry;
|
|
29
|
+
|
|
30
|
+
export type GeoJSONTilePointGeometry = {
|
|
31
|
+
simplifiedType: 1;
|
|
32
|
+
geometry: number[];
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type GeoJSONTileLineGeometry = {
|
|
36
|
+
simplifiedType: 1;
|
|
37
|
+
geometry: number[][];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type GeoJSONTilePolygonGeometry = {
|
|
41
|
+
simplifiedType: 1;
|
|
42
|
+
geometry: number[][][];
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export function createProtoFeature(
|
|
46
|
+
id: any,
|
|
47
|
+
type: 'Point' | 'MultiPoint' | 'LineString' | 'MultiLineString' | 'Polygon' | 'MultiPolygon',
|
|
48
|
+
geometry: any[],
|
|
49
|
+
tags
|
|
50
|
+
): ProtoFeature {
|
|
51
|
+
const feature: ProtoFeature = {
|
|
52
|
+
// eslint-disable-next-line
|
|
53
|
+
id: id == null ? null : id,
|
|
54
|
+
type,
|
|
55
|
+
simplifiedType: undefined!, // TODO
|
|
56
|
+
geometry,
|
|
57
|
+
tags,
|
|
58
|
+
minX: Infinity,
|
|
59
|
+
minY: Infinity,
|
|
60
|
+
maxX: -Infinity,
|
|
61
|
+
maxY: -Infinity
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// TODO break out into separate function
|
|
65
|
+
switch (type) {
|
|
66
|
+
case 'Point':
|
|
67
|
+
case 'MultiPoint':
|
|
68
|
+
case 'LineString':
|
|
69
|
+
calcLineBBox(feature, geometry);
|
|
70
|
+
break;
|
|
71
|
+
|
|
72
|
+
case 'MultiLineString':
|
|
73
|
+
for (const line of geometry) {
|
|
74
|
+
calcLineBBox(feature, line);
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
|
|
78
|
+
case 'Polygon':
|
|
79
|
+
// the outer ring (ie [0]) contains all inner rings
|
|
80
|
+
calcLineBBox(feature, geometry[0]);
|
|
81
|
+
break;
|
|
82
|
+
|
|
83
|
+
case 'MultiPolygon':
|
|
84
|
+
for (const polygon of geometry) {
|
|
85
|
+
// the outer ring (ie [0]) contains all inner rings
|
|
86
|
+
calcLineBBox(feature, polygon[0]);
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
|
|
90
|
+
default:
|
|
91
|
+
throw new Error(String(type));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return feature;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function calcLineBBox(feature, geometry) {
|
|
98
|
+
for (let i = 0; i < geometry.length; i += 3) {
|
|
99
|
+
feature.minX = Math.min(feature.minX, geometry[i]);
|
|
100
|
+
feature.minY = Math.min(feature.minY, geometry[i + 1]);
|
|
101
|
+
feature.maxX = Math.max(feature.maxX, geometry[i]);
|
|
102
|
+
feature.maxY = Math.max(feature.maxY, geometry[i + 1]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
* @param last last coord to simplify
|
|
12
12
|
* @param sqTolerance tolerance (square distance)
|
|
13
13
|
*/
|
|
14
|
-
export function
|
|
14
|
+
export function simplifyPath(
|
|
15
|
+
coords: number[],
|
|
16
|
+
first: number,
|
|
17
|
+
last: number,
|
|
18
|
+
sqTolerance: number
|
|
19
|
+
): void {
|
|
15
20
|
let maxSqDist = sqTolerance;
|
|
16
21
|
const mid = (last - first) >> 1;
|
|
17
22
|
let minPosToMid = last - first;
|
|
@@ -41,9 +46,9 @@ export function simplify(coords: number[], first: number, last: number, sqTolera
|
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
if (maxSqDist > sqTolerance) {
|
|
44
|
-
if (index - first > 3)
|
|
49
|
+
if (index - first > 3) simplifyPath(coords, first, index, sqTolerance);
|
|
45
50
|
coords[index + 2] = maxSqDist;
|
|
46
|
-
if (last - index > 3)
|
|
51
|
+
if (last - index > 3) simplifyPath(coords, index, last, sqTolerance);
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
|