オープンストリートマップを利用したオープンデータの可視化②・Leaflet

https://gyazo.com/c06db3990e6a6ab4c4e476c84e829cbe

Leafletとは

前回はuMAPというサービスを利用して, 日進市のオープンデータをオープンストリートマップに重ねて表示しました. uMAPを用いると,ブラウザ上で手軽にオリジナルの地図を作成することができますが, 作成された地図は静的で,ユーザとのインタラクションに応じて動的に変化させることはできません. そこで,今回はLeafletを利用して,オリジナルの地図を作成することに挑戦しましょう. Leafletは,「りーふれっと」と読み,プログラミング言語であるJavaScriptのライブラリの一つです. オープンソースで開発されており,BSD 2-Clauseライセンスであるため, クレジットさえ表示すれば,商用利用・改変・配布が可能です. Leafletを用いると,デスクトップPCやモバイル環境に適したオンライン地図を表示することができます. JavaScriptで制御可能であるため,ユーザとのインタラクションに応じて動的に地図を変更することが可能です. もちろん,前回紹介したGeoJSON形式のデータの取り込みも可能です. 今回は,このLeafletを用いて日進市の観光マップを作成します.

オープンデータの準備

日進市のオープンデータミュージアムにある 観光情報データを利用します. ここでは,名称緯度・経度の情報を利用することにします. 下記はCSV形式で表現されたデータです.

名称,緯度,経度
岩崎城址公園,35.1455654,137.0420547
愛知牧場,35.1306941,137.0876883
五色園,35.1557573,137.0682229
レトロでんしゃ館,35.1228602,137.0221455
旧市川家住宅,35.12896,137.033636

今回は,上記のテキスト情報だけでなく,下記の5つの画像ファイルを利用します. これらは日進市のイベント情報を提供しているぐるぐるNISSHINに掲載されていますが, オープンデータではないことに注意してください(授業向けに許可を得て利用しています). 全ての画像ファイルをダウンロードしておいてください.

iwasaki bokujyou goshikien retro ichikawa

上記の観光情報と画像ファイル名を,下記のようにGeoJSON形式に変換します. 画像ファイル名はpropertiesに記載しています. ここでは,経度・緯度の順番で指定することに注意してください.

{
	"type": "FeatureCollection",
	"features": [
		{
			"type": "Feature",
			"geometry":
				{
					"type": "Point",
					"coordinates": [137.0420547,35.1455654]
				},
			"properties":
				{
					"名称": "岩崎城址公園",
					"画像": "iwasaki.jpg"
				}
		},
		{
			"type": "Feature",
			"geometry":
				{
					"type": "Point",
					"coordinates": [137.0876883,35.1306941]
				},
			"properties":
				{
					"名称": "愛知牧場",
					"画像": "bokujyou.jpg"
				}
		},
		{
			"type": "Feature",
			"geometry":
				{
					"type": "Point",
					"coordinates": [137.0682229,35.1557573]
				},
			"properties":
				{
					"名称": "五色園",
					"画像": "goshikien.jpg"
				}
		},
		{
			"type": "Feature",
			"geometry":
				{
					"type": "Point",
					"coordinates": [137.0221455,35.1228602]
				},
			"properties":
				{
					"名称": "レトロでんしゃ",
					"画像": "retro.jpg"
				}
		},
		{
			"type": "Feature",
			"geometry":
				{
					"type": "Point",
					"coordinates": [137.033636,35.12896]
				},
			"properties":
				{
					"名称": "旧市川家住宅",
					"画像": "ichikawa.jpg"
				}
		}			
	]
}

特定の住所やランドマークの緯度・経度を知りたい場合は, ジオコーディングのサービスGeocodingを利用すると良いです. 例えば, 椙山女学園大学 で検索すると, 緯度:35.15937経度: 136.987185であることが分かります.

Leafletでオンライン地図

それでは,Leafletを利用して,上記のGeoJSON形式の観光情報を表示するオンライン地図を作成していきましょう. LeafletはJavaScriptのライブラリであるため,HTMLファイルを作成し,JavaScriptで内部に地図を埋め込む形になります. まずは,index.htmlを作成します. このとき,index.htmlと同じフォルダに,上記の5つの画像ファイルを配置してください. ファイルの編集にはAtomを用いると良いでしょう(メディア棟のPCにインストールされています).

下記のソースコードをindex.htmlに入力してください. コーディングが苦手な場合は,ソースコードをコピー・ペーストで構いません(HTMLはコンピュータと情報Ⅱで学習します). id属性にmapidが指定されているdiv要素が,Leafletで地図を表示する箇所になります. また,L.map関数の引数である35.130621, 137.037568が「地図の中心の緯度・経度」, また,13が「表示倍率」を表しています. ソースコードを入力したら,ブラウザで開いてみましょう. 35.130621, 137.037568は日進市役所の緯度・経度であるため, 地図の中心に日進市役所が表示されているはずです.

<!DOCTYPE html>

<head>
  <meta charset="UTF-8">
  <title>日進市 観光マップ</title>
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" />
  <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>
</head>

<body>
  <div id="mapid" style="width:500px; height:500px"></div>

  <script>
    var mymap = L.map('mapid').setView([35.130621, 137.037568], 13);
    L.tileLayer(
        'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        { attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }
    ).addTo(mymap);

  </script>
</body>

</html>

次に,GeoJSON形式の観光情報を読み込みます. 読み込まれたデータは変数に格納して扱うことができます. ここでは,dataという名前の変数を用いています. L.geoJSON関数で,変数dataを読み込み,対応するマーカーを表示します. 併せてマーカーをクリックしたときに,ポップアップで表示する情報を設定できます. ここでは,施設の名称に加えて,対応する画像ファイルを表示しています(画像ファイルの表示にはimg要素を用います). ソースコードを入力したら,ブラウザで開いてみましょう. 5つのマーカーが表示されているはずです. また,マーカーをクリックすると施設名称と画像が表示されます.

data = {
	"type": "FeatureCollection",
	"features": [
	{
		"type": "Feature",
		"geometry":
		{
			"type": "Point",
			"coordinates": [137.0420547,35.1455654]
		},
		"properties":
		{
			"名称": "岩崎城址公園",
			"画像": "iwasaki.jpg"
		}
	},
	{
		"type": "Feature",
		"geometry":
		{
			"type": "Point",
			"coordinates": [137.0876883,35.1306941]
		},
		"properties":
		{
			"名称": "愛知牧場",
			"画像": "bokujyou.jpg"
		}
	},
	{
		"type": "Feature",
		"geometry":
		{
			"type": "Point",
			"coordinates": [137.0682229,35.1557573]
		},
		"properties":
		{
			"名称": "五色園",
			"画像": "goshikien.jpg"
		}
	},
	{
		"type": "Feature",
		"geometry":
		{
			"type": "Point",
			"coordinates": [137.0221455,35.1228602]
		},
		"properties":
		{
			"名称": "レトロでんしゃ",
			"画像": "retro.jpg"
		}
	},
	{
		"type": "Feature",
		"geometry":
		{
			"type": "Point",
			"coordinates": [137.033636,35.12896]
		},
		"properties":
		{
			"名称": "旧市川家住宅",
			"画像": "ichikawa.jpg"
		}
	}
	]
}


L.geoJSON(data,{
    onEachFeature: function(feature, layer){
        layer.bindPopup(
            "<p style='width:150px'>" + feature.properties.名称 + "</p>" +
            "<p><img src=" + feature.properties.画像 + " /></p>"
        )
    }
}).addTo(mymap);

参考書籍