トップOpenStreetMap > OpenStreetMapのデータ構造

OpenStreetMapのデータ構造

JOSMのファイル出力

狭い地域のOSM(OpenStreetMap)データであれば、多くのマッパーが使用している OSM エディタである JOSM[1] の ファイル出力を使うのが一番簡単であろう。

JOSM は OSM の Overpass API[2] により、OSMデータをダウンロードしている。 JOSMによるのではなく、直接 Overpass API を使って OSMデータをダウンロードすることもできる。

JOSMで三宅島の OSMデータをダウンロードした。

JOSMの場合、文字列は一重引用符であるが、その他の方法で OSMデータを入手した場合は二重引用符で括られていることが多い。

OSMデータは大きくは順に nodeセクション、wayセクション、relationセクションの三つで構成される。 ただし、セクションの始まりと終わりを示すようなタグはない。あった方がパースの効率は上がるのだが。

下に、ごく一部を抜粋した結果を示す。

  1. バス停、信号機など pointデータの場合、一つの nodeセクションで完結している。ただし、バス停が バス路線relationのメンバーになるなど、relation から参照されることがある。また、完結した point データが way から参照されることもある。

    殆どのノードは道路とか建物などの折れ線データの座標を表すものである。一つの node が多数の way あるいは relation から参照されることがある。

  2. way は道路などの折れ線データまたは建物や森林などのポリゴンデータを表す。 ノード(頂点)については id のみで、その座標位置は nodeセクションで管理されている。
  3. relation は複合的な地物を表現するもので、node、way、relation をメンバーとして持つ。 このうち、メンバーとして relation を持つような relation を super relation と呼んでいる。

    地図としてのレンダリングでは super relation は除外するのが普通である。 メンバーの relation をレンダリングするため、描画が欠けるわけではない。

    例えば、バス路線リレーションの場合、上り、下り、あるいは、種々の変形路線をそれぞれ relation とするが、 それらを取りまとめる super relation が存在する。

  4. node、way、relation は多くのタグを持つが、地図のレンダリングに使われるものはその一部に過ぎない。
  5. JOSMの出力では文字列は一重引用符「'」で括られる。 一般には OSM(xml) では、二重引用符「"」で括られることが多い。
<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' generator='JOSM'>
  <node id='711468649' timestamp='2015-09-13T14:30:43Z' uid='664547' user='smellman' visible='true' version='2' changeset='34000952' lat='34.0781465' lon='139.5625333'>
    <tag k='KSJ2:CompositeCurve' v='cv60Airport' />
    <tag k='KSJ2:NA3' v='三宅島空港' />
    <tag k='KSJ2:airport_id' v='cf02_31' />
    <tag k='note' v='National-Land Numerical Information (Airport) 2007, MLIT Japan' />
    <tag k='note:ja' v='国土数値情報(空港データ)平成19年 国土交通省' />
    <tag k='source' v='KSJ2' />
    <tag k='source_ref' v='http://nlftp.mlit.go.jp/ksj/jpgis/datalist/KsjTmplt-C28-v1_1.html' />
  </node>
  <node id='1049158228' timestamp='2010-12-19T15:50:41Z' uid='146930' user='Tom_G3X' visible='true' version='1' changeset='6707298' lat='34.1162461' lon='139.5466017' />
  <node id='1049158268' timestamp='2010-12-19T15:50:42Z' uid='146930' user='Tom_G3X' visible='true' version='1' changeset='6707298' lat='34.1207358' lon='139.4995371' />
  <node id='1049158556' timestamp='2010-12-19T15:50:47Z' uid='146930' user='Tom_G3X' visible='true' version='1' changeset='6707298' lat='34.0725952' lon='139.4814884' />
  <node id='1049158905' timestamp='2010-12-19T15:50:52Z' uid='146930' user='Tom_G3X' visible='true' version='1' changeset='6707298' lat='34.0795194' lon='139.4856784' />

  <way id='368017249' timestamp='2015-08-28T17:35:28Z' uid='664547' user='smellman' visible='true' version='1' changeset='33648912'>
    <nd ref='3718838012' />
    <nd ref='3718838011' />
    <nd ref='3718838009' />
    <nd ref='3718838008' />
    <nd ref='3718838012' />
    <tag k='building' v='yes' />
  </way>
  
  <way id='154522597' timestamp='2016-09-17T01:12:10Z' uid='692002' user='下り専門' visible='true' version='3' changeset='42218256'>
    <nd ref='1670494025' />
    <nd ref='1670494061' />
    <nd ref='1670494135' />
    <tag k='highway' v='unclassified' />
  </way>
  
  <relation id='12172683' timestamp='2021-01-29T18:31:20Z' uid='10743925' user='BartekChom' visible='true' version='2' changeset='98382678'>
    <member type='way' ref='424083558' role='' />
    <member type='way' ref='424083557' role='' />
    <member type='way' ref='444552975' role='' />
    <tag k='name' v='東京~三宅島・御蔵島・八丈島航路' />
    <tag k='name:en' v='Tokyo-Miyake-Mikura-Hachijo' />
    <tag k='name:ja' v='東京~三宅島・御蔵島・八丈島航路' />
    <tag k='operator' v='東海汽船' />
    <tag k='route' v='ferry' />
    <tag k='type' v='route' />
    <tag k='website' v='https://www.tokaikisen.co.jp/' />
  </relation>
</osm>

OSMデータの解析

OSMのデータサイズに見合う十分な主メモリが使える場合には、 class Node、class Way、class Relation を定義して、それぞれの id をキーとして、 HashMap<Long、Node> mapNode、HashMap<Long、Way> mapWay、HashMap<Long、Relation> mapRelation で管理するのが一番分かりやすい。

例えば、三宅島のOSMデータであれば、これが可能である。

しかし、日本地図全体となると、パソコンの主メモリでは到底扱いきれない。日本地図全体の OSM データ(xml形式)は、現在 40数GBになる。xml形式には冗長性があるとは言っても、class Node、Way、Relation でも別のオーバヘッド があるため、簡単にメモリにのるものではない。

自作OSM地図ではもっと凝った方法で Node の座標値データを管理している。これについては別のページで述べる。

海岸線データ

海岸線データも OSMデータに含まれるが、標準OSM地図では別のやり方でレンダリングしている。

三宅島のデータを調べると、海岸線の部分、部分はそれぞれ wayデータ(タグはnatural=coastline)として存在するが、全体を管理するような relation は存在しない。

別の島では、natural=coastline タグを持つ relation ではなく、place=island の relation のメンバー way が natural=coastline となっていた。

現在、自作OSM地図では標準OSM地図と同じように、OSMデータの natural=coastline を抜き出して、別途管理している陸地ポリゴンあるいは水域ポリゴンを使用しているが、これらのデータはシェイプファイル形式のため、 その扱いに手数がかかる。 できれば、日本地図だけを対象として、OSMデータから直接陸地ポリゴンデータを取り出したい。 この場合は、relationのパースではなく、直接、way データをつなぎ合わせてポリゴンデータを構築する必要がある。

この場合、本州、北海道、四国、九州といった面積の大きいものは一つのポリゴンではなく、それぞれ、いくつかに分割したポリゴンとしたい。その詳細は別のページで述べる。

リファレンス

[1] JOSM
[2] JA:Overpass API