概要
トグルホールディングス AIエンジニアの政岡です。トグルアドベントカレンダー15日目の記事です。 GISに関わることになったが、GeoJSONって何だ?ってなっている人に向けて書きました。
GeoJSONとは?
GeoJSONとは地理空間データをJSON形式で取り扱うための形式す。RFC7946で定義されています。主にウェブアプリケーションや地理情報システム(GIS)で利用され、地理的なポイント、ライン、ポリゴンといった図形や、それに付随する情報を格納します。テキスト形式なので、人にも機械にも読みやすいという特徴がありますが、大量のデータを取り扱う際にはデータ容量が大きくなってしまいます。
他の地理空間情報を取り扱う形式の例としてEsri社が定義したshp形式やKeyhole社(現Google Eargh)kml形式などがあります。
GeoJSONの基本構造
GeoJSONでは、地図上で表示される物体(地物、オブジェクト)はジオメトリという言葉を用いて表します。7つのジオメトリ型があります。それぞれを表す地物は以下のとおりです。 - Point(点) - MultiPoint(点群) - LineString(線) - MultiLineString(線群) - Polygon(多角形) - MultiPolygon(多角形群) - GeometryCollection(オブジェクト群)
これだけあれば地物を表現するのに事足りなさそうですね。GeoJSONでは、[経度, 緯度]のリストで座標を、座標のリストで線や多角形の地物を表現します。では、どのように記述するのか、Point型とPolygon型を具体例として示します。type と coordinates が必須です。
- Point 皇居の位置(緯度:35.6856、経度:139.7528)を表す点。
{ "type": "Point", "coordinates": [139.7528, 35.6856] }
- Polygon (0,0), (1,0), (0,1)を結ぶ三角形。
{ "type": "Polygon", "coordinates": [[ [0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [0.0, 0.0] ]] }
座標の順序は経度→緯度の順になっています。適当な三角形の座標でも、それっぽい緯度経度の座標でもx→yの順番で表現できるので便利です。とはいえ、日本語でよく使う順序、緯度経度、と逆なのでお気をつけを。
実際にソースコードを書くときは、経度が英語でlongitude、緯度が英語でlatitudeなので、[lng, lat]や[lon, lat]とすることが多いです。
余談ですが、地理空間情報を扱うサービスによって、内部で取り扱う際の緯度経度の順番は異なる場合があるので注意が必要です。 - Google Maps: [lat, lng] - Mapbox: [lng, lat]
ジオメトリの構造を比較
基本的に座標リストのネストの深さが異なります。
"coordinates": [lng, lat] // Point "coordinates": [ [lng, lat], [lng, lat], [lng, lat] ] // LineString "coordinates": [ [ [lng, lat], [lng, lat], [lng, lat] ] ] // Polygon
"coordinates": [ [lng, lat], [lng, lat], [lng, lat] ] // MultiPoint
"coordinates": [ [[lng, lat], [lng, lat], [lng, lat]], [[lng, lat], [lng, lat], [lng, lat]] ] // MultiLineString
"coordinates": [ [[[lng, lat], [lng, lat], [lng, lat]]], [[[lng, lat], [lng, lat], [lng, lat]]] ] // MultiPolygon
簡単にまとめると以下の感じです。 - Point - ひとつの座標、[lng, lat] - LineString - Pointのリスト - Polygon - LineStringのリスト - MultiPoint - Pointのリスト、あるいは、線 - MultiLineString - LineStringのリスト - MulitPolygon - Polygonのリスト
以下のPolygonは内側に穴をもちます。座標のリストが2つありますが、MultiPolygonではありません。 座標順は、 外側のリング→反時計回り 内側のリング(穴)→時計回り です。 MultiPolygonは、複数の独立したPolygonを表現するときに使用します。
{ "type": "Polygon", "coordinates": [ [ [0, 0], [10, 0], [10, 10], [0, 10], [0, 0] ], [ [2, 2], [8, 2], [8, 8], [2, 8], [2, 2] ] ] }
ジオメトリに情報を持たせる
基本的なジオメトリで地物を表現できるようになりました。しかし、これができただけだと、その地物の形状はわかるが一体何者?となりかねません。そこで登場するのがFeature型やFeatureCollection型です。
Feature型
Feature型はpropertiesキーででジオメトリに属性をもたせます。先程の皇居の例を使用すると以下のとおりです。
{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [139.7528, 35.6856] }, "properties": { "country": "Japan", "city": "Tokyo", "address": "千代田区千代田1-1" "name": "皇居", } }
Point型では「点」でしたが、Feature型ではその点が「皇居」で「千代田区千代田1-1」という住所をもっている、ということがわかります。キーは以下のとおりです。他のジオメトリ型でも同様です。
- type: Feature
- geometry: 7つの基本ジオメトリ型のいずれか
- properties: JSON形式の属性情報(このキーはなくても良い)
FeatureCollection型
FeatureCollection型では、複数の地物を取り扱うことができます。。ジオメトリをFeatureでラップしているので何でも来いという感じです。
{ "type": "FeatureCollection", "features": [ {"type": "Feature", "geometry": {...}, "properties": {...}}, {"type": "Feature", "geometry": {...}, "properties": {...}}, {"type": "Feature", "geometry": {...}, "properties": {...}} ] }
例えば、東京タワー、スカイツリー、京都タワー、のように様々な塔の情報をかき集めると、それぞれが位置する点と属性情報でFeatureを得ることができます。また、各塔の敷地をPolygonとしたり、それぞれの塔を結ぶ線をLineStringとしたりすると、点のときと同様にFeatureを得ることができます。FeatureCollectionは、これらのFeatureをまとめることができるのです。
まとめ
最初に簡単に知っておきたい内容をつらつらと書いてみました。詳細を知りたくなった方はRFC7946に目を通してみてください!