Create an interactive thematic map using the skills you learnt during lesson 5. You can use Folium, or any other suitable Python package - feel free to experiment).
The map should contain more than one layer (from at least two different data sets). Pay attention to classification and visualisation (appropriate colour scheme choice, etc.). Write your code in this notebook, and store the resulting maps in .html format (plus possibly additional files, depending on your approach) in the NOTEBOOK_DIRECTORY / "docs" folder.
レッスン5で学んだスキルを使って、インタラクティブな(双方向性を持つ)主題図を作ってください。Folium、もしくは別の適したPytonのパッケージを使ってください。いろいろ試してください。
この地図は、(少なくとも2つのデータセットから作成された)複数のレイヤーを含むべきです。分類と可視化のやり方に注意してください。(適切な配色の選択など)ソースコードをこのノートブックに書いてください。そして、作成した地図を.html
フォーマットとして、NOTEBOOK_DIRECTORY / "docs"
フォルダに保存してください。(あなたのやり方によっては、他にもファイルがあるかも)
Topic of the map 地図のトピック
- Use any of the data sets we have used during the course (travel time data, population grid), or any other data set of your interest (for example, open data sets from Statistics Finland, or the open geo-data from the Helsinki Region Infoshare). If you download data sets, add, commit, and push them to the DATA_DIRECTORY. Be sure to include an attribution to each data set in your output map!
- Feel free to start from and adapt examples from the course material! You can take one step further and add additional analysis to, e.g., the shopping centre dominance or the population within vincinity of certain addresses)
- This should not be an interactive version of your submission for problem 1! Create something new!
- この学習コースで使ったデータセット(移動時間、人口グリッド)、または、あなたが興味ある他のデータセット(例えば、Statistics Finlandが公開しているデータセット、または、Helsinki Region Infoshareが公開している地理データセット)、いろいろなデータセットを使ってください。データセットをダウンロードしたら、
DATA_DIRECTORY
に追加・コミット・プッシュしてください。(※1) 作成した地図に、それぞれのデータの帰属情報を含めることを忘れずに。 - このコースで紹介した題材から初めて、他のデータセットを適用してみてください! さらに一歩進んで、例えば、ショッピングセンターの支配地域であったり、とある場所近辺の人口など、追加の分析ができます
- これは problem 1で提出した地図をインタラクティブにしたものにすべきでない!(何か新しく作って!)
Criteria 評価基準
- The map has more than one data layer (for instance, the results of an analysis, and the road network to illustrate a complex spatial pattern). If (and only if) you think it adds additional value, feel free to add a base map (but a base map does not count as an own layer) (2 points)
- The map portrays the output of an analysis or a classification that adds value beyond just displaying the raw data (3 points)
- The map follows good cartographic practices (appropriate map extent and zoom level, colour scheme, legend and data sources, etc.) (5 points)
- The map demonstrates the skills learnt during lesson 5, such as interactive elements (popups, etc.). (3 points)
- この地図は、複数のデータレイヤーを持つ(例えば、分析結果のレイヤーと道路ネットワーク複雑な空間パターンのレイヤー)。付加価値として、ベースマップを追加する(ただし、ベースマップはレイヤーとして計上しません)(2ポイント)
- この地図は、分析または分類の結果を表示する。その結果は元としたデータ以上の価値がある(3ポイント)
- その地図は、地図作成のグッドプラクティスに沿っている(適切な地図の大きさとズームレベル、配色、凡例、データの提供元など)(5ポイント)
- この地図は双方向の要素などレッスン5で学んだスキルを明示する(3ポイント)
Output 結果
- Save the map(s) in html format in NOTEBOOK_DIRECTORY / "docs" folder, remember to add, commit, and push them to the GitHub repository
- Remember to also add, commit, and push input data sets and code
- 地図を
.htmlフォーマットとして、
NOTEBOOK_PATH / "docs"`フォルダに保存してください。(原文はNOTEBOOK_DIRECTORYになっているが、誤字だと思われる)コミットとGitHubのレポジトリへのプッシュを忘れずに(※1) - 使用したデータセットや作成したソースコードのコミットやプッシュを忘れずに(※1)
※1 gitやGitHubを使わないので、該当のディレクトリにファイルを格納するだけです。
では実践です。入力データは以下です。
- exercise-4で使用したYKR_grid_EPSG3067.gpkgファイル (ファイルは、ここにあります)
- 人口グリッド、WFSエンドポイント: https://kartta.hsy.fi/geoserver/wfs から取得する
- 地下鉄の路線、WFSエンドポイント: https://kartta.hel.fi/ws/geoserver/avoindata/wfs から取得する
- 地下鉄の駅、同上
- 電車の路線、同上
- 電車の駅、同上
import pathlib
NOTEBOOK_PATH = pathlib.Path().resolve()
DATA_DIRECTORY = NOTEBOOK_PATH / "data"
OUTPUT_DIRECTORY = NOTEBOOK_PATH / "docs"
YKR_grid_EPSG3067.gpkgファイルは、dataディレクトリに格納します。
必要なパッケージをインポートします。
import pandas as pd
import geopandas as gpd
import folium
人口グリッドをWFSから読み込み、列フィルタ、列名変更、ID列の追加(値は0からの連番)をします。
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# 人口グリッドを取得
population_grid = (
gpd.read_file(
"https://kartta.hsy.fi/geoserver/wfs"
"?service=wfs"
"&version=2.0.0"
"&request=GetFeature"
"&typeName=asuminen_ja_maankaytto:Vaestotietoruudukko_2020"
"&srsName=EPSG:4326"
"&bbox=24.6,60.1,25.2,60.4,EPSG:4326"
)
.set_crs("EPSG:4326")
)[["index", "asukkaita", "geometry"]].rename(columns={
"asukkaita": "population"
})
population_grid["id"] = population_grid.index.astype(str)
population_grid.head()
人口グリッドのCRSをEPSG:3857(Web メルカトル)にします。
# CRSをEPSG:3857に
print(population_grid.crs)
population_grid = population_grid.to_crs("EPSG:3857")
print(population_grid.crs)
YKR_grid_EPSG3067.gpkgファイルから、ショッピングセンターとその住所のデータセットを作成します。
YKR_grid = gpd.read_file(DATA_DIRECTORY / "YKR_grid_EPSG3067.gpkg")
YKR_name = {
5878070: "Jumbo",
5878087: "Dixi",
5902043: "Myyrmanni",
5944003: "Itis",
5975373: "Forum",
5978593: "Iso_Omena",
5980260: "Ruoholahti",
}
# ショッピングセンター名の列を追加
for key, value in YKR_name.items():
YKR_grid.loc[YKR_grid.YKR_ID == key, "NAME"] = value
# ショッピングセンターを設定した行のみを抽出
YKR_shopping_center_grid = YKR_grid[~pd.isna(YKR_grid.NAME)]
YKR_shopping_center_grid
上記で作成したデータセットのCRSをEPSG:3857(Web メルカトル)にします。
ポイントマーカーとして表示するため、ショッピングセンターのgeometry(Polygon)を、ポリゴンの重心(Point)に置き換えます。
# ポイントマーカーとして表示するため、ポリゴンをポイントに
YKR_shopping_center_grid.geometry = YKR_shopping_center_grid.centroid
YKR_shopping_center_grid
地下鉄・鉄道のデータセットをWFSから読み込みます。
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# Web Feature ServiceのURL
WFS_BASE_URL = (
"https://kartta.hel.fi/ws/geoserver/avoindata/wfs"
"?service=wfs"
"&version=2.0.0"
"&request=GetFeature"
"&srsName=EPSG:3879"
"&typeName={layer:s}"
)
# 地下鉄の路線を取得
metro = (
gpd.read_file(
WFS_BASE_URL.format(layer="avoindata:Seutukartta_liikenne_metro_rata")
)
.set_crs("EPSG:3879")
)
# 地下鉄の駅を取得
metroasemat = gpd.read_file(
WFS_BASE_URL.format(layer="avoindata:Seutukartta_liikenne_metroasemat")
).set_crs("EPSG:3879")
# 鉄道の駅を取得
juna = (
gpd.read_file(
WFS_BASE_URL.format(layer="avoindata:Seutukartta_liikenne_juna_rata")
)
.set_crs("EPSG:3879")
)
# 鉄道の駅を取得
junaasemat = gpd.read_file(
WFS_BASE_URL.format(layer="avoindata:Seutukartta_liikenne_juna_asema")
).set_crs("EPSG:3879")
地下鉄・鉄道のデータセットのCRSをEPSG:3857(Web メルカトル)にします。
# CRSをEPSG:3857に
print("metro")
print(metro.crs)
metro = metro.to_crs("EPSG:3857")
print(metro.crs)
print("\n")
print("metroasemat")
print(metroasemat.crs)
metroasemat = metroasemat.to_crs("EPSG:3857")
print(metroasemat.crs)
print("\n")
print("juna")
print(juna.crs)
juna = juna.to_crs("EPSG:3857")
print(juna.crs)
print("\n")
print("junaasemat")
print(junaasemat.crs)
junaasemat = junaasemat.to_crs("EPSG:3857")
print(junaasemat.crs)
素材がそろいましたので、インタラクティブ地図を表示します。
# インタラクティブマップを生成
interactive_map = folium.Map(
location=(60.2, 25.0),
zoom_start=11,
tiles="https://mt1.google.com/vt/lyrs=r&x={x}&y={y}&z={z}",
attr="Google maps",
)
# 人口グリッドのレイヤーを追加
population_grid_layer = folium.Choropleth(
geo_data=population_grid,
data=population_grid,
columns=("id", "population"),
key_on="feature.id",
bins=9,
fill_color="YlOrRd",
line_weight=0,
legend_name="Population, 2020",
highlight=True
)
population_grid_layer.add_to(interactive_map)
# ショッピングセンターのレイヤー(ツールチップあり)を追加
YKR_shopping_center_grid_layer = folium.features.GeoJson(
YKR_shopping_center_grid,
name="NAME",
popup=folium.GeoJsonPopup(
fields=["NAME"],
aliases=["Name"],
localize=True,
labels=True,
)
)
YKR_shopping_center_grid_layer.add_to(interactive_map)
# 地下鉄の路線のレイヤー(ツールチップあり)を追加
metro_layer = folium.features.GeoJson(
metro,
name = "metrorata",
color = "red",
boder=True,
popup=folium.GeoJsonPopup(
fields=["metrorata"],
aliases=["Metrorata"],
localize=True,
labels=True,
)
)
metro_layer.add_to(interactive_map)
# 地下鉄の駅のレイヤー(ツールチップあり)を追加
metroasemat_layer = folium.features.GeoJson(
metroasemat,
name = "metroasema",
color = "blue",
popup=folium.GeoJsonPopup(
fields=["metroasema"],
aliases=["Metroasema"],
localize=True,
labels=True,
)
)
metroasemat_layer.add_to(interactive_map)
# 鉄道の路線のレイヤー(ツールチップあり)を追加
juna_layer = folium.features.GeoJson(
juna,
name = "rataosuus",
color = "red",
popup=folium.GeoJsonPopup(
fields=["rataosuus"],
aliases=["Rataosuus"],
localize=True,
labels=True,
)
)
juna_layer.add_to(interactive_map)
# 鉄道の駅のレイヤー(ツールチップあり)を追加
junaasemat_layer = folium.features.GeoJson(
junaasemat,
name = "asemapaikka",
color = "blue",
popup=folium.GeoJsonPopup(
fields=["asemapaikka"],
aliases=["asemapaikka"],
localize=True,
labels=True,
)
)
junaasemat_layer.add_to(interactive_map)
# インタラクティブマップを表示
interactive_map
中心部で人口密度が高く、地下鉄の駅も多い箇所には、ForumとRuoholahtiがあります。
中心部から少し離れた駅の近くには、Iso_Omena・Itis・Myyrmanni・Dixiがあります。
Jumboは他と少し特色が違います。駅から少し離れていて、人口密度も高いとは言えません。ただ、近くに国際空港があります。空港併設型のショッピングセンターでしょうか。
最後に、htmlファイルとして保存します。
interactive_map.save(OUTPUT_DIRECTORY / "base-map.html")
Lesson 5振り返り
After this lesson, you should know how to:
- create static thematic maps comprising of multiple data layers using GeoPandas and matplotlib,
- add base maps, such as OpenStreetMap, to such maps using contextily,
- create simple interactive maps using Folium, and
- enrich the interactive maps with popups and hover tooltips.
- GeoPandasとmatplotlibを使って複数のデータ層をもつ静的な主題図を作る →できました
- contextilyを使って、静的な主題図に、OpenStreetMapなどの基地図を追加する →できました
- Foliumを使って、シンプルなインタラクティブ地図を作る →できました
- ポップアップやマウスホバー時のツールチップ表示などで、インタラクティブ地図を拡張できる →できました