Posted at

Basemapでシェープファイルを扱う(翻訳)

英文

Working with shapefiles

https://basemaptutorial.readthedocs.io/en/latest/shapefile.html

をGoogle翻訳で翻訳したもの。


シェープファイルを扱う

Basemapがベクトルファイルを処理する方法は、他のライブラリとはまったく異なるため、注意が必要です。


基本的な使い方

シェープファイルをプロットする最も簡単な方法から始めましょう。


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

・最初のパラメータshapefile名は、shp拡張子を付けずに指定する必要があります。 ライブラリは、すべてのshp、sbf、およびshxファイルがこの名前で存在することを前提としています。

・2番目のパラメータは、後で説明するように、Basemapインスタンスからシェープファイル情報に後でアクセスするための名前です。

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

・ファイルはEPSG:4326、つまり緯度/経度座標でなければなりません。 あなたのファイルがそうでなければ、あなたはそれを変換するためにogr2ogrを使うことができます

・要素は2次元だけでなければならない

・この例は、要素がポリゴンまたはポリラインの場合にのみ表示されます。

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


ポイントデータを読む

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


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

・2番目のパラメーターはlightnings、およびBasemapインスタンスマップという名前が付けられているため、形状ファイル要素は、ジオメトリにはmap.lightningsを、要素フィールドにアクセスするにはmap.lightnings_infoを使用してアクセスできます

・shapefileメソッドは、要素数、 ここで定義されたコードを持つジオメトリタイプ、およびバウンディングボックスを含むシーケンスを返します。

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

○zipは各ジオメトリとそのフィールド値を結合します

○辞書を繰り返すときのように、各要素をforで繰り返すことができます。

・この例では、振幅という名前のフィールドを使用して、稲妻が正または負の電流を持っているかどうかを推測し、それぞれの場合に異なる記号を描画することができます。

・シンボルを変更するためにmarker属性を使用して、メソッドplotで点をプロットします


ポリゴン情報

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


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

・すべての要素を繰り返すには、最後の例のようにzipを使用します。

・フィルタリングに使用できる 'nombre'というフィールドがあります。 この例では、値「Selva」のみが選択されています

・線をプロットするには、x座標とy座標を別々の配列にする必要がありますが、ジオメトリは各点を対として与えます。 それを行う方法についての説明があります 'ここhttp://stackoverflow.com/questions/13635032/what-is-the-inverse-function-of-zip-in-python' _

・形状はplotメソッドを使用してプロットされ、マーカーを削除して線のみを取得します


塗りつぶしポリゴン

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


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

・matplotlibは、PatchCollectionと呼ばれるクラスを使用します。これは、公式のドキュメントで説明されているように、塗りつぶされたポリゴンを追加するために設定されたセットです。

・この場合、形状はPolygon型です。 それを作成するために、座標はでこぼこの配列になければなりません。 2番目の引数は、閉じるポリゴンを設定します。

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