シンプルなWebGIS「VanillaGIS」の紹介
はじめに
オープンソースのGISにはQGISというド定番・大正義が存在しますが、インストールの手間、投影法など、若干敷居が高くなっています。ウェブ上で公開されている多数のGISデータ(国土数値情報等)の内容をすぐに確認出来る、シンプルなWebGISがあれば便利なんじゃないかと思い開発したのがVanillaGISです。
VanillaGIS
こんな感じで動作するLeafletのコントロールを作成しました。ポリゴンとポリライン以外想定していないので、ポイントへの対応はまだされてません。公式のControl.LayerとプラグインのControl.Opacityを参考にしました。https://t.co/7WHEoXG5b3 pic.twitter.com/97ZWoYMNqZ
— Kanahiro@Labo288 (@kigchi999) 2019年6月17日
技術概要
主な使用ライブラリ
- Leaflet(JavaScript)
- Flask(Python)
フロントエンド
Leafletと以下の外部プラグインを使用しています。
- Leaflet.Control.Custom
- Leaflet.Control.Draw
- Leaflet.Control.Appearance(自作プラグイン)
バックエンド
- Flask
- SQLite
- SQLAlchemy
技術詳細
バックエンド(Flask)
前提としてRESTful APIを意識し、URLはリソースを参照する形式になっています。
/(ルート)
- GET
地図画面の表示。
- POST
外部ファイル(.zip(シェープファイル), .geojson)を投げるとjsonデータを返します。 .zipファイルの中身はシェープファイル(.shp, .shx, dbf)である必要があります。 pyshpモジュールを利用し、内部的にjsonに変換しています(LeafletはGeoJSONを読み込めるため)。 オープンデータで提供されるシェープファイルの多くはShift-JISエンコーディングですが、UTF-8やその他のエンコードである場合も踏まえ、通常利用されるすべてのエンコードに対応させています。Pythonでデコードする際、エンコードが相違しているとUnicode Errorが発生します。事前に主要なエンコードをリストにしておき、デコードでエラーが発生しなくなるまで各エンコードを順番にトライします(以下の記事で紹介しています)。
/user_map/<map_id>
- GET
ユーザーが作成し保存したカスタムマップの、レイヤーデータ以外を返します。
- PUT
ユーザーが作成し保存したカスタムマップの、レイヤーデータを返します。 GETで返すと、レイヤーデータが読み込むまでページ全体の読み込みが完了しないため、GETとはレスポンスを分離しています。Fetchにより非同期でレスポンスを取得します。
- POST
ユーザーが作成したカスタムマップをDBに保存します。
/export
これだけnot RESTfulです。
- POST
ユーザーが作成し保存したレイヤーを投げるとjsonデータが返ってきます。 フロントでは、返ってきたデータを.geojsonとしてダウンロードさせます。
フロントエンド
シングルページアプリケーションで、常にindex.htmlが表示されます。 /user_map/<map_id>では、index.htmlにDBから取得したデータを渡しています。 Leafletと外部プラグイン(各種Control)を組み合わせる事でGUIを実装しています。
使用しているControl
- L.control.scale
純正プラグイン。地図の縮尺を表示。
- L.control.custom
外部プラグイン。htmlを記述する事でかなり自由にGUIを作成可能。
- L.control.draw
外部プラグイン。手書き図形の作図機能。
- L.control.Appearance
自作プラグイン。純正のL.control.layerと、外部プラグインのL.control.Opacityを参考に作成。 ベースマップ切り替え、オーバーレイのオンオフ、レイヤーごとの透過度設定、オーバーレイごとの色設定、オーバーレイの削除。 各レイヤーをひとつのプラグインで管理したくて作成(Chromeで動作確認済み)。 ※レイヤーのプロパティにcolorを設定しないと、色設定機能は動作しません。
外部ファイル読み込み
ウィンドウにドラッグドロップする事で、ファイルを読み込みます。 対応している形式は.zip(.shp, .shx, .dbfのアーカイブ)か.geojsonです。 すべてFetchでサーバーに投げて、返ってきた.jsonをLeafletマップに追加します。