File size: 1,399 Bytes
9ae1216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
 * @param {SchemaElement[]} schema
 * @param {KeyValue[] | undefined} key_value_metadata
 * @returns {void}
 */
export function markGeoColumns(schema, key_value_metadata) {
  // Prepare the list of GeoParquet columns
  /** @type {Map<string, LogicalType>} */
  const columns = new Map()
  const geo = key_value_metadata?.find(({ key }) => key === 'geo')?.value
  const decodedColumns = (geo && JSON.parse(geo)?.columns) ?? {}
  for (const [name, column] of Object.entries(decodedColumns)) {
    if (column.encoding !== 'WKB') continue

    const type = column.edges === 'spherical' ? 'GEOGRAPHY' : 'GEOMETRY'
    const id = column.crs?.id ?? column.crs?.ids?.[0]
    const crs = id ? `${id.authority}:${id.code.toString()}` : undefined
    // Note: we can't infer GEOGRAPHY's algorithm from GeoParquet
    columns.set(name, { type, crs })
  }

  // Mark schema elements with logical type
  // Only look at root-level columns of type BYTE_ARRAY without existing logical_type
  for (let i = 1; i < schema.length; i++) { // skip root
    const { logical_type, name, num_children, type } = schema[i]
    if (num_children) {
      i += num_children
      continue // skip the element and its children
    }
    if (type === 'BYTE_ARRAY' && !logical_type) {
      schema[i].logical_type = columns.get(name)
    }
  }
}

/**
 * @import {KeyValue, LogicalType, SchemaElement} from '../src/types.js'
 */