QGISで架空地図を描く

#0 概要
無料の地理情報システムQGISは本来地球上の地図を描いたりするのに使うツールですが、これを使って自分の作った異世界の地図を描くこともできます。
この記事では、架空地図の描き方を解説していきます。
QGISのダウンロードは[こちら](https://qgis.org/ja/site/forusers/download.html)。
この記事ではQGISのバージョンは3.16.11を使用しています。

#1-1 あらかじめ作成した海岸線データ(SVGなど)がある場合
あらかじめ作成した海岸線データがない場合は1-2から始めてください。
まず海岸線データをDXFに変換します。SVGの場合、無料ソフト[Inkscape](https://inkscape.org/release/inkscape-1.1.1/)を利用して変換できます。PNGなどでもできるかもしれませんがわかりません。

Inkscapeを使用する場合、SVGをInkscapeで開きます。矩形などはパスに変換してください。\[ファイル\]->\[名前を付けて保存\]で、ファイルの種類でデスクトップカッティングプロッターを選択して保存します。保存する際にダイアログが出てきますが、単位はmm、エンコーディングはUTF-8を指定してください。

保存したら四隅の座標（単位はmm）をInkscapeの「PNG画像にエクスポート」タブで確認し、メモしておきます。

次にQGISを開いて、新規プロジェクトを開きます。\[プロジェクト\]->\[プロパティ\]->\[座標参照系(CRS)\]から、座標参照系(CRS, Coordinate Reference System)を設定します。海岸線データが正距円筒図法の場合、WGS 84 (EPSG:4326)、メルカトル図法の場合、WGS 84 / World Mercator (EPSG:6893)にします。（ほかのCRSでもよいですが、その場合下に出てくるgeoref X/Yに入れる座標を調整しないといけません。）

\[プラグイン\]->\[プラグインの管理とインストール\]から、AnotherDFXImporterをインストールします。

インストールできたら、\[ベクタ\]->\[DXF Import/Convert\]->\[Import or Convert\]を選択し、出てきたダイアログで、Browseボタンから先ほど保存したDXFファイルを選択し、CharsetをUTF-8として、Use coordinate transformationにチェックを入れます。

Transformation settingタブで、Indentical pointsを選択し、4 point (Georef)を選択し、先ほどのungeoref Xとungeoref Yの列に先ほどの四隅の座標を設定します。右側がX軸正方向、上側がY軸正方向となることに注意してください。

georef X、georef Yの列に設定する値はCRSによって異なります。

######WGS 84 (EPSG:4326)の場合
このCRSでは単位は度です。

|   | georef X | georef Y |
|:-:|:-:|:-:|
| 左上  | $-180$  | $90$  |
| 右上  | $180$  | $90$  |
| 左下  | $-180$  | $-90$  |
| 右下  | $180$  | $-90$  |



######WGS 84 / World Mercator (EPSG:6893)の場合
このCRSでは単位はmです。
海岸線データの横:縦の比が$1:a$のとき、以下のようになります。

|   | georef X | georef Y |
|:-:|:-:|:-:|
| 左上  | $-20037508.3428$  | $20037508.3428\times a$  |
| 右上  | $20037508.3428$  | $20037508.3428\times a$  |
| 左下  | $-20037508.3428$  | $-20037508.3428\times a$  |
| 右下  | $20037508.3428$  | $-20037508.3428\times a$  |



ここまで出来たら、Importボタンを押します。出てきたレイヤの座標が設定した通りになっているか確認して、2に進んでください。

#1-2 あらかじめ作成した海岸線データ(SVGなど)がない場合

QGISを開いて、新規プロジェクトを開きます。\[プロジェクト\]->\[プロパティ\]->\[座標参照系(CRS)\]から、座標参照系(CRS, Coordinate Reference System)を設定します。地図の図法を決めます。正距円筒図法の場合、WGS 84 (EPSG:4326)、メルカトル図法の場合、WGS 84 / World Mercator (EPSG:6893)にします。（ほかの図法、CRSでもよいです。）

\[レイヤ\]->\[レイヤを作成\]->\[新規GeoPackageレイヤ\]を選択し、データベースの行の右端の点が3つ並んだボタンを押し、保存場所とレイヤの名前を設定します。ジオメトリタイプはラインにして、OKボタンを押します。

ここまで出来たら自由に海岸線を引いてください。線の引き方などは[こちら](https://slhistory.at.webry.info/202009/article_1.html)のページを見てください。

#2 等高線を描く

\[プロセシング\]->\[ツールボックス\]->\[ベクタジオメトリ\]->\[オフセット線\]をダブルクリックし、距離に-100000m(急峻な地形にしたい場合はより0に近い負の値にしてもよいです。距離に正の値を設定すると海岸線の外側に線が引かれます。)を設定してください。レイヤが海岸線のレイヤになっていることを確認し、海岸線以外がすでに海岸線のレイヤにある場合、海岸線のみを選択し、「選択した地物のみ」にチェックを入れてください。実行を押すと海岸線の内側100kmのところに線が引かれます。これを頂点などを微調整して、高さ100mの等高線とします。

同様にして、1000m（500mなどでもよいです）間隔の等高線を引きます。

#3 ポリゴン化する

\[プロセシング\]->\[ツールボックス\]->\[ベクタジオメトリ\]->\[ポリゴン化（Polygonize）\]をダブルクリックし、等高線をポリゴン化します。できたポリゴンが重なり合っている場合、\[ベクタ\]->\[空間演算ツール\]->\[差分（Difference）\]等を使って重なりを除去してください。

\[ベクタ\]->\[データ管理ツール\]->\[ベクタレイヤのマージ\]でポリゴンを1つのレイヤにまとめます。

#4 ランダムに点を配置し、標高を設定する

\[ベクタ\]->\[調査ツール\]->\[ポリゴン内部にランダム点群\]（上から4番目の方）をクリックし、「地物当たりの点の数」は1000程度に設定して実行ボタンを押します。

0m以上100m未満のポリゴンを選択します。ツールバーの黄色い四角の右下に青いピンがあるマークをクリックします。「選択する地物のあるレイヤ」にランダムな点のレイヤ、「比較対象の地物のあるレイヤ」にポリゴンのレイヤを指定し、「選択した地物のみ」にチェックを入れます。「交差する」のみにチェックが入っていることを確認し、「現在の選択状態を以下のように変更する」は「新たに選択」を指定し、実行すると、0m以上100m未満の範囲にある点が選択されます。

ツールバー1段目右側の![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242464/ea10db53-8226-573a-5df5-237c179f7b11.png)ボタンをクリックして出てきたダイアログで、![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242464/b6167106-0db6-aa0e-3654-5aa02b0461ee.png)ボタンを押し、![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242464/1ee7d9cf-e069-462c-eaec-df46ee68f522.png)ボタンを押して属性を追加します。属性名は何でもよいですが、標高を記録するので、elevationなどにしておくとよいでしょう。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242464/0bc04cfe-32c4-3e4e-da3b-f78afeb75fa1.png)ボタンの下にあるセレクトボックスで、新規作成した属性を選択し、その右側にある入力ボックスにrand(0,99)と入力します。選択の更新ボタンを押します。

同様の要領で他の標高の点についても標高を設定します。標高によってrand()の中身は変えてください。例えば1000m以上2000m未満なら、rand(1000,1999)とすればよいです。

#5 TIN内挿
\[プロセシング\]->\[ツールボックス\]->\[内挿\]->\[TIN内挿\]で「入力ベクタ」にランダムな点のレイヤ、「内挿対象の属性」に先ほど作った属性を指定し、領域は右のボタンを押して\[レイヤから計算\]を選択し、ランダムな点のレイヤを選択します。出力ラスタサイズはピクセルサイズ10000mか0.1度程度がよいと思います。あまり小さくしすぎるとメモリが不足したり長時間かかってしまいます。内挿方法についてはClough-Toucher（キュービック法）がおすすめです。実行すると、標高が記録されたラスタレイヤが出来上がります。
\[レイヤ\]->\[レイヤのプロパティ\]の「シンボロジ」で色などを変えると地図っぽくなります。

これではまだカクカクしていていやだという方は、\[プロセシング\]->\[ツールボックス\]->\[ラスタ作成\]->\[乱数ラスタの作成（一様分布）\]でランダムなラスタを作ります。\[プロセシング\]->\[ツールボックス\]->\[GRASS\]->\[ラスタ(r.*)\]->\[r.neighbors\]で「入力ラスタ」にそのラスタを設定して、近隣状態に関する関数をaverageにして、隣接関係のサイズを15程度にして、実行すると、移動平均をとったラスタが出てきます。（GRASSを使う際エンコーディングエラーが出ることがありますが、これはパソコンのロケールをアメリカに変更して実行するとうまくいきます。）\[ラスタ\]->\[ラスタ計算機\]でそのラスタをTIN内挿したラスタに足してやると、カクカクがもっと山脈っぽくなります。

#6 おわりに

このやり方で作った地図がこちらになります。（陰影などをつけて立体感をわかりやすくしてあります。）
![20211102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242464/fa14d40f-96e2-8c37-0720-5a6a308b1dc7.png)

QGISは今回作った標高ラスタから川の流れを計算したりすることなどもできるのですが、それについて解説すると長くなるので今回はここまでとします。
読んでいただきありがとうございました。