座標系の変換

座標系の変換

緯度経度は度になっているが
面積、距離などを求める時には変換が必要

https://sorabatake.jp/20670/
も参考にする

Name: WGS 84

– Lat[north]: Geodetic latitude (degree)
– Lon[east]: Geodetic longitude (degree)

がよく使われる
これはGPSで使われる

WGS 84
これを
EPSGにすると4326
https://epsg.io/4326
単位は度

これは世界

日本近辺に特化したものが
EPSG:6668
https://epsg.io/6668
単位は度

日本付近に絞るならこちらを使う方が良さそう

EPSG:6691
https://epsg.io/6691
これは
単位がメートルになっている
こちらも日本周辺がメイン

Area of use: Japan – between 138°E and 144°E, onshore and offshore.
となっているので
それ以外のエリアの精度が正しくないことがあるので注意

とりあえず品川の情報を表示

shinagawa
	N03_001	N03_002	N03_003	N03_004	N03_007	geometry
87	東京都	None	品川区	None	13109	POLYGON ((139.75501 35.61771, 139.75507 35.617...
88	東京都	None	品川区	None	13109	POLYGON ((139.77231 35.62188, 139.77302 35.621...
89	東京都	None	品川区	None	13109	POLYGON ((139.75953 35.625, 139.75966 35.6216,...
90	東京都	None	品川区	None	13109	POLYGON ((139.71943 35.64167, 139.71953 35.641...

座標情報を見るなら crs で表示できる

shinagawa.crs

結果は

<Geographic 2D CRS: EPSG:6668>
Name: JGD2011
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: Japan - onshore and offshore.
- bounds: (122.38, 17.09, 157.65, 46.05)
Datum: Japanese Geodetic Datum 2011
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich

この中で注目するのは

EPSG:6668

- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)

から
単位は度であることがわかる

同様に路線図の crs も確認する

gdf.crs

結果は

<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

こちらも

EPSG:4326

- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)

から単位は度であることがわかる

この2つはEPSGコードが異なるため
このままだと一緒に使えないので変換をして合わせる

今回は路線図のEPSGコードを6668に変換するので
to_crs を使う

gdf.to_crs(epsg=6668,inplace=True)
gdf.crs

これで

<Geographic 2D CRS: EPSG:6668>
Name: JGD2011
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: Japan - onshore and offshore.
- bounds: (122.38, 17.09, 157.65, 46.05)
Datum: Japanese Geodetic Datum 2011
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich

となる

行政データのプロット

行政データのプロット

今回は国土数値情報の行政区域データを使う

https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03-v2_3.html
これは市区町村の境界が表示できる

今回は東京都の平成29年のものを使う
N03-170101_13_GML.zip
をダウンロード

ダブルクリックで解凍し

mv ~/Downloads/N03-170101_13_GML .

で移動

この中にあるシェープファイルを使う
N03-17_13_170101.shp
を使う

拡張子 .shpがシェープファイル

まずはこのファイルの読み込み

gyosei = gpd.read_file('./N03-170101_13_GML/N03-17_13_170101.shp')
gyosei

N03_001	N03_002	N03_003	N03_004	N03_007	geometry	
0	東京都	None	千代田区	None	13101	POLYGON ((139.77287 35.7037, 139.77279 35.7031...
1	東京都	None	中央区	None	13102	POLYGON ((139.78341 35.69645, 139.78459 35.696...
2	東京都	None	港区	None	13103	POLYGON ((139.77129 35.62841, 139.77128 35.628...
3	東京都	None	港区	None	13103	POLYGON ((139.76689 35.62774, 139.76718 35.627...
4	東京都	None	港区	None	13103	POLYGON ((139.77022 35.63199, 139.77046 35.631...
...	...	...	...	...	...	...
6205	東京都	None	None	所属未定地	None	POLYGON ((139.8413 35.64702, 139.84131 35.6471...
6206	東京都	None	None	所属未定地	None	POLYGON ((139.80438 35.60061, 139.80399 35.600...
6207	東京都	None	None	所属未定地	None	POLYGON ((139.81937 35.60899, 139.81923 35.608...
6208	東京都	None	None	所属未定地	None	POLYGON ((139.81009 35.61355, 139.81069 35.613...
6209	東京都	None	None	所属未定地	None	POLYGON ((139.82664 35.5976, 139.827 35.59703,...
6210 rows × 6 columns

となる

次にこの中から品川区のデータに絞るため
まずは区のみに絞る

そのためにまずはNoneのあるデータを除く

gyosei_tmp = gyosei.dropna(subset=['N03_003'])
gyosei_tmp

これで

N03_001	N03_002	N03_003	N03_004	N03_007	geometry	
0	東京都	None	千代田区	None	13101	POLYGON ((139.77287 35.7037, 139.77279 35.7031...
1	東京都	None	中央区	None	13102	POLYGON ((139.78341 35.69645, 139.78459 35.696...
2	東京都	None	港区	None	13103	POLYGON ((139.77129 35.62841, 139.77128 35.628...
3	東京都	None	港区	None	13103	POLYGON ((139.76689 35.62774, 139.76718 35.627...
4	東京都	None	港区	None	13103	POLYGON ((139.77022 35.63199, 139.77046 35.631...
...	...	...	...	...	...	...
140	東京都	None	西多摩郡	瑞穂町	13303	POLYGON ((139.35786 35.74464, 139.35776 35.744...
141	東京都	None	西多摩郡	瑞穂町	13303	POLYGON ((139.35 35.79414, 139.35016 35.79364,...
142	東京都	None	西多摩郡	日の出町	13305	POLYGON ((139.19302 35.78875, 139.19307 35.788...
143	東京都	None	西多摩郡	檜原村	13307	POLYGON ((139.10611 35.77867, 139.10644 35.778...
144	東京都	None	西多摩郡	奥多摩町	13308	POLYGON ((139.01912 35.89826, 139.01941 35.898...

となる

次にこのデータから区を含むものだけに絞り込む

gyosei_ku = gyosei_tmp['N03_003'].str.contains('区')
gyosei_ku

とすれば

0       True
1       True
2       True
3       True
4       True
       ...  
140    False
141    False
142    False
143    False
144    False
Name: N03_003, Length: 117, dtype: bool

となって判別できるので

この条件式を使って

gyosei_ku = gyosei_tmp[gyosei_tmp['N03_003'].str.contains('区')]
gyosei_ku

とすれば

N03_001	N03_002	N03_003	N03_004	N03_007	geometry	
0	東京都	None	千代田区	None	13101	POLYGON ((139.77287 35.7037, 139.77279 35.7031...
1	東京都	None	中央区	None	13102	POLYGON ((139.78341 35.69645, 139.78459 35.696...
2	東京都	None	港区	None	13103	POLYGON ((139.77129 35.62841, 139.77128 35.628...
3	東京都	None	港区	None	13103	POLYGON ((139.76689 35.62774, 139.76718 35.627...
4	東京都	None	港区	None	13103	POLYGON ((139.77022 35.63199, 139.77046 35.631...
...	...	...	...	...	...	...
107	東京都	None	葛飾区	None	13122	POLYGON ((139.87626 35.79479, 139.87661 35.793...
108	東京都	None	江戸川区	None	13123	POLYGON ((139.86285 35.63532, 139.86299 35.635...
109	東京都	None	江戸川区	None	13123	POLYGON ((139.8638 35.63722, 139.86391 35.6371...
110	東京都	None	江戸川区	None	13123	POLYGON ((139.8556 35.63856, 139.85563 35.6385...
111	東京都	None	江戸川区	None	13123	POLYGON ((139.89018 35.75055, 139.89044 35.750...
112 rows × 6 columns

というように区のみにできる

これで東京23区の表示をする

gyosei_ku.plot()

これで区の区切りが白い線になっているのがわかる

次に品川区のみ色を変更する

ax = gyosei_ku.plot()
gdf.plot(ax=ax,color='orange',markersize=1)
ax = gyosei_ku.plot()
gdf.plot(ax=ax,color='orange',markersize=1)

次に品川のみに絞り込む

shinagawa = gyosei[gyosei['N03_003']=='品川区']
shinagawa

これで

N03_001	N03_002	N03_003	N03_004	N03_007	geometry	
87	東京都	None	品川区	None	13109	POLYGON ((139.75501 35.61771, 139.75507 35.617...
88	東京都	None	品川区	None	13109	POLYGON ((139.77231 35.62188, 139.77302 35.621...
89	東京都	None	品川区	None	13109	POLYGON ((139.75953 35.625, 139.75966 35.6216,...
90	東京都	None	品川区	None	13109	POLYGON ((139.71943 35.64167, 139.71953 35.641...

となる

次に品川区のみ表示する

ax = shinagawa.plot()
gdf.plot(ax=ax,color='orange',markersize=2)


CSVファイルの読み込みとgeopandas

CSVファイルの読み込みとgeopandas

今回は品川区のオープンデータを使う

https://www.city.shinagawa.tokyo.jp/PC/kuseizyoho/digitaltransformation/opendate/index.html

品川だと避難所はCSVで提供されている
他にも公共施設
AED
交通事故などもある

とりあえず今回は公共施設のCSVを使うhttps://catalog.data.metro.tokyo.lg.jp/organization/t131091?q=公共施設&sort=score+desc%2C+metadata_modified+desc
で調べたら
https://www.city.shinagawa.tokyo.jp/ct/other000081600/kokyoshisetsu.csv
のリンクになった

import requests

url = "https://www.city.shinagawa.tokyo.jp/ct/other000081600/kokyoshisetsu.csv"
save_path = "kokyoshisetsu.csv"

r = requests.get(url)
r.raise_for_status()  # エラーなら例外を出す
with open(save_path, "wb") as f:
    f.write(r.content)

print(f"保存しました: {save_path}")

を実行してファイルをダウンロード

このデータを使うには
まず pandas にして次にgeodataflameにする

df = pd.read_csv('./kokyoshisetsu.csv',encoding='shift-jis')
df

これで

	施設名	施設名(英語)	カテゴリ	電話番号	郵便番号	住所	緯度	経度	説明(日本語)	説明(英語)	FAX番号	開所時間帯	開所時刻	閉所時刻	利用料金	画像URL	サムネイル画像URL	ホームページアドレス	創設日	創設者
0	品川区役所	Shinagawa City Office	区役所	03-3777-1111	140-0005	東京都品川区広町2-1-36	35.608837	139.73024	区役所	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
1	品川第一地域センター	Shinagawa Dai-ichi Community Ctr.	地域センター	03-3450-2000	140-0001	東京都品川区北品川3-11-16	35.616681	139.74008	地域センター	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
2	品川第二地域センター	Shinagawa Dai-ni Community Ctr.	地域センター	03-3472-2000	140-0004	東京都品川区南品川5-3-20	35.611373	139.74129	地域センター	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
3	大崎第一地域センター	Osaki Dai-ichi Community Ctr.	地域センター	03-3491-2000	141-0031	東京都品川区西五反田3-6-3	35.627776	139.71686	地域センター	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
4	大崎第二地域センター	Osaki Dai-ni Community Ctr.	地域センター	03-3492-2000	141-0032	東京都品川区大崎2-9-4	35.616945	139.72757	地域センター	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...
753	なぎさ会館	Nagisa Funeral Hall	区民生活関連施設	03-5471-2700	140-0012	東京都品川区勝島3-1-3	35.596317	139.74173	葬祭施設	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
754	臨海斎場	NaN	区民生活関連施設	03-5755-2833	143-0001	東京都大田区東海1-3-1	35.585557	139.75282	葬祭施設	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
755	品川区消費者センター	Consumers' Ctr.	区民生活関連施設	03-5718-7181	140-0014	東京都品川区大井1-14-1 大井1丁目共同ビル4階	35.607696	139.73146	消費生活相談	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
756	男女共同参画センター	Equality of Gender Ctr.	区民生活関連施設	03-5479−4104	140-0011	東京都品川区東大井5−18−1品川区立総合区民会館3階	35.606177	139.73584	男女共同参画	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
757	品川区就業センター	NaN	区民生活関連施設	03-5498-6353	141-0033	東京都品川区西品川1-28-3	35.609295	139.72769	就業支援	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
758 rows × 20 columns

となる

施設名から経度まではデータがあるが
それ以降はデータがないので読み込む部分を指定する

絞り込みは df.locを使う

しかし

df = df.loc[:,'施設名':'経度']

で何も表示されない

print(df.columns.tolist())

で調べたら

['施設名', '施設名(英語)', 'カテゴリ', '電話番号', '郵便番号', '住所', '緯度', '経度']

subset = df.loc[:, '施設名':'経度']
subset

としたら表示された

単純に最後にdfを表示しないだけだった

df = df.loc[:, '施設名':'経度']
df

施設名	施設名(英語)	カテゴリ	電話番号	郵便番号	住所	緯度	経度	
0	品川区役所	Shinagawa City Office	区役所	03-3777-1111	140-0005	東京都品川区広町2-1-36	35.608837	139.73024
1	品川第一地域センター	Shinagawa Dai-ichi Community Ctr.	地域センター	03-3450-2000	140-0001	東京都品川区北品川3-11-16	35.616681	139.74008
2	品川第二地域センター	Shinagawa Dai-ni Community Ctr.	地域センター	03-3472-2000	140-0004	東京都品川区南品川5-3-20	35.611373	139.74129
3	大崎第一地域センター	Osaki Dai-ichi Community Ctr.	地域センター	03-3491-2000	141-0031	東京都品川区西五反田3-6-3	35.627776	139.71686
4	大崎第二地域センター	Osaki Dai-ni Community Ctr.	地域センター	03-3492-2000	141-0032	東京都品川区大崎2-9-4	35.616945	139.72757
...	...	...	...	...	...	...	...	...
753	なぎさ会館	Nagisa Funeral Hall	区民生活関連施設	03-5471-2700	140-0012	東京都品川区勝島3-1-3	35.596317	139.74173
754	臨海斎場	NaN	区民生活関連施設	03-5755-2833	143-0001	東京都大田区東海1-3-1	35.585557	139.75282
755	品川区消費者センター	Consumers' Ctr.	区民生活関連施設	03-5718-7181	140-0014	東京都品川区大井1-14-1 大井1丁目共同ビル4階	35.607696	139.73146
756	男女共同参画センター	Equality of Gender Ctr.	区民生活関連施設	03-5479−4104	140-0011	東京都品川区東大井5−18−1品川区立総合区民会館3階	35.606177	139.73584
757	品川区就業センター	NaN	区民生活関連施設	03-5498-6353	141-0033	東京都品川区西品川1-28-3	35.609295	139.72769
758 rows × 8 columns

となった

次に各列に対してNaNがあるか調べる

df.isna().any()

結果は

施設名        False
施設名(英語)     True
カテゴリ       False
電話番号        True
郵便番号       False
住所         False
緯度         False
経度         False
dtype: bool

これでfalseになっているものは全て入っているのが確認できる
今回のデータは必要な
施設名
住所
緯度経度
が入っているのが確認できる

次にデータタイプを確認

type(df)

で識別すると

pandas.core.frame.DataFrame

これで 冤罪は pandas の dataflameになっているのがわかる

これを geopandasへ変換する

変換するには緯度経度を使ってジオメトリ列を作成する

このジオメトリ列を使って geodataflameへ変換する

まずはジオメトリ列の作成
これは

geometry = gpd.points_from_xy(df['経度'],df['緯度'])

で簡単にできる

<GeometryArray>
[ <POINT (139.73 35.609)>,  <POINT (139.74 35.617)>, <POINT (139.741 35.611)>,
 <POINT (139.717 35.628)>, <POINT (139.728 35.617)>, <POINT (139.738 35.596)>,
  <POINT (139.73 35.604)>, <POINT (139.721 35.598)>, <POINT (139.706 35.619)>,
 <POINT (139.704 35.611)>,
 ...
 <POINT (139.749 35.622)>, <POINT (139.736 35.614)>, <POINT (139.733 35.618)>,
 <POINT (139.714 35.614)>, <POINT (139.753 35.608)>, <POINT (139.742 35.596)>,
 <POINT (139.753 35.586)>, <POINT (139.731 35.608)>, <POINT (139.736 35.606)>,
 <POINT (139.728 35.609)>]
Length: 758, dtype: geometry

これを使って geodataflameへ変換する

gdf = gpd.GeoDataFrame(df,geometry=geometry)
gdf

これで

施設名	施設名(英語)	カテゴリ	電話番号	郵便番号	住所	緯度	経度	geometry	
0	品川区役所	Shinagawa City Office	区役所	03-3777-1111	140-0005	東京都品川区広町2-1-36	35.608837	139.73024	POINT (139.73024 35.60884)
1	品川第一地域センター	Shinagawa Dai-ichi Community Ctr.	地域センター	03-3450-2000	140-0001	東京都品川区北品川3-11-16	35.616681	139.74008	POINT (139.74008 35.61668)
2	品川第二地域センター	Shinagawa Dai-ni Community Ctr.	地域センター	03-3472-2000	140-0004	東京都品川区南品川5-3-20	35.611373	139.74129	POINT (139.74129 35.61137)
3	大崎第一地域センター	Osaki Dai-ichi Community Ctr.	地域センター	03-3491-2000	141-0031	東京都品川区西五反田3-6-3	35.627776	139.71686	POINT (139.71686 35.62778)
4	大崎第二地域センター	Osaki Dai-ni Community Ctr.	地域センター	03-3492-2000	141-0032	東京都品川区大崎2-9-4	35.616945	139.72757	POINT (139.72757 35.61694)
...	...	...	...	...	...	...	...	...	...
753	なぎさ会館	Nagisa Funeral Hall	区民生活関連施設	03-5471-2700	140-0012	東京都品川区勝島3-1-3	35.596317	139.74173	POINT (139.74173 35.59632)
754	臨海斎場	NaN	区民生活関連施設	03-5755-2833	143-0001	東京都大田区東海1-3-1	35.585557	139.75282	POINT (139.75282 35.58556)
755	品川区消費者センター	Consumers' Ctr.	区民生活関連施設	03-5718-7181	140-0014	東京都品川区大井1-14-1 大井1丁目共同ビル4階	35.607696	139.73146	POINT (139.73146 35.6077)
756	男女共同参画センター	Equality of Gender Ctr.	区民生活関連施設	03-5479−4104	140-0011	東京都品川区東大井5−18−1品川区立総合区民会館3階	35.606177	139.73584	POINT (139.73584 35.60618)
757	品川区就業センター	NaN	区民生活関連施設	03-5498-6353	141-0033	東京都品川区西品川1-28-3	35.609295	139.72769	POINT (139.72769 35.6093)
758 rows × 9 columns

というように
geometryが追加される

これでタイプを確認

type(gdf)

結果は

geopandas.geodataframe.GeoDataFrame

となって GeoDataflameになっているのが確認できる

これで
Csvファイルからジオメトリを作成し、それを元にGeoDataflameの作成ができた

さらに図で表示

gdf.plot()

geopandas関連

PythonでのGIS・位置情報データのハンドリング実践

ShapelyやGeoPandas、Folium、Plotlyなどによるさまざまなデータ処理・可視化手法を学ぶ

OSMNXはopenstreetmap による最短経路の算出

内容の実践はdocker を使ってるけど
Pipでインストールも可能

Esri japanでGISの活用事例が載っている

今回はpythonでやるのでQGISは使わない

シェープファイルのサイズはそれぞれ2GBまで
フィールド名は英数字10文字
日本語なら5文字まで

geopandas関連

 pip install geopandas

でインストール

次に地図関連

pip install folium

pip install matplotlib

で可視化ツールのインストール

pip install jupyter

でインストール

jupyter-notebook   

で起動

以下コード

import geopandas as gpd
import folium
import matplotlib.pyplot as plt

でインポート

path = gpd.datasets.get_path('nybb')
gdf = gpd.read_file(path)
gdf.head()

でデータ取得して表示するはずが

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[3], line 1
----> 1 path = gpd.datasets.get_path('nybb')
      2 gdf = gpd.read_file(path)
      3 gdf.head()

File ~/.pyenv/versions/3.11.0/lib/python3.11/site-packages/geopandas/datasets/__init__.py:18, in get_path(dataset)
     12 error_msg = (
     13     "The geopandas.dataset has been deprecated and was removed in GeoPandas "
     14     f"1.0. You can get the original '{dataset}' data from "
     15     f"{ne_message if 'natural' in dataset else nybb_message}"
     16 )
     17 if dataset in _prev_available:
---> 18     raise AttributeError(error_msg)
     19 else:
     20     error_msg = (
     21         "The geopandas.dataset has been deprecated and "
     22         "was removed in GeoPandas 1.0. New sample datasets are now available "
     23         "in the geodatasets package (https://geodatasets.readthedocs.io/en/latest/)"
     24     )

AttributeError: The geopandas.dataset has been deprecated and was removed in GeoPandas 1.0. You can get the original 'nybb' data from the geodatasets package.

from geodatasets import get_path
path_to_file = get_path('nybb')

原因は
GeoPandas 1.0 以降では gpd.datasets.get_path(‘nybb’) が削除された ため
代わりに、geodatasets パッケージを使う必要がある

pip install geodatasets

でインストール

インポート文を

import geopandas as gpd
import folium
import matplotlib.pyplot as plt
from geodatasets import get_path 

にして

# path = gpd.datasets.get_path('nybb')
# データセットの取得
path = get_path("nybb")
gdf = gpd.read_file(path)
gdf.head()

これで

Downloading file 'nybb_16a.zip' from 'https://www.nyc.gov/assets/planning/download/zip/data-maps/open-data/nybb_16a.zip' to '/Users/snowpool/Library/Caches/geodatasets'.
Extracting 'nybb_16a/nybb.shp' from '/Users/snowpool/Library/Caches/geodatasets/nybb_16a.zip' to '/Users/snowpool/Library/Caches/geodatasets/nybb_16a.zip.unzip'
Extracting 'nybb_16a/nybb.shx' from '/Users/snowpool/Library/Caches/geodatasets/nybb_16a.zip' to '/Users/snowpool/Library/Caches/geodatasets/nybb_16a.zip.unzip'
Extracting 'nybb_16a/nybb.dbf' from '/Users/snowpool/Library/Caches/geodatasets/nybb_16a.zip' to '/Users/snowpool/Library/Caches/geodatasets/nybb_16a.zip.unzip'
Extracting 'nybb_16a/nybb.prj' from '/Users/snowpool/Library/Caches/geodatasets/nybb_16a.zip' to '/Users/snowpool/Library/Caches/geodatasets/nybb_16a.zip.unzip'
	BoroCode	BoroName	Shape_Leng	Shape_Area	geometry
0	5	Staten Island	330470.010332	1.623820e+09	MULTIPOLYGON (((970217.022 145643.332, 970227....
1	4	Queens	896344.047763	3.045213e+09	MULTIPOLYGON (((1029606.077 156073.814, 102957...
2	3	Brooklyn	741080.523166	1.937479e+09	MULTIPOLYGON (((1021176.479 151374.797, 102100...
3	1	Manhattan	359299.096471	6.364715e+08	MULTIPOLYGON (((981219.056 188655.316, 980940....
4	2	Bronx	464392.991824	1.186925e+09	MULTIPOLYGON (((1012821.806 229228.265, 101278...

というように無事に表示される

次に表ではなく図で描画

gdf.plot()

で簡単に描画できる

次に座標情報を表示

gdf.crs

次に座標系の変換

gdf = gdf.to_crs(epsg=4326)
print(gdf.crs)
gdf.head()

これで座標が緯度経度に変わっている

EPSG:4326
	BoroCode	BoroName	Shape_Leng	Shape_Area	geometry
0	5	Staten Island	330470.010332	1.623820e+09	MULTIPOLYGON (((-74.05051 40.56642, -74.05047 ...
1	4	Queens	896344.047763	3.045213e+09	MULTIPOLYGON (((-73.83668 40.59495, -73.83678 ...
2	3	Brooklyn	741080.523166	1.937479e+09	MULTIPOLYGON (((-73.86706 40.58209, -73.86769 ...
3	1	Manhattan	359299.096471	6.364715e+08	MULTIPOLYGON (((-74.01093 40.68449, -74.01193 ...
4	2	Bronx	464392.991824	1.186925e+09	MULTIPOLYGON (((-73.89681 40.79581, -73.89694 ...

緯度経度に変換すれば foliumで地図表示ができる

まずは地図の表示

m = folium.Map(location=[40.7,-73.96],zoom_start=10,tiles='CaltoDB positiuon')
m

としたらエラー

単純に

CartoDB positron

の間違い

m = folium.Map(location=[40.7,-73.96],zoom_start=10,tiles='CartoDB positron')
m

が正解

次に地図上にgeopandas情報を描画する
まずはこの情報を上から見ていくので

for __, r in gdf.iterrows():
    sim_geo = gpd.GeoSeries(r['geometory']).simplify(tolerance=0.001)
    geo_j = sim_geo.to_json()
    geo_j = folium.GeoJson(data=geo_j,style_function=lambda x:{'fillColor':'orange'})
    folium.Popup(r['BoroName']).add_to(geo_j)
    geo_j.add_to(m)
m

今回もエラー

原因は今回もスペルミス

geometory

じゃなくて

geometry

が正解

これで地図の上に情報が表示される

geopandas関連その2

今回は shapely を使う

import pandas as pd
import geopandas as gpd
import matplotlib as plt
from shapely.geometry import Point,LineString, Polygon

まずはPoint の練習

#Point
point = Point(0.0,1.0)
point

これで座標を指定するとそこに⭕️が表示される

この座標を出すなら

print(point)

とすれば

POINT (0 1)

と座標を表示できる

ジオメトリタイプを調べるなら

point.geom_type

というように

.geom_type

をつけることでタイプの判別ができる

次にLineStringの練習

line = LineString([(0,0),(1,1),(3,0),(5,2)])
line

これで折れ線が表示される

print(line)

LINESTRING (0 0, 1 1, 3 0, 5 2)

というように配列の座標を見れる

次はPolygon

polygon = Polygon([(0,0),(1,1),(3,0)])
polygon

これで三角形が表示される

polygon = Polygon([(0,0),(0,1),(1,1),(1,0)])
polygon

これで四角形

これらをまとめて行うのがジオメトリコレクション

#multipoint
from shapely.geometry import MultiPoint,MultiLineString,MultiPolygon

で必要なインポートを行う

points = MultiPoint([(0,0),(1,0)])
points

で2つの座標に⭕️が表示される

coords = [((0,0),(1,1)),((-1,0),(1,0))]
lines = MultiLineString(coords)
lines

これで2つの線が憑依される

a = Polygon([(0,0),(0,1),(1,1),(1,0)])
b =Polygon([(2,0),(2,1),(3,1),(3,0)])
polygons = MultiPolygon([a,b])
polygons

で2つの四角が表示される

次に LineString の長さ

l = LineString([(1,-1),(1,0),(2,0),(2,1)])
l

この長さを求めるには
.length を使う

これは道路などで使うことになる

次に polygonの面積

p=Polygon([(3,-1),(4,0),(3,1)])
p

で三角形

面積は
areaで求めることができるので

p.area

とすれば

1.0

となる

次にbuffer
これは Point LineString に幅を与えてpolygonにするもの

s = gpd.GeoSeries(
    [
        Point(0,0),
        LineString([(1,-1),(1,0),(2,0),(2,1)]),
        Polygon([(3,-1),(4,0),(3,1)])
    ])
s

結果は

0                         POINT (0 0)
1    LINESTRING (1 -1, 1 0, 2 0, 2 1)
2    POLYGON ((3 -1, 4 0, 3 1, 3 -1))
dtype: geometry

次に

s.buffer(0.5)

とすると

0    POLYGON ((0.5 0, 0.49759 -0.04901, 0.49039 -0....
1    POLYGON ((0.5 0, 0.50241 0.04901, 0.50961 0.09...
2    POLYGON ((2.5 -1, 2.5 1, 2.50241 1.04901, 2.50...
dtype: geometry

s.buffer(0.5)[0]

で円ができる
これは半径0.5の円

次にLineString での buffer

s.buffer(0.5)[1]

これで線の周りが追加されて図みたいになっている
この時に角はまるくなる

同様にpolygonも試す

s.buffer(0.5)[2]

これで三角形の角がまるくなる

これらは後々、ジオメトリの空間結合で使う
例えば予測地点の100m以内のみ表示などで使う