UNPKG

@kibeo/loaders.gl-mvt

Version:

Loader for Mapbox Vector Tiles

361 lines (318 loc) 13.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.featuresToBinary = featuresToBinary; exports.TEST_EXPORTS = void 0; var _polygon = require("@math.gl/polygon"); function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function featuresToBinary(features, firstPassData) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return fillArrays(features, firstPassData, { numericPropKeys: options.numericPropKeys || extractNumericPropKeys(features), PositionDataType: options.PositionDataType || Float32Array }); } var TEST_EXPORTS = { extractNumericPropKeys: extractNumericPropKeys, fillArrays: fillArrays }; exports.TEST_EXPORTS = TEST_EXPORTS; function extractNumericPropKeys(features) { var numericPropKeys = {}; var _iterator = _createForOfIteratorHelper(features), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var feature = _step.value; if (feature.properties) { for (var key in feature.properties) { var numericSoFar = numericPropKeys[key]; if (numericSoFar || numericSoFar === undefined) { var val = feature.properties[key]; numericPropKeys[key] = isNumeric(val); } } } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return Object.keys(numericPropKeys).filter(function (k) { return numericPropKeys[k]; }); } function fillArrays(features) { var firstPassData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var pointPositionsCount = firstPassData.pointPositionsCount, pointFeaturesCount = firstPassData.pointFeaturesCount, linePositionsCount = firstPassData.linePositionsCount, linePathsCount = firstPassData.linePathsCount, lineFeaturesCount = firstPassData.lineFeaturesCount, polygonPositionsCount = firstPassData.polygonPositionsCount, polygonObjectsCount = firstPassData.polygonObjectsCount, polygonRingsCount = firstPassData.polygonRingsCount, polygonFeaturesCount = firstPassData.polygonFeaturesCount; var numericPropKeys = options.numericPropKeys, _options$PositionData = options.PositionDataType, PositionDataType = _options$PositionData === void 0 ? Float32Array : _options$PositionData; var coordLength = 2; var GlobalFeatureIdsDataType = features.length > 65535 ? Uint32Array : Uint16Array; var points = { positions: new PositionDataType(pointPositionsCount * coordLength), globalFeatureIds: new GlobalFeatureIdsDataType(pointPositionsCount), featureIds: pointFeaturesCount > 65535 ? new Uint32Array(pointPositionsCount) : new Uint16Array(pointPositionsCount), numericProps: {}, properties: [] }; var lines = { pathIndices: linePositionsCount > 65535 ? new Uint32Array(linePathsCount + 1) : new Uint16Array(linePathsCount + 1), positions: new PositionDataType(linePositionsCount * coordLength), globalFeatureIds: new GlobalFeatureIdsDataType(linePositionsCount), featureIds: lineFeaturesCount > 65535 ? new Uint32Array(linePositionsCount) : new Uint16Array(linePositionsCount), numericProps: {}, properties: [] }; var polygons = { polygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonObjectsCount + 1) : new Uint16Array(polygonObjectsCount + 1), primitivePolygonIndices: polygonPositionsCount > 65535 ? new Uint32Array(polygonRingsCount + 1) : new Uint16Array(polygonRingsCount + 1), positions: new PositionDataType(polygonPositionsCount * coordLength), triangles: [], globalFeatureIds: new GlobalFeatureIdsDataType(polygonPositionsCount), featureIds: polygonFeaturesCount > 65535 ? new Uint32Array(polygonPositionsCount) : new Uint16Array(polygonPositionsCount), numericProps: {}, properties: [] }; for (var _i = 0, _arr = [points, lines, polygons]; _i < _arr.length; _i++) { var object = _arr[_i]; var _iterator2 = _createForOfIteratorHelper(numericPropKeys), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var propName = _step2.value; object.numericProps[propName] = new Float32Array(object.positions.length / coordLength); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } } lines.pathIndices[linePathsCount] = linePositionsCount; polygons.polygonIndices[polygonObjectsCount] = polygonPositionsCount; polygons.primitivePolygonIndices[polygonRingsCount] = polygonPositionsCount; var indexMap = { pointPosition: 0, pointFeature: 0, linePosition: 0, linePath: 0, lineFeature: 0, polygonPosition: 0, polygonObject: 0, polygonRing: 0, polygonFeature: 0, feature: 0 }; var _iterator3 = _createForOfIteratorHelper(features), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var feature = _step3.value; var geometry = feature.geometry; var properties = feature.properties || {}; switch (geometry.type) { case 'Point': case 'MultiPoint': handlePoint(geometry, points, indexMap, coordLength, properties); points.properties.push(keepStringProperties(properties, numericPropKeys)); indexMap.pointFeature++; break; case 'LineString': case 'MultiLineString': handleLineString(geometry, lines, indexMap, coordLength, properties); lines.properties.push(keepStringProperties(properties, numericPropKeys)); indexMap.lineFeature++; break; case 'Polygon': case 'MultiPolygon': handlePolygon(geometry, polygons, indexMap, coordLength, properties); polygons.properties.push(keepStringProperties(properties, numericPropKeys)); indexMap.polygonFeature++; break; default: throw new Error('Invalid geometry type'); } indexMap.feature++; } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } return makeAccessorObjects(points, lines, polygons, coordLength); } function handlePoint(geometry, points, indexMap, coordLength, properties) { points.positions.set(geometry.data, indexMap.pointPosition * coordLength); var nPositions = geometry.data.length / coordLength; fillNumericProperties(points, properties, indexMap.pointPosition, nPositions); points.globalFeatureIds.fill(indexMap.feature, indexMap.pointPosition, indexMap.pointPosition + nPositions); points.featureIds.fill(indexMap.pointFeature, indexMap.pointPosition, indexMap.pointPosition + nPositions); indexMap.pointPosition += nPositions; } function handleLineString(geometry, lines, indexMap, coordLength, properties) { lines.positions.set(geometry.data, indexMap.linePosition * coordLength); var nPositions = geometry.data.length / coordLength; fillNumericProperties(lines, properties, indexMap.linePosition, nPositions); lines.globalFeatureIds.fill(indexMap.feature, indexMap.linePosition, indexMap.linePosition + nPositions); lines.featureIds.fill(indexMap.lineFeature, indexMap.linePosition, indexMap.linePosition + nPositions); for (var i = 0, il = geometry.lines.length; i < il; ++i) { var start = geometry.lines[i]; var end = i === il - 1 ? geometry.data.length : geometry.lines[i + 1]; lines.pathIndices[indexMap.linePath++] = indexMap.linePosition; indexMap.linePosition += (end - start) / coordLength; } } function handlePolygon(geometry, polygons, indexMap, coordLength, properties) { polygons.positions.set(geometry.data, indexMap.polygonPosition * coordLength); var nPositions = geometry.data.length / coordLength; fillNumericProperties(polygons, properties, indexMap.polygonPosition, nPositions); polygons.globalFeatureIds.fill(indexMap.feature, indexMap.polygonPosition, indexMap.polygonPosition + nPositions); polygons.featureIds.fill(indexMap.polygonFeature, indexMap.polygonPosition, indexMap.polygonPosition + nPositions); for (var l = 0, ll = geometry.lines.length; l < ll; ++l) { var startPosition = indexMap.polygonPosition; polygons.polygonIndices[indexMap.polygonObject++] = startPosition; var areas = geometry.areas[l]; var lines = geometry.lines[l]; var nextLines = geometry.lines[l + 1]; for (var i = 0, il = lines.length; i < il; ++i) { var start = lines[i]; var end = i === il - 1 ? nextLines === undefined ? geometry.data.length : nextLines[0] : lines[i + 1]; polygons.primitivePolygonIndices[indexMap.polygonRing++] = indexMap.polygonPosition; indexMap.polygonPosition += (end - start) / coordLength; } var endPosition = indexMap.polygonPosition; triangulatePolygon(polygons, areas, lines, { startPosition: startPosition, endPosition: endPosition, coordLength: coordLength }); } } function triangulatePolygon(polygons, areas, lines, _ref) { var startPosition = _ref.startPosition, endPosition = _ref.endPosition, coordLength = _ref.coordLength; var start = startPosition * coordLength; var end = endPosition * coordLength; var polygonPositions = polygons.positions.subarray(start, end); var offset = lines[0]; var holes = lines.slice(1).map(function (n) { return (n - offset) / coordLength; }); var indices = (0, _polygon.earcut)(polygonPositions, holes, coordLength, areas); for (var t = 0, tl = indices.length; t < tl; ++t) { polygons.triangles.push(startPosition + indices[t]); } } function makeAccessorObjects(points, lines, polygons, coordLength) { var returnObj = { points: { positions: { value: points.positions, size: coordLength }, globalFeatureIds: { value: points.globalFeatureIds, size: 1 }, featureIds: { value: points.featureIds, size: 1 }, numericProps: points.numericProps, properties: points.properties }, lines: { pathIndices: { value: lines.pathIndices, size: 1 }, positions: { value: lines.positions, size: coordLength }, globalFeatureIds: { value: lines.globalFeatureIds, size: 1 }, featureIds: { value: lines.featureIds, size: 1 }, numericProps: lines.numericProps, properties: lines.properties }, polygons: { polygonIndices: { value: polygons.polygonIndices, size: 1 }, primitivePolygonIndices: { value: polygons.primitivePolygonIndices, size: 1 }, positions: { value: polygons.positions, size: coordLength }, triangles: { value: new Uint32Array(polygons.triangles), size: 1 }, globalFeatureIds: { value: polygons.globalFeatureIds, size: 1 }, featureIds: { value: polygons.featureIds, size: 1 }, numericProps: polygons.numericProps, properties: polygons.properties } }; for (var geomType in returnObj) { for (var numericProp in returnObj[geomType].numericProps) { returnObj[geomType].numericProps[numericProp] = { value: returnObj[geomType].numericProps[numericProp], size: 1 }; } } return returnObj; } function fillNumericProperties(object, properties, index, length) { for (var numericPropName in object.numericProps) { if (numericPropName in properties) { object.numericProps[numericPropName].fill(properties[numericPropName], index, index + length); } } } function keepStringProperties(properties, numericKeys) { var props = {}; for (var key in properties) { if (!numericKeys.includes(key)) { props[key] = properties[key]; } } return props; } function isNumeric(x) { return Number.isFinite(x); } //# sourceMappingURL=features-to-binary.js.map