@loaders.gl/gis 4.2.0-alpha.4 → 4.2.0-alpha.5

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