"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // dist/index.js var dist_exports = {}; __export(dist_exports, { GEOPARQUET_METADATA_JSON_SCHEMA: () => GEOPARQUET_METADATA_JSON_SCHEMA, binaryToGeojson: () => binaryToGeojson, binaryToGeometry: () => binaryToGeometry, convertWKBTableToGeoJSON: () => convertWKBTableToGeoJSON, flatGeojsonToBinary: () => flatGeojsonToBinary, geojsonToBinary: () => geojsonToBinary, geojsonToFlatGeojson: () => geojsonToFlatGeojson, getGeoMetadata: () => getGeoMetadata, getGeometryColumnsFromSchema: () => getGeometryColumnsFromSchema, setGeoMetadata: () => setGeoMetadata, transformBinaryCoords: () => transformBinaryCoords, transformGeoJsonCoords: () => transformGeoJsonCoords, unpackGeoMetadata: () => unpackGeoMetadata, unpackJSONStringMetadata: () => unpackJSONStringMetadata }); module.exports = __toCommonJS(dist_exports); // dist/lib/geo/geoparquet-metadata-schema.js var GEOPARQUET_METADATA_JSON_SCHEMA = { $schema: "http://json-schema.org/draft-07/schema#", title: "GeoParquet", description: "Parquet metadata included in the geo field.", type: "object", required: ["version", "primary_column", "columns"], properties: { version: { type: "string", const: "1.0.0-beta.1" }, primary_column: { type: "string", minLength: 1 }, columns: { type: "object", minProperties: 1, patternProperties: { ".+": { type: "object", required: ["encoding", "geometry_types"], properties: { encoding: { type: "string", const: "WKB" }, geometry_types: { type: "array", uniqueItems: true, items: { type: "string", pattern: "^(GeometryCollection|(Multi)?(Point|LineString|Polygon))( Z)?$" } }, crs: { oneOf: [ { $ref: "https://proj.org/schemas/v0.5/projjson.schema.json" }, { type: "null" } ] }, edges: { type: "string", enum: ["planar", "spherical"] }, orientation: { type: "string", const: "counterclockwise" }, bbox: { type: "array", items: { type: "number" }, oneOf: [ { description: "2D bbox consisting of (xmin, ymin, xmax, ymax)", minItems: 4, maxItems: 4 }, { description: "3D bbox consisting of (xmin, ymin, zmin, xmax, ymax, zmax)", minItems: 6, maxItems: 6 } ] }, epoch: { type: "number" } } } }, additionalProperties: false } } }; // dist/lib/geo/geoparquet-metadata.js function getGeoMetadata(schema) { const geoMetadata = parseJSONStringMetadata(schema, "geo"); if (!geoMetadata) { return null; } for (const column of Object.values(geoMetadata.columns || {})) { if (column.encoding) { column.encoding = column.encoding.toLowerCase(); } } return geoMetadata; } function setGeoMetadata(schema, geoMetadata) { const stringifiedGeoMetadata = JSON.stringify(geoMetadata); schema.metadata.geo = stringifiedGeoMetadata; } function unpackGeoMetadata(schema) { const geoMetadata = getGeoMetadata(schema); if (!geoMetadata) { return; } const { version, primary_column, columns } = geoMetadata; if (version) { schema.metadata["geo.version"] = version; } if (primary_column) { schema.metadata["geo.primary_column"] = primary_column; } schema.metadata["geo.columns"] = Object.keys(columns || {}).join(""); for (const [columnName, columnMetadata] of Object.entries(columns || {})) { const field = schema.fields.find((field2) => field2.name === columnName); if (field) { if (field.name === primary_column) { setFieldMetadata(field, "geo.primary_field", "true"); } unpackGeoFieldMetadata(field, columnMetadata); } } } function unpackGeoFieldMetadata(field, columnMetadata) { for (const [key, value] of Object.entries(columnMetadata || {})) { switch (key) { case "geometry_types": setFieldMetadata(field, `geo.${key}`, value.join(",")); break; case "bbox": setFieldMetadata(field, `geo.crs.${key}`, JSON.stringify(value)); break; case "crs": for (const [crsKey, crsValue] of Object.entries(value || {})) { switch (crsKey) { case "id": const crsId = typeof crsValue === "object" ? ( // @ts-ignore `${crsValue == null ? void 0 : crsValue.authority}:${crsValue == null ? void 0 : crsValue.code}` ) : JSON.stringify(crsValue); setFieldMetadata(field, `geo.crs.${crsKey}`, crsId); break; default: setFieldMetadata(field, `geo.crs.${crsKey}`, typeof crsValue === "string" ? crsValue : JSON.stringify(crsValue)); break; } } break; case "edges": default: setFieldMetadata(field, `geo.${key}`, typeof value === "string" ? value : JSON.stringify(value)); } } } function setFieldMetadata(field, key, value) { field.metadata = field.metadata || {}; field.metadata[key] = value; } function parseJSONStringMetadata(schema, metadataKey) { const stringifiedMetadata = schema.metadata[metadataKey]; if (!stringifiedMetadata) { return null; } try { const metadata = JSON.parse(stringifiedMetadata); if (!metadata || typeof metadata !== "object") { return null; } return metadata; } catch { return null; } } function unpackJSONStringMetadata(schema, metadataKey) { const json = parseJSONStringMetadata(schema, metadataKey); for (const [key, value] of Object.entries(json || {})) { schema.metadata[`${metadataKey}.${key}`] = typeof value === "string" ? value : JSON.stringify(value); } } // dist/lib/geo/geoarrow-metadata.js var GEOARROW_ENCODINGS = [ "geoarrow.multipolygon", "geoarrow.polygon", "geoarrow.multilinestring", "geoarrow.linestring", "geoarrow.multipoint", "geoarrow.point", "geoarrow.wkb", "geoarrow.wkt" ]; var GEOARROW_COLUMN_METADATA_ENCODING = "ARROW:extension:name"; var GEOARROW_COLUMN_METADATA_METADATA = "ARROW:extension:metadata"; function getGeometryColumnsFromSchema(schema) { const geometryColumns = {}; for (const field of schema.fields) { const metadata = getGeometryMetadataForField(field); if (metadata) { geometryColumns[field.name] = metadata; } } return geometryColumns; } function getGeometryMetadataForField(field) { var _a, _b; let metadata = null; let geoEncoding = (_a = field.metadata) == null ? void 0 : _a[GEOARROW_COLUMN_METADATA_ENCODING]; if (geoEncoding) { geoEncoding = geoEncoding.toLowerCase(); if (geoEncoding === "wkb") { geoEncoding = "geoarrow.wkb"; } if (geoEncoding === "wkt") { geoEncoding = "geoarrow.wkt"; } if (!GEOARROW_ENCODINGS.includes(geoEncoding)) { console.warn(`Invalid GeoArrow encoding: ${geoEncoding}`); } else { metadata = metadata || {}; metadata.encoding = geoEncoding; } } const columnMetadata = (_b = field.metadata) == null ? void 0 : _b[GEOARROW_COLUMN_METADATA_METADATA]; if (columnMetadata) { try { metadata = JSON.parse(columnMetadata); } catch (error) { console.warn("Failed to parse GeoArrow metadata", error); } } return metadata || null; } // dist/lib/tables/convert-table-to-geojson.js var import_schema = require("@loaders.gl/schema"); function convertWKBTableToGeoJSON(table, schema, loaders) { const geoMetadata = getGeoMetadata(schema); const primaryColumn = geoMetadata == null ? void 0 : geoMetadata.primary_column; if (!primaryColumn) { throw new Error("no geometry column"); } const columnMetadata = geoMetadata.columns[primaryColumn]; const features = []; const length = (0, import_schema.getTableLength)(table); for (let rowIndex = 0; rowIndex < length; rowIndex++) { const row = (0, import_schema.getTableRowAsObject)(table, rowIndex); const geometry = parseGeometry(row[primaryColumn], columnMetadata, loaders); delete row[primaryColumn]; const feature = { type: "Feature", geometry, properties: row }; features.push(feature); } return { shape: "geojson-table", schema, type: "FeatureCollection", features }; } function parseGeometry(geometry, columnMetadata, loaders) { var _a, _b; switch (columnMetadata.encoding) { case "wkt": const wktLoader = loaders.find((loader) => loader.id === "wkt"); return ((_a = wktLoader == null ? void 0 : wktLoader.parseTextSync) == null ? void 0 : _a.call(wktLoader, geometry)) || null; case "wkb": default: const wkbLoader = loaders.find((loader) => loader.id === "wkb"); const arrayBuffer = ArrayBuffer.isView(geometry) ? geometry.buffer.slice(geometry.byteOffset, geometry.byteOffset + geometry.byteLength) : geometry; const geojson = (_b = wkbLoader == null ? void 0 : wkbLoader.parseSync) == null ? void 0 : _b.call(wkbLoader, arrayBuffer, { wkb: { shape: "geojson-geometry" } }); return geojson; } } // dist/lib/binary-features/flat-geojson-to-binary.js var import_polygon = require("@math.gl/polygon"); function flatGeojsonToBinary(features, geometryInfo, options) { const propArrayTypes = extractNumericPropTypes(features); const numericPropKeys = Object.keys(propArrayTypes).filter((k) => propArrayTypes[k] !== Array); return fillArrays(features, { propArrayTypes, ...geometryInfo }, { numericPropKeys: options && options.numericPropKeys || numericPropKeys, PositionDataType: options ? options.PositionDataType : Float32Array, triangulate: options ? options.triangulate : true }); } function extractNumericPropTypes(features) { const propArrayTypes = {}; for (const feature of features) { if (feature.properties) { for (const key in feature.properties) { const val = feature.properties[key]; propArrayTypes[key] = deduceArrayType(val, propArrayTypes[key]); } } } return propArrayTypes; } function fillArrays(features, geometryInfo, options) { const { pointPositionsCount, pointFeaturesCount, linePositionsCount, linePathsCount, lineFeaturesCount, polygonPositionsCount, polygonObjectsCount, polygonRingsCount, polygonFeaturesCount, propArrayTypes, coordLength } = geometryInfo; const { numericPropKeys = [], PositionDataType = Float32Array, triangulate = true } = options; const hasGlobalId = features[0] && "id" in features[0]; const GlobalFeatureIdsDataType = features.length > 65535 ? Uint32Array : Uint16Array; const points = { type: "Point", positions: new PositionDataType(pointPositionsCount * coordLength), globalFeatureIds: new GlobalFeatureIdsDataType(pointPositionsCount), featureIds: pointFeaturesCount > 65535 ? new Uint32Array(pointPositionsCount) : new Uint16Array(pointPositionsCount), numericProps: {}, properties: [], fields: [] }; const lines = { type: "LineString", 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: [], fields: [] }; const polygons = { type: "Polygon", 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), globalFeatureIds: new GlobalFeatureIdsDataType(polygonPositionsCount), featureIds: polygonFeaturesCount > 65535 ? new Uint32Array(polygonPositionsCount) : new Uint16Array(polygonPositionsCount), numericProps: {}, properties: [], fields: [] }; if (triangulate) { polygons.triangles = []; } for (const object of [points, lines, polygons]) { for (const propName of numericPropKeys) { const T = propArrayTypes[propName]; object.numericProps[propName] = new T(object.positions.length / coordLength); } } lines.pathIndices[linePathsCount] = linePositionsCount; polygons.polygonIndices[polygonObjectsCount] = polygonPositionsCount; polygons.primitivePolygonIndices[polygonRingsCount] = polygonPositionsCount; const indexMap = { pointPosition: 0, pointFeature: 0, linePosition: 0, linePath: 0, lineFeature: 0, polygonPosition: 0, polygonObject: 0, polygonRing: 0, polygonFeature: 0, feature: 0 }; for (const feature of features) { const geometry = feature.geometry; const properties = feature.properties || {}; switch (geometry.type) { case "Point": handlePoint(geometry, points, indexMap, coordLength, properties); points.properties.push(keepStringProperties(properties, numericPropKeys)); if (hasGlobalId) { points.fields.push({ id: feature.id }); } indexMap.pointFeature++; break; case "LineString": handleLineString(geometry, lines, indexMap, coordLength, properties); lines.properties.push(keepStringProperties(properties, numericPropKeys)); if (hasGlobalId) { lines.fields.push({ id: feature.id }); } indexMap.lineFeature++; break; case "Polygon": handlePolygon(geometry, polygons, indexMap, coordLength, properties); polygons.properties.push(keepStringProperties(properties, numericPropKeys)); if (hasGlobalId) { polygons.fields.push({ id: feature.id }); } indexMap.polygonFeature++; break; default: throw new Error("Invalid geometry type"); } indexMap.feature++; } return makeAccessorObjects(points, lines, polygons, coordLength); } function handlePoint(geometry, points, indexMap, coordLength, properties) { points.positions.set(geometry.data, indexMap.pointPosition * coordLength); const 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); const 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 (let i = 0, il = geometry.indices.length; i < il; ++i) { const start = geometry.indices[i]; const end = i === il - 1 ? geometry.data.length : geometry.indices[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); const 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 (let l = 0, ll = geometry.indices.length; l < ll; ++l) { const startPosition = indexMap.polygonPosition; polygons.polygonIndices[indexMap.polygonObject++] = startPosition; const areas = geometry.areas[l]; const indices = geometry.indices[l]; const nextIndices = geometry.indices[l + 1]; for (let i = 0, il = indices.length; i < il; ++i) { const start = indices[i]; const end = i === il - 1 ? ( // last line, so either read to: nextIndices === void 0 ? geometry.data.length : nextIndices[0] ) : indices[i + 1]; polygons.primitivePolygonIndices[indexMap.polygonRing++] = indexMap.polygonPosition; indexMap.polygonPosition += (end - start) / coordLength; } const endPosition = indexMap.polygonPosition; triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength }); } } function triangulatePolygon(polygons, areas, indices, { startPosition, endPosition, coordLength }) { if (!polygons.triangles) { return; } const start = startPosition * coordLength; const end = endPosition * coordLength; const polygonPositions = polygons.positions.subarray(start, end); const offset = indices[0]; const holes = indices.slice(1).map((n) => (n - offset) / coordLength); const triangles = (0, import_polygon.earcut)(polygonPositions, holes, coordLength, areas); for (let t = 0, tl = triangles.length; t < tl; ++t) { polygons.triangles.push(startPosition + triangles[t]); } } function wrapProps(obj, size) { const returnObj = {}; for (const key in obj) { returnObj[key] = { value: obj[key], size }; } return returnObj; } function makeAccessorObjects(points, lines, polygons, coordLength) { const binaryFeatures = { shape: "binary-feature-collection", points: { ...points, positions: { value: points.positions, size: coordLength }, globalFeatureIds: { value: points.globalFeatureIds, size: 1 }, featureIds: { value: points.featureIds, size: 1 }, numericProps: wrapProps(points.numericProps, 1) }, lines: { ...lines, positions: { value: lines.positions, size: coordLength }, pathIndices: { value: lines.pathIndices, size: 1 }, globalFeatureIds: { value: lines.globalFeatureIds, size: 1 }, featureIds: { value: lines.featureIds, size: 1 }, numericProps: wrapProps(lines.numericProps, 1) }, polygons: { ...polygons, positions: { value: polygons.positions, size: coordLength }, polygonIndices: { value: polygons.polygonIndices, size: 1 }, primitivePolygonIndices: { value: polygons.primitivePolygonIndices, size: 1 }, globalFeatureIds: { value: polygons.globalFeatureIds, size: 1 }, featureIds: { value: polygons.featureIds, size: 1 }, numericProps: wrapProps(polygons.numericProps, 1) } // triangles not expected }; if (binaryFeatures.polygons && polygons.triangles) { binaryFeatures.polygons.triangles = { value: new Uint32Array(polygons.triangles), size: 1 }; } return binaryFeatures; } function fillNumericProperties(object, properties, index, length) { for (const numericPropName in object.numericProps) { if (numericPropName in properties) { const value = properties[numericPropName]; object.numericProps[numericPropName].fill(value, index, index + length); } } } function keepStringProperties(properties, numericKeys) { const props = {}; for (const key in properties) { if (!numericKeys.includes(key)) { props[key] = properties[key]; } } return props; } function deduceArrayType(x, constructor) { if (constructor === Array || !Number.isFinite(x)) { return Array; } return constructor === Float64Array || Math.fround(x) !== x ? Float64Array : Float32Array; } // dist/lib/binary-features/extract-geometry-info.js function extractGeometryInfo(features) { let pointPositionsCount = 0; let pointFeaturesCount = 0; let linePositionsCount = 0; let linePathsCount = 0; let lineFeaturesCount = 0; let polygonPositionsCount = 0; let polygonObjectsCount = 0; let polygonRingsCount = 0; let polygonFeaturesCount = 0; const coordLengths = /* @__PURE__ */ new Set(); for (const feature of features) { const geometry = feature.geometry; switch (geometry.type) { case "Point": pointFeaturesCount++; pointPositionsCount++; coordLengths.add(geometry.coordinates.length); break; case "MultiPoint": pointFeaturesCount++; pointPositionsCount += geometry.coordinates.length; for (const point of geometry.coordinates) { coordLengths.add(point.length); } break; case "LineString": lineFeaturesCount++; linePositionsCount += geometry.coordinates.length; linePathsCount++; for (const coord of geometry.coordinates) { coordLengths.add(coord.length); } break; case "MultiLineString": lineFeaturesCount++; for (const line of geometry.coordinates) { linePositionsCount += line.length; linePathsCount++; for (const coord of line) { coordLengths.add(coord.length); } } break; case "Polygon": polygonFeaturesCount++; polygonObjectsCount++; polygonRingsCount += geometry.coordinates.length; const flattened = geometry.coordinates.flat(); polygonPositionsCount += flattened.length; for (const coord of flattened) { coordLengths.add(coord.length); } break; case "MultiPolygon": polygonFeaturesCount++; for (const polygon of geometry.coordinates) { polygonObjectsCount++; polygonRingsCount += polygon.length; const flattened2 = polygon.flat(); polygonPositionsCount += flattened2.length; for (const coord of flattened2) { coordLengths.add(coord.length); } } break; default: throw new Error(`Unsupported geometry type: ${geometry.type}`); } } return { coordLength: coordLengths.size > 0 ? Math.max(...coordLengths) : 2, pointPositionsCount, pointFeaturesCount, linePositionsCount, linePathsCount, lineFeaturesCount, polygonPositionsCount, polygonObjectsCount, polygonRingsCount, polygonFeaturesCount }; } // dist/lib/binary-features/geojson-to-flat-geojson.js var import_polygon2 = require("@math.gl/polygon"); function geojsonToFlatGeojson(features, options = { coordLength: 2, fixRingWinding: true }) { return features.map((feature) => flattenFeature(feature, options)); } function flattenPoint(coordinates, data, indices, options) { indices.push(data.length); data.push(...coordinates); for (let i = coordinates.length; i < options.coordLength; i++) { data.push(0); } } function flattenLineString(coordinates, data, indices, options) { indices.push(data.length); for (const c of coordinates) { data.push(...c); for (let i = c.length; i < options.coordLength; i++) { data.push(0); } } } function flattenPolygon(coordinates, data, indices, areas, options) { let count = 0; const ringAreas = []; const polygons = []; for (const lineString of coordinates) { const lineString2d = lineString.map((p) => p.slice(0, 2)); let area = (0, import_polygon2.getPolygonSignedArea)(lineString2d.flat()); const ccw = area < 0; if (options.fixRingWinding && (count === 0 && !ccw || count > 0 && ccw)) { lineString.reverse(); area = -area; } ringAreas.push(area); flattenLineString(lineString, data, polygons, options); count++; } if (count > 0) { areas.push(ringAreas); indices.push(polygons); } } function flattenFeature(feature, options) { const { geometry } = feature; if (geometry.type === "GeometryCollection") { throw new Error("GeometryCollection type not supported"); } const data = []; const indices = []; let areas; let type; switch (geometry.type) { case "Point": type = "Point"; flattenPoint(geometry.coordinates, data, indices, options); break; case "MultiPoint": type = "Point"; geometry.coordinates.map((c) => flattenPoint(c, data, indices, options)); break; case "LineString": type = "LineString"; flattenLineString(geometry.coordinates, data, indices, options); break; case "MultiLineString": type = "LineString"; geometry.coordinates.map((c) => flattenLineString(c, data, indices, options)); break; case "Polygon": type = "Polygon"; areas = []; flattenPolygon(geometry.coordinates, data, indices, areas, options); break; case "MultiPolygon": type = "Polygon"; areas = []; geometry.coordinates.map((c) => flattenPolygon(c, data, indices, areas, options)); break; default: throw new Error(`Unknown type: ${type}`); } return { ...feature, geometry: { type, indices, data, areas } }; } // dist/lib/binary-features/geojson-to-binary.js function geojsonToBinary(features, options = { fixRingWinding: true, triangulate: true }) { const geometryInfo = extractGeometryInfo(features); const coordLength = geometryInfo.coordLength; const { fixRingWinding } = options; const flatFeatures = geojsonToFlatGeojson(features, { coordLength, fixRingWinding }); return flatGeojsonToBinary(flatFeatures, geometryInfo, { numericPropKeys: options.numericPropKeys, PositionDataType: options.PositionDataType || Float32Array, triangulate: options.triangulate }); } // dist/lib/binary-features/binary-to-geojson.js function binaryToGeojson(data, options) { const globalFeatureId = options == null ? void 0 : options.globalFeatureId; if (globalFeatureId !== void 0) { return getSingleFeature(data, globalFeatureId); } return parseFeatures(data, options == null ? void 0 : options.type); } function getSingleFeature(data, globalFeatureId) { const dataArray = normalizeInput(data); for (const data2 of dataArray) { let lastIndex = 0; let lastValue = data2.featureIds.value[0]; for (let i = 0; i < data2.featureIds.value.length; i++) { const currValue = data2.featureIds.value[i]; if (currValue === lastValue) { continue; } if (globalFeatureId === data2.globalFeatureIds.value[lastIndex]) { return parseFeature(data2, lastIndex, i); } lastIndex = i; lastValue = currValue; } if (globalFeatureId === data2.globalFeatureIds.value[lastIndex]) { return parseFeature(data2, lastIndex, data2.featureIds.value.length); } } throw new Error(`featureId:${globalFeatureId} not found`); } function parseFeatures(data, type) { const dataArray = normalizeInput(data, type); return parseFeatureCollection(dataArray); } function binaryToGeometry(data, startIndex, endIndex) { switch (data.type) { case "Point": return pointToGeoJson(data, startIndex, endIndex); case "LineString": return lineStringToGeoJson(data, startIndex, endIndex); case "Polygon": return polygonToGeoJson(data, startIndex, endIndex); default: const unexpectedInput = data; throw new Error(`Unsupported geometry type: ${unexpectedInput == null ? void 0 : unexpectedInput.type}`); } } function normalizeInput(data, type) { const features = []; if (data.points) { data.points.type = "Point"; features.push(data.points); } if (data.lines) { data.lines.type = "LineString"; features.push(data.lines); } if (data.polygons) { data.polygons.type = "Polygon"; features.push(data.polygons); } return features; } function parseFeatureCollection(dataArray) { const features = []; for (const data of dataArray) { if (data.featureIds.value.length === 0) { continue; } let lastIndex = 0; let lastValue = data.featureIds.value[0]; for (let i = 0; i < data.featureIds.value.length; i++) { const currValue = data.featureIds.value[i]; if (currValue === lastValue) { continue; } features.push(parseFeature(data, lastIndex, i)); lastIndex = i; lastValue = currValue; } features.push(parseFeature(data, lastIndex, data.featureIds.value.length)); } return features; } function parseFeature(data, startIndex, endIndex) { const geometry = binaryToGeometry(data, startIndex, endIndex); const properties = parseProperties(data, startIndex, endIndex); const fields = parseFields(data, startIndex, endIndex); return { type: "Feature", geometry, properties, ...fields }; } function parseFields(data, startIndex = 0, endIndex) { return data.fields && data.fields[data.featureIds.value[startIndex]]; } function parseProperties(data, startIndex = 0, endIndex) { const properties = Object.assign({}, data.properties[data.featureIds.value[startIndex]]); for (const key in data.numericProps) { properties[key] = data.numericProps[key].value[startIndex]; } return properties; } function polygonToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) { const { positions } = data; const polygonIndices = data.polygonIndices.value.filter((x) => x >= startIndex && x <= endIndex); const primitivePolygonIndices = data.primitivePolygonIndices.value.filter((x) => x >= startIndex && x <= endIndex); const multi = polygonIndices.length > 2; if (!multi) { const coordinates2 = []; for (let i = 0; i < primitivePolygonIndices.length - 1; i++) { const startRingIndex = primitivePolygonIndices[i]; const endRingIndex = primitivePolygonIndices[i + 1]; const ringCoordinates = ringToGeoJson(positions, startRingIndex, endRingIndex); coordinates2.push(ringCoordinates); } return { type: "Polygon", coordinates: coordinates2 }; } const coordinates = []; for (let i = 0; i < polygonIndices.length - 1; i++) { const startPolygonIndex = polygonIndices[i]; const endPolygonIndex = polygonIndices[i + 1]; const polygonCoordinates = polygonToGeoJson(data, startPolygonIndex, endPolygonIndex).coordinates; coordinates.push(polygonCoordinates); } return { type: "MultiPolygon", coordinates }; } function lineStringToGeoJson(data, startIndex = -Infinity, endIndex = Infinity) { const { positions } = data; const pathIndices = data.pathIndices.value.filter((x) => x >= startIndex && x <= endIndex); const multi = pathIndices.length > 2; if (!multi) { const coordinates2 = ringToGeoJson(positions, pathIndices[0], pathIndices[1]); return { type: "LineString", coordinates: coordinates2 }; } const coordinates = []; for (let i = 0; i < pathIndices.length - 1; i++) { const ringCoordinates = ringToGeoJson(positions, pathIndices[i], pathIndices[i + 1]); coordinates.push(ringCoordinates); } return { type: "MultiLineString", coordinates }; } function pointToGeoJson(data, startIndex, endIndex) { const { positions } = data; const coordinates = ringToGeoJson(positions, startIndex, endIndex); const multi = coordinates.length > 1; if (multi) { return { type: "MultiPoint", coordinates }; } return { type: "Point", coordinates: coordinates[0] }; } function ringToGeoJson(positions, startIndex, endIndex) { startIndex = startIndex || 0; endIndex = endIndex || positions.value.length / positions.size; const ringCoordinates = []; for (let j = startIndex; j < endIndex; j++) { const coord = Array(); for (let k = j * positions.size; k < (j + 1) * positions.size; k++) { coord.push(Number(positions.value[k])); } ringCoordinates.push(coord); } return ringCoordinates; } // dist/lib/binary-features/transform.js function transformBinaryCoords(binaryFeatures, transformCoordinate) { if (binaryFeatures.points) { transformBinaryGeometryPositions(binaryFeatures.points, transformCoordinate); } if (binaryFeatures.lines) { transformBinaryGeometryPositions(binaryFeatures.lines, transformCoordinate); } if (binaryFeatures.polygons) { transformBinaryGeometryPositions(binaryFeatures.polygons, transformCoordinate); } return binaryFeatures; } function transformBinaryGeometryPositions(binaryGeometry, fn) { const { positions } = binaryGeometry; for (let i = 0; i < positions.value.length; i += positions.size) { const coord = Array.from(positions.value.subarray(i, i + positions.size)); const transformedCoord = fn(coord); positions.value.set(transformedCoord, i); } } function transformGeoJsonCoords(features, fn) { for (const feature of features) { feature.geometry.coordinates = coordMap(feature.geometry.coordinates, fn); } return features; } function coordMap(array, fn) { if (isCoord(array)) { return fn(array); } return array.map((item) => { return coordMap(item, fn); }); } function isCoord(array) { return Array.isArray(array) && Number.isFinite(array[0]) && Number.isFinite(array[1]); } //# sourceMappingURL=index.cjs.map