PostgreのOSMテーブルをOpenLRがデコードできるよう準備する

# はじめに

この記事では、OpenStreetMapの地図を使ってOpenLRをデコードするために必要なテーブルを作成する方法を説明します。
自分の中では最適と思われる方法で変換しておりますが、あくまで個人の意見なのでご留意ください。
環境に合わせて変更できる箇所は下記に記載しております。

実装の部分に関しては、下記記事を参照してください。

https://qiita.com/westTraffic/items/914401cc1768b37852c1

### 前提
OpenStreetMapをosm2pgsqlを使って変換処理が完了している前提で説明します。
osm2pgsqlはオープンライブラリで、OpenStretMapの地図をpostgres SQLデータベースに変換します。

### roadsテーブル

- スキーマ名: public
- テーブル名: olr_road

スキーマ名、テーブル名は環境に合わせて変更してください。

```
CREATE TABLE public.olr_road (    
id BIGINT PRIMARY KEY,    
frc int2,
fow int2,
flowdir int2,
from_int bigint,
to_int bigint,
len float8,
geom GEOMETRY(LineString, 4326)
);

CREATE INDEX ind_public_olr_road_from_int ON public.olr_road (from_int);
CREATE INDEX ind_public_olr_road_to_int ON public.olr_road (to_int);
CREATE INDEX ind_public_olr_road_geom ON public.olr_road USING gist (geom);
```

#### roadsテーブルにデータ挿入

先にコードを示します。

```
INSERT INTO public.olr_road
select id,
case 
when w.tags ->> 'highway' in ('motorway', 'motorway_link') then 0
when w.tags ->> 'highway' in ('trunk', 'trunk_link') then 1
when w.tags ->> 'highway' in ('primary', 'primary_link') then 2
when w.tags ->> 'highway' in ('secondary', 'secondary_link') then 3
when w.tags ->> 'highway' in ('tertiary', 'tertiary_link') then 4
else 6
end as frc,
case 
when w.tags ->> 'junction' = 'roundabout' then 4
when w.tags ->> 'highway' in ('motorway_link', 'trunk_link', 'primary_link', 'secondary_link', 'tertiary_link') then 6
when w.tags ->> 'highway' = 'motorway' then 1
when w.tags ->> 'highway' = 'trunk' then 2
else 3
end as fow,
case 	
when w.tags->> 'oneway' = 'yes' then 3
when w.tags->> 'oneway' = '-1' then 2
else 1
end as flowdir,
nodes[1] as from_int,
nodes[array_upper(nodes, 1)] AS to_int,
ST_Length(r.way::geography) AS len,
way as geom
from public.planet_osm_ways as w
inner join public.planet_osm_line as r
on w.id = r.osm_id
where w.tags ->> 'highway' in (
'motorway','motorway_link','trunk','trunk_link','primary', 'primary_link',
'secondary', 'secondary_link','tertiary','tertiary_link','residential', 'road',
'unclassified','service','living_street'
)
```

##### frc(functional road class)
highwayタグの値に基づき、frcを定義しています。
条件や数値については環境に合わせて調整してください。

##### fow(form of way)
roundaboutはjunctionタグから定義しています。
それ以外のfowの定義はhighwayタグの値をもとに道路形状を"推測して"定義しています。
現状、OSMにはform of wayとマッチするタグが存在しないのでこの方法を使用しています。
もしおすすめの方法があればぜひ教えてください。

##### flowdir
onewayタグの値に基づき、flowdirを定義しています。
- yesの場合、順方向の一方通行
- -1の場合、逆方向の一方通行
いずれの場合も一方通行とみなしています。

##### from_int(from intersectionの略)
リンクの開始ノードIDを定義しています。
waysテーブルのnodesフィールドの1番目の要素を開始ノードIDとしてみなしています。

##### to_int(to intersectionの略)
リンクの終了ノードIDを定義しています。
waysテーブルのnodesフィールドの最後の要素を終了ノードIDとしてみなしています。

##### len(リンク長)
リンクの長さを定義しています。
lineテーブルのgeometryフィールド(way)の長さをメートルに変換しています。

##### 条件
lineテーブルには全ての線形情報が格納されていますが、ここでは車両が通行できる(と思われる)道路のみを対象としています。
必要に応じて調整してください。

### nodesテーブル

- スキーマ名: public
- テーブル名: olr_node

スキーマ名、テーブル名は環境に合わせて変更してください。

```
CREATE TABLE public.olr_node (    
    id BIGINT PRIMARY KEY,    
    geom GEOMETRY(POINT, 4326)
);

CREATE INDEX ind_public_olr_node_geom ON public.olr_node (geom);
```

#### nodesテーブルにデータ挿入

先にコードを示します。

```
INSERT INTO public.olr_node (id, geom)
SELECT DISTINCT
n.id,
ST_SetSRID(
ST_MakePoint(n.lon / 1e7::float, n.lat / 1e7::float), 
4326
)::geometry(Point, 4326) AS geom
FROM public.planet_osm_nodes AS n
INNER JOIN public.planet_osm_ways AS w
ON n.id = w.nodes[1] OR n.id = w.nodes[array_upper(w.nodes, 1)]
where w.tags ->> 'highway' in (
'motorway','motorway_link','trunk','trunk_link','primary', 'primary_link',
'secondary', 'secondary_link','tertiary','tertiary_link','residential', 'road',
'unclassified','service','living_street'
)
```

nodeテーブルには、int型で緯度・経度が格納されています。
それをgeometry型に変換してnodesテーブルに挿入します。

# まとめ
上記2つのテーブルが準備できたら準備完了です。

下記を参考にOpenLRのデコードを試してみてください。
その際、`myMapReader.py`の`SCHEMA`、`TABLE_LINE`、`TABLE_NODE`を環境に合わせることを忘れないでください。

https://qiita.com/westTraffic/items/914401cc1768b37852c1