@loaders.gl/gis 4.0.0-alpha.5 → 4.0.0-alpha.6

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 (68) hide show
  1. package/dist/bundle.js +2 -2
  2. package/dist/es5/bundle.js +6 -0
  3. package/dist/es5/bundle.js.map +1 -0
  4. package/dist/es5/index.js +59 -0
  5. package/dist/es5/index.js.map +1 -0
  6. package/dist/es5/lib/binary-to-geojson.js +255 -0
  7. package/dist/es5/lib/binary-to-geojson.js.map +1 -0
  8. package/dist/es5/lib/extract-geometry-info.js +167 -0
  9. package/dist/es5/lib/extract-geometry-info.js.map +1 -0
  10. package/dist/es5/lib/flat-geojson-to-binary-types.js +2 -0
  11. package/dist/es5/lib/flat-geojson-to-binary-types.js.map +1 -0
  12. package/dist/es5/lib/flat-geojson-to-binary.js +344 -0
  13. package/dist/es5/lib/flat-geojson-to-binary.js.map +1 -0
  14. package/dist/es5/lib/geojson-to-binary.js +26 -0
  15. package/dist/es5/lib/geojson-to-binary.js.map +1 -0
  16. package/dist/es5/lib/geojson-to-flat-geojson.js +136 -0
  17. package/dist/es5/lib/geojson-to-flat-geojson.js.map +1 -0
  18. package/dist/es5/lib/transform.js +57 -0
  19. package/dist/es5/lib/transform.js.map +1 -0
  20. package/dist/esm/bundle.js +4 -0
  21. package/dist/esm/bundle.js.map +1 -0
  22. package/dist/esm/index.js +6 -0
  23. package/dist/esm/index.js.map +1 -0
  24. package/dist/esm/lib/binary-to-geojson.js +223 -0
  25. package/dist/esm/lib/binary-to-geojson.js.map +1 -0
  26. package/dist/esm/lib/extract-geometry-info.js +84 -0
  27. package/dist/esm/lib/extract-geometry-info.js.map +1 -0
  28. package/dist/esm/lib/flat-geojson-to-binary-types.js +2 -0
  29. package/dist/esm/lib/flat-geojson-to-binary-types.js.map +1 -0
  30. package/dist/esm/lib/flat-geojson-to-binary.js +305 -0
  31. package/dist/esm/lib/flat-geojson-to-binary.js.map +1 -0
  32. package/dist/esm/lib/geojson-to-binary.js +22 -0
  33. package/dist/esm/lib/geojson-to-binary.js.map +1 -0
  34. package/dist/esm/lib/geojson-to-flat-geojson.js +97 -0
  35. package/dist/esm/lib/geojson-to-flat-geojson.js.map +1 -0
  36. package/dist/esm/lib/transform.js +40 -0
  37. package/dist/esm/lib/transform.js.map +1 -0
  38. package/dist/index.js +18 -6
  39. package/dist/lib/binary-to-geojson.d.ts +1 -1
  40. package/dist/lib/binary-to-geojson.d.ts.map +1 -1
  41. package/dist/lib/binary-to-geojson.js +201 -242
  42. package/dist/lib/extract-geometry-info.js +93 -102
  43. package/dist/lib/flat-geojson-to-binary-types.d.ts +4 -4
  44. package/dist/lib/flat-geojson-to-binary-types.d.ts.map +1 -1
  45. package/dist/lib/flat-geojson-to-binary-types.js +2 -2
  46. package/dist/lib/flat-geojson-to-binary.d.ts +1 -1
  47. package/dist/lib/flat-geojson-to-binary.d.ts.map +1 -1
  48. package/dist/lib/flat-geojson-to-binary.js +346 -309
  49. package/dist/lib/geojson-to-binary.d.ts +1 -1
  50. package/dist/lib/geojson-to-binary.d.ts.map +1 -1
  51. package/dist/lib/geojson-to-binary.js +23 -20
  52. package/dist/lib/geojson-to-flat-geojson.d.ts +1 -1
  53. package/dist/lib/geojson-to-flat-geojson.d.ts.map +1 -1
  54. package/dist/lib/geojson-to-flat-geojson.js +116 -104
  55. package/dist/lib/transform.d.ts +1 -1
  56. package/dist/lib/transform.d.ts.map +1 -1
  57. package/dist/lib/transform.js +51 -42
  58. package/package.json +6 -6
  59. package/src/lib/flat-geojson-to-binary.ts +1 -0
  60. package/dist/bundle.js.map +0 -1
  61. package/dist/index.js.map +0 -1
  62. package/dist/lib/binary-to-geojson.js.map +0 -1
  63. package/dist/lib/extract-geometry-info.js.map +0 -1
  64. package/dist/lib/flat-geojson-to-binary-types.js.map +0 -1
  65. package/dist/lib/flat-geojson-to-binary.js.map +0 -1
  66. package/dist/lib/geojson-to-binary.js.map +0 -1
  67. package/dist/lib/geojson-to-flat-geojson.js.map +0 -1
  68. package/dist/lib/transform.js.map +0 -1
@@ -1,339 +1,376 @@
1
- import { earcut } from '@math.gl/polygon';
2
- export function flatGeojsonToBinary(features, geometryInfo, options) {
3
- const propArrayTypes = extractNumericPropTypes(features);
4
- const numericPropKeys = Object.keys(propArrayTypes).filter(k => propArrayTypes[k] !== Array);
5
- return fillArrays(features, {
6
- propArrayTypes,
7
- ...geometryInfo
8
- }, {
9
- numericPropKeys: options && options.numericPropKeys || numericPropKeys,
10
- PositionDataType: options ? options.PositionDataType : Float32Array
11
- });
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
+ });
12
29
  }
13
- export const TEST_EXPORTS = {
14
- extractNumericPropTypes
30
+ exports.flatGeojsonToBinary = flatGeojsonToBinary;
31
+ exports.TEST_EXPORTS = {
32
+ extractNumericPropTypes
15
33
  };
16
-
34
+ /**
35
+ * Extracts properties that are always numeric
36
+ *
37
+ * @param features
38
+ * @returns object with numeric types
39
+ */
17
40
  function extractNumericPropTypes(features) {
18
- const propArrayTypes = {};
19
-
20
- for (const feature of features) {
21
- if (feature.properties) {
22
- for (const key in feature.properties) {
23
- const val = feature.properties[key];
24
- propArrayTypes[key] = deduceArrayType(val, propArrayTypes[key]);
25
- }
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
+ }
26
53
  }
27
- }
28
-
29
- return propArrayTypes;
54
+ return propArrayTypes;
30
55
  }
31
-
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
32
65
  function fillArrays(features, geometryInfo, options) {
33
- const {
34
- pointPositionsCount,
35
- pointFeaturesCount,
36
- linePositionsCount,
37
- linePathsCount,
38
- lineFeaturesCount,
39
- polygonPositionsCount,
40
- polygonObjectsCount,
41
- polygonRingsCount,
42
- polygonFeaturesCount,
43
- propArrayTypes,
44
- coordLength
45
- } = geometryInfo;
46
- const {
47
- numericPropKeys = [],
48
- PositionDataType = Float32Array
49
- } = options;
50
- const hasGlobalId = features[0] && 'id' in features[0];
51
- const GlobalFeatureIdsDataType = features.length > 65535 ? Uint32Array : Uint16Array;
52
- const points = {
53
- type: 'Point',
54
- positions: new PositionDataType(pointPositionsCount * coordLength),
55
- globalFeatureIds: new GlobalFeatureIdsDataType(pointPositionsCount),
56
- featureIds: pointFeaturesCount > 65535 ? new Uint32Array(pointPositionsCount) : new Uint16Array(pointPositionsCount),
57
- numericProps: {},
58
- properties: [],
59
- fields: []
60
- };
61
- const lines = {
62
- type: 'LineString',
63
- pathIndices: linePositionsCount > 65535 ? new Uint32Array(linePathsCount + 1) : new Uint16Array(linePathsCount + 1),
64
- positions: new PositionDataType(linePositionsCount * coordLength),
65
- globalFeatureIds: new GlobalFeatureIdsDataType(linePositionsCount),
66
- featureIds: lineFeaturesCount > 65535 ? new Uint32Array(linePositionsCount) : new Uint16Array(linePositionsCount),
67
- numericProps: {},
68
- properties: [],
69
- fields: []
70
- };
71
- const polygons = {
72
- type: 'Polygon',
73
- polygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonObjectsCount + 1) : new Uint16Array(polygonObjectsCount + 1),
74
- primitivePolygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonRingsCount + 1) : new Uint16Array(polygonRingsCount + 1),
75
- positions: new PositionDataType(polygonPositionsCount * coordLength),
76
- triangles: [],
77
- globalFeatureIds: new GlobalFeatureIdsDataType(polygonPositionsCount),
78
- featureIds: polygonFeaturesCount > 65535 ? new Uint32Array(polygonPositionsCount) : new Uint16Array(polygonPositionsCount),
79
- numericProps: {},
80
- properties: [],
81
- fields: []
82
- };
83
-
84
- for (const object of [points, lines, polygons]) {
85
- for (const propName of numericPropKeys) {
86
- const T = propArrayTypes[propName];
87
- object.numericProps[propName] = new T(object.positions.length / coordLength);
88
- }
89
- }
90
-
91
- lines.pathIndices[linePathsCount] = linePositionsCount;
92
- polygons.polygonIndices[polygonObjectsCount] = polygonPositionsCount;
93
- polygons.primitivePolygonIndices[polygonRingsCount] = polygonPositionsCount;
94
- const indexMap = {
95
- pointPosition: 0,
96
- pointFeature: 0,
97
- linePosition: 0,
98
- linePath: 0,
99
- lineFeature: 0,
100
- polygonPosition: 0,
101
- polygonObject: 0,
102
- polygonRing: 0,
103
- polygonFeature: 0,
104
- feature: 0
105
- };
106
-
107
- for (const feature of features) {
108
- const geometry = feature.geometry;
109
- const properties = feature.properties || {};
110
-
111
- switch (geometry.type) {
112
- case 'Point':
113
- handlePoint(geometry, points, indexMap, coordLength, properties);
114
- points.properties.push(keepStringProperties(properties, numericPropKeys));
115
-
116
- if (hasGlobalId) {
117
- points.fields.push({
118
- id: feature.id
119
- });
120
- }
121
-
122
- indexMap.pointFeature++;
123
- break;
124
-
125
- case 'LineString':
126
- handleLineString(geometry, lines, indexMap, coordLength, properties);
127
- lines.properties.push(keepStringProperties(properties, numericPropKeys));
128
-
129
- if (hasGlobalId) {
130
- lines.fields.push({
131
- id: feature.id
132
- });
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);
133
120
  }
134
-
135
- indexMap.lineFeature++;
136
- break;
137
-
138
- case 'Polygon':
139
- handlePolygon(geometry, polygons, indexMap, coordLength, properties);
140
- polygons.properties.push(keepStringProperties(properties, numericPropKeys));
141
-
142
- if (hasGlobalId) {
143
- polygons.fields.push({
144
- id: feature.id
145
- });
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');
146
168
  }
147
-
148
- indexMap.polygonFeature++;
149
- break;
150
-
151
- default:
152
- throw new Error('Invalid geometry type');
169
+ indexMap.feature++;
153
170
  }
154
-
155
- indexMap.feature++;
156
- }
157
-
158
- return makeAccessorObjects(points, lines, polygons, coordLength);
171
+ // Wrap each array in an accessor object with value and size keys
172
+ return makeAccessorObjects(points, lines, polygons, coordLength);
159
173
  }
160
-
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
+ */
161
183
  function handlePoint(geometry, points, indexMap, coordLength, properties) {
162
- points.positions.set(geometry.data, indexMap.pointPosition * coordLength);
163
- const nPositions = geometry.data.length / coordLength;
164
- fillNumericProperties(points, properties, indexMap.pointPosition, nPositions);
165
- points.globalFeatureIds.fill(indexMap.feature, indexMap.pointPosition, indexMap.pointPosition + nPositions);
166
- points.featureIds.fill(indexMap.pointFeature, indexMap.pointPosition, indexMap.pointPosition + nPositions);
167
- indexMap.pointPosition += nPositions;
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;
168
190
  }
169
-
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
+ */
170
200
  function handleLineString(geometry, lines, indexMap, coordLength, properties) {
171
- lines.positions.set(geometry.data, indexMap.linePosition * coordLength);
172
- const nPositions = geometry.data.length / coordLength;
173
- fillNumericProperties(lines, properties, indexMap.linePosition, nPositions);
174
- lines.globalFeatureIds.fill(indexMap.feature, indexMap.linePosition, indexMap.linePosition + nPositions);
175
- lines.featureIds.fill(indexMap.lineFeature, indexMap.linePosition, indexMap.linePosition + nPositions);
176
-
177
- for (let i = 0, il = geometry.indices.length; i < il; ++i) {
178
- const start = geometry.indices[i];
179
- const end = i === il - 1 ? geometry.data.length : geometry.indices[i + 1];
180
- lines.pathIndices[indexMap.linePath++] = indexMap.linePosition;
181
- indexMap.linePosition += (end - start) / coordLength;
182
- }
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
+ }
183
216
  }
184
-
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
+ */
185
226
  function handlePolygon(geometry, polygons, indexMap, coordLength, properties) {
186
- polygons.positions.set(geometry.data, indexMap.polygonPosition * coordLength);
187
- const nPositions = geometry.data.length / coordLength;
188
- fillNumericProperties(polygons, properties, indexMap.polygonPosition, nPositions);
189
- polygons.globalFeatureIds.fill(indexMap.feature, indexMap.polygonPosition, indexMap.polygonPosition + nPositions);
190
- polygons.featureIds.fill(indexMap.polygonFeature, indexMap.polygonPosition, indexMap.polygonPosition + nPositions);
191
-
192
- for (let l = 0, ll = geometry.indices.length; l < ll; ++l) {
193
- const startPosition = indexMap.polygonPosition;
194
- polygons.polygonIndices[indexMap.polygonObject++] = startPosition;
195
- const areas = geometry.areas[l];
196
- const indices = geometry.indices[l];
197
- const nextIndices = geometry.indices[l + 1];
198
-
199
- for (let i = 0, il = indices.length; i < il; ++i) {
200
- const start = indices[i];
201
- const end = i === il - 1 ? nextIndices === undefined ? geometry.data.length : nextIndices[0] : indices[i + 1];
202
- polygons.primitivePolygonIndices[indexMap.polygonRing++] = indexMap.polygonPosition;
203
- indexMap.polygonPosition += (end - start) / coordLength;
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 });
204
252
  }
205
-
206
- const endPosition = indexMap.polygonPosition;
207
- triangulatePolygon(polygons, areas, indices, {
208
- startPosition,
209
- endPosition,
210
- coordLength
211
- });
212
- }
213
253
  }
214
-
215
- function triangulatePolygon(polygons, areas, indices, {
216
- startPosition,
217
- endPosition,
218
- coordLength
219
- }) {
220
- const start = startPosition * coordLength;
221
- const end = endPosition * coordLength;
222
- const polygonPositions = polygons.positions.subarray(start, end);
223
- const offset = indices[0];
224
- const holes = indices.slice(1).map(n => (n - offset) / coordLength);
225
- const triangles = earcut(polygonPositions, holes, coordLength, areas);
226
-
227
- for (let t = 0, tl = triangles.length; t < tl; ++t) {
228
- polygons.triangles.push(startPosition + triangles[t]);
229
- }
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
+ // @ts-expect-error TODO can earcut handle binary arrays? Add tests?
272
+ const triangles = (0, polygon_1.earcut)(polygonPositions, holes, coordLength, areas);
273
+ // Indices returned by triangulation are relative to start
274
+ // of polygon, so we need to offset
275
+ for (let t = 0, tl = triangles.length; t < tl; ++t) {
276
+ polygons.triangles.push(startPosition + triangles[t]);
277
+ }
230
278
  }
231
-
279
+ /**
280
+ * Wraps an object containing array into accessors
281
+ *
282
+ * @param obj
283
+ * @param size
284
+ */
232
285
  function wrapProps(obj, size) {
233
- const returnObj = {};
234
-
235
- for (const key in obj) {
236
- returnObj[key] = {
237
- value: obj[key],
238
- size
239
- };
240
- }
241
-
242
- return returnObj;
286
+ const returnObj = {};
287
+ for (const key in obj) {
288
+ returnObj[key] = { value: obj[key], size };
289
+ }
290
+ return returnObj;
243
291
  }
244
-
292
+ /**
293
+ * Wrap each array in an accessor object with value and size keys
294
+ *
295
+ * @param points
296
+ * @param lines
297
+ * @param polygons
298
+ * @param coordLength
299
+ * @returns object
300
+ */
245
301
  function makeAccessorObjects(points, lines, polygons, coordLength) {
246
- return {
247
- points: { ...points,
248
- positions: {
249
- value: points.positions,
250
- size: coordLength
251
- },
252
- globalFeatureIds: {
253
- value: points.globalFeatureIds,
254
- size: 1
255
- },
256
- featureIds: {
257
- value: points.featureIds,
258
- size: 1
259
- },
260
- numericProps: wrapProps(points.numericProps, 1)
261
- },
262
- lines: { ...lines,
263
- positions: {
264
- value: lines.positions,
265
- size: coordLength
266
- },
267
- pathIndices: {
268
- value: lines.pathIndices,
269
- size: 1
270
- },
271
- globalFeatureIds: {
272
- value: lines.globalFeatureIds,
273
- size: 1
274
- },
275
- featureIds: {
276
- value: lines.featureIds,
277
- size: 1
278
- },
279
- numericProps: wrapProps(lines.numericProps, 1)
280
- },
281
- polygons: { ...polygons,
282
- positions: {
283
- value: polygons.positions,
284
- size: coordLength
285
- },
286
- polygonIndices: {
287
- value: polygons.polygonIndices,
288
- size: 1
289
- },
290
- primitivePolygonIndices: {
291
- value: polygons.primitivePolygonIndices,
292
- size: 1
293
- },
294
- triangles: {
295
- value: new Uint32Array(polygons.triangles),
296
- size: 1
297
- },
298
- globalFeatureIds: {
299
- value: polygons.globalFeatureIds,
300
- size: 1
301
- },
302
- featureIds: {
303
- value: polygons.featureIds,
304
- size: 1
305
- },
306
- numericProps: wrapProps(polygons.numericProps, 1)
307
- }
308
- };
302
+ return {
303
+ points: {
304
+ ...points,
305
+ positions: { value: points.positions, size: coordLength },
306
+ globalFeatureIds: { value: points.globalFeatureIds, size: 1 },
307
+ featureIds: { value: points.featureIds, size: 1 },
308
+ numericProps: wrapProps(points.numericProps, 1)
309
+ },
310
+ lines: {
311
+ ...lines,
312
+ positions: { value: lines.positions, size: coordLength },
313
+ pathIndices: { value: lines.pathIndices, size: 1 },
314
+ globalFeatureIds: { value: lines.globalFeatureIds, size: 1 },
315
+ featureIds: { value: lines.featureIds, size: 1 },
316
+ numericProps: wrapProps(lines.numericProps, 1)
317
+ },
318
+ polygons: {
319
+ ...polygons,
320
+ positions: { value: polygons.positions, size: coordLength },
321
+ polygonIndices: { value: polygons.polygonIndices, size: 1 },
322
+ primitivePolygonIndices: { value: polygons.primitivePolygonIndices, size: 1 },
323
+ triangles: { value: new Uint32Array(polygons.triangles), size: 1 },
324
+ globalFeatureIds: { value: polygons.globalFeatureIds, size: 1 },
325
+ featureIds: { value: polygons.featureIds, size: 1 },
326
+ numericProps: wrapProps(polygons.numericProps, 1)
327
+ }
328
+ };
309
329
  }
310
-
330
+ /**
331
+ * Add numeric properties to object
332
+ *
333
+ * @param object
334
+ * @param properties
335
+ * @param index
336
+ * @param length
337
+ */
311
338
  function fillNumericProperties(object, properties, index, length) {
312
- for (const numericPropName in object.numericProps) {
313
- if (numericPropName in properties) {
314
- const value = properties[numericPropName];
315
- object.numericProps[numericPropName].fill(value, index, index + length);
339
+ for (const numericPropName in object.numericProps) {
340
+ if (numericPropName in properties) {
341
+ const value = properties[numericPropName];
342
+ object.numericProps[numericPropName].fill(value, index, index + length);
343
+ }
316
344
  }
317
- }
318
345
  }
319
-
346
+ /**
347
+ * Keep string properties in object
348
+ *
349
+ * @param properties
350
+ * @param numericKeys
351
+ * @returns object
352
+ */
320
353
  function keepStringProperties(properties, numericKeys) {
321
- const props = {};
322
-
323
- for (const key in properties) {
324
- if (!numericKeys.includes(key)) {
325
- props[key] = properties[key];
354
+ const props = {};
355
+ for (const key in properties) {
356
+ if (!numericKeys.includes(key)) {
357
+ props[key] = properties[key];
358
+ }
326
359
  }
327
- }
328
-
329
- return props;
360
+ return props;
330
361
  }
331
-
362
+ /**
363
+ *
364
+ * Deduce correct array constructor to use for a given value
365
+ *
366
+ * @param x value to test
367
+ * @param constructor previous constructor deduced
368
+ * @returns PropArrayConstructor
369
+ */
332
370
  function deduceArrayType(x, constructor) {
333
- if (constructor === Array || !Number.isFinite(x)) {
334
- return Array;
335
- }
336
-
337
- return constructor === Float64Array || Math.fround(x) !== x ? Float64Array : Float32Array;
371
+ if (constructor === Array || !Number.isFinite(x)) {
372
+ return Array;
373
+ }
374
+ // If this or previous value required 64bits use Float64Array
375
+ return constructor === Float64Array || Math.fround(x) !== x ? Float64Array : Float32Array;
338
376
  }
339
- //# sourceMappingURL=flat-geojson-to-binary.js.map