From cc6cc86ba41816a3a9e6d72723a84d1ad19c5f8c Mon Sep 17 00:00:00 2001 From: Kenny Daniel Date: Sun, 28 Sep 2025 22:13:18 -0700 Subject: [PATCH] Fix geospatial metadata parsing --- src/constants.js | 9 +++++++++ src/metadata.js | 17 +++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/constants.js b/src/constants.js index 821534c..c926860 100644 --- a/src/constants.js +++ b/src/constants.js @@ -83,3 +83,12 @@ export const BoundaryOrder = [ 'ASCENDING', 'DESCENDING', ] + +/** @type {import('../src/types.d.ts').EdgeInterpolationAlgorithm[]} */ +export const EdgeInterpolationAlgorithm = [ + 'SPHERICAL', + 'VINCENTY', + 'THOMAS', + 'ANDOYER', + 'KARNEY', +] diff --git a/src/metadata.js b/src/metadata.js index e4e4900..d7349d9 100644 --- a/src/metadata.js +++ b/src/metadata.js @@ -1,10 +1,15 @@ -import { CompressionCodec, ConvertedType, Encoding, FieldRepetitionType, PageType, ParquetType } from './constants.js' +import { CompressionCodec, ConvertedType, EdgeInterpolationAlgorithm, Encoding, FieldRepetitionType, PageType, ParquetType } from './constants.js' import { DEFAULT_PARSERS, parseDecimal, parseFloat16 } from './convert.js' import { getSchemaPath } from './schema.js' import { deserializeTCompactProtocol } from './thrift.js' export const defaultInitialFetchSize = 1 << 19 // 512kb +const decoder = new TextDecoder() +function decode(/** @type {Uint8Array} */ value) { + return value && decoder.decode(value) +} + /** * Read parquet metadata from an async buffer. * @@ -100,10 +105,6 @@ export function parquetMetadata(arrayBuffer, { parsers } = {}) { const metadataOffset = metadataLengthOffset - metadataLength const reader = { view, offset: metadataOffset } const metadata = deserializeTCompactProtocol(reader) - const decoder = new TextDecoder() - function decode(/** @type {Uint8Array} */ value) { - return value && decoder.decode(value) - } // Parse metadata from thrift data const version = metadata.field_1 @@ -249,12 +250,12 @@ function logicalType(logicalType) { if (logicalType?.field_16) return { type: 'VARIANT' } if (logicalType?.field_17) return { type: 'GEOMETRY', - crs: logicalType.field_17.field_1, + crs: decode(logicalType.field_17.field_1), } if (logicalType?.field_18) return { type: 'GEOGRAPHY', - crs: logicalType.field_18.field_1, - algorithm: logicalType.field_18.field_2, + crs: decode(logicalType.field_18.field_1), + algorithm: EdgeInterpolationAlgorithm[logicalType.field_18.field_2], } return logicalType }