【G-Map Project】架空地図のGISデータを作りたい

シリーズ化するかどうかは未定となっています。皆さん、GISデータをいじったことはありますか?
たいていの場合はいじるとしても国土数値情報とかからシェープデータを持ってきててんやわんやすることが多いと思います。僕自身も、シェープデータを駆使して警察署のエリアから交差点の場所を推定したりするプログラムを作っていたりしますが、今回はその中でも架空地図のGISデータに絞っています。
んで毎回初めに言っているんですが、この内容はただの日記とかメモとかです。情報を共有するために書いているわけではないので、適当な日本語ですし伝わるような書き方をしていません。なので読み物だと思ってください。ただ、この中から適宜情報が役に立つことがあればうれしいなあって感じです。基本は自己満足の世界なんですよ。


G-Map Projectとは?

決してG○○GLE社のあのマップのことをさしているわけではありません。名前の由来はわかると思うのでもう割愛するとして、前述したとおりに「架空地図のGISデータを作成する」プロジェクトとなります。
日本を参考にGISデータ化したものは、国土数値情報だったり道路交通情報センターのオープンデータだったりと多種多様に転がっていますが、自分の脳内で完結する架空地図(敷いては架空国家、架空世界)に関してはそんなものを誰も用意してくれるはずがありません。ならば作ってしまおうということで始まったのがこのプロジェクト。まあ、プロジェクトといってもやっているのは僕一人ですが。

架空地図のGIS化とは

架空地図というのは、基本的に下書き地図があると思います。いきなり本番で清書している方もいらっしゃるかもしれませんが、ふつうは何かしら下書きのような形で残すでしょう。僕もそうで、A4のコピー用紙(少し前までは裏紙を使用していました)に1:30000の縮尺で下書き地図を描いています。

しかし、「今描いている場所のデータ」を取りたいときにどうしましょう。例えば、「今描画している一般府県道のリストが欲しい」となったとき、律儀にExcelか何かに描いたものを入力していきますか? それで時給が発生するならやりますが、到底自己満足のため無償です。そしてこの方法だといつか確実に整合性が取れなくなります。そして全く別の位置にある同一番号の路線が数多く誕生する原因にもなります。

他にも取得したいデータとして、「鉄道駅の数」とか「市町村の面積」とかありますよね? ね? え、ない? もうブラウザバックしていいですよ。

こういう需要をかなえてくれるのがGISデータです。こちらを使用することで夢がとてつもなく広がります。

  • 各市町村の面積がわかります。

  • 各市町村にどれくらいの町名があり、町名表示未実施の割合などを算出できます。

  • 鉄道駅名リストを作成できます。道路ももちろんです。

  • うまくデータを作れば、最短経路の算出などもできます。

  • 他にも無数にいろいろなことができますよ。

ね? 少し楽しくなってきたでしょう? 自分で思い描いた架空世界が現実的な数値をもって生きてくるのです。架空地図のGISデータ化。さあ皆様もやってみましょうよ。

もちろん前提条件が必要です

GISデータを作るにあたってはもちろんのことながら前提条件が必要となります。その中でもとりわけ重要なのが、「国の座標系」です。

こんなところまで考えている人はなかなかいらっしゃらないと思います。僕もはっきりとは考えていませんでした。ですが、この座標系が存在しえないと地図の作成はかなり難しいです。あなたの考える世界が完全に二次元の世界で構成されているならば(世界の果てが存在するならば)平面座標系でもいいかもしれません。ですが、ふつうは地球なり外部の惑星なり「球体」に国家が存在しているはずです。なのでそれを平面に投影する際の座標変換が必要になります。これについては次章で。

さらに、前提条件としてほかにも「データの粒度」がカギになります。例えば鉄道駅1つで考えてみます。鉄道駅に欲しいデータはなんでしょうか。
最低限、「駅の名前」「駅の場所」「所属する路線名」は欲しいところです。ですが、鉄道ファンの方はもしかすると「駅のホーム数」「駅の略称?」「その駅でなる発車メロディー」のような情報が欲しくなるかもしれません。ではこれも入れますか? さらに必要なものはありますか? 鉄道に限らず、道路、市町村などでどこまで考え込みますか? そんな「粒度」が、前提条件としてやってきます。ここに関しては、あなたが今思い浮かべているデータ量と吟味しておけば平気です。ほとんどのデータは後から追加もできるので、まずは最低限のデータから書き起こしていけばいいと思います。

さて、長くなりましたがこのような形でG-Map Projectを立ち上げ、今は僕の架空世界「天の原銀河皇国連邦」についてのGISデータを作成しています。

ところでGISデータってなあに?

話にならないのでググってください。めちゃくちゃざっくりいえば「ポリゴン」「ライン」「ポイント」で構成された地理情報です。さっきも例に挙げた「鉄道駅」であれば、「緯度経度」で指定した「場所」に「ポイント」を設置し、そのポイントに「鉄道駅名称」等のデータを属性として埋め込むことで表現します。いわばデータベースです。

GISデータの表現の仕方についてはいろいろありますが、G-Map Projectでは「PostGIS」を使用しています。SQLの知識が必要ですが、慣れるとSQLだけで結構いろいろなことができるようになるのでできる幅が広がります。

あとGISデータをいじる際は絶対に「QGIS」を導入しておきましょう。Windows、Mac、Linux全部入ります。スマホは知らん。オープンソースで無料、GISに関する様々な操作ができるのでもうこれなしでは何もできません。

架空世界の座標系を定める

さて、前章でも紹介した前提条件である「座標系」についてです。こちらはあなたが思い描く世界が何なのかによっていろいろ振り分けてみるといいと思います。proj書式なるものが出てきますが何のことかわからないと思うので(僕もわかりません)、無視して結構です。ちなみに迷ったらWGS4326使えばいいと思います(あとはWGS84とか)。

都道府県単位レベルの大きさの場合

架空鉄道などに携わっている方に多いとされる、地方レベル・都道府県レベルの情報しかない場合です。この場合は正直どんな座標系を使っても変わりません。WGS4326とか使用してみましょう。緯度経度で表すので地球みたいな惑星を想定していれば緯度経度を指定するだけで大体いい感じになります。平面座標系とかでもいいかも。その場合緯度経度は使えなくなります。

日本とかアメリカみたいな国家レベルの場合

だいぶでかくなってくるので、適切な座標系を選択しないとメルカトル図法におけるグリーンランドみたいな現象が発生します。特にアメリカとかロシアみたいな広大な土地を持っているとのことであればなおのこと必要です。この場合、緯度経度が判明しているなら素直にWGS4326を使用しましょう。多分環境とかも地球と同じだと思いますので。

地球を飛び出す場合

G-Map Projectではここに該当します。所謂宇宙(とか別世界)に完全に架空で存在する場合です。この場合はその国家が所属する惑星に対する定義が必要になります。現実味に合わせるのであればケプラーの法則とかを利用して惑星の質量、直径などを割り出す必要があります。一度僕もやってみたことがありますが、所属する惑星が木星レベルになり非現実的になったのでここは省略しました。こういう覚悟があるならやってみるといいです。
惑星は基本的に楕円球に近似することができます(自転の向きが傾いているとかも考慮してくださいね)。なので長短それぞれの半径が分かれば緯度経度との相互変換ができます。proj書式を使用して、楕円体である4326や84をカスタマイズしましょう。

G-Map Projectでは?

上記の通り、「天の原銀河皇国連邦」の「白明星」を中心とした恒星系「白明系」の第3~第5惑星という位置づけになっているので、地球を飛び出すどころか銀河系も飛び出しています。ですが、正直現実味を帯びた計算は非常にめんどくさいです。

また、現在描画している「成平国」はおそらくどんなにでかくてもロシア以上の大きさにはならないだろうということで、でもほかの国に関する情報も考慮したうえで、以下のような設定にしました。

地球と同様の扁平率で、長短半径が地球の3倍である。

これなら超絶簡単で、WGS84なりWGS4326なりの座標系(楕円近似)で表現できます。ただし、緯度経度から「絶対距離」(メートル)を算出する場合は距離をすべて3倍する必要があります。
こうすることで、実は後述するPostGISとの連携がすごい楽になります。本当はもっと設定を凝ったほうがいいと思いますが、いったんこの方式で現在は行っています。なのでG-Map ProjectのGISデータは実は地球のGISデータと若干互換性があります(笑) (ただし地球のGISデータと比較するとあらゆるデータが3倍になっています)。

こういう妥協が受け入れられない場合はGIS化は難しいかもしれませんね。

データベースを決定する

GISデータはいろいろな形式があり、「GeoJSON」「KML」「WKT」「PostGIS」「シェープファイル」…と無数にあります。この中でも僕は特に扱いやすいものとして、PostGISを上げます。G-Map ProjectでもPostGISを使用しています。

PostGISとは?

これもググってほしいんですが、PostGISはPostgreSQLというRDB(リレーショナルデータベース)の拡張機能です。MySQLとか聞いたことあると思いますが、あの仲間であるデータベースのプラグインだと思ってください。これにより、普段使っているSQLでGISデータを扱うことができます。GISデータ以外は通常のPostgreSQLと変わらないので、何かと便利です。

MySQLにもジオメトリ型が存在するのでGISデータは作成可能ですが、まだ発展途上で関数が圧倒的に不足しています。なのでRDBを使用する場合は断然PostGISでしょう。

ちなみにシェープファイルは日本語が属性名として使えなかったり、ファイルサイズ制限があったりするのであえてこれで作る理由がありません。

PostGISの作り方

詳しくはググれ!
一応Ubuntuでのやり方は書いておきます。Windowsの場合はインストーラーでインストールしてください。

sudo apt update
sudo apt install -y postgresql-15 # バージョンは適宜変えて
sudo apt install -y postgresql-15-postgis-3 # バージョン適宜変えて
sudo psql -u postgres
# psqlでSQL打ち込む
CREATE USER hogehoge WITH PASSWORD 'パスワード';
CREATE DATABASE gis_data; # GISデータベースを作成
ALTER DATABASE gis_data OWNER TO hogehoge;
USE gis_data;
CREATE EXTENSION postgis;

だいたいこんな感じで作れます。

テーブルを作ってQGISと連携する

だんだん解説書じみてきたんで端折ります。ここはあくまでG-Map Projectではこういう風にしているよって報告で。

テーブルの作成

QGISに取り込む際には既存のPostGISから読み込むことになるのでQGISから作成することが難しいです。できなくはないですが十中八九データ型がいかれるので作ってからのほうがいいです。

で、テーブルをどのように作るかですが、ぶっちゃけ自由です
さっき少し触れた「データの粒度」に適したテーブルを作ってください。
G-Map Projectではそこそこな粒度で作成しているので、ざっくり以下のような感じでテーブルを作っています。(スキーマも分けていますがここではテーブル名だけで)

道路テーブル(road)

「路線コード(主キー)」「路線種類(国道?主要地方道?などのコード)」「路線名称(通り名か橋・トンネル名)」「路線ジオメトリ(LINESTRING)」「最高時速」「一方通行フラグ(0=双方向、1=順方向、2=逆方向)」「車線数」「路線番号(あれば)」「管理府県」をカラムとしています。とりあえずこれだけあればほかのデータは算出可能かな、ということで。今後も追加されていくかもしれません。

鉄道テーブル(railway)

「会社コード(事業者)」「路線コード」「駅コード(以上3つが主キー)」「駅番号」「駅名称(漢字、ふりがな)」「駅ホーム数(ダミー)」。駅ホーム数は将来時刻表などを作成するときに使用するかなあってことでとりあえず入れているだけです。なので現在ダミーとして2が入っています。単線ホームは存在しないことになっています(笑)
鉄道ファンではないので最低限の情報しか入れていませんが、会社テーブルと路線テーブルを使用し、ビューには乗り換え用テーブルを作るなどリレーショナルデータベースとしての正規化は結構行っています。こうすることで乗り換え案内とか作れるんですよ。

行政区画テーブル(area)

市町村単位でのものとして「都道府県コード」「市郡コード」「市町村コード」「市町村名称」「市町村タイプ(市?区?町?村?)」を導入しています。さらに都道府県テーブル、市郡テーブルを作成し、リレーションしています。これにより、QGISでは適切に行政区画を作成していれば自動で都道府県の面積を算出できたりするわけです。すごい。

なおこれトポロジ化していないのでポリゴンエラーが結構起きています。直すのもめんどくさくて放置していますが。

その他テーブル

信号交差点を表す「intersection」、施設を表す「building」、川や湖を表す「river」「lake」等のテーブルを作成しています。これくらい作成するとおおむねいい感じに仕上がります。

QGISでいじるのは

基本的にQGISでは、下書き地図を読み込んで上からなぞっていく形になります。その際のやり方をまとめておきますね。あくまで僕のやり方です。

まず、スキャナーなどを使用してA4のコピー用紙に書いたものをすべて取り込みます。この際に僕は図面番号を付与しています(想像地図研究所さんと同じようなつけ方です)。これをPythonスクリプトなどを用いて1枚に結合します。結果は10000px四方みたいなとんでもない大きさになるため、メモリに載せきれない場合は適宜縮小してください。しかしこちらの場合は縮小すると路線番号とかの下書きが見えなくなるので1枚当たり1000px程度の解像度にしています。なので2025年1月15日現在、40000px四方くらいありビューアーでは開けません。

画像が作成できたら、その図面が指し示す緯度経度を最低4点設定してください。例えば、僕の場合は城坂市の岬を基準にしています。そこから前提条件で利用した座標系を使用して投影変換を行います。(QGISの場合はジオリファレンサでできます)。完了したらQGISに取り込めます。

んで取り込んだら先ほど追加したテーブルをQGISに貼り付けます。この際、リレーションなどをQGISで使わないのならば(QGISはあくまでなぞるだけ)、ジオメトリカラムが存在するテーブルだけ取り込めばOKです。見た目の変化は好きなようにしてください。鉄道は白黒のまだら模様にしたり(JRみたいな)、道路は種別で色を分けたり……。

取り込み終わったらあとはなぞるだけです。頑張ってください。ここが一番気の遠くなる作業です。飽きたらほかのことをしましょう。ギブなら潔くあきらめましょう。ここからは興味と集中力の問題です。

さあどんなことをしてみようか!

ここまでできれば、あなたの架空世界はもうGISデータになっています。いろいろなことをしてみましょう! 例えば、G-Map Projectでは以下のようなことができます。

今まで描画した領域の道路リストを自動作成

描いていると「今何号線まで描いたっけ」とかなることがあります。これを自動化することで、描いている際にこのリストを見るだけで描いていない番号がわかるという優れもの。
roadテーブルを作成しているので、こいつをもとに加工してみましょう。路線番号、路線種類、都道府県管理情報で絞り込むことができるので、この3つでGROUP BYしてORDER BYかけると実現できます。

乗り換え案内を作成

railwayテーブルとstationテーブルを使用します。まずこの2つのテーブルからうまい具合に加工してトポロジ情報を作成します。僕の場合はpgRoutingを使用したり、2つのテーブルを駆使して無理やり自動作成したビューを作成したりしました。

あとはこのノード情報に対して出発地と目的地を指定してダイクストラ法などを用いて最短距離を求めれば乗り換え案内ができます。
別途fee(運賃)テーブルを用意してあげれば運賃も算出できます。僕の場合はさらにdiagram(鉄道ダイヤ)テーブルを作成し、直通運転や区間運転、時刻を指定した乗り換え案内の作成にも踏み出しています(といっても現在まともなものはできていません)。

番外編:地図を自動作成

これに関しては別記事で改めてまとめる予定ですが、実はGISデータを使用して地図を作成することもできます。まだこれは調べながらやっているのであまり深くはできていませんが、マップルに準拠した地図を作成しようとしています。

Mapnikと呼ばれる、C++のライブラリ(Pythonでも動きます)を使用してPostGISと連携し、GISデータを基に地図を作成します。これが意外と楽しいです。かゆいところに手が届かない仕様なのが残念ですが。

まあ後自動生成なのでそりゃあ人が手作りで作ったものに比べると結構お粗末なものにはなります。でもパッと見た感じいい感じになります。ワクワクしてきましたか? 銀連先生の次回の記事にこうご期待ください。

最後に

というわけで、シリーズ化するかどうかわかりませんが(7500文字ぶり2回目)、G-Map Projectということで架空地図のGISデータ化について残してみました。今回は今までの紹介のような形としていろいろ触れてきましたが、もし進捗や機会などがあればいろいろここで日記形式でつらつら発信していこうかと思います。

実はこのプロジェクトは1度リセットしており、現在は2代目となっています。初代プロジェクトのデータベースはまだ生きているので、実は以下のリンクを参照するとまだ過去のプロジェクトのバージョンのデータを見ることができます。しかしこのころとはちょっと今変わっているので、必ずしも今のデータと一致はしません。

2025年1月15日現在の情報です。今後進捗によっては新しいバージョンになるかもしれません。何の予告なしに。

というわけで、ちょこっと書くだけのつもりが8000文字になりましたとさ。以上、国家の戯言をお送りしました。

シリーズ化するかどうかはマジでわかりません。ここ以外で残すかもしれません。(500文字ぶり3回目)

それではばいならあ。

いいなと思ったら応援しよう!