OpenStreetMapは内部で地物に対するタグ情報を持っているため、地図画像としてだけでなくデータベースとしての利用価値も高そうです。ここでは、PostgreSQLにインポートしたOpenStreetMapのデータを見てみます。
なお、OpenStreetMapのデータは日々更新されているため、ここに記載のデータ件数やタグ情報はあくまで現時点のものです。また、OpenStreetMapに登録されているデータは必ず正しいという保証はないため、それを承知で利用する必要があります。
目次
PostgreSQL 上での OpenStreetMap のテーブル
OpenStreetMapデータのインポートにosm2pgsqlを使用した場合、PostgreSQL内に以下のテーブルの形でインポートされます。
今回はOpenStreetMap の日本域データをインポートでインポートした環境で行っています。
生成されるデータ
以下のテーブルで保持されるデータは、Mapnikがレンダリングを行う際に利用されます:
planet_osm_line: DBにインポート対象と指定されたすべてのWayが格納されます
planet_osm_point: DBにインポート対象と指定されたすべてのNodeが、タグ情報と共に格納されます
planet_osm_polygon: DBにインポート対象と指定されたすべてのPolygonが格納されます。リレーション情報もここで解決されるようです
planet_osm_roads: 低ズームレベルで利用される、`planet_osm_line`のサブセットを格納します。`planet_osm_line`は、広域の地図を作成するには含まれる情報が多すぎます。選択基準は、セットされるタグによってなされます(FIXME: highway? railway? other?)
JA:Osm2pgsql/schema
Intermediate tables (中間テーブル)
DBへのインポートがスリムモード(slim mode)で行われた場合、以下のテーブルが生成されるようです。これらのテーブルは、メモリの容量が少ない場合や、分単位の差分ファイルを利用する場合に必要となります。ジオメトリはOSMの形式を利用します(ノードの緯度/経度、設定された投影法(デフォルトはspherical mercator)、nodeのwayへの参照)。また、OSMフォーマットから最低限の変換のみが利用されます
planet_osm_nodes: imported nodes in raw format
planet_osm_rels: imported relations in raw format
planet_osm_ways: imported ways in raw format
JA:Osm2pgsql/schema
relsとwaysではtagsというカラムに地物のタグ情報が格納されています。ただ、データ型がテキスト配列型で{key, value, key, value, …}という内容になっているため、奇数番目がキー、偶数番目が値、さらにタグの個数がレコードごとにまちまちであることも自分で考慮してハンドリングしなければならないため扱いにくいです。
一方、point、line、polygon、roadsのtagsカラムはhstore型に整形済みのため、PostgreSQL上で扱いやすくなっています。
そこで、これらの4テーブルのtagsカラムについて、どのようなタグが存在しているのか調べてみます。
hstore型データを扱う演算子や関数は色々あり、ここでは主にskeys
関数を使います。hstoreのキーを集合として返してくれます。
タグの件数
全てのレコードにタグがあるわけではなく、tagsカラムが空欄でタグが無いレコードも多いようです。
1レコードに対してタグが複数設定されているデータがあるため、重複も含めてキーをカウントするとタグは結構な数になります。
ではタグのキーは何種類あるかというと、テーブルごとに異なりますが大体1000~3000種類、4つのテーブル全体でまとめてカウントすると4504種類になります。
select (select count(*) from planet_osm_point) "レコード数", (select count(*) from planet_osm_point where tags <> '') "タグがあるレコード", (select count(*) from (select skeys(tags) from planet_osm_point) a) "タグのキー", (select count(*) from (select distinct skeys(tags) from planet_osm_point) a) "キーの種類"
テーブル | レコード数 | タグがあるレコード | タグのキー | キーの種類 |
---|---|---|---|---|
planet_osm_point | 2000939 | 859189 | 2137234 | 2851 |
planet_osm_line | 9167560 | 1147055 | 3600175 | 1989 |
planet_osm_polygon | 14751883 | 696343 | 1381433 | 2276 |
planet_osm_roads | 611171 | 369982 | 2245640 | 1137 |
select count(*) from ( select skeys(tags) keys from planet_osm_point union select skeys(tags) keys from planet_osm_line union select skeys(tags) keys from planet_osm_polygon union select skeys(tags) keys from planet_osm_roads ) a
count |
---|
4504 |
よく使われているタグのキー
上位20件です。nameというのは当然ながらよく使われているようです。
select keys, count(*) cnt from ( select skeys(tags) keys from planet_osm_point ) a group by keys order by cnt desc
planet_osm_point | planet_osm_line | planet_osm_polygon | planet_osm_roads | ||||
---|---|---|---|---|---|---|---|
name:en | 192700 | name:ja | 442675 | building:levels | 217631 | name:en | 267439 |
name:ja | 143618 | lanes | 355092 | parking | 76017 | name:ja | 252585 |
operator | 86313 | name:en | 321315 | roof:colour | 72283 | lanes | 241247 |
crossing | 77660 | footway | 199670 | addr:city | 61274 | maxspeed | 95772 |
public_transport | 75492 | maxspeed | 132608 | name:en | 52031 | gauge | 71422 |
ele | 64617 | operator | 111933 | roof:shape | 48989 | electrified | 70241 |
bus | 51871 | gauge | 93791 | addr:quarter | 40704 | toll | 68930 |
name:ja_rm | 50965 | electrified | 88699 | area | 40344 | operator | 68346 |
brand | 45211 | voltage | 85926 | addr:province | 38922 | smoothness | 62988 |
opening_hours | 42989 | frequency | 80381 | addr:postcode | 37206 | usage | 59867 |
phone | 40499 | smoothness | 79041 | name:ja | 35494 | motorcycle | 58497 |
cuisine | 40115 | toll | 69703 | addr:neighbourhood | 35033 | motorcar | 58463 |
website | 36756 | operator:ja | 65519 | sport | 32860 | voltage | 58079 |
traffic_signals | 34914 | usage | 64519 | crop | 27069 | frequency | 57538 |
emergency | 34241 | operator:en | 62911 | addr:block_number | 25121 | operator:ja | 54336 |
addr:postcode | 29434 | motorcar | 60745 | addr:street | 24395 | operator:en | 48709 |
information | 28631 | motorcycle | 60530 | operator | 24264 | official_name | 46723 |
wikidata | 28307 | crossing | 56687 | golf | 22082 | alt_name | 40202 |
level | 28120 | official_name | 50126 | wikidata | 21320 | name:ja_rm | 32478 |
branch | 27246 | name:ja_rm | 45120 | website | 17822 | name:ko | 30132 |
日本語タグ
「~:ja」というのは日本語タグのキーのようです。125種類が存在しています。
select keys, count(*) cnt from ( select skeys(tags) keys from planet_osm_point union all select skeys(tags) keys from planet_osm_line union all select skeys(tags) keys from planet_osm_polygon union all select skeys(tags) keys from planet_osm_roads ) a where keys like '%:ja' group by keys order by cnt desc
name:ja | 874372 |
operator:ja | 124809 |
brand:ja | 20361 |
species:ja | 6699 |
genus:ja | 3690 |
bridge:name:ja | 3607 |
alt_name:ja | 2976 |
cuisine:ja | 2838 |
official_name:ja | 1377 |
denomination:ja | 1109 |
tunnel:name:ja | 921 |
wikipedia:ja | 882 |
old_name:ja | 713 |
name_alt:ja | 662 |
short_name:ja | 322 |
nat_name:ja | 313 |
start_date:ja | 180 |
loc_name:ja | 171 |
network:ja | 163 |
owner:ja | 118 |
tunnel:start_date:ja | 94 |
taxon:ja | 90 |
addr:ja | 87 |
religion:ja | 81 |
branch:ja | 81 |
place_name:ja | 72 |
reg_name:ja | 65 |
ref:ja | 59 |
is_in:ja | 54 |
shelter_type:ja | 50 |
description:ja | 49 |
junction:name:ja | 44 |
product:ja | 35 |
training:ja | 34 |
opening_date:ja | 32 |
addr:full:ja | 29 |
hazard_type:ja | 23 |
was:cuisine:ja | 16 |
produce:ja | 15 |
faculty:ja | 15 |
tunnel:opening_date:ja | 15 |
was:name:ja | 14 |
destination:lang:ja | 13 |
language:ja | 12 |
disused:name:ja | 11 |
addr:quarter:ja | 10 |
to:ja | 10 |
artist_name:ja | 10 |
trees:ja | 9 |
tactile_writing:braille:ja | 8 |
bridge:opening_date:ja | 7 |
crop:ja | 7 |
addr:city:ja | 7 |
addr:housename:ja | 7 |
is_in:island:ja | 7 |
denotation:ja | 6 |
speech_output:ja | 6 |
hairdresser:ja | 6 |
addr:province:ja | 5 |
website:ja | 5 |
bus_line[0]:ja | 5 |
wheelchair:description:ja | 5 |
contact:phone:ja | 4 |
phone:ja | 4 |
destination:street:lang:ja | 4 |
statue:ja | 4 |
disused:cuisine:ja | 4 |
sport:ja | 4 |
vending:ja | 3 |
beauty:ja | 3 |
FIXME:ja | 3 |
aed:location:ja | 3 |
healthcare:speciality:ja | 3 |
fixme:ja | 3 |
subject:ja | 3 |
massage:ja | 3 |
shop:ja | 3 |
addr:block_number:ja | 3 |
works:ja | 2 |
abandoned:name:ja | 2 |
alt_name_1:ja | 2 |
construction:name:ja | 2 |
craft:ja | 2 |
cuisune:ja | 2 |
doctors:ja | 2 |
enshrine:main:ja | 2 |
exit_to:ja | 2 |
local_name:ja | 2 |
name:en:ja | 2 |
name_1:ja | 2 |
url:ja | 2 |
was:note:ja | 2 |
office:ja | 1 |
menu_languages:ja | 1 |
int_name:ja | 1 |
sorting_name:ja | 1 |
int:ja | 1 |
historic:civilization:ja | 1 |
full_name:ja | 1 |
designation:ja | 1 |
stationery:ja | 1 |
demolished:tunnel:name:ja | 1 |
strat_date:ja | 1 |
demolished:name:ja | 1 |
suisine:ja | 1 |
deli:ja | 1 |
cutline:ja | 1 |
cusine:ja | 1 |
trade:ja | 1 |
traffic_signals:designation:ja | 1 |
cuisien:ja | 1 |
cuijone:ja | 1 |
clothes:ja | 1 |
bridge:reg_name:ja | 1 |
brand:short_name:ja | 1 |
addr:neighbourhood:ja | 1 |
books:language:ja | 1 |
blind:description:ja | 1 |
amenity:ja | 1 |
abandoned:note:ja | 1 |
was:operator:ja | 1 |
addr:suburb:ja | 1 |
addr:street:ja | 1 |
proposed:description:ja | 1 |
old_website:ja | 1 |
タグの値
特定のキーに対する値は、?
演算子(hstoreがキーを含むかどうか)と->
演算子(キーの値を取り出す)で調べられます。例えば以下のようにすると日本語の橋の名前が1475個得られ「日本には大体1475個くらい橋があるらしい」ということが分かります(冒頭で述べたとおりどれくらい正確かはさておき)。
select distinct tags->'bridge:name:ja' from planet_osm_line where tags ? 'bridge:name:ja'