Как извлечь отдельные значения из GeoJSON в BigQuery - PullRequest
1 голос
/ 26 марта 2019

У меня есть строка GeoJSON для многоточечной геометрии. Я хочу извлечь каждую из этих точек в таблицу отдельных геометрических точек в BigQuery

Мне удалось достичь геометрической точки для одной из точек. Я хочу сделать это для всех остальных в автоматическом режиме. Я уже пытался преобразовать строку в массив, но он остается массивом размера 1 со всем содержимым в виде одной строки.

Это то, что мне помогло: я смог извлечь одну точку и преобразовать ее в геометрию

WITH temp_table as (select '{ "type": "MultiPoint", "coordinates": [ [ 20, 10 ], [ 30, 5 ], [ 90, 50 ], [ 40, 80 ] ]  }' as string) 

select ST_GEOGPOINT(CAST(JSON_EXTRACT(string, '$.coordinates[0][0]') as FLOAT64), CAST(JSON_EXTRACT(string, '$.coordinates[0][1]') as FLOAT64))  from temp_table

В результате POINT(20 10)

Я могу написать ручные запросы для каждого из этих пунктов и выполнить UNION ALL, но это не будет масштабироваться или работать каждый раз. Я хочу достичь этого так, чтобы он мог делать это автоматически. В архитектурных целях мы не можем манипулировать строками в таких языках, как Python.

1 Ответ

4 голосов
/ 26 марта 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT 
  ARRAY(
    SELECT ST_GEOGPOINT(
      CAST(SPLIT(pair)[OFFSET(0)] AS FLOAT64), CAST(SPLIT(pair)[SAFE_OFFSET(1)] AS FLOAT64)) 
    FROM UNNEST(REGEXP_EXTRACT_ALL(JSON_EXTRACT(STRING, '$.coordinates'), r'\[(\d+,\d+)\]')) pair
  ) points
FROM `project.dataset.temp_table`  

Вы можете проверить, поиграть с выше, используя пример данных из вашего вопроса, как в примере ниже

#standardSQL
WITH `project.dataset.temp_table` AS (
  SELECT '{ "type": "MultiPoint", "coordinates": [ [ 20, 10 ], [ 30, 5 ], [ 90, 50 ], [ 40, 80 ] ]  }' AS STRING
) 
SELECT 
  ARRAY(
    SELECT ST_GEOGPOINT(
      CAST(SPLIT(pair)[OFFSET(0)] AS FLOAT64), CAST(SPLIT(pair)[SAFE_OFFSET(1)] AS FLOAT64)) 
    FROM UNNEST(REGEXP_EXTRACT_ALL(JSON_EXTRACT(STRING, '$.coordinates'), r'\[(\d+,\d+)\]')) pair
  ) points
FROM `project.dataset.temp_table`   

с результатом

Row points   
1   POINT(20 10)     
    POINT(30 5)  
    POINT(90 50)     
    POINT(40 80)     

Примечание: в вышеприведенной версии - массив точек создается для каждой соответствующей исходной строки. Очевидно, вы можете настроить его так, чтобы он выровнялся, как в примере ниже

#standardSQL
WITH `project.dataset.temp_table` AS (
  SELECT '{ "type": "MultiPoint", "coordinates": [ [ 20, 10 ], [ 30, 5 ], [ 90, 50 ], [ 40, 80 ] ]  }' AS STRING
) 
SELECT 
  ST_GEOGPOINT(
      CAST(SPLIT(pair)[OFFSET(0)] AS FLOAT64), CAST(SPLIT(pair)[SAFE_OFFSET(1)] AS FLOAT64)
  ) points
FROM `project.dataset.temp_table`, UNNEST(REGEXP_EXTRACT_ALL(JSON_EXTRACT(STRING, '$.coordinates'), r'\[(\d+,\d+)\]')) pair   

с результатом

Row points   
1   POINT(20 10)     
2   POINT(30 5)  
3   POINT(90 50)     
4   POINT(40 80)     
...