UNPKG

@loaders.gl/geoarrow

Version:

GeoArrow columnar geometry encoding and decoding

125 lines (124 loc) 3.98 kB
// loaders.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import * as arrow from 'apache-arrow'; /** * Examines a column containing GeoArrow formatted data and returns information about the geometry type * that can be useful during traversal * @see https://geoarrow.org/format.html#memory-layouts */ // eslint-disable-next-line max-statements export function getGeoArrowGeometryInfo(arrowField) { if (arrowField.type instanceof arrow.Utf8) { return { compatibleEncodings: ['geoarrow.wkt'], nesting: 0, /** @note: Dimension encoded in WKT */ dimension: 2, coordinates: 'interleaved', valueType: 'double' }; } if (arrowField.type instanceof arrow.Binary || arrowField.type instanceof arrow.LargeBinary) { return { compatibleEncodings: ['geoarrow.wkb'], nesting: 0, /** @note: Dimension encoded in WKB */ dimension: 2, coordinates: 'interleaved', valueType: 'double' }; } let coordinateInfo = getCoordinateFieldInfo(arrowField); // A point is just a Coordinate if (coordinateInfo) { return { compatibleEncodings: ['geoarrow.point'], nesting: 0, ...coordinateInfo }; } // A line string or a multipoint is a List<Coordinate> if (!(arrowField.type instanceof arrow.List)) { return null; } arrowField = arrowField.type.children[0]; coordinateInfo = getCoordinateFieldInfo(arrowField); if (coordinateInfo) { return { compatibleEncodings: ['geoarrow.linestring', 'geoarrow.multipoint'], nesting: 1, ...coordinateInfo }; } // A polygon or a multiline string are List<List<Coordinate>> if (!(arrowField.type instanceof arrow.List)) { return null; } arrowField = arrowField.type.children[0]; coordinateInfo = getCoordinateFieldInfo(arrowField); if (coordinateInfo) { return { compatibleEncodings: ['geoarrow.polygon', 'geoarrow.multilinestring'], nesting: 2, ...coordinateInfo }; } // A multipolygons are List<List<List<Coordinate>>> if (!(arrowField.type instanceof arrow.List)) { return null; } arrowField = arrowField.type.children[0]; coordinateInfo = getCoordinateFieldInfo(arrowField); if (coordinateInfo) { return { compatibleEncodings: ['geoarrow.multipolygon'], nesting: 3, ...coordinateInfo }; } return null; } /** * @see https://geoarrow.org/format.html#memory-layouts */ function getCoordinateFieldInfo(arrowField) { // interleaved case if (arrowField.type instanceof arrow.FixedSizeList) { const dimension = arrowField.type.listSize; if (dimension < 2 || dimension > 4) { return null; } const child = arrowField.type.children[0]; // Spec currently only supports 64 bit coordinates if (!(child.type instanceof arrow.Float)) { return null; } return { coordinates: 'interleaved', dimension: dimension, valueType: 'double' }; } // separated case if (arrowField.type instanceof arrow.Struct) { const children = arrowField.type.children; const dimension = children.length; if (dimension < 2 || dimension > 4) { return null; } // Spec currently only supports 64 bit coordinates for (const child of children) { if (!(child.type instanceof arrow.Float)) { return null; } } return { coordinates: 'separated', dimension: dimension, valueType: 'double' }; } // No other types are valid coordinates return null; }