Basemapでシェープファイルを扱う（翻訳）

英文
Working with shapefiles
https://basemaptutorial.readthedocs.io/en/latest/shapefile.html
をGoogle翻訳で翻訳したもの。

##シェープファイルを扱う
Basemapがベクトルファイルを処理する方法は、他のライブラリとはまったく異なるため、注意が必要です。
###基本的な使い方
シェープファイルをプロットする最も簡単な方法から始めましょう。

```python:sample.py
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

map = Basemap(llcrnrlon=-0.5,llcrnrlat=39.8,urcrnrlon=4.,urcrnrlat=43.,
             resolution='i', projection='tmerc', lat_0 = 39.5, lon_0 = 1)

map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='#ddaa66',lake_color='aqua')
map.drawcoastlines()

map.readshapefile('../sample_files/comarques', 'comarques')

plt.show()
```

![fuyou.png](https://qiita-image-store.s3.amazonaws.com/0/238800/af3a73fa-9b6d-bdfc-eb32-145e16110b4c.png)

 ・最初のパラメータshapefile名は、shp拡張子を付けずに指定する必要があります。 ライブラリは、すべてのshp、sbf、およびshxファイルがこの名前で存在することを前提としています。
 ・2番目のパラメータは、後で説明するように、Basemapインスタンスからシェープファイル情報に後でアクセスするための名前です。 

いくつかの制限があります。

 ・ファイルはEPSG：4326、つまり緯度/経度座標でなければなりません。 あなたのファイルがそうでなければ、あなたはそれを変換するためにogr2ogrを使うことができます
 ・要素は2次元だけでなければならない
 ・この例は、要素がポリゴンまたはポリラインの場合にのみ表示されます。 

画像が示すように、結果はポリゴン（またはポリライン）の境界線だけになります。 それらを埋めるために、最後のセクションを見てください。 

###ポイントデータを読む
点のプロットはもう少し複雑です。 まず、シェープファイルが読み込まれ、次に散布図、プロット、またはニーズに合ったmatplotlib関数を使用して点がプロットされます。

```python:sample_1.py
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

map = Basemap(llcrnrlon=-0.5,llcrnrlat=39.8,urcrnrlon=4.,urcrnrlat=43.,
             resolution='i', projection='tmerc', lat_0 = 39.5, lon_0 = 1)

map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='#ddaa66',lake_color='aqua')
map.drawcoastlines()

map.readshapefile('../sample_files/comarques', 'comarques')

lightning_info = map.readshapefile('../sample_files/lightnings', 'lightnings')

print lightning_info

for info, lightning in zip(map.lightnings_info, map.lightnings):
    if float(info['amplitude']) < 0:
        marker = '_'
    else:
        marker = '+'
    map.plot(lightning[0], lightning[1], marker=marker, color='m', markersize=8, markeredgewidth=2)

plt.show()
```

この例は、嵐の間にカタルーニャの上に落ちた雷を示しています

![fuyou1.png](https://qiita-image-store.s3.amazonaws.com/0/238800/7da2af95-c7e2-eedf-fe10-08528a6dd60f.png)

・2番目のパラメーターはlightnings、およびBasemapインスタンスマップという名前が付けられているため、形状ファイル要素は、ジオメトリにはmap.lightningsを、要素フィールドにアクセスするにはmap.lightnings_infoを使用してアクセスできます
・shapefileメソッドは、要素数、 ここで定義されたコードを持つジオメトリタイプ、およびバウンディングボックスを含むシーケンスを返します。

・行17は、すべての要素を繰り返すための考えられる方法を示しています

  ○zipは各ジオメトリとそのフィールド値を結合します
  ○辞書を繰り返すときのように、各要素をforで繰り返すことができます。 

・この例では、振幅という名前のフィールドを使用して、稲妻が正または負の電流を持っているかどうかを推測し、それぞれの場合に異なる記号を描画することができます。
・シンボルを変更するためにmarker属性を使用して、メソッドplotで点をプロットします 

###ポリゴン情報
この例では、shapefile属性を使用していくつかの形状のみを選択する方法を示します。


```python:test.py
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

map = Basemap(llcrnrlon=-0.5,llcrnrlat=39.8,urcrnrlon=4.,urcrnrlat=43.,
             resolution='i', projection='tmerc', lat_0 = 39.5, lon_0 = 1)

map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='#ddaa66',lake_color='aqua')
map.drawcoastlines()

map.readshapefile('../sample_files/comarques', 'comarques', drawbounds = False)

for info, shape in zip(map.comarques_info, map.comarques):
    if info['nombre'] == 'Selva':
        x, y = zip(*shape) 
        map.plot(x, y, marker=None,color='m')
plt.show()
```

![fuyou2.png](https://qiita-image-store.s3.amazonaws.com/0/238800/3e1c1ff5-0882-ad8c-6866-e3a6eb211647.png)

・すべての要素を繰り返すには、最後の例のようにzipを使用します。
・フィルタリングに使用できる 'nombre'というフィールドがあります。 この例では、値「Selva」のみが選択されています
・線をプロットするには、x座標とy座標を別々の配列にする必要がありますが、ジオメトリは各点を対として与えます。 それを行う方法についての説明があります 'ここ<http://stackoverflow.com/questions/13635032/what-is-the-inverse-function-of-zip-in-python>' _
・形状はplotメソッドを使用してプロットされ、マーカーを削除して線のみを取得します 

###塗りつぶしポリゴン
シェイプファイルをプロットする基本的な方法は、これがシェイプタイプの場合、ポリゴンを塗りつぶさないことです。 これを行う方法は次のとおりです。

```python:test.py
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
from matplotlib.patches import PathPatch
import numpy as np

fig     = plt.figure()
ax      = fig.add_subplot(111)

map = Basemap(llcrnrlon=-0.5,llcrnrlat=39.8,urcrnrlon=4.,urcrnrlat=43.,
             resolution='i', projection='tmerc', lat_0 = 39.5, lon_0 = 1)

map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='#ddaa66',lake_color='aqua')
map.drawcoastlines()

map.readshapefile('../sample_files/comarques', 'comarques', drawbounds = False)

patches   = []

for info, shape in zip(map.comarques_info, map.comarques):
    if info['nombre'] == 'Selva':
        patches.append( Polygon(np.array(shape), True) )
        
ax.add_collection(PatchCollection(patches, facecolor= 'm', edgecolor='k', linewidths=1., zorder=2))

plt.show()
```

![fuyou3.png](https://qiita-image-store.s3.amazonaws.com/0/238800/c7a29a08-1804-70b7-39f1-19b9ebbf93d9.png)

・matplotlibは、PatchCollectionと呼ばれるクラスを使用します。これは、公式のドキュメントで説明されているように、塗りつぶされたポリゴンを追加するために設定されたセットです。
・この場合、形状はPolygon型です。 それを作成するために、座標はでこぼこの配列になければなりません。 2番目の引数は、閉じるポリゴンを設定します。 

私はStackOverflowでそれを行う方法を学びました