@loaders.gl/gis 3.1.0 → 3.1.1

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.
Files changed (49) hide show
  1. package/dist/es5/index.js +16 -0
  2. package/dist/es5/index.js.map +1 -1
  3. package/dist/es5/lib/extract-geometry-info.js +204 -0
  4. package/dist/es5/lib/extract-geometry-info.js.map +1 -0
  5. package/dist/es5/lib/flat-geojson-to-binary-types.js +2 -0
  6. package/dist/es5/lib/flat-geojson-to-binary-types.js.map +1 -0
  7. package/dist/es5/lib/flat-geojson-to-binary.js +397 -0
  8. package/dist/es5/lib/flat-geojson-to-binary.js.map +1 -0
  9. package/dist/es5/lib/geojson-to-binary.js +15 -579
  10. package/dist/es5/lib/geojson-to-binary.js.map +1 -1
  11. package/dist/es5/lib/geojson-to-flat-geojson.js +169 -0
  12. package/dist/es5/lib/geojson-to-flat-geojson.js.map +1 -0
  13. package/dist/esm/index.js +2 -0
  14. package/dist/esm/index.js.map +1 -1
  15. package/dist/esm/lib/extract-geometry-info.js +105 -0
  16. package/dist/esm/lib/extract-geometry-info.js.map +1 -0
  17. package/dist/esm/lib/flat-geojson-to-binary-types.js +2 -0
  18. package/dist/esm/lib/flat-geojson-to-binary-types.js.map +1 -0
  19. package/dist/esm/lib/flat-geojson-to-binary.js +339 -0
  20. package/dist/esm/lib/flat-geojson-to-binary.js.map +1 -0
  21. package/dist/esm/lib/geojson-to-binary.js +17 -410
  22. package/dist/esm/lib/geojson-to-binary.js.map +1 -1
  23. package/dist/esm/lib/geojson-to-flat-geojson.js +116 -0
  24. package/dist/esm/lib/geojson-to-flat-geojson.js.map +1 -0
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +5 -1
  28. package/dist/lib/extract-geometry-info.d.ts +8 -0
  29. package/dist/lib/extract-geometry-info.d.ts.map +1 -0
  30. package/dist/lib/extract-geometry-info.js +96 -0
  31. package/dist/lib/flat-geojson-to-binary-types.d.ts +58 -0
  32. package/dist/lib/flat-geojson-to-binary-types.d.ts.map +1 -0
  33. package/dist/lib/flat-geojson-to-binary-types.js +2 -0
  34. package/dist/lib/flat-geojson-to-binary.d.ts +37 -0
  35. package/dist/lib/flat-geojson-to-binary.d.ts.map +1 -0
  36. package/dist/lib/flat-geojson-to-binary.js +375 -0
  37. package/dist/lib/geojson-to-binary.d.ts +12 -36
  38. package/dist/lib/geojson-to-binary.d.ts.map +1 -1
  39. package/dist/lib/geojson-to-binary.js +18 -360
  40. package/dist/lib/geojson-to-flat-geojson.d.ts +17 -0
  41. package/dist/lib/geojson-to-flat-geojson.d.ts.map +1 -0
  42. package/dist/lib/geojson-to-flat-geojson.js +128 -0
  43. package/package.json +5 -4
  44. package/src/index.ts +2 -0
  45. package/src/lib/extract-geometry-info.ts +101 -0
  46. package/src/lib/flat-geojson-to-binary-types.ts +58 -0
  47. package/src/lib/flat-geojson-to-binary.ts +564 -0
  48. package/src/lib/geojson-to-binary.ts +24 -459
  49. package/src/lib/geojson-to-flat-geojson.ts +171 -0
package/dist/index.js CHANGED
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
2
  // Types from `@loaders.gl/schema`
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.transformGeoJsonCoords = exports.transformBinaryCoords = exports.binaryToGeometry = exports.binaryToGeoJson = exports.binaryToGeojson = exports.geojsonToBinary = void 0;
4
+ exports.transformGeoJsonCoords = exports.transformBinaryCoords = exports.binaryToGeometry = exports.binaryToGeoJson = exports.binaryToGeojson = exports.geojsonToFlatGeojson = exports.geojsonToBinary = exports.flatGeojsonToBinary = void 0;
5
5
  // Functions
6
+ var flat_geojson_to_binary_1 = require("./lib/flat-geojson-to-binary");
7
+ Object.defineProperty(exports, "flatGeojsonToBinary", { enumerable: true, get: function () { return flat_geojson_to_binary_1.flatGeojsonToBinary; } });
6
8
  var geojson_to_binary_1 = require("./lib/geojson-to-binary");
7
9
  Object.defineProperty(exports, "geojsonToBinary", { enumerable: true, get: function () { return geojson_to_binary_1.geojsonToBinary; } });
10
+ var geojson_to_flat_geojson_1 = require("./lib/geojson-to-flat-geojson");
11
+ Object.defineProperty(exports, "geojsonToFlatGeojson", { enumerable: true, get: function () { return geojson_to_flat_geojson_1.geojsonToFlatGeojson; } });
8
12
  var binary_to_geojson_1 = require("./lib/binary-to-geojson");
9
13
  Object.defineProperty(exports, "binaryToGeojson", { enumerable: true, get: function () { return binary_to_geojson_1.binaryToGeojson; } });
10
14
  Object.defineProperty(exports, "binaryToGeoJson", { enumerable: true, get: function () { return binary_to_geojson_1.binaryToGeoJson; } });
@@ -0,0 +1,8 @@
1
+ import { Feature, GeojsonGeometryInfo } from '@loaders.gl/schema';
2
+ /**
3
+ * Initial scan over GeoJSON features
4
+ * Counts number of coordinates of each geometry type and
5
+ * keeps track of the max coordinate dimensions
6
+ */
7
+ export declare function extractGeometryInfo(features: Feature[]): GeojsonGeometryInfo;
8
+ //# sourceMappingURL=extract-geometry-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-geometry-info.d.ts","sourceRoot":"","sources":["../../src/lib/extract-geometry-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAEhE;;;;GAIG;AAEH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,mBAAmB,CA4F5E"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractGeometryInfo = void 0;
4
+ /**
5
+ * Initial scan over GeoJSON features
6
+ * Counts number of coordinates of each geometry type and
7
+ * keeps track of the max coordinate dimensions
8
+ */
9
+ // eslint-disable-next-line complexity, max-statements
10
+ function extractGeometryInfo(features) {
11
+ // Counts the number of _positions_, so [x, y, z] counts as one
12
+ let pointPositionsCount = 0;
13
+ let pointFeaturesCount = 0;
14
+ let linePositionsCount = 0;
15
+ let linePathsCount = 0;
16
+ let lineFeaturesCount = 0;
17
+ let polygonPositionsCount = 0;
18
+ let polygonObjectsCount = 0;
19
+ let polygonRingsCount = 0;
20
+ let polygonFeaturesCount = 0;
21
+ const coordLengths = new Set();
22
+ for (const feature of features) {
23
+ const geometry = feature.geometry;
24
+ switch (geometry.type) {
25
+ case 'Point':
26
+ pointFeaturesCount++;
27
+ pointPositionsCount++;
28
+ coordLengths.add(geometry.coordinates.length);
29
+ break;
30
+ case 'MultiPoint':
31
+ pointFeaturesCount++;
32
+ pointPositionsCount += geometry.coordinates.length;
33
+ for (const point of geometry.coordinates) {
34
+ coordLengths.add(point.length);
35
+ }
36
+ break;
37
+ case 'LineString':
38
+ lineFeaturesCount++;
39
+ linePositionsCount += geometry.coordinates.length;
40
+ linePathsCount++;
41
+ for (const coord of geometry.coordinates) {
42
+ coordLengths.add(coord.length);
43
+ }
44
+ break;
45
+ case 'MultiLineString':
46
+ lineFeaturesCount++;
47
+ for (const line of geometry.coordinates) {
48
+ linePositionsCount += line.length;
49
+ linePathsCount++;
50
+ // eslint-disable-next-line max-depth
51
+ for (const coord of line) {
52
+ coordLengths.add(coord.length);
53
+ }
54
+ }
55
+ break;
56
+ case 'Polygon':
57
+ polygonFeaturesCount++;
58
+ polygonObjectsCount++;
59
+ polygonRingsCount += geometry.coordinates.length;
60
+ const flattened = geometry.coordinates.flat();
61
+ polygonPositionsCount += flattened.length;
62
+ for (const coord of flattened) {
63
+ coordLengths.add(coord.length);
64
+ }
65
+ break;
66
+ case 'MultiPolygon':
67
+ polygonFeaturesCount++;
68
+ for (const polygon of geometry.coordinates) {
69
+ polygonObjectsCount++;
70
+ polygonRingsCount += polygon.length;
71
+ const flattened = polygon.flat();
72
+ polygonPositionsCount += flattened.length;
73
+ // eslint-disable-next-line max-depth
74
+ for (const coord of flattened) {
75
+ coordLengths.add(coord.length);
76
+ }
77
+ }
78
+ break;
79
+ default:
80
+ throw new Error(`Unsupported geometry type: ${geometry.type}`);
81
+ }
82
+ }
83
+ return {
84
+ coordLength: coordLengths.size > 0 ? Math.max(...coordLengths) : 2,
85
+ pointPositionsCount,
86
+ pointFeaturesCount,
87
+ linePositionsCount,
88
+ linePathsCount,
89
+ lineFeaturesCount,
90
+ polygonPositionsCount,
91
+ polygonObjectsCount,
92
+ polygonRingsCount,
93
+ polygonFeaturesCount
94
+ };
95
+ }
96
+ exports.extractGeometryInfo = extractGeometryInfo;
@@ -0,0 +1,58 @@
1
+ import type { TypedArray } from '@loaders.gl/schema';
2
+ /**
3
+ * Permissable constructor for numeric props
4
+ */
5
+ export declare type PropArrayConstructor = Float32ArrayConstructor | Float64ArrayConstructor | ArrayConstructor;
6
+ /**
7
+ * Collection type for holding intermediate binary data before conversion to `BinaryPointGeometry`
8
+ */
9
+ export declare type Points = {
10
+ type: 'Point';
11
+ positions: Float32Array | Float64Array;
12
+ globalFeatureIds: Uint16Array | Uint32Array;
13
+ featureIds: Uint16Array | Uint32Array;
14
+ numericProps: {
15
+ [key: string]: TypedArray;
16
+ };
17
+ properties: {}[];
18
+ fields: {
19
+ id?: string | number;
20
+ }[];
21
+ };
22
+ /**
23
+ * Collection type for holding intermediate binary data before conversion to `BinaryLineStringGeometry`
24
+ */
25
+ export declare type Lines = {
26
+ type: 'LineString';
27
+ positions: Float32Array | Float64Array;
28
+ pathIndices: Uint16Array | Uint32Array;
29
+ globalFeatureIds: Uint16Array | Uint32Array;
30
+ featureIds: Uint16Array | Uint32Array;
31
+ numericProps: {
32
+ [key: string]: TypedArray;
33
+ };
34
+ properties: {}[];
35
+ fields: {
36
+ id?: string | number;
37
+ }[];
38
+ };
39
+ /**
40
+ * Collection type for holding intermediate binary data before conversion to `BinaryPolygonGeometry`
41
+ */
42
+ export declare type Polygons = {
43
+ type: 'Polygon';
44
+ positions: Float32Array | Float64Array;
45
+ polygonIndices: Uint16Array | Uint32Array;
46
+ primitivePolygonIndices: Uint16Array | Uint32Array;
47
+ triangles: number[];
48
+ globalFeatureIds: Uint16Array | Uint32Array;
49
+ featureIds: Uint16Array | Uint32Array;
50
+ numericProps: {
51
+ [key: string]: TypedArray;
52
+ };
53
+ properties: {}[];
54
+ fields: {
55
+ id?: string | number;
56
+ }[];
57
+ };
58
+ //# sourceMappingURL=flat-geojson-to-binary-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flat-geojson-to-binary-types.d.ts","sourceRoot":"","sources":["../../src/lib/flat-geojson-to-binary-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAEnD;;GAEG;AACH,oBAAY,oBAAoB,GAC5B,uBAAuB,GACvB,uBAAuB,GACvB,gBAAgB,CAAC;AAErB;;GAEG;AACH,oBAAY,MAAM,GAAG;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,YAAY,GAAG,YAAY,CAAC;IACvC,gBAAgB,EAAE,WAAW,GAAG,WAAW,CAAC;IAC5C,UAAU,EAAE,WAAW,GAAG,WAAW,CAAC;IACtC,YAAY,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAA;KAAC,CAAC;IAC1C,UAAU,EAAE,EAAE,EAAE,CAAC;IACjB,MAAM,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACtB,EAAE,CAAC;CACL,CAAC;AAEF;;GAEG;AACH,oBAAY,KAAK,GAAG;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,YAAY,GAAG,YAAY,CAAC;IACvC,WAAW,EAAE,WAAW,GAAG,WAAW,CAAC;IACvC,gBAAgB,EAAE,WAAW,GAAG,WAAW,CAAC;IAC5C,UAAU,EAAE,WAAW,GAAG,WAAW,CAAC;IACtC,YAAY,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAA;KAAC,CAAC;IAC1C,UAAU,EAAE,EAAE,EAAE,CAAC;IACjB,MAAM,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACtB,EAAE,CAAC;CACL,CAAC;AAEF;;GAEG;AACH,oBAAY,QAAQ,GAAG;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,YAAY,GAAG,YAAY,CAAC;IACvC,cAAc,EAAE,WAAW,GAAG,WAAW,CAAC;IAC1C,uBAAuB,EAAE,WAAW,GAAG,WAAW,CAAC;IACnD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,EAAE,WAAW,GAAG,WAAW,CAAC;IAC5C,UAAU,EAAE,WAAW,GAAG,WAAW,CAAC;IACtC,YAAY,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAA;KAAC,CAAC;IAC1C,UAAU,EAAE,EAAE,EAAE,CAAC;IACjB,MAAM,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACtB,EAAE,CAAC;CACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,37 @@
1
+ import type { BinaryFeatures, FlatFeature, GeojsonGeometryInfo } from '@loaders.gl/schema';
2
+ import { PropArrayConstructor } from './flat-geojson-to-binary-types';
3
+ /**
4
+ * Convert binary features to flat binary arrays. Similar to
5
+ * `geojsonToBinary` helper function, except that it expects
6
+ * a binary representation of the feature data, which enables
7
+ * 2X-3X speed increase in parse speed, compared to using
8
+ * geoJSON. See `binary-vector-tile/VectorTileFeature` for
9
+ * data format detais
10
+ *
11
+ * @param features
12
+ * @param geometryInfo
13
+ * @param options
14
+ * @returns filled arrays
15
+ */
16
+ export declare function flatGeojsonToBinary(features: FlatFeature[], geometryInfo: GeojsonGeometryInfo, options?: FlatGeojsonToBinaryOptions): BinaryFeatures;
17
+ /**
18
+ * Options for `flatGeojsonToBinary`
19
+ */
20
+ export declare type FlatGeojsonToBinaryOptions = {
21
+ numericPropKeys?: string[];
22
+ PositionDataType?: Float32ArrayConstructor | Float64ArrayConstructor;
23
+ };
24
+ export declare const TEST_EXPORTS: {
25
+ extractNumericPropTypes: typeof extractNumericPropTypes;
26
+ };
27
+ /**
28
+ * Extracts properties that are always numeric
29
+ *
30
+ * @param features
31
+ * @returns object with numeric types
32
+ */
33
+ declare function extractNumericPropTypes(features: FlatFeature[]): {
34
+ [key: string]: PropArrayConstructor;
35
+ };
36
+ export {};
37
+ //# sourceMappingURL=flat-geojson-to-binary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flat-geojson-to-binary.d.ts","sourceRoot":"","sources":["../../src/lib/flat-geojson-to-binary.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,cAAc,EACd,WAAW,EAIX,mBAAmB,EAEpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,oBAAoB,EAA0B,MAAM,gCAAgC,CAAC;AAE7F;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,WAAW,EAAE,EACvB,YAAY,EAAE,mBAAmB,EACjC,OAAO,CAAC,EAAE,0BAA0B,kBAerC;AAED;;GAEG;AACH,oBAAY,0BAA0B,GAAG;IACvC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,uBAAuB,GAAG,uBAAuB,CAAC;CACtE,CAAC;AAEF,eAAO,MAAM,YAAY;;CAExB,CAAC;AAEF;;;;;GAKG;AACH,iBAAS,uBAAuB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;IACzD,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACrC,CAgBA"}
@@ -0,0 +1,375 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TEST_EXPORTS = exports.flatGeojsonToBinary = void 0;
4
+ /* eslint-disable indent */
5
+ const polygon_1 = require("@math.gl/polygon");
6
+ /**
7
+ * Convert binary features to flat binary arrays. Similar to
8
+ * `geojsonToBinary` helper function, except that it expects
9
+ * a binary representation of the feature data, which enables
10
+ * 2X-3X speed increase in parse speed, compared to using
11
+ * geoJSON. See `binary-vector-tile/VectorTileFeature` for
12
+ * data format detais
13
+ *
14
+ * @param features
15
+ * @param geometryInfo
16
+ * @param options
17
+ * @returns filled arrays
18
+ */
19
+ function flatGeojsonToBinary(features, geometryInfo, options) {
20
+ const propArrayTypes = extractNumericPropTypes(features);
21
+ const numericPropKeys = Object.keys(propArrayTypes).filter((k) => propArrayTypes[k] !== Array);
22
+ return fillArrays(features, {
23
+ propArrayTypes,
24
+ ...geometryInfo
25
+ }, {
26
+ numericPropKeys: (options && options.numericPropKeys) || numericPropKeys,
27
+ PositionDataType: options ? options.PositionDataType : Float32Array
28
+ });
29
+ }
30
+ exports.flatGeojsonToBinary = flatGeojsonToBinary;
31
+ exports.TEST_EXPORTS = {
32
+ extractNumericPropTypes
33
+ };
34
+ /**
35
+ * Extracts properties that are always numeric
36
+ *
37
+ * @param features
38
+ * @returns object with numeric types
39
+ */
40
+ function extractNumericPropTypes(features) {
41
+ const propArrayTypes = {};
42
+ for (const feature of features) {
43
+ if (feature.properties) {
44
+ for (const key in feature.properties) {
45
+ // If property has not been seen before, or if property has been numeric
46
+ // in all previous features, check if numeric in this feature
47
+ // If not numeric, Array is stored to prevent rechecking in the future
48
+ // Additionally, detects if 64 bit precision is required
49
+ const val = feature.properties[key];
50
+ propArrayTypes[key] = deduceArrayType(val, propArrayTypes[key]);
51
+ }
52
+ }
53
+ }
54
+ return propArrayTypes;
55
+ }
56
+ /**
57
+ * Fills coordinates into pre-allocated typed arrays
58
+ *
59
+ * @param features
60
+ * @param geometryInfo
61
+ * @param options
62
+ * @returns an accessor object with value and size keys
63
+ */
64
+ // eslint-disable-next-line complexity
65
+ function fillArrays(features, geometryInfo, options) {
66
+ const { pointPositionsCount, pointFeaturesCount, linePositionsCount, linePathsCount, lineFeaturesCount, polygonPositionsCount, polygonObjectsCount, polygonRingsCount, polygonFeaturesCount, propArrayTypes, coordLength } = geometryInfo;
67
+ const { numericPropKeys = [], PositionDataType = Float32Array } = options;
68
+ const hasGlobalId = features[0] && 'id' in features[0];
69
+ const GlobalFeatureIdsDataType = features.length > 65535 ? Uint32Array : Uint16Array;
70
+ const points = {
71
+ type: 'Point',
72
+ positions: new PositionDataType(pointPositionsCount * coordLength),
73
+ globalFeatureIds: new GlobalFeatureIdsDataType(pointPositionsCount),
74
+ featureIds: pointFeaturesCount > 65535
75
+ ? new Uint32Array(pointPositionsCount)
76
+ : new Uint16Array(pointPositionsCount),
77
+ numericProps: {},
78
+ properties: [],
79
+ fields: []
80
+ };
81
+ const lines = {
82
+ type: 'LineString',
83
+ pathIndices: linePositionsCount > 65535
84
+ ? new Uint32Array(linePathsCount + 1)
85
+ : new Uint16Array(linePathsCount + 1),
86
+ positions: new PositionDataType(linePositionsCount * coordLength),
87
+ globalFeatureIds: new GlobalFeatureIdsDataType(linePositionsCount),
88
+ featureIds: lineFeaturesCount > 65535
89
+ ? new Uint32Array(linePositionsCount)
90
+ : new Uint16Array(linePositionsCount),
91
+ numericProps: {},
92
+ properties: [],
93
+ fields: []
94
+ };
95
+ const polygons = {
96
+ type: 'Polygon',
97
+ polygonIndices: polygonPositionsCount > 65535
98
+ ? new Uint32Array(polygonObjectsCount + 1)
99
+ : new Uint16Array(polygonObjectsCount + 1),
100
+ primitivePolygonIndices: polygonPositionsCount > 65535
101
+ ? new Uint32Array(polygonRingsCount + 1)
102
+ : new Uint16Array(polygonRingsCount + 1),
103
+ positions: new PositionDataType(polygonPositionsCount * coordLength),
104
+ triangles: [],
105
+ globalFeatureIds: new GlobalFeatureIdsDataType(polygonPositionsCount),
106
+ featureIds: polygonFeaturesCount > 65535
107
+ ? new Uint32Array(polygonPositionsCount)
108
+ : new Uint16Array(polygonPositionsCount),
109
+ numericProps: {},
110
+ properties: [],
111
+ fields: []
112
+ };
113
+ // Instantiate numeric properties arrays; one value per vertex
114
+ for (const object of [points, lines, polygons]) {
115
+ for (const propName of numericPropKeys) {
116
+ // If property has been numeric in all previous features in which the property existed, check
117
+ // if numeric in this feature
118
+ const T = propArrayTypes[propName];
119
+ object.numericProps[propName] = new T(object.positions.length / coordLength);
120
+ }
121
+ }
122
+ // Set last element of path/polygon indices as positions length
123
+ lines.pathIndices[linePathsCount] = linePositionsCount;
124
+ polygons.polygonIndices[polygonObjectsCount] = polygonPositionsCount;
125
+ polygons.primitivePolygonIndices[polygonRingsCount] = polygonPositionsCount;
126
+ const indexMap = {
127
+ pointPosition: 0,
128
+ pointFeature: 0,
129
+ linePosition: 0,
130
+ linePath: 0,
131
+ lineFeature: 0,
132
+ polygonPosition: 0,
133
+ polygonObject: 0,
134
+ polygonRing: 0,
135
+ polygonFeature: 0,
136
+ feature: 0
137
+ };
138
+ for (const feature of features) {
139
+ const geometry = feature.geometry;
140
+ const properties = feature.properties || {};
141
+ switch (geometry.type) {
142
+ case 'Point':
143
+ handlePoint(geometry, points, indexMap, coordLength, properties);
144
+ points.properties.push(keepStringProperties(properties, numericPropKeys));
145
+ if (hasGlobalId) {
146
+ points.fields.push({ id: feature.id });
147
+ }
148
+ indexMap.pointFeature++;
149
+ break;
150
+ case 'LineString':
151
+ handleLineString(geometry, lines, indexMap, coordLength, properties);
152
+ lines.properties.push(keepStringProperties(properties, numericPropKeys));
153
+ if (hasGlobalId) {
154
+ lines.fields.push({ id: feature.id });
155
+ }
156
+ indexMap.lineFeature++;
157
+ break;
158
+ case 'Polygon':
159
+ handlePolygon(geometry, polygons, indexMap, coordLength, properties);
160
+ polygons.properties.push(keepStringProperties(properties, numericPropKeys));
161
+ if (hasGlobalId) {
162
+ polygons.fields.push({ id: feature.id });
163
+ }
164
+ indexMap.polygonFeature++;
165
+ break;
166
+ default:
167
+ throw new Error('Invalid geometry type');
168
+ }
169
+ indexMap.feature++;
170
+ }
171
+ // Wrap each array in an accessor object with value and size keys
172
+ return makeAccessorObjects(points, lines, polygons, coordLength);
173
+ }
174
+ /**
175
+ * Fills (Multi)Point coordinates into points object of arrays
176
+ *
177
+ * @param geometry
178
+ * @param points
179
+ * @param indexMap
180
+ * @param coordLength
181
+ * @param properties
182
+ */
183
+ function handlePoint(geometry, points, indexMap, coordLength, properties) {
184
+ points.positions.set(geometry.data, indexMap.pointPosition * coordLength);
185
+ const nPositions = geometry.data.length / coordLength;
186
+ fillNumericProperties(points, properties, indexMap.pointPosition, nPositions);
187
+ points.globalFeatureIds.fill(indexMap.feature, indexMap.pointPosition, indexMap.pointPosition + nPositions);
188
+ points.featureIds.fill(indexMap.pointFeature, indexMap.pointPosition, indexMap.pointPosition + nPositions);
189
+ indexMap.pointPosition += nPositions;
190
+ }
191
+ /**
192
+ * Fills (Multi)LineString coordinates into lines object of arrays
193
+ *
194
+ * @param geometry
195
+ * @param lines
196
+ * @param indexMap
197
+ * @param coordLength
198
+ * @param properties
199
+ */
200
+ function handleLineString(geometry, lines, indexMap, coordLength, properties) {
201
+ lines.positions.set(geometry.data, indexMap.linePosition * coordLength);
202
+ const nPositions = geometry.data.length / coordLength;
203
+ fillNumericProperties(lines, properties, indexMap.linePosition, nPositions);
204
+ lines.globalFeatureIds.fill(indexMap.feature, indexMap.linePosition, indexMap.linePosition + nPositions);
205
+ lines.featureIds.fill(indexMap.lineFeature, indexMap.linePosition, indexMap.linePosition + nPositions);
206
+ for (let i = 0, il = geometry.indices.length; i < il; ++i) {
207
+ // Extract range of data we are working with, defined by start
208
+ // and end indices (these index into the geometry.data array)
209
+ const start = geometry.indices[i];
210
+ const end = i === il - 1
211
+ ? geometry.data.length // last line, so read to end of data
212
+ : geometry.indices[i + 1]; // start index for next line
213
+ lines.pathIndices[indexMap.linePath++] = indexMap.linePosition;
214
+ indexMap.linePosition += (end - start) / coordLength;
215
+ }
216
+ }
217
+ /**
218
+ * Fills (Multi)Polygon coordinates into polygons object of arrays
219
+ *
220
+ * @param geometry
221
+ * @param polygons
222
+ * @param indexMap
223
+ * @param coordLength
224
+ * @param properties
225
+ */
226
+ function handlePolygon(geometry, polygons, indexMap, coordLength, properties) {
227
+ polygons.positions.set(geometry.data, indexMap.polygonPosition * coordLength);
228
+ const nPositions = geometry.data.length / coordLength;
229
+ fillNumericProperties(polygons, properties, indexMap.polygonPosition, nPositions);
230
+ polygons.globalFeatureIds.fill(indexMap.feature, indexMap.polygonPosition, indexMap.polygonPosition + nPositions);
231
+ polygons.featureIds.fill(indexMap.polygonFeature, indexMap.polygonPosition, indexMap.polygonPosition + nPositions);
232
+ // Unlike Point & LineString geometry.indices is a 2D array
233
+ for (let l = 0, ll = geometry.indices.length; l < ll; ++l) {
234
+ const startPosition = indexMap.polygonPosition;
235
+ polygons.polygonIndices[indexMap.polygonObject++] = startPosition;
236
+ const areas = geometry.areas[l];
237
+ const indices = geometry.indices[l];
238
+ const nextIndices = geometry.indices[l + 1];
239
+ for (let i = 0, il = indices.length; i < il; ++i) {
240
+ const start = indices[i];
241
+ const end = i === il - 1
242
+ ? // last line, so either read to:
243
+ nextIndices === undefined
244
+ ? geometry.data.length // end of data (no next indices)
245
+ : nextIndices[0] // start of first line in nextIndices
246
+ : indices[i + 1]; // start index for next line
247
+ polygons.primitivePolygonIndices[indexMap.polygonRing++] = indexMap.polygonPosition;
248
+ indexMap.polygonPosition += (end - start) / coordLength;
249
+ }
250
+ const endPosition = indexMap.polygonPosition;
251
+ triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength });
252
+ }
253
+ }
254
+ /**
255
+ * Triangulate polygon using earcut
256
+ *
257
+ * @param polygons
258
+ * @param areas
259
+ * @param indices
260
+ * @param param3
261
+ */
262
+ function triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength }) {
263
+ const start = startPosition * coordLength;
264
+ const end = endPosition * coordLength;
265
+ // Extract positions and holes for just this polygon
266
+ const polygonPositions = polygons.positions.subarray(start, end);
267
+ // Holes are referenced relative to outer polygon
268
+ const offset = indices[0];
269
+ const holes = indices.slice(1).map((n) => (n - offset) / coordLength);
270
+ // Compute triangulation
271
+ const triangles = (0, polygon_1.earcut)(polygonPositions, holes, coordLength, areas);
272
+ // Indices returned by triangulation are relative to start
273
+ // of polygon, so we need to offset
274
+ for (let t = 0, tl = triangles.length; t < tl; ++t) {
275
+ polygons.triangles.push(startPosition + triangles[t]);
276
+ }
277
+ }
278
+ /**
279
+ * Wraps an object containing array into accessors
280
+ *
281
+ * @param obj
282
+ * @param size
283
+ */
284
+ function wrapProps(obj, size) {
285
+ const returnObj = {};
286
+ for (const key in obj) {
287
+ returnObj[key] = { value: obj[key], size };
288
+ }
289
+ return returnObj;
290
+ }
291
+ /**
292
+ * Wrap each array in an accessor object with value and size keys
293
+ *
294
+ * @param points
295
+ * @param lines
296
+ * @param polygons
297
+ * @param coordLength
298
+ * @returns object
299
+ */
300
+ function makeAccessorObjects(points, lines, polygons, coordLength) {
301
+ return {
302
+ points: {
303
+ ...points,
304
+ positions: { value: points.positions, size: coordLength },
305
+ globalFeatureIds: { value: points.globalFeatureIds, size: 1 },
306
+ featureIds: { value: points.featureIds, size: 1 },
307
+ numericProps: wrapProps(points.numericProps, 1)
308
+ },
309
+ lines: {
310
+ ...lines,
311
+ positions: { value: lines.positions, size: coordLength },
312
+ pathIndices: { value: lines.pathIndices, size: 1 },
313
+ globalFeatureIds: { value: lines.globalFeatureIds, size: 1 },
314
+ featureIds: { value: lines.featureIds, size: 1 },
315
+ numericProps: wrapProps(lines.numericProps, 1)
316
+ },
317
+ polygons: {
318
+ ...polygons,
319
+ positions: { value: polygons.positions, size: coordLength },
320
+ polygonIndices: { value: polygons.polygonIndices, size: 1 },
321
+ primitivePolygonIndices: { value: polygons.primitivePolygonIndices, size: 1 },
322
+ triangles: { value: new Uint32Array(polygons.triangles), size: 1 },
323
+ globalFeatureIds: { value: polygons.globalFeatureIds, size: 1 },
324
+ featureIds: { value: polygons.featureIds, size: 1 },
325
+ numericProps: wrapProps(polygons.numericProps, 1)
326
+ }
327
+ };
328
+ }
329
+ /**
330
+ * Add numeric properties to object
331
+ *
332
+ * @param object
333
+ * @param properties
334
+ * @param index
335
+ * @param length
336
+ */
337
+ function fillNumericProperties(object, properties, index, length) {
338
+ for (const numericPropName in object.numericProps) {
339
+ if (numericPropName in properties) {
340
+ const value = properties[numericPropName];
341
+ object.numericProps[numericPropName].fill(value, index, index + length);
342
+ }
343
+ }
344
+ }
345
+ /**
346
+ * Keep string properties in object
347
+ *
348
+ * @param properties
349
+ * @param numericKeys
350
+ * @returns object
351
+ */
352
+ function keepStringProperties(properties, numericKeys) {
353
+ const props = {};
354
+ for (const key in properties) {
355
+ if (!numericKeys.includes(key)) {
356
+ props[key] = properties[key];
357
+ }
358
+ }
359
+ return props;
360
+ }
361
+ /**
362
+ *
363
+ * Deduce correct array constructor to use for a given value
364
+ *
365
+ * @param x value to test
366
+ * @param constructor previous constructor deduced
367
+ * @returns PropArrayConstructor
368
+ */
369
+ function deduceArrayType(x, constructor) {
370
+ if (constructor === Array || !Number.isFinite(x)) {
371
+ return Array;
372
+ }
373
+ // If this or previous value required 64bits use Float64Array
374
+ return constructor === Float64Array || Math.fround(x) !== x ? Float64Array : Float32Array;
375
+ }
@@ -1,43 +1,19 @@
1
- import { Feature } from '@loaders.gl/schema';
1
+ import type { Feature } from '@loaders.gl/schema';
2
2
  import type { BinaryFeatures } from '@loaders.gl/schema';
3
+ /**
4
+ * Options for `geojsonToBinary`
5
+ */
3
6
  export declare type GeojsonToBinaryOptions = {
4
- coordLength?: number;
7
+ fixRingWinding: boolean;
5
8
  numericPropKeys?: string[];
6
- PositionDataType?: Function;
7
- };
8
- /** Convert GeoJSON features to flat binary arrays */
9
- export declare function geojsonToBinary(features: Feature[], options?: GeojsonToBinaryOptions): BinaryFeatures;
10
- export declare const TEST_EXPORTS: {
11
- firstPass: typeof firstPass;
12
- secondPass: typeof secondPass;
9
+ PositionDataType?: Float32ArrayConstructor | Float64ArrayConstructor;
13
10
  };
14
- declare type PropArrayConstructor = Float32ArrayConstructor | Float64ArrayConstructor | ArrayConstructor;
15
- declare type FirstPassData = {
16
- coordLength: number;
17
- numericPropKeys: string[];
18
- propArrayTypes: {
19
- [key: string]: PropArrayConstructor;
20
- };
21
- pointPositionsCount: number;
22
- pointFeaturesCount: number;
23
- linePositionsCount: number;
24
- linePathsCount: number;
25
- lineFeaturesCount: number;
26
- polygonPositionsCount: number;
27
- polygonObjectsCount: number;
28
- polygonRingsCount: number;
29
- polygonFeaturesCount: number;
30
- };
31
- /**
32
- * Initial scan over GeoJSON features
33
- * Counts number of coordinates of each geometry type and
34
- * keeps track of the max coordinate dimensions
35
- */
36
- declare function firstPass(features: Feature[]): FirstPassData;
37
11
  /**
38
- * Second scan over GeoJSON features
39
- * Fills coordinates into pre-allocated typed arrays
12
+ * Convert GeoJSON features to flat binary arrays
13
+ *
14
+ * @param features
15
+ * @param options
16
+ * @returns features in binary format, grouped by geometry type
40
17
  */
41
- declare function secondPass(features: any, firstPassData: FirstPassData, options: Required<GeojsonToBinaryOptions>): BinaryFeatures;
42
- export {};
18
+ export declare function geojsonToBinary(features: Feature[], options?: GeojsonToBinaryOptions): BinaryFeatures;
43
19
  //# sourceMappingURL=geojson-to-binary.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"geojson-to-binary.d.ts","sourceRoot":"","sources":["../../src/lib/geojson-to-binary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAoB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAEvD,oBAAY,sBAAsB,GAAG;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,QAAQ,CAAC;CAC7B,CAAC;AAEF,qDAAqD;AACrD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,GAAE,sBAA2B,GACnC,cAAc,CAOhB;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAC;AAEF,aAAK,oBAAoB,GAAG,uBAAuB,GAAG,uBAAuB,GAAG,gBAAgB,CAAC;AAEjG,aAAK,aAAa,GAAG;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAAA;KAAC,CAAC;IAEtD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AAEH,iBAAS,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,aAAa,CA2GrD;AAED;;;GAGG;AAEH,iBAAS,UAAU,CACjB,QAAQ,KAAA,EACR,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,QAAQ,CAAC,sBAAsB,CAAC,kBAyI1C"}
1
+ {"version":3,"file":"geojson-to-binary.d.ts","sourceRoot":"","sources":["../../src/lib/geojson-to-binary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAMvD;;GAEG;AACH,oBAAY,sBAAsB,GAAG;IACnC,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,CAAC,EAAE,uBAAuB,GAAG,uBAAuB,CAAC;CACtE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,GAAE,sBAA+C,GACvD,cAAc,CAShB"}