Python 地図の表示

地図資料

ジオコーディング

インストール

pip install geocoder geopy

名前から緯度経度の取得

import geocoder

location = "熊本市役所"
ret = geocoder.osm(location, timeout=5.0)
ret.latlng

OpenStreatMapで検索できるもののみ

IPアドレスから緯度経度の取得

位置情報

import geocoder

ret = geocoder.ip('me')
ret.geojson

緯度経度のみ

import geocoder

ret = geocoder.ip('me')
lat = ret.geojson['features'][0]['properties']['lat']
lng = ret.geojson['features'][0]['properties']['lng']
print( [lat, lng] )

2地点から距離の取得

import geocoder
from geopy import distance

ret1 = geocoder.osm("熊本市役所", timeout=5.0)
print(ret1.latlng)

ret2 = geocoder.osm("熊本 鶴屋", timeout=5.0)
print(ret2.latlng)

# 距離
dist = distance.distance(ret1.latlng, ret2.latlng).km
print(dist, 'Km')

※参考:国土地理院のAPIを利用し住所から緯度経度を得る

import requests

url = "https://msearch.gsi.go.jp/address-search/AddressSearch?q="
adr = "熊本市中央区手取本町8番9号"
response = requests.get(url + adr)
response.json()[0]["geometry"]["coordinates"]

foliumのインストール

foliumは地図を表示するライブラリ。

pip install folium

地図の表示

Jyupiterでの表示例

folium.Mapクラスでlocationに中心位置を指定する。

import folium

map = folium.Map(location=[32.8032, 130.7080]) 
map

zoom_startにズームレベル(0~18、大きい方が拡大)を設定する。

import folium

map = folium.Map(location=[32.8032, 130.7080], zoom_start = 15) 
map

HTMLで保存

import folium

map = folium.Map(location=[32.8032, 130.7080], zoom_start = 15) 
map.save('map.html')

マーカー

map = folium.Map(location=[32.8032, 130.7080], zoom_start = 15) 

# マーカーの追加
marker = folium.Marker([32.8032, 130.7080])
marker.add_to(map)

map

popupでクリックしたときに表示する文字を設定できる

map = folium.Map(location=[32.8032, 130.7080], zoom_start = 15) 

# マーカーの追加
marker = folium.Marker([32.8032, 130.7080], popup="熊本市役所")
marker.add_to(map)

map

popupにはHTMLが使用可能

map = folium.Map(location=[32.8032, 130.7080], zoom_start = 15) 

marker = folium.Marker([32.8032, 130.7080], popup='<div style="width:5em">熊本市役所</div>')
marker.add_to(map)

map

アイコンの変更

marker2 = folium.Marker([32.80237,130.711038], popup="鶴屋", icon=folium.Icon(color="red",icon="home"))
marker2.add_to(map)
map

folium.Icon

colorの種類
[‘red’, ‘blue’, ‘green’, ‘purple’, ‘orange’, ‘darkred’,’lightred’, ‘beige’, ‘darkblue’, ‘darkgreen’, ‘cadetblue’, ‘darkpurple’, ‘white’, ‘pink’, ‘lightblue’, ‘lightgreen’, 
‘gray’, ‘black’, ‘lightgray’]
iconの種類

以下の「glyphicon glyphicon-XXX」のXXX部分を指定。
例:glyphicon glyphicon-plus → icon="plus"

https://getbootstrap.com/docs/3.3/components/

データからマーカー表示

熊本県オープンデータより「熊本県「くまもとフリーWi-Fi」設置箇所一覧」を取得

import pandas as pd
df = pd.read_csv("145338.csv", encoding="cp932")
df.head()

DataFrameから1つずつ取得する例。

for index, row in df.iterrows():
    print(row['名称'])

地図への表示例

import folium

map = folium.Map(location=[32.8032, 130.7080], zoom_start = 15) 

for index, row in df.iterrows():
    lat = row['緯度']
    lng = row['経度']
    popup = row['名称']
    marker = folium.Marker([lat, lng], popup=popup)
    marker.add_to(map)

map

まとめてマーカー表示

foliumのプラグインであるMarkerClusterを使うと、マーカーを地域毎にまとめてその数を表示できる。

import folium
from folium.plugins import MarkerCluster

map = folium.Map(location=[32.8032, 130.7080], zoom_start = 15) 
marker_cluster = MarkerCluster()

for index, row in df.iterrows():
    lat = row['緯度']
    lng = row['経度']
    popup = row['名称']
    marker = folium.Marker([lat, lng], popup=popup)
    marker.add_to(marker_cluster)

marker_cluster.add_to(map)
map

独自のマーカー

DivIconを使用し、HTMLで独自のマーカーを作成できる。

from folium.features import DivIcon

map = folium.Map(location=[32.8032, 130.7080],zoom_start = 15) 

marker = folium.Marker([32.8032, 130.7080], icon = DivIcon(
    icon_size=(80,36),
    html='<div style="font-size: 12pt; color: blue; background-color: white; text-align: center">熊本市役所</div>'
))
marker.add_to(map)

map

指定地点を中心に円を描く。

en = folium.Circle(
    location=[32.80237,130.711038], # 中心
    radius=100, # 半径100m
    color='#ff0000', # 枠の色
    fill_color='#0000ff' # 塗りつぶしの色
)
en.add_to(map)

map

Circle を CircleMarkerにするとradiusがピクセル単位になる。

ヒートマップ

指定地点を中心に円を描き重なる点は赤い色になる。

※くまもとフリーWi-Fiの例

import folium
from folium.plugins import HeatMap

map = folium.Map(location=[32.8032, 130.7080], zoom_start = 15) 

data = df[['緯度','経度']].values.tolist()
HeatMap(data, radius=20, blur=3).add_to(map)
map

Circle を CircleMarkerにするとradiusがピクセル単位になる。

線の描画

folium.PolyLine(locations=位置のリスト).add_to(地図)

import folium

shiyakusho = [32.8032, 130.7080]
kencho = [32.7904, 130.7421]

map = folium.Map(location=shiyakusho, zoom_start = 13) 

folium.PolyLine(locations=[shiyakusho,kencho]).add_to(map)

map

他の地図の表示

標準の地図の種類

Mapのコンストラクタにtilesを指定。

import folium

map = folium.Map(
		location=[32.8032, 130.7080],
		zoom_start = 15,
		tiles='cartodb positron'
) 
map
OpenStreetMap標準
cartodb positron薄い色
cartodbdark_matterダーク

他の地図タイル

国土地理院から提供されている地図タイルを表示。

地理院タイル一覧より「ベースマップ標準地図」のURLを用意し、tilesに指定する。attrに出典を記述する。

https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png
import folium
map = folium.Map(location=[32.8032, 130.7080],
              zoom_start = 15,
              tiles = "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
              attr = "国土地理院")
map

地図タイルを重ねる

国土地理院から提供されている地図タイル画像を重ねて描画できる。

データの準備

ハザードマップポータルサイトより「 洪水浸水想定区域(想定最大規模)」のURLを用意する。
https://disaportaldata.gsi.go.jp/raster/01_flood_l2_shinsuishin_data/{z}/{x}/{y}.png

地図の表示

folium.raster_layers.TileLayer オブジェクトを作成し、add_to で地図タイルを重ねる。 fmtはデータ形式(デフォールトはjpeg)、attrに出典、opacityに透明度を設定。
import folium
map = folium.Map(location=[32.8032, 130.7080],zoom_start = 12) 

folium.raster_layers.TileLayer(
    tiles='https://disaportaldata.gsi.go.jp/raster/01_flood_l2_shinsuishin_data/{z}/{x}/{y}.png',
    fmt='image/png',
    attr="国土交通省各地方整備局等",
    opacity=0.7
).add_to(map)

map

令和2年7月豪雨 浸水推定図 球磨川水系球磨川 人吉市周辺 を重ねてみよう。

区域毎に色分け

区域毎に色分けした図=コロプレス図を描画できる。

区域のデータを準備

市町村の区域を表すデータが国土交通省からGeoJson形式で公開されている。

国土数値情報ダウンロード

「行政区域(ポリゴン)」より熊本の最新データをダウンロードする。

地図の表示

ズームは大きめにする。

import folium

map = folium.Map(location=[32.8032, 130.7080],zoom_start = 10) 

# GeoJsonファイルを読み込む
import json
f = open('N03-21_43_210101.geojson', 'r', encoding='utf-8')
geojson = json.load(f)
f.close()

# GeoJsonファイルを指定し、コロプレス図を作成
ch = folium.Choropleth(geo_data=geojson )
ch.add_to(map)

map

データの準備

データを元にコロプレス図を色分けする。
サンプルデータとして熊本県の市区町村別人口(kumamoto_pop.csv)を使用する。(住民基本台帳に基づく人口、人口動態及び世帯数調査より作成)。

import pandas as pd
df = pd.read_csv("kumamoto_pop.csv")
df

区域分けの表示

まず、GeoJsonとデータを対応させるキーを決める。通常は市区町村名で良いが、今回のデータの場合、GeoJsonと人口データで同一の名称のものがない(GeoJsonではN03_003に「玉名郡」、N03_004に「南関町」と分かれているが、人口データは「玉名郡南関町」と1つになっている)。そこで、団体コード(GeoJsonではN03_007)を利用する。

dataにはDataFrame、columnsにはその中で使うキーとなる列(団体コード)と色を決定する値となる列(計)、key_onにはGeoJson側のキーとなる場所、fill_colorには色を指定する。

fill_colorの色はここを参照

map = folium.Map(location=[32.8032, 130.7080],zoom_start = 10) 

ch = folium.Choropleth(geo_data=geojson, 
                data=df,
                columns=['団体コード', '計'],
                key_on='feature.properties.N03_007',
                fill_color='OrRd' )
ch.add_to(map)

map

※key_onはJSONファイルの以下を見て判断する。このとき、featuresの配列に値が入っているが、配列の1要素ということで feature となる(sが無い)。feature.properties.N03_007 とはfeatures配列の一要素内の properties 内の N03_007 となる。

"features": [
{ "type": "Feature", "properties": { "N03_001": "熊本県", "N03_002": null, "N03_003": "熊本市", "N03_004": "熊本市中央区", "N03_007": "43101" },

また、fill_opacityで塗りつぶしの透明度、line_colorで線の色、line_opacityで色の透明度を指定できる。

map = folium.Map(location=[32.8032, 130.7080],zoom_start = 10) 

ch = folium.Choropleth(geo_data=geojson, 
                data=df,
                columns=['団体コード', '計'],
                key_on='feature.properties.N03_007',
                fill_opacity=0.7, 
                line_opacity=0.2,
                line_color='red',                
                fill_color='OrRd' )
ch.add_to(map)

map

そのほか、欠損がある地域の色をnan_fill_color="#888888" のようにして指定できる。

その他の設定は公式で