22 GeoJSON地理データの使用
GeoJSONオブジェクトは、地理的データを表すJSONオブジェクトです。GeoJSONデータの作成、索引付けおよび問合せの例を示します。
GeoJSONオブジェクト: ジオメトリ、機能、機能コレクション
GeoJSONは、様々なジオメトリ・エンティティを表すJSONオブジェクトやこれらの組合せとユーザー定義のプロパティを一緒に使用します。
位置は、2つ以上の空間(数値)座標の配列で、先頭から3つは、一般的に経度、緯度および標高を表します。
ジオメトリ・オブジェクトには、表22-1に示すように、type
フィールドと(ジオメトリ・コレクション・オブジェクトを除いて)coordinates
フィールドがあります。
ジオメトリ・コレクションは、type
がGeometryCollection
のジオメトリ・オブジェクトです。このオブジェクトには、coordinates
フィールドのかわりにgeometries
フィールドがあります。この値は、GeometryCollection
オブジェクト以外のジオメトリ・オブジェクトの配列です。
表22-1 ジオメトリ・コレクション以外のGeoJSONジオメトリ・オブジェクト
type フィールド
|
coordinates フィールド
|
---|---|
Point |
位置。 |
MultiPoint |
位置の配列。 |
LineString |
2つ以上の位置の配列。 |
MultiLineString |
位置のLineString 配列の配列。
|
Polygon |
最初と最後の位置が一致する(同等の)LineString が配列として含まれるMultiLineString 。ポリゴンの配列に複数の配列が含まれる場合、最初の配列は外側のポリゴンを表し、その他はその中の穴を表します。
|
MultiPolygon |
位置のPolygon 配列の配列。つまり、位置の多次元の配列。
|
機能オブジェクトには、値がFeature
のtype
フィールドと、値がジオメトリ・オブジェクトのgeometry
フィールドと、任意のJSONオブジェクトを値にできるproperties
フィールドがあります。
機能コレクション・オブジェクトには、値がFeatureCollection
のtype
フィールドと、値が機能オブジェクトの配列のfeatures
フィールドがあります。
例22-1に、features
配列に3つの機能が含まれる機能コレクション・オブジェクトを表します。最初の機能のgeometry
のタイプはPoint
で、2つ目のタイプはLineString
で、3つ目のタイプはPolygon
です。
GeoJSONデータの問合せおよび索引付け
SQL/JSON問合せファンクションおよび条件を使用して、GeoJSONデータを調べたり、その一部を(Oracle Spatial and GraphのSDO_GEOMETRY
オブジェクト型インスタンスを含む)非JSONデータとして投影できます。これは例22-2、例22-3、例22-5で説明しています。
問合せのパフォーマンスを向上させるために、GeoJSONデータに適用する関数json_value
で、Oracle Spatial and Graphの索引(型MDSYS.SPATIAL_INDEX
)を作成できます。これを、例22-4に示します。
例22-4では、ジオメトリ機能の配列(最初の要素)の特定の1つの要素のみを索引付けします。ファンクションjson_value
のBツリー索引は、スカラー値のみを対象にできます。例22-3のような、任意の数の配列要素を対象とした問合せのパフォーマンスを改善するために、次の操作を実行できます。
-
ON STATEMENTの、リフレッシュ可能な配列データのマテリアライズド・ビューを作成し、インメモリーにそのビューを配置します。
-
配列データに対して空間索引を作成します。
SDO_GEOMETRYオブジェクト型インスタンスと空間操作
Oracle Spatial and GraphのSDO_GEOMETRY
オブジェクト型インスタンスをGeoJSONオブジェクトに、また、GeoJSONオブジェクトをSDO_GEOMETRY
インスタンスに変換できます。
Oracle Spatial and Graphでの操作を、GeoJSONオブジェクトから取得したSDO_GEOMETRY
オブジェクトに対して使用できます。たとえば、PL/SQLパッケージSDO_GEOM
で演算子sdo_distance
を使用して、2つのジオメトリ・オブジェクト間の最短距離を計算できます。これは、最も近い2つの地点または2つのセグメント間(各オブジェクトから1つの地点またはセグメントまで)の距離です。これを、例22-5に示します。
関連項目:
-
GeoJSONデータとOracle Spatial and Graphを連携して使用する方法の詳細は、Oracle Spatial and Graph開発者ガイドを参照してください。
-
Oracle Spatial and Graphと
SDO_GEOMETRY
オブジェクト型の詳細は、Oracle Spatial and Graph開発者ガイドを参照してください。 -
GeoJSONの詳細は、GeoJSON.orgを参照してください
-
GeoJSONデータの詳細は、『The GeoJSON Format Specification』を参照してください
例22-1 GeoJSONデータを使用した表
この例では、GeoJSON文書の列geo_doc
を持つ、表j_geo
を作成します。
ここでは、このような文書が1つだけ挿入されます。この文書には、type
FeatureCollection
のGeoJSONオブジェクトと、type
Feature
のオブジェクトのfeatures
配列が1つずつ含まれます。これらのオブジェクトには、それぞれ、type
Point
、LineString
およびPolygon
のgeometry
があります。
CREATE TABLE j_geo
(id VARCHAR2 (32) NOT NULL,
geo_doc VARCHAR2 (4000) CHECK (geo_doc IS JSON));
INSERT INTO j_geo
VALUES (1,
'{"type" : "FeatureCollection",
"features" : [{"type" : "Feature",
"geometry" : {"type" : "Point",
"coordinates" : [-122.236111, 37.482778]},
"properties" : {"Name" : Redwood City"}},
{"type" : "Feature",
"geometry" : {"type" : "LineString",
"coordinates" : [[102.0, 0.0],
[103.0, 1.0],
[104.0, 0.0],
[105.0, 1.0]]},
"properties" : {"prop0" : "value0",
"prop1" : 0.0}},
{"type" : "Feature",
"geometry" : {"type" : "Polygon",
"coordinates" : [[[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]]]},
"properties" : {"prop0" : "value0",
"prop1" : {"this" : "that"}}}]}');
例22-2 GeoJSON機能のgeometryオブジェクトのSDO_GEOMETRYインスタンスとしての選択
この例では、SQL/JSONファンクションjson_value
を使用して、配列features
の最初の要素からフィールドgeometry
の値を選択します。値は、JSONデータとしてではなくOracle Spatial and Graphデータとして、つまり、SQL文字列やLOBインスタンスではなくPL/SQLオブジェクト型SDO_GEOMETRY
として戻されます。
SELECT json_value(geo_doc, '$.features[0].geometry'
RETURNING SDO_GEOMETRY
ERROR ON ERROR)
FROM j_geo;
戻される値は、次のようになります。これは、経度および緯度(座標)がそれぞれ122.236111と37.482778の地点を表します。
SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(-122.236111, 37.482778, NULL), NULL, NULL)
関連項目:
SQL/JSONファンクションjson_value
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
例22-3 GeoJSON機能の複数のgeometryオブジェクトのSDO_GEOMETRYとしての取得
この例では、SQL/JSONファンクションjson_table
を使用して、配列features
の各要素にあるフィールドgeometry
の値を、仮想表の列sdo_val
として投影します。取得されたデータは、SDO_GEOMETRY
として戻されます。
SELECT jt.*
FROM j_geo,
json_table(geo_doc, '$.features[*]'
COLUMNS (sdo_val SDO_GEOMETRY PATH '$.geometry')) jt;
関連項目:
Oracle Database SQL言語リファレンス(SQL/JSONファンクションjson_table
の詳細)
問合せに対して、次の3つの行が戻されます。1つ目の行は、例22-2と同じPoint
を表します。2つ目の行は、LineString
配列を表します。3つ目はPolygon
を表します。
SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(-122.236111, 37.482778, NULL), NULL, NULL)
SDO_GEOMETRY(2002, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 2, 1),
SDO_ORDINATE_ARRAY(102, 0, 103, 1, 104, 0, 105, 1))
SDO_GEOMETRY(2003, 4326, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1),
SDO_ORDINATE_ARRAY(100, 0, 101, 0, 101, 1, 100, 1, 100, 0))
属性SDO_ELEM_INFO_ARRAY
の2つ目と3つ目の要素は、属性SDO_ORDINATE_ARRAY
で提供される座標を解釈する方法を指定します。これらは、戻される最初の行が線ストリング(2)で直線セグメント(1)を持ち、2つ目の行がポリゴン(2003)で直線セグメント(1)を持つことを示します。
例22-4 スカラーGeoJSONデータの空間索引の作成
この例では、配列features
の最初の要素のフィールドgeometry
に対して、MDSYS.SPATIAL_INDEX
型のjson_value
関数ベースの索引を作成します。これにより、その値を取得するためのjson_value
を使用した問合せのパフォーマンスが向上します。
CREATE INDEX geo_first_feature_idx
ON j_geo (json_value(geo_doc, '$.features[0].geometry'
RETURNING SDO_GEOMETRY))
INDEXTYPE IS MDSYS.SPATIAL_INDEX;
例22-5 GeoJSONジオメトリと空間演算子の使用
この例では、最初のfeatures
要素のgeometry
フィールドが特定の地点から100キロメートル以内にある文書(この表では1つだけ)を選択します。ここでは、目的の地点はリテラルに表されています(coordinates
が、カリフォルニア州サンフランシスコの経度と緯度)。この地点から各ジオメトリ・オブジェクトまでの距離が計算されます。
問合せは、計算された距離を基準にして、選択した文書の順番を決めます。距離計算に対する許容誤差のメートル数は、この問合せではリテラル引数の100として指定されています。
SELECT id,
json_value(geo_doc, '$features[0].properties.Name') "Name",
SDO_GEOM.sdo_distance(
json_value(geo_doc, '$features[0].geometry') RETURNING SDO_GEOMETRY,
SDO_GEOMETRY(2001,
4326,
SDO_POINT_TYPE(-122.416667, 37.783333, NULL),
NULL,
NULL),
100, -- Tolerance in meters
'unit=KM') "Distance in kilometers"
FROM j_geo
WHERE sdo_within_distance(
json_value(geo_doc, '$.features[0].geometry' RETURNING SDO_GEOMETRY),
SDO_GEOMETRY(2001,
4326,
SDO_POINT_TYPE(-122.416667, 37.783333, NULL),
NULL,
NULL),
'distance=100 unit=KM')
= 'TRUE';
関連項目:
SQL/JSONファンクションjson_value
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
問合せの結果、次の1行が戻されます。
ID Name Distance in kilometers
----- -------------- ----------------------
1 Redwood City 26.9443035
例22-6 GeoJSONデータに対するマテリアライズド・ビューの作成
CREATE OR REPLACE MATERIALIZED VIEW geo_doc_view
BUILD IMMEDIATE
REFRESH FAST ON STATEMENT WITH ROWID
AS SELECT g.rowid, jt.*
FROM j_geo g,
json_table(geo_doc, '$.features[*]'
COLUMNS (sdo_val SDO_GEOMETRY PATH '$.geometry')) jt;
例22-7 GeoJSONデータに対するマテリアライズド・ビューの空間索引の作成
この例ではまず、いくつかの空間索引メタデータを移入することにより、空間索引の作成の準備を行います。それから、例22-6で作成されたマテリアライズド・ビューgeo_doc_view
のSDO_GEOMETRY
列sdo_val
に索引を作成します。ビュー名および列名を除き、索引メタデータを移入するためのコードは固定です。マテリアライズド・ビューの空間索引の作成が必要になるたびにそれを使用します。
-- Populate spatial-indexing metadata
INSERT INTO USER_SDO_GEOM_METADATA
VALUES ('GEO_DOC_VIEW',
'SDO_VAL',
MDSYS.sdo_dim_array(
MDSYS.sdo_dim_element('Longitude', -180, 180, 0.05),
MDSYS.sdo_dim_element('Latitude', -90, 90, 0.05)),
7
4326);
-- Create spatial index on geometry column of materialized view
CREATE INDEX geo_all_features_idx ON geo_doc_view(sdo_val)
INDEXTYPE IS MDSYS.SPATIAL_INDEX V2;
親トピック: GeoJSON地理データ