Automating GIS Processes 2024 写経　Exercise 2 (Problem 2)

https://github.com/Automating-GIS-processes-II-2024/exercise-2/blob/main/Exercise-2-problem-2.ipynb

# Problem 2: Points to map (7 points)

> In this task, we continue to learn how to create geometries from latitude and longitude coordinates.

> Our aim is to plot a map of points, based on a set of longitude and latitude coordinates that are stored in a csv file.

引き続き、緯度経度から座標群を作成します。
目的は、CSVファイルに保存された緯度経度の集合を地図にプロットすることです。


> The input data is stored in the CSV spreadsheet some_posts.csv in the directory data. The coordinates stored there are in WGS84 format (decimal degrees, EPSG:4326), and the first few rows of data look like this:

> The data has 81379 rows and consists of locations and times of de-identified social media posts inside Kruger national park in South Africa:

> Note: Although the data is based on real social media data, the userids and timestamps have been randomized making it impossible to link the data to the original posts.

some_posts.csvファイルを入力とします。このファイルはWGS84（EPSG:4326）で10進法の度数（decimal degrees）を保持しています。
（「10進法の度数（decimal degrees）って何？」という感じですが、小数点を含む緯度経度（°をつけないやつ）と思っていれば良いでしょう）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/f441882b-cee7-40dd-9c5f-fe4560929a37.png)


データは81379行あり、南アフリカのクルーガー国立公園内でのSNSへの匿名投稿の場所・タイムスタンプ・ユーザーIDで構成されています。ただ、実際の投稿と紐づかないように、タイムスタンプやユーザーIDはランダムにしています。



https://www.google.com/maps/place/%E3%82%AF%E3%83%AB%E3%83%BC%E3%82%AC%E3%83%BC%E5%9B%BD%E7%AB%8B%E5%85%AC%E5%9C%92/@-24.0875586,31.4764953,10.63z/data=!4m6!3m5!1s0x1ec34896c535a0a1:0x9a504ed31f67787b!8m2!3d-23.9883848!4d31.5547402!16zL20vMDFzbjF6?entry=ttu&g_ep=EgoyMDI1MDUyNi4wIKXMDSoASAFQAw%3D%3D

（唐突に南アフリカですね。都合の良いデータだったのか筆者の趣味なのか。）


## a) Read the CSV file

> - Read the data from some_posts.csv into a Pandas dataframe called data

some_posts.csvを`dataframe`として読み込みます。

```
import pathlib
import pandas as pd

DATA_DIRECTORY = pathlib.Path().resolve() / "data"

data = pd.read_csv(DATA_DIRECTORY / "some_posts.csv")
data.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/d899e4ff-237e-406e-bad1-ee8d6b59f149.png)


データが81379行あることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/9f559a87-9c0a-4d86-b34e-7704530a960a.png)


## b) Add a geometry column and fill it with geometries

> - Create an empty column called geometry where you will store shapely Point objects
> - Insert Point objects into the column geometry based on the coordinate columns

> You want to create a shapely.geometry.Point for each row, based on the columns lon and lat. There are different approaches to this task, we encourage you to try to use the apply() method of the data frame, together with a lambda function (see the hints for exercise 1, and the hints for this exercise)

`geometry`列を追加して、そこに`coordinate`列の値から作成した`Pointオブジェクト`を設定します。
折角なので、ラムダ関数と`apply() `メソッドを使ってやってみましょう。


ヒントは[こちら](https://qiita.com/t_t_japan/items/c55c30931bc884265da5)。


```
from shapely.geometry import Point

data['geometry'] = data.apply(lambda row: Point(row.lon, row.lat), axis=1)

# Check the result
print(data['geometry'].head())
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/d214d4be-8796-420d-855f-1933c342a7c0.png)

## c) Convert the pandas.DataFrame into a geopandas.GeoDataFrame

> - Convert data into a geopandas.GeoDataFrame using its constructor. (See the hints for this exercise for additional instructions)
> - Make sure that the resulting GeoDataFrame has a coordinate reference system defined

GeoDataFrameのコンストラクタで、GeoDataFrameに変換しましょう。

ヒントは[こちら](https://qiita.com/t_t_japan/items/c55c30931bc884265da5)。

```
import geopandas as gpd

data = gpd.GeoDataFrame(data, geometry='geometry', crs="EPSG:4326")
data.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/77193ebe-4cc0-4106-acbe-55b7df042954.png)


また、GeoDataFrame変換後にCRSが設定されていることを確認しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/819360ce-8844-4b6e-b257-1d3692b90abe.png)

## d) Save the data in Shapefile format as kruger_points.shp inside the data directory

kruger_points.shpとしてファイル保存しましょう。

```
data.to_file(DATA_DIRECTORY / "kruger_points.shp")
```
```
# Check that the output file exists
import pathlib
assert pathlib.Path(DATA_DIRECTORY / "kruger_points.shp").exists()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/7ea9a520-b021-4df2-9f50-10b17987c572.png)

ファイルが存在するので、`assert`は何も出力されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/ae7eb7f2-f05e-4c38-94ae-6aa7c6687293.png)



## e) Create a simple map of the points

せっかくなので、kruger_points.shpを読み込んで、プロットしてみましょう。

```
gpd.read_file(DATA_DIRECTORY / "kruger_points.shp").plot()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/7c4e8dfc-a11c-410e-a3d5-d7b5be4d336a.png)


## Optional: Download the output shapefile and create a map using a Desktop GIS 

> For example, overlay the points with a basemap. Post the resulting map in the #week2 slack channel.

vscodeに、[Geo Data Viewer](https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.geo-data-viewer)を入れて、kruger_points.shpを表示してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4076503/9e51ec3b-f828-49d9-a399-bd8652a7390a.png)

（わかりにくいですが）南アフリカのクルーガー国立公園の地図にPointの座標群が重畳されています。