Problem 3: How many people live near shopping centers? (10 points)
In the last step of this analysis, use a spatial join to relate data from a population grid data set to the buffer layer created in problem 2 to find out how many people live in all population grid cells that are within 1.5 km distance from each shopping centre.
Use the same population grid data set as during lesson 3 (load it directly from WFS, don’t forget to assign a CRS).
最後に、spacial join(空間結合)で人口グリッドのデータセットをProblm2で作成したバッファに関連付けて、どのくらいの人がそれぞれのショッピングセンターの1.5km以内にいるのかを特定しましょう。
人口グリッドは、lessen3で使用したものです。WFS (Web Feature Service) から取得します。CRSを設定することも忘れずに。
Feel free to divide your solution into more codeblocks than prepared! Remember to add comments to your code :)
必要に応じてコードブロックを用意されたものから増やしてもよいです。あと、コメントも入れましょう。
a) Load the population grid data set and the buffer geometries (2 points)
人口グリッドとバッファを読み込みます。
Use the same population grid data set as during lesson 3 (load it directly from WFS, don’t forget to assign a CRS). Load the data into a GeoDataFrame called population_grid.
(optional) If you want, discard unneeded columns and translate the remaining column names from Finnish to English.
人口グリッドは、lessen3で使用したものです。WFS (Web Feature Service) から取得します。CRSを設定することも忘れずに。GeoDataFrame
型のpopulation_grid
に格納します。
不要な列を削除したり、必要な列の列名をフィンランド語から英語に変換してもよいです。
まずは準備。
import pandas as pd
import geopandas as gpd
import pathlib
NOTEBOOK_PATH = pathlib.Path().resolve()
DATA_DIRECTORY = NOTEBOOK_PATH / "data"
人口グリッドを読み込み、CRSを設定します。
#WFSでデータ取得
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:3879"
)
# CRSを設定
print(f"before crs:{population_grid.crs}")
population_grid.crs = "EPSG:3879"
print(f"after crs:{population_grid.crs}")
必要な列のみにして、リネームします。
# 列フィルター、リネーム
population_grid = population_grid[["asukkaita", "geometry"]]
population_grid = population_grid.rename(columns={"asukkaita": "population"})
population_grid.head()
assert
で型やCRSのチェックをします。
# 型・CRSチェック
import pyproj
assert isinstance(population_grid, gpd.GeoDataFrame)
assert population_grid.crs == pyproj.CRS("EPSG:3879")
Load the buffers computed in problem 2 into a GeoDataFrame called shopping_centre_buffers. Add an assert statement to check whether the two data frames are in the same CRS.
Problm2で作成したバッファを読み込み、GeoDataFrame
型のshopping_centre_buffers
に格納します。
assertで2つのGeoDataFrame
が同じCRSであることを確認します。
shopping_centre_buffers = gpd.read_file(DATA_DIRECTORY/"shopping_centres_buffered.gpkg", layer="buffers")
shopping_centre_buffers.head()
# 型・CRSチェック
import pyproj
assert isinstance(shopping_centre_buffers, gpd.GeoDataFrame)
assert shopping_centre_buffers.geometry.geom_type.unique() == ["Polygon"]
assert shopping_centre_buffers.crs == pyproj.CRS("EPSG:3879")
おまけとして、2つのGeoDataFrame
をプロットしてみましょう。
# shopping_centre_buffersに、population_gridを重畳
ax= shopping_centre_buffers.plot(
figsize=(10, 10),
column="name",
legend=True,
)
population_grid.plot(
ax=ax,
alpha=0.3, # 透過の割合
)
バッファの内側・外側がイメージできました。
この後、バッファの内側の人口を集計していきます。
b) Carry out a spatial join between the population_grid and the shopping_centre_buffers (4 points)
spacial join(空間結合)で人口グリッドのデータセットをProblm2で作成したバッファを空間結合します。
Join the shopping centre’s id column (and others, if you want) to the population grid data frame, for all population grid cells that are within the buffer area of each shopping centre. Use a join-type that retains only rows from both input data frames for which the geometric predicate is true.
(ここはとても読み取りずらい。。。)
ショッピングセンターのid列(他の列はお好みで)を人口グリッドのGeoDataFrame
に追加します。
sjoin()
メソッドのhow
には"innder"、predicate
には"within"を設定して、両方のデータセットいずれにも存在するレコードだけ残すようにします。
population_grid_with_id_name = population_grid.sjoin(
shopping_centre_buffers,
how="inner",
predicate="within"
)[["id", "name", "population", "geometry"]]
population_grid_with_id_name.head(100)
c) Compute the population sum around shopping centres (4 points)
ショッピングセンター周辺の人口を計上します。
Group the resulting (joint) data frame by shopping centre (id or name), and calculate the sum() of the population living inside the 1.5 km radius around them.
Print the results, for instance, in the form "12345 people live within 1.5 km from REDI".
上記で空間結合したデータセットをグループ化して、各ショッピングセンターの1.5km圏内の人口(合計)を求めます。
結果は、例えば、「12345人がREDIの1.5km圏内に住んでいます」と出力します。
for name, df in population_grid_with_id_name.groupby("name"):
print(
f"{df['population'].sum():,}人が {name}の1.5km圏内に住んでいます"
)
文字だけだとよくわからないので、プロットしてみましょう。
# population_grid_with_id_nameに、population_gridを重畳
ax= population_grid_with_id_name.plot(
figsize=(10, 10),
column="name",
legend=True,
)
population_grid.plot(
ax=ax,
alpha=0.3, # 透過の割合
)
10,907人が Jumboの1.5km圏内に住んでいます
グーグルマップを見る限り、Jumboの北側は住宅地でないようですね。
直近のプロットと整合していると思います。
d) Reflection
振り返り
Good job! You are almost done with this week’s exercise. Please quickly answer the following short questions:
- How challenging did you find problems 1-3 (on scale to 1-5), and why?
- What was easy?
- What was difficult?
今回の演習はほとんど終わりです。以下の質問に手早く答えてください。
- problemの1から3で挑戦的・やりがいがある、と思ったのはどこ?その理由は? →problem3、プロットしてみると面白い
- 簡単だったのは? →特になし
- 難しかったのは? →problem3、問題の趣旨を理解するのに時間がかかった
Lesson 3振り返り
Learning goals
After this lesson, you should know how to:
- geocode addresses, i.e., convert a list of addresses into a list of coordinates,
- query whether a point is inside a polygon, and
- join two vector data sets based on their features’ location
- 住所のリストを座標のリストに変換する →できました
- とある点がポリゴンの内側にあるかどうかを問い合わせする →できました
- 2つのベクターデータを、それぞれの地物の場所に基づいて結合する →できました
次は Lession 4です。
Exercise 4が大変そうなので、8月末までかかるかもしれません。