1. 序章

この記事では、地理空間アプリケーションのコアアーキテクチャと重要な要素について理解します。 まず、地理空間アプリケーションとは何か、およびそれを構築する際の一般的な課題を理解することから始めます。

地理空間アプリケーションの重要な側面の1つは、直感的なマップで有用なデータを表現することです。 ただし、この記事では、主にバックエンドでの地理空間データの処理と、今日の業界で利用可能なオプションに焦点を当てます。

2. 地理空間アプリケーションとは何ですか?

地理空間アプリケーションの意味を理解することから始めましょう。 これらは基本的にアプリケーションであり、地理空間データを利用してコア機能を提供します。

簡単に言うと、地理空間データとは、場所、場所、地図、ナビゲーションなどを表すデータです。 特別な定義がなくても、私たちはこれらのアプリケーションに完全に囲まれています。 たとえば、私たちのお気に入りのライドシェアリングアプリケーション、フードデリバリーアプリケーション、映画予約アプリケーションはすべて地理空間アプリケーションです。

地理空間データは、基本的に地球の表面上またはその近くにあるオブジェクト、イベント、またはその他の機能を説明する情報です。 たとえば、今日の夕方に私たちのお気に入りのシェイクスピア劇を上演している最寄りの劇場を提案できるアプリケーションを考えてみてください。 それは、劇場の位置情報を演劇の属性情報およびイベントの時間情報と組み合わせることによってそれを行うことができます。

地理空間データには、他にもいくつかの便利なアプリケーションがあり、日々の価値を提供します。たとえば、目的地に連れて行ってくれるタクシーを1日の任意の時間に近くに配置しようとする場合などです。 または、その重要な貨物が到着するのを待つことができず、ありがたいことに、それが輸送中の場所を正確に見つけることができる場合。

実際、これは、最近私たちが頻繁に使用するいくつかのアプリケーションの基本的な要件になっています。

3. 地理空間テクノロジー

地理空間アプリケーションを構築する際のニュアンスを理解する前に、そのようなアプリケーションを強化するコアテクノロジーのいくつかを見ていきましょう。 これらは、地理空間データを有用な形式で生成、処理、および提示するのに役立つ基盤となるテクノロジーです。

リモートセンシング(RS)は、離れた場所で反射および放出された放射線を測定することにより、エリアの物理的特性を検出および監視するプロセスです。 通常、これはリモートセンシング衛星を使用して行われます。 測量、インテリジェンス、さらには商用アプリケーションの分野で重要な用途があります。

全地球測位システム(GPS)は、中軌道(MEO)を飛行する24個の衛星のネットワークに基づく衛星ベースのナビゲーションシステムを指します。 それは、4つ以上のGPS衛星への遮るもののない視線を持っている地球上のどこにでも適切な受信機に地理的位置と時間情報を提供することができます。

地理情報システム(GIS)は、すべてのタイプのデータを作成、管理、分析、およびマッピングするシステムです。 たとえば、場所データを、その場所に存在するものなどのより説明的な情報と統合するのに役立ちます。 これは、いくつかの業界でのコミュニケーションと意思決定の改善に役立ちます。

4. 地理空間アプリケーションの構築における課題

地理空間アプリケーションを構築するときにどのような設計上の選択を行う必要があるかを理解するには、関連する課題を知ることが重要です。 通常、地理空間アプリケーションでは、大量の地理空間データのリアルタイム分析が必要です。 たとえば、自然災害のある最近の被害を受けた場所への最短の代替ルートを見つけることは、ファーストレスポンダーにとって非常に重要です。

したがって、基本的に、地理空間アプリケーションの基盤となる要件の1つは、大量の地理空間データを保存し、非常に低いレイテンシで任意のクエリを容易にすることです。 ここで、空間データの性質と、なぜ特別な処理が必要なのかを理解することも重要です。 基本的に、空間データは幾何学的空間で定義されたオブジェクトを表します。

都市の周りにいくつかの興味深い場所があると想像してみましょう。 場所は通常、緯度、経度、および(場合によっては)標高によって記述されます。

さて、私たちが本当に興味を持っているのは、特定の場所の近くの場所を見つけることです。 したがって、この場所からすべての可能な場所までの距離を計算する必要があります。 このようなクエリは、私たちがよく知っている通常のデータベースクエリとはまったく異なります。 これらは空間クエリとして知られています。 それらは幾何学的データ型を含み、空間的関係を考慮しますこれらの形状の間。

効率的なインデックスがなければ、本番データベースはおそらく存続しないことはすでにわかっています。 これは、空間データにも当てはまります。 ただし、その性質上、通常のインデックスは、空間データおよび実行する空間クエリのタイプに対してはあまり効率的ではありません。 したがって、空間操作をより効率的に実行するのに役立つ、空間インデックスと呼ばれる特殊なインデックスが必要です。

5. 空間データ型とクエリ

空間データを処理する際の課題を理解したので、いくつかのタイプの空間データに注意することが重要です。 さらに、それらに対していくつかの興味深いクエリを実行して、固有の要件を満たすことができます。 これらのデータ型のいくつかと、それらに対して実行できる操作について説明します。

私たちは通常、空間参照系に関する空間データについて話します。 これは、座標系とデータムで構成されています。 アフィン、円筒、デカルト、楕円体、線形、極、球、垂直などのいくつかの座標系があります。 データムは、原点の位置、スケール、および座標系の方向を定義するパラメータのセットです。

大まかに言えば、空間データをサポートする多くのデータベースは、それらを2つのカテゴリ、ジオメトリ、および地理に分類します。

ジオメトリは、空間データをフラットな座標系に格納します。 これは、デカルト空間での座標を使用して、点、線、領域などの形状を表すのに役立ちます。 地理は、丸い地球の座標系に基づいて空間データを保存します。 これは、地球の表面上の同じ形状を緯度と経度の座標で表すのに役立ちます。

空間データを使用して行うことができる照会には、2つの基本的なタイプがあります。 これらは基本的に最近傍を見つけるため、またはさまざまなタイプの範囲クエリを送信するためです。 以前に最近傍を見つけるためのクエリの例はすでに見てきました。 一般的な考え方は、クエリポイントに最も近い特定の数のアイテムを識別することです。

他の重要なタイプのクエリは範囲クエリです。 ここでは、クエリ範囲内にあるすべてのアイテムを知ることに関心があります。 クエリ範囲は、クエリポイントから特定の半径を持つ長方形または円にすることができます。 たとえば、この種のクエリを使用して、立っている場所から半径2マイル以内にあるすべてのイタリアンレストランを特定できます。

6. 空間データのデータ構造

ここで、空間インデックスの作成により適したデータ構造のいくつかを理解します。 これは、それらが通常のインデックスとどのように異なるのか、そしてなぜそれらが空間操作をより効率的に処理するのかを理解するのに役立ちます。 常に、これらのデータ構造のほとんどすべてがツリーデータ構造のバリエーションです。

6.1. 通常のデータベースインデックス

データベースインデックスは、基本的にデータ取得操作の速度を向上させるデータ構造です。 インデックスがないと、関心のある行を検索するためにすべての行を調べる必要があります。 ただし、かなりのサイズのテーブルの場合、インデックスを通過するだけでもかなりの時間がかかる可能性があります。

ただし、キーをフェッチする手順の数を減らし、それを行うためのディスク操作の数を減らすことが重要です。 Bツリーまたはバランスツリーは、すべてのノードにいくつかのソートされたキーと値のペアを格納する自己バランスツリーデータ構造です。 これは、ディスクからの1回の読み取り操作で、プロセッサキャッシュ内のより多くのキーセットをプルするのに役立ちます。

Bツリーはかなりうまく機能しますが、通常、データベースインデックスの構築にはB+ツリーを使用します。 B +ツリーは、リーフノードにのみ値またはデータを格納するという事実を除いて、Bツリーと非常によく似ています。

ここでは、すべてのリーフノードもリンクされているため、キーと値のペアへの順序付けられたアクセスが提供されます。 ここでの利点は、リーフノードがインデックスの最初のレベルを提供し、内部ノードがマルチレベルのインデックスを提供することです。

通常のデータベースインデックスは、単一のディメンションでのキーの順序付けに重点を置いています。 たとえば、データベーステーブルの郵便番号などの属性の1つにインデックスを作成できます。 これは、特定の郵便番号または郵便番号の範囲内のすべての場所を照会するのに役立ちます。

6.2. 空間データベースインデックス

地理空間アプリケーションでは、最近傍または範囲クエリに関心があることがよくあります。 たとえば、特定の地点から10マイル以内のすべての場所を検索したい場合があります。 通常のデータベースインデックスは、ここではあまり有用ではありません。 実際、空間インデックスを構築するためのより適切なデータ構造は他にもあります。

最も一般的に使用されるデータ構造の1つは、Rツリーです。 Rツリーは1984年にAntoninGuttmanによって最初に提案され、場所などの空間オブジェクトを格納するのに適しています。 Rツリーの背後にある基本的なアイデアは、近くのオブジェクトをグループ化し、ツリーの次に高いレベルで最小の外接長方形でそれらを表すことです。

ほとんどの操作では、RツリーはBツリーとそれほど変わりません。 主な違いは、境界矩形を使用して、サブツリー内を検索するかどうかを決定することです。 パフォーマンスを向上させるには、長方形があまりにも多くの空きスペースをカバーしないようにし、長方形があまり重ならないようにする必要があります。 最も興味深いことに、Rツリーは3つ以上の次元をカバーするように拡張できます。

空間インデックスを構築するためのもう1つのデータ構造は、 Kdツリーです。これは、Rツリーのわずかなバリエーションです。 Kdツリーは、データスペースを複数の長方形に分割するのではなく、2つに分割します。 したがって、Kdツリーのツリーノードは、境界ボックスではなく、分離平面を表します。 Kdツリーは実装が簡単で高速であることが証明されていますが、常に変化するデータには適していません。

これらのデータ構造の背後にある重要なアイデアは、基本的にデータを軸に沿った領域に分割し、ツリーノードに格納することです。 実際、BSPツリーやR *ツリーなど、使用できるデータ構造は他にもかなりあります。

7. ネイティブサポート付きのデータベース

空間データが通常のデータとどのように異なり、なぜ特別な処理が必要なのかはすでに見てきました。 したがって、地理空間アプリケーションを構築するために必要なのは、空間データ型の格納をネイティブにサポートでき、空間クエリを効率的に実行できるデータベースです。 このようなデータベース管理システムを空間データベース管理システムと呼びます。

ほとんどすべての主流のデータベースは、空間データに対してある程度のサポートを提供し始めています。 これには、 MySQL Microsoft SQL Server PostgreSQL Redis MongoDB Elasticsearch 、およびNeo4J。 ただし、 GeoMesa PostGIS Oracle Spatial など、専用の空間データベースも利用できます。

7.1. Redis

Redis は、データベース、キャッシュ、またはメッセージブローカーとして使用できるメモリ内データ構造ストアです。 メモリ内で効率的に操作を実行するため、ネットワークのオーバーヘッドと遅延を最小限に抑えることができます。 Redisは、ハッシュ、セット、ソートされたセット、リスト、文字列などのさまざまなデータ構造をサポートしています。 私たちにとって特に興味深いのは、スコアでソートされた、メンバーに順序付けられたビューを追加するソート済みセットです。

地理空間インデックスは、基になるデータ構造として並べ替えられたセットを使用してRedisに実装されます。 Redisは、実際にはジオハッシュアルゴリズムを使用して、緯度と経度をソート済みセットのスコアにエンコードします。 Geo Setは、Sorted Setで実装された主要なデータ構造であり、Redisの地理空間データをより抽象的なレベルでサポートします。

Redisは、地理空間インデックスを操作し、新しいセットの作成やセット内のメンバーの追加や更新などの一般的な操作を実行するためのシンプルなコマンドを提供します。 たとえば、新しいセットを作成し、コマンドラインからそのセットにメンバーを追加するには、GEOADDコマンドを使用できます。

GEOADD locations 20.99 65.44 Vehicle-1 23.99 55.45 Vehicle-2

ここでは、「ロケーション」と呼ばれるジオセットにいくつかの車両のロケーションを追加しています。

Redisには、ZRANGE、ZSCAN、GEOPOSなど、インデックスを読み取るためのいくつかの方法も用意されています。 さらに、コマンドGEODISTを使用して、セット内のメンバー間の距離を計算できます。 しかし、最も興味深いコマンドは、場所でインデックスを検索できるコマンドです。 たとえば、コマンドGEORADIUSYMEMBERを使用して、特定のメンバーの半径範囲内にあるメンバーを検索できます。

GEORADIUSBYMEMBER locations Vehicle-3 1000 m

ここでは、3台目の車両から半径1km以内にある他のすべての車両を見つけることに関心があります。

Redisは、大量の地理空間データを保存し、低遅延の地理空間クエリを実行するためのサポートを提供する上で、非常に強力でシンプルです。

7.2. MongoDB

MongoDB は、ドキュメント指向のデータベース管理システムであり、JSONのようなドキュメントとオプションのスキーマを使用してデータを格納します。 フィールドクエリ、範囲クエリ、正規表現など、ドキュメントを検索するいくつかの方法を提供します。 ドキュメントをプライマリインデックスとセカンダリインデックスにインデックス付けすることもできます。 さらに、シャーディングとレプリケーションを備えたMongoDBは、高可用性と水平方向のスケーラビリティを提供します。

空間データをGeoJSONオブジェクトまたはレガシー座標ペアとしてMongoDBに保存できます。 GeoJSONオブジェクトは、地球のような表面上に位置データを保存するのに役立ちますが、レガシー座標ペアは、ユークリッド平面で表現できるデータを保存するのに役立ちます。

GeoJSONデータを指定するには、 type という名前のフィールドでGeoJSONオブジェクトタイプを示し、coordinatesという名前のフィールドでオブジェクトの座標を示す埋め込みドキュメントを使用できます。

db.vehicles.insert( {
    name: "Vehicle-1",
    location: { type: "Point", coordinates: [ 83.97, 70.77 ] }
} )

ここでは、Vehiclesという名前のドキュメントをコレクションに追加しています。 埋め込まれたドキュメントは、経度と緯度の座標を持つタイプPointのGeoJSONオブジェクトです。

さらに、MongoDB は、地理空間クエリをサポートするために、2dsphereや2dなどの複数の地理空間インデックスタイプを提供します。 2dsphere は、地球のような球のジオメトリを計算するクエリをサポートしています。

db.vehicles.createIndex( { location : "2dsphere" } )

ここでは、コレクションのlocationフィールドに2dsphereインデックスを作成しています。

最後に、MongoDB は、地理空間データの検索を容易にするために、いくつかの地理空間クエリ演算子を提供します。 演算子には、 geoIntersects geoWithin near 、およびnearSphereがあります。 これらの演算子は、平面または球上のジオメトリを解釈できます。

たとえば、near演算子を使用する方法を見てみましょう。

db.places.find(
   {
     location:
       { $near:
          {
            $geometry: { type: "Point", coordinates: [ 93.96, 30.78 ] },
            $minDistance: 500,
            $maxDistance: 1000
          }
       }
   }
)

ここでは、前述のGeoJSON Pointから500メートル以上1,000メートル以内のドキュメントを検索しています。

柔軟なスキーマ、スケール効率、および地理空間データの固有のサポートを使用してJSONのようなデータを表現する能力により、MongoDBは地理空間アプリケーションに非常に適しています。

7.3. PostGIS

PostgreSQL は、 SQL準拠を提供し、ACIDトランザクションを備えたリレーショナルデータベース管理システムです。 さまざまなワークロードをサポートするのに非常に用途が広いです。 PostgreSQLには、同期レプリケーションの組み込みサポートと、通常のBツリーおよびハッシュテーブルインデックスの組み込みサポートが含まれています。 PostGIS は、PostgreSQL用の空間データベースエクステンダーです。

基本的に、 PostGISは、PostgreSQL に地理空間データを保存し、SQLで位置クエリを実行するためのサポートを追加します。 Point LineString Polygonなどのジオメトリタイプを追加します。 さらに、R-tree-over-GiST(汎用検索ツリー)を使用して空間インデックスを提供します。 最後に、地理空間測定とセット操作のための空間演算子も追加します。

いつものようにPostgreSQLデータベースを作成し、PostGIS拡張機能がそれを使用できるようにすることができます。 基本的に、データは行と列に格納されますが、PostGISは、空間参照識別子(SRID)によって定義された特定の座標系のデータを含むジオメトリ列を導入します。 PostGISは、さまざまなGISデータ形式をロードするための多くのオプションも追加します。

PostGIS は、ジオメトリと地理データ型の両方をサポートします。 通常のSQLクエリを使用して、テーブルを作成し、地理データ型を挿入できます。

CREATE TABLE vehicles (name VARCHAR, geom GEOGRAPHY(Point));
INSERT INTO vehicles VALUES ('Vehicle-1', 'POINT(44.34 82.96)');

ここでは、新しいテーブル「車両」を作成し、ポイントジオメトリを使用して特定の車両の位置を追加しました。

PostGISは、データに対して空間操作を実行するためにかなりの数の空間関数を追加します。 たとえば、空間関数 ST_AsText を使用して、ジオメトリデータをテキストとして読み取ることができます。

SELECT name, ST_AsText(geom) FROM vehicles;

もちろん、私たちにとって、より有用なクエリは、特定のポイントの近くにあるすべての車両を探すことです。

SELECT geom FROM vehicles 
  WHERE ST_Distance( geom, 'SRID=4326;POINT(43.32 68.35)' ) < 1000

ここでは、指定されたポイントから半径1km以内のすべての車両を検索しています。

PostGISはPostgreSQLに空間機能を追加し、空間データによく知られたSQLセマンティクスを活用できるようにします。 さらに、PostgreSQLを使用することのすべての利点から利益を得ることができます。

8. 業界標準と仕様

空間データのサポートがデータベース層で拡大していることを確認しましたが、アプリケーション層についてはどうでしょうか。 地理空間アプリケーションを構築するには、空間データを効率的に処理できるコードを作成する必要があります。

さらに、異なるコンポーネント間で空間データを表現および転送するための標準と仕様が必要です。 さらに、言語バインディングは、Javaなどの言語で地理空間アプリケーションを構築する際にサポートできます。

このセクションでは、地理空間アプリケーションの分野で行われている標準化の一部、それらが作成した標準、および使用可能なライブラリについて説明します。

8.1. 標準化の取り組み

この分野では多くの開発が行われ、複数の組織の共同作業を通じて、いくつかの標準とベストプラクティスが確立されました。 まず、さまざまな業界にわたる地理空間アプリケーションの進歩と標準化に貢献しているいくつかの組織を見てみましょう。

Environmental Systems Research Institute(ESRI)は、地理情報システム(GIS)ソフトウェアおよびジオデータベース管理アプリケーションの最も古くて最大の国際的サプライヤーの1つです。 彼らはデスクトップ、サーバー、モバイルなどの複数のプラットフォームを対象としたArcGISという名前で一連のGISソフトウェアを開発しています。 また、シェープファイル、ファイルジオデータベース、Esriグリッド、モザイクなど、ベクトルとラスターの両方のデータ型のデータ形式を確立して促進しています。

Open Geospatial Consortium(OGC)は、公開されているインターフェイス仕様を開発するためのコンセンサスプロセスに参加している、300以上の企業、政府機関、大学からなる国際的な業界コンソーシアムです。 これらの仕様により、あらゆる種類のアプリケーションがアクセスでき、役立つ複雑な空間情報とサービスが可能になります。 現在、OGC標準は、空間参照系識別子(SRID)、Geography Markup Language(GML)、およびSimple Features – SQL(SFS)を含む30を超える標準で構成されています。

Open Source Geospatial Foundation(OSGeo)は、オープンな地理空間技術とデータの共同開発をサポートおよび促進する非営利、非政府組織です。 タイルマップサービス(TMS)のような地理空間仕様を促進します。 さらに、はGeoToolsやPostGISのようないくつかの地理空間ライブラリの開発にも役立ちます。 また、データの表示、編集、分析のためのデスクトップGISであるQGISなどのアプリケーションでも機能します。 これらは、OSGeoが傘下で推進しているプロジェクトのほんの一部です。

8.2. 地理空間標準:OGC GeoAPI

GeoAPI 実装標準は、GeoAPIライブラリを介して、地理情報を操作するためにを使用できる一連のタイプとメソッドを含むJava言語APIを定義します。 地理情報の基本構造は、国際標準化機構(ISO)の技術委員会211およびOGCによって採用された仕様に従う必要があります。

GeoAPIは、実装に依存しないJavaインターフェースを提供します。 GeoAPIを実際に使用する前に、サードパーティの実装のリストから選択する必要があります。 GeoAPIを使用して、いくつかの地理空間操作を実行できます。 たとえば、EPSGコードから座標参照系(CRS)を取得できます。 次に、CRSのペア間の地図投影のような座標操作を実行できます。

CoordinateReferenceSystem sourceCRS = 
  crsFactory.createCoordinateReferenceSystem("EPSG:4326");  // WGS 84
CoordinateReferenceSystem targetCRS = 
  crsFactory.createCoordinateReferenceSystem("EPSG:3395");  // WGS 84 / World Mercator
CoordinateOperation operation = opFactory.createOperation(sourceCRS, targetCRS);
double[] sourcePt = new double[] {
  27 + (59 + 17.0 / 60) / 60,         // 27°59'17"N
  86 + (55 + 31.0 / 60) / 60          // 86°55'31"E
};
double[] targetPt = new double[2];
operation.getMathTransform().transform(sourcePt, 0, targetPt, 0, 1);

ここでは、GeoAPIを使用して地図投影を実行し、単一のCRSポイントを変換しています。

既存のライブラリのラッパーとして利用できるGeoAPIのサードパーティの実装がいくつかあります。たとえば、NetCDFラッパー、Proj.6ラッパー、GDALラッパーなどです。

8.3. 地理空間ライブラリ:OSGeo GeoTools

GeoTools は、地理空間データを操作するためのオープンソースJavaライブラリを提供するOSGeoプロジェクトです。 GeoToolsのデータ構造は基本的にOGC仕様に基づいています。 これは、主要な空間概念とデータ構造のインターフェースを定義します。 また、機能アクセスをサポートするデータアクセスAPI、レンダリングされたステートレスローメモリ、およびXMLスキーマを使用してGMLコンテンツにバインドする解析テクノロジが付属しています。

GeoToolsで地理空間データを作成するには、フィーチャタイプを定義する必要があります。 最も簡単な方法は、クラスSimpleFeatureTypeを使用することです。

SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("Location");
builder.setCRS(DefaultGeographicCRS.WGS84);
builder
  .add("Location", Point.class);
  .length(15)
  .add("Name", String.class);
SimpleFeatureType VEHICLE = builder.buildFeatureType();

機能タイプの準備ができたら、これを使用してSimpleFeatureBuilderで機能を作成できます。

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(VEHICLE);
DefaultFeatureCollection collection = new DefaultFeatureCollection();
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);

また、コレクションをインスタンス化して機能を保存し、GeoToolsファクトリクラスをインスタンス化してその場所のPointを作成します。 これで、特定の場所を機能としてコレクションに追加できます。

Point point = geometryFactory.createPoint(new Coordinate(13.46, 42.97));
featureBuilder.add(point);
featureBuilder.add("Vehicle-1");
collection.add(featureBuilder.buildFeature(null))

これは、GeoToolsライブラリでできることのほんの一部にすぎません。 GeoTools は、ベクトルとラスターの両方のデータ型を操作するためのサポートを提供します。 また、shapefileなどの標準形式のデータを操作することもできます。

9. 結論

このチュートリアルでは、地理空間アプリケーションの構築の基本について説明しました。 このようなアプリケーションの性質と構築における課題について説明しました。 これは、利用できるさまざまなタイプの空間データとデータ構造を理解するのに役立ちました。

さらに、空間データの保存、空間インデックスの作成、および空間操作の実行をネイティブでサポートするいくつかのオープンソースデータベースを調べました。 最後に、地理空間アプリケーションの標準化の取り組みを推進する業界のコラボレーションのいくつかについても説明しました。