地理空間データ型

Snowflakeは、地球表面のポイント、ライン、ポリゴンなどの地理空間機能をネイティブでサポートしています。

このトピックの内容:

データ型

Snowflakeは、地理空間データに次のデータ型を提供します。

  • Snowflakeは、地球を完全な球体であるかのようにモデル化する GEOGRAPHY データ型を提供します。

  • GEOMETRY は、平面(ユークリッド、デカルト)座標系の機能を表すデータ型です。

GEOGRAPHY データ型

GEOGRAPHY データ型は WGS 84標準に従います(空間参照 ID 4326。詳細については、https://spatialreference.org/ref/epsg/wgs-84/を参照)。

地球上のポイントは、経度(-180度から+180度)および緯度(-90から+90)で表されます。

高度は現在サポートされていません。

線分は、地球表面の測地弧として解釈されます。

Snowflakeは、 GEOGRAPHY データ型を操作する 地理空間関数 も提供します。

地理空間データ(例: 経度と緯度のデータ、 WKT、 WKB、 GeoJSON など)がある場合は、 VARCHAR、VARIANT、または NUMBER 列にあるデータを元の形式で保持するのではなく、このデータを変換して GEOGRAPHY 列に保存する必要があります。。データを GEOGRAPHY 列に保存すると、地理空間機能を使用するクエリのパフォーマンスが大幅に向上します。

GEOMETRY データ型

GEOMETRY データ型は、平面(ユークリッド、デカルト)座標系の機能を表します。

座標は、実数(x、y)のペアとして表されます。現在、2D座標のみがサポートされています。

XとYの単位は、 GEOMETRY オブジェクトに関連付けられた 空間参照系(SRS) によって決定されます。空間参照系は、 空間参照系識別子(SRID) 番号によって識別されます。GEOMETRY オブジェクトの作成時に、または ST_SETSRID の呼び出しによって、 SRID が提供される場合を除き、 SRID は0です。

Snowflakeは、 GEOMETRY データ型で動作する地理空間関数 のセットを提供します。これらの関数に対して、

  • ジオメトリが非平面 SRS を使用している場合でも、すべての関数は平面座標を想定しています。

  • 測定関数(例: ST_LENGTH)は、座標系と同じ単位を使用します。

  • 複数の GEOMETRY 式を引数として受け入れる関数(例: ST_DISTANCE)の場合、入力式は同じ SRS で定義する必要があります。

地理空間の入出力

次のセクションでは、地理空間データの読み取りおよび書き込み時にサポートされる標準の形式とオブジェクト型について説明します。

サポートされている標準の入出力形式

GEOGRAPHY および GEOMETRY データ型は、次の業界標準の入出力形式をサポートしています。

次の参照資料には、関連項目が記載されています。

これらの標準から逸脱する場合については、Snowflakeのドキュメントに明記されています。

GEOGRAPHY 値の GeoJSON の取り扱いに関する注意

WKT および WKB 標準では、形式のみを指定します。WKT/WKB オブジェクトのセマンティクスは、参照システム(平面や球など)に依存します。

一方、 GeoJSON 標準では、形式とそのセマンティクスの両方を指定します。GeoJSON ポイントは明示的に WGS 84座標であり、 GeoJSON 線分は平面エッジ(直線)であると想定されています。

それとは対照的に、Snowflake GEOGRAPHY データ型は、 GeoJSON 形式の入力または出力を含むすべての線分を測地弧として解釈します。本質的に、Snowflakeは GeoJSON を球形のセマンティクスを持つ JSON 形式の WKT として扱います。

GEOGRAPHY 値の EWKT および EWKB の取り扱いに関する注意

EWKT と EWKB は非標準のフォーマットであり、 PostGIS によって導入されます。これらは、データで使用する座標参照系を指定する 空間参照系識別子(SRID) を含めることにより、 WKT および WKB 形式を拡張します。Snowflakeは現在、 SRID=4326にマップされる WGS84 のみをサポートしています。

デフォルトでは、 EWKB または EWKT 入力値に4326以外の SRID が含まれている場合、Snowflakeはエラーを発行します。逆に、すべての EWKB と EWKT 出力値には SRID=4326があります。

サポートされている地理空間オブジェクト型

GEOGRAPHY および GEOMETRY のデータ型は、次の型の地理空間オブジェクトを保存できます。

  • WKT / WKB / EWKT / EWKB / GeoJSON 地理空間オブジェクト:

    • ポイント

    • MultiPoint

    • LineString

    • MultiLineString

    • ポリゴン

    • MultiPolygon

    • GeometryCollection

  • これらの GeoJSON 固有の地理空間オブジェクト:

    • 機能

    • FeatureCollection

結果セットの出力形式の指定

セッションパラメーター GEOGRAPHY_OUTPUT_FORMAT および GEOMETRY_OUTPUT_FORMAT は、結果セット内にある GEOGRAPHY 型および GEOMETRY 型の列のレンダリングを(それぞれ)制御します。

GEOGRAPHY_OUTPUT_FORMAT および GEOMETRY パラメーターは、次のいずれかの値を指定できます。

パラメーター値

説明

GeoJSON (デフォルト)

GEOGRAPHY / GEOMETRY の結果は、 GeoJSON 形式の OBJECT としてレンダリングされます。

WKT

GEOGRAPHY / GEOMETRY の結果は、 WKT 形式の VARCHAR としてレンダリングされます。

WKB

GEOGRAPHY / GEOMETRY の結果は、 WKB 形式の BINARY としてレンダリングされます。

EWKT

GEOGRAPHY / GEOMETRY の結果は、 EWKT 形式の VARCHAR としてレンダリングされます。

EWKB

GEOGRAPHY / GEOMETRY の結果は、 EWKB 形式の BINARY としてレンダリングされます。

EWKT および EWKB の場合、出力では SRID は常に4326です。 EWKT および EWKB の取り扱いに関する注意 をご参照ください。

このパラメーターは、Snowflake UI と SnowSQL コマンドラインクライアント、および JDBC、 ODBC、node.js、pythonなどのドライバーとコネクタを含むすべてのクライアントに影響します。

例: JDBC ドライバーは、 GEOGRAPHY タイプの結果列(この例では列 i)に対して次のメタデータを返します。

  • GEOGRAPHY_OUTPUT_FORMAT='GeoJSON' または GEOMETRY_OUTPUT_FORMAT='GeoJSON' の場合、

    • ResultSetMetaData.getColumnType(i) は、 java.sql.Types.VARCHAR を返します。

    • ResultSetMetaData.getColumnClassName(i) は、 "java.lang.String" を返します。

  • GEOGRAPHY_OUTPUT_FORMAT='WKT' または 'EWKT' の場合、または GEOMETRY_OUTPUT_FORMAT='WKT' または 'EWKT' の場合、

    • ResultSetMetaData.getColumnType(i) は、 java.sql.Types.VARCHAR を返します。

    • ResultSetMetaData.getColumnClassName(i) は、 "java.lang.String" を返します。

  • GEOGRAPHY_OUTPUT_FORMAT='WKB' または 'EWKB' の場合、または GEOMETRY_OUTPUT_FORMAT='WKB' または 'EWKB' の場合、

    • ResultSetMetaData.getColumnType(i) は、 java.sql.Types.BINARY を返します。

    • ResultSetMetaData.getColumnClassName(i) は、 "[B" (バイトの配列)を返します。

注釈

データベース固有の型名 (JDBC では getColumnTypeName、 ODBC では SQL_DESC_TYPE_NAME 記述子)を取得するための APIs は、 GEOGRAPHY_OUTPUT_FORMAT および GEOMETRY_OUTPUT_FORMAT パラメーターの値に関係なく、型名に GEOGRAPHY および GEOMETRY を常に返します。詳細については、以下をご参照ください。

GEOGRAPHY データの挿入とクエリの例

以下のコードは、 GEOGRAPHY データ型のサンプルの入力と出力を示しています。次の点に注意してください。

  • WKT、 EWKT、および GeoJSON の座標の場合、経度は緯度の前に表示されます(例: POINT(lon lat))。

  • WKB および EWKB 出力では、 BINARY_OUTPUT_FORMAT パラメーターが HEX (パラメーターのデフォルト値)に設定されていると想定しています。

この例では、 GEOGRAPHY 列のテーブルを作成し、 WKT 形式でデータを挿入し、さまざまな出力形式でデータを返します。

create table geospatial_table (id INTEGER, g GEOGRAPHY);
insert into geospatial_table values
    (1, 'POINT(-122.35 37.55)'), (2, 'LINESTRING(-124.20 42.00, -120.01 41.99)');
alter session set GEOGRAPHY_OUTPUT_FORMAT='GeoJSON';
select g
    from geospatial_table
    order by id;
+------------------------+
| G                      |
|------------------------|
| {                      |
|   "coordinates": [     |
|     -122.35,           |
|     37.55              |
|   ],                   |
|   "type": "Point"      |
| }                      |
| {                      |
|   "coordinates": [     |
|     [                  |
|       -124.2,          |
|       42               |
|     ],                 |
|     [                  |
|       -120.01,         |
|       41.99            |
|     ]                  |
|   ],                   |
|   "type": "LineString" |
| }                      |
+------------------------+
alter session set GEOGRAPHY_OUTPUT_FORMAT='WKT';
select g
    from geospatial_table
    order by id;
+-------------------------------------+
| G                                   |
|-------------------------------------|
| POINT(-122.35 37.55)                |
| LINESTRING(-124.2 42,-120.01 41.99) |
+-------------------------------------+
alter session set GEOGRAPHY_OUTPUT_FORMAT='WKB';
select g
    from geospatial_table
    order by id;
+------------------------------------------------------------------------------------+
| G                                                                                  |
|------------------------------------------------------------------------------------|
| 01010000006666666666965EC06666666666C64240                                         |
| 010200000002000000CDCCCCCCCC0C5FC00000000000004540713D0AD7A3005EC01F85EB51B8FE4440 |
+------------------------------------------------------------------------------------+
alter session set GEOGRAPHY_OUTPUT_FORMAT='EWKT';
select g
    from geospatial_table
    order by id;
+-----------------------------------------------+
| G                                             |
|-----------------------------------------------|
| SRID=4326;POINT(-122.35 37.55)                |
| SRID=4326;LINESTRING(-124.2 42,-120.01 41.99) |
+-----------------------------------------------+
alter session set GEOGRAPHY_OUTPUT_FORMAT='EWKB';
select g
    from geospatial_table
    order by id;
+--------------------------------------------------------------------------------------------+
| G                                                                                          |
|--------------------------------------------------------------------------------------------|
| 0101000020E61000006666666666965EC06666666666C64240                                         |
| 0102000020E610000002000000CDCCCCCCCC0C5FC00000000000004540713D0AD7A3005EC01F85EB51B8FE4440 |
+--------------------------------------------------------------------------------------------+

Snowflakeでの地理空間データの使用

次のセクションでは、地理空間データの読み取りおよび書き込み時にサポートされる標準の形式とオブジェクト型について説明します。

GEOMETRY で異なる SRIDs を使用した場合の効果について

GEOMETRY 列には、異なる SRIDs を持つオブジェクトを挿入できます。列に複数の SRID が含まれている場合は、重要なパフォーマンス最適化の一部が適用されません。これにより、特に地理空間述語で結合する場合に、クエリが遅くなる可能性があります。

GEOGRAPHY 列および GEOMETRY 列での DML 操作の実行

GEOGRAPHY または GEOMETRY の列が DML 操作のターゲットである場合(INSERT、 COPY、 UPDATE、 MERGE、または CREATE TABLE AS ...)、列のソース式は、次の型のいずれかです。

  • GEOGRAPHY または GEOMETRY: 型 GEOGRAPHY または GEOMETRY の式は通常、解析関数、コンストラクター関数、または既存の GEOGRAPHY または GEOMETRY の列の結果です。サポートされている関数と関数のカテゴリの包括的なリストについては、 地理空間関数 をご参照ください。

  • VARCHAR : WKT、 WKB (16進数形式)、 EWKT、 EWKB (16進数形式)、または GeoJSON 形式の文字列として解釈されます( TO_GEOGRAPHY(VARCHAR) を参照)。

  • BINARY: WKB バイナリとして解釈されます(TO_GEOGRAPHY(BINARY) および

  • TO_GEOMETRY(BINARY) を参照)。

  • VARIANT: GeoJSON オブジェクトとして解釈されます(TO_GEOGRAPHY(VARIANT) および TO_GEOMETRY(VARIANT) を参照)。

ステージからの地理空間データのロード

ステージ内の CSV または JSON / AVRO ファイルからのデータは、直接(つまり、コピー変換なしで) GEOGRAPHY 列にロードできます。

他のファイル形式(Parquet、 ORC など)からのデータのロードは、 COPY 変換を介して可能です。

Java UDFs での地理空間データの使用

Java UDFs は、 GEOGRAPHY 型を引数および戻り値として許可します。詳細については パラメーターと戻り値型の SQL-Javaデータ型のマッピング および GEOGRAPHY 値のインラインJava UDF への引き渡し をご参照ください。

JavaScript UDFs での地理空間データの使用

JavaScript UDFs GEOGRAPHY 型を引数および戻り値として許可します。

JavaScript UDF に型 GEOGRAPHY の引数がある場合、その引数は UDF 本体内で JSON オブジェクトとして GeoJSON 形式で表示されます。

JavaScript UDF が GEOGRAPHY を返す場合、 UDF 本体は JSON オブジェクトを GeoJSON 形式で返すことが期待されています。

たとえば、次の2つの JavaScript UDFs は、組み込み関数 ST_X および ST_MAKEPOINT とほぼ同等です。

create or replace function my_st_x(G geography) returns real
language javascript
as
$$
  if (G["type"] != "Point")
  {
     throw "Not a point"
  }
  return G["coordinates"][0]
$$;

create or replace function my_st_makepoint(LNG real, LAT real) returns geography
language javascript
as
$$
  g = {}
  g["type"] = "Point"
  g["coordinates"] = [ LNG, LAT ]
  return g
$$;

使用する地理空間データ型の選択(GEOGRAPHY または GEOMETRY)

次のセクションでは、 GEOGRAPHY と GEOMETRY のデータ型の違いについて説明します。

GEOGRAPHY と GEOMETRY の違いについて

GEOGRAPHY と GEOMETRY のデータ型両方とも地理空間機能を定義しますが、これらの型は異なるモデルを使用します。次のテーブルは、相違点をまとめたものです。

GEOGRAPHY データ型

GEOMETRY データ型

  • 球面上の特徴を定義します。

  • WGS84 座標系のみ。SRID は常に4326です。

  • 座標は緯度(-90から90)と経度(-180から180)です。

  • 測定操作の結果(ST_LENGTH、 ST_AREA など)はメートル単位です。

  • セグメントは、地球表面の測地弧として解釈されます。

  • 平面上の特徴を定義します。

  • 任意の座標系がサポートされています。

  • 座標値の単位は、空間参照系によって定義されます。

  • 測定操作の結果(ST_LENGTH、 ST_AREA など)は、座標と同じ単位です。たとえば、入力座標が度単位の場合、結果は度単位になります。

  • セグメントは、平面上の直線として解釈されます。

GEOGRAPHY と GEOMETRY のデータ型を比較する例

次の例では、 GEOGRAPHY と GEOMETRY のデータ型を入力として使用した場合の地理空間関数の出力を比較しています。

例1: ベルリンとサンフランシスコの間の距離に対するクエリ

次のテーブルは、 GEOGRAPHY 型と GEOMETRY 型の ST_DISTANCE の出力を比較しています。

ST_DISTANCE . GEOGRAPHY 入力の使用

ST_DISTANCE . GEOMETRY 入力の使用

SELECT ST_DISTANCE(
         ST_POINT(13.4814, 52.5015),
         ST_POINT(-121.8212, 36.8252))
       AS distance_in_meters;
+--------------------+
| DISTANCE_IN_METERS |
|--------------------|
|   9182410.99227821 |
+--------------------+
SELECT ST_DISTANCE(
         ST_GEOM_POINT(13.4814, 52.5015),
         ST_GEOM_POINT(-121.8212, 36.8252))
       AS distance_in_degrees;
+---------------------+
| DISTANCE_IN_DEGREES |
|---------------------|
|       136.207708844 |
+---------------------+

上記の例が示すように、

  • GEOGRAPHY 入力値では、入力座標は度単位、出力値はメートル単位です。(結果は9,182 km。)

  • GEOMETRY 入力値では、入力座標と出力値は度です。(結果は136.208度。)

例2: ドイツの領域のクエリ

次のテーブルは、 GEOGRAPHY 型と GEOMETRY 型の ST_AREA の出力を比較しています。

ST_AREA . GEOGRAPHY 入力の使用

ST_AREA . GEOMETRY 入力の使用

SELECT ST_AREA(border) AS area_in_sq_meters
  FROM world_countries
  WHERE name = 'Germany';
+-------------------+
| AREA_IN_SQ_METERS |
|-------------------|
|  356379183635.591 |
+-------------------+
SELECT ST_AREA(border) as area_in_sq_degrees
  FROM world_countries_geom
  WHERE name = 'Germany';
+--------------------+
| AREA_IN_SQ_DEGREES |
|--------------------|
|       45.930026848 |
+--------------------+

上記の例が示すように、

  • GEOGRAPHY 入力値の場合、入力座標は度単位、出力値は平方メートル単位です。(結果は356,379 km^2。)

  • GEOMETRY 入力値の場合、入力座標は度単位で、出力値は平方度単位です。(結果は45.930平方度。)

例3: ベルリンからサンフランシスコまでの線に重なる国名のクエリ

次のテーブルは、 GEOGRAPHY 型と GEOMETRY 型の ST_INTERSECTS の出力を比較しています。

ST_INTERSECTS . GEOGRAPHY 入力の使用

ST_INTERSECTS . GEOMETRY 入力の使用

SELECT name FROM world_countries WHERE
  ST_INTERSECTS(border,
    TO_GEOGRAPHY(
      'LINESTRING(13.4814 52.5015, -121.8212 36.8252)'
    ));
+--------------------------+
| NAME                     |
|--------------------------|
| Germany                  |
| Denmark                  |
| Iceland                  |
| Greenland                |
| Canada                   |
| United States of America |
+--------------------------+
SELECT name FROM world_countries_geom WHERE
  ST_INTERSECTS(border,
    TO_GEOMETRY(
      'LINESTRING(13.4814 52.5015, -121.8212 36.8252)'
    ));
+--------------------------+
| NAME                     |
|--------------------------|
| Germany                  |
| Belgium                  |
| Netherlands              |
| United Kingdom           |
| United States of America |
+--------------------------+
Countries intersecting when using GEOGRAPHY Countries intersecting when using GEOMETRY

入力データ検証の違いについて

入力形状の GEOMETRY または GEOGRAPHY オブジェクトを作成するには、 単純な特徴の OGC 規則 に従って、整形式で有効な形状を使用する必要があります。次のセクションでは、入力データの有効性が GEOMETRY と GEOGRAPHY でどのように異なるかについて説明します。

有効な GEOGRAPHY の場合でも無効な GEOMETRY の形状

指定された形状が、有効な GEOGRAPHY オブジェクトでも、無効な GEOMETRY オブジェクトである可能性があります(逆も同様)。

たとえば、自己交差ポリゴンは OGC 規則では許可されていません。特定の点のセットは、デカルト領域では交差するが球面上では交差しないエッジを定義する場合があります。次のポリゴンを考えてみましょう。

POLYGON((0 50, 25 50, 50 50, 0 50))

デカルト領域では、この多角形は線に劣化し、結果として無効になります。

ただし、球面上では、この同じポリゴンはそれ自体と交差せず、有効です。

POLYGON((0 50, 25 50, 50 50, 0 50)) invalid geometry, but valid geography

変換関数とコンストラクター関数は検証を異なる方法で処理

入力データが無効な場合、GEOMETRY 関数と GEOGRAPHY 関数はさまざまな方法で検証を処理します。

  • GEOGRAPHY オブジェクト(例: TO_GEOGRAPHY)を作成して変換する関数は、閉じていないループ、スパイク、カット、ポリゴン内の自己交差ループなどの問題を処理するために形状を修復しようとする場合があります。

    関数が形状の修復に成功した場合、関数は GEOGRAPHY オブジェクトを返します。

  • GEOMETRY オブジェクト(例: TO_GEOMETRY)を作成して変換する関数は、形状を修復する機能をサポートしていません。

GEOGRAPHY と GEOMETRY の間の変換

Snowflakeは、GEOGRAPHY から GEOMETRY へのキャスト(およびその逆)をサポートしていません。Snowflakeは、異なる空間参照系(SRS)を使用するオブジェクトの変換もサポートしていません。

GEOGRAPHY オブジェクトを GEOMETRY オブジェクトに(または GEOMETRY を GEOGRAPHY に)変換する必要がある場合は、中間形式として GeoJSON を使用できます。

次の例では、GEOGRAPHY オブジェクト geography_expression を SRID 0 を使用して GEOMETRY オブジェクトに変換します。

SELECT TO_GEOMETRY(ST_ASGEOJSON(geography_expression));

GEOMETRY オブジェクトの SRID を設定する必要がある場合は、 ST_SETSRID 関数を呼び出します。たとえば、 SRID 4326 を使用して GEOGRAPHY オブジェクト geography_expression を GEOMETRY オブジェクトに変換するには、

SELECT ST_SETSRID(TO_GEOMETRY(ST_ASGEOJSON(geography_expression)), 4326);
最上部に戻る