2020年2月17日月曜日

GeoPandas GeoDataFrame 操作

GeoPandas 0.6.0
基本操作です。
※見やすさのため不要なインデントをつけています。

空間演算は 以下を参照。
 spatial overlays
https://github.com/geopandas/geopandas/blob/master/examples/overlays.ipynb
Spatial Joins
https://github.com/geopandas/geopandas/blob/master/examples/spatial_joins.ipynb
  1. import geopandas as gpd
  2. #Ver. 0.6.3
  3.  
  4. #読み込み
  5. #SHP、GeoJSON、GeoPackage に対応
  6. gdf = gpd.read_file('./A.shp')
  7. #フォルダ内のSHPファイルを全て読み込み結合
  8. import glob
  9. import pandas as pd
  10. shpfiles = [
  11. shpfile for shpfile in glob.glob('./shp/*.shp')]
  12. gdf = pd.concat(
  13. [gpd.read_file(shpfile)for shpfile in shpfiles])
  14. #df(csv)からgdfを作成
  15. #https://gis.stackovernet.com/ja/q/47396
  16. import pandas as pd
  17. from shapely.geometry import Point
  18. geometry = [Point(xy) for xy in zip(df.lon, df.lat)]
  19. crs = {'init': 'epsg:6668'}
  20. gdf = gpd.GeoDataFrame(df, crs=crs, geometry=geometry)
  21.  
  22. #書き込みSHP、GeoJSON、GeoPackage
  23. #shpは仕様上、属性255種までの制限あり。型の制限もあり。
  24. #geojsonはQGISで読みこみ可。Arcはtoolboxから変換。
  25. #geojsonはdaytime型不可。→事前にstr型変換
  26. gdf.to_file('./A.shp')
  27. gdf.to_file('./A.geojson', driver='GeoJSON')
  28.  
  29. #型変換(pandasと同操作)
  30. gdf['時刻']=gdf['時刻'].astype(str)
  31. #A列(属性)削除 (pandasと同操作)
  32. gdf.drop('A',axis=1)
  33.  
  34. #列名(属性名)変更 (pandasと同操作)
  35. gdf.columns = ['A','B','geometry']
  36.  
  37. #'都道府県'列(属性)から3県を含む行抽出 (pandasと同操作)
  38. gdf3=gdf[(gdf['都道府県']=='茨城')|
  39. (gdf['都道府県']=='埼玉')|
  40. (gdf['都道府県']=='群馬')|]
  41.  
  42. #型変換(pandasと同操作)
  43. gdf['時刻']=gdf['時刻'].astype(str)
  44. #属性の追加、演算(pandasと同操作)
  45. gdf['C']=gdf['A']-gdf['B']
  46.  
  47. #県単位でディゾルブ(地物をまとめる)
  48. gdf=gdf3.dissolve(by='都道府県')
  49. #属性結合
  50. #gdfにA列をkeyとしてDataFrameを属性結合
  51. #df.merge だと df になる
  52. gdf=gdf.merge(df, on='A')
  53.  
  54. #Coordinate Reference Systems
  55. #CRS確認
  56. gdf.crs
  57. #gdf1のCRSをgdf2のCRSに変更(一致)
  58. #EPSG:4612 : JGD2000
  59. #EPSG:6668 : JGD2011
  60. gdf1 = gdf1.to_crs(gdf2.crs)
  61. #地図プロット
  62. #matplotlibベース
  63. #1レイヤー
  64. gdf.plot(figsize=(10, 10),
  65. alpha=0.5,
  66. edgecolor='k')
  67. #3レイヤー:gdfを重ねて表示
  68.  #Choropleth Map(ポリゴン1枚目)
  69.  base=gdf1.plot(figsize=(10, 10),
  70.   column='A',
  71. cmap='OrRd',
  72. alpha=0.8,
  73. legend=True,
  74. legend_kwds={'label':'aaa',
  75. orientation:'horizontal'})
  76. #ポリゴンを重ねる(2枚目)
  77. ax=gdf2.plot(ax=base,
  78. facecolor='none',
  79. edgecolor='gray',
  80.    alpha=0.8)
  81.  #ポイントを重ねる(3枚目)
  82.  ax=gdf3.plot(ax=base,
  83.    marker='o',
  84.    color='red',
  85.    markersize=5)
  86.   #仕上げ
  87. ax.set_xlabel('longitude')
  88. ax.set_ylabel('latitude')
  89. ax.grid()
  90. ax.set_axisbelow(True) #grid moves back
  91. #保存する場合は import matplotlib.pyplot as plt からの
  92. plt.savefig("./aaa.png")
  93.  
20200220 Foliumでの図化は移動しました。
https://phreeqc.blogspot.com/2020/02/folium.html


番外編: rasterstats を用いたラスターからの統計量取得。
大量処理は速度面で不可。
  1. #空間演算
  2. from rasterstats import zonal_stats
  3. zonal_stats(gdf, './aaa.tif', stats=['max'])
  4. #フォルダ内のgeotiffを全て読み込み、統計量をgdfに結合
  5. import glob
  6. import os
  7. path = './input/*.tif'
  8. files= glob.glob(path)
  9. for i, name in enumerate(files) :
  10. print(i)
  11. file_name = os.path.splitext(
  12. os.path.basename(files[i]))[0]
  13. print(file_name)
  14. stats=pd.DataFrame(zonal_stats(gdf,
  15. files[i],
  16. stats=['max', 'count']))
  17. gdf_max[file_name]=stats['max']
  18. gdf_count[file_name]=stats['count']
  19.  
  20.  

0 件のコメント:

コメントを投稿