2

Python でシェープファイルにいくつかの地域のマップを描画しようとしています。私の基本的なアプローチはこれです:

shp = fiona.open("C:/Users/nils/Documents/Maps/my_shapefile.shp")
bds = shp.bounds
ll = (bds[0], bds[1])
ur = (bds[2], bds[3])
coords = list(ll + ur)
w, h = coords[2] - coords[0], coords[3] - coords[1]

# Make figure instance, add Basemap and CCG boundaries from shapefile
fig, ax = plt.subplots(figsize=(12,10))
m = Basemap(projection="tmerc", lon_0 = -2., lat_0 = 49., ellps="WGS84",
        llcrnrlon = coords[0], llcrnrlat = coords[1],
        urcrnrlon = coords[2], urcrnrlat = coords[3],
        lat_ts = 0, resolution="i", suppress_ticks=True)
m.readshapefile("C:/Users/nils/Documents/Maps/my_shapefile.shp", "Regions")

# Extract polygon coordinates of  and names of regions to plot from shapefile
to_plot = ["region_A", "region_B", "region_C"]
poly = []; name = []
for coordinates, region in zip(m.Regions, m.Regions_info):
    if any(substr in region["name"] for substr in to_plot):
        poly.append(Polygon(coordinates))
        name.append(region["name"])

# Turn polygons into patches using descartes
patches = []
for i in poly:
    patches.append(PolygonPatch(i, facecolor='#006400', edgecolor='#787878', lw=0.25, alpha=0.5))

# Add PatchCollection to basemap
ax.add_collection(PatchCollection(patches, match_original=True))

これに関する私の問題は、シェープファイルがより広い地理的領域をカバーしていることですが、この領域のサブセットのみをプロットしたいということです (たとえば、英国のシェープファイルを持っているが、ウェールズのすべての地域の地図をプロットしたいと考えています)。これで、正しい領域を識別し、上記の例のようにそれらのパッチのみを追加できますが、matplotlib は引き続きシェープファイル内のすべての領域の境界をプロットし、フィオナのbounds方法によって識別された境界は明らかにパッチのサブセットから独立しています。選ばれました。

これに関連して 2 つの質問があります。

  1. シェープファイルで定義されたパッチのサブセットの境界のみを描画するように matplotlib を取得するにはどうすればよいですか?

  2. boundフィオナのメソッドがシェープファイル全体に対して行うのと同様に、パッチのサブセットの境界を取得するにはどうすればよいですか?

4

2 に答える 2

2

2番目の部分にも答えるために、目的の結果を達成する関数を次に示します。

def get_bounds(patch_list):

m = Basemap()
# Read in shapefile, without drawing anything
m.readshapefile("C:/Users/ngudat/Documents/Maps/CCG/CCG_boundaries_2015", "patches", drawbounds=False)

# initialize boundaries (this is a bit of a manual step, might be better to intialize to boundaries of first patch or something)
lon_min = 0.
lon_max = -3.
lat_min = 60.
lat_max = 0.

for (shape, patch_name) in zip(m.patches, m.patches_info):
    if patches["name"] in patch_list:
        lon, lat = zip(*shape)
        if min(lon) < lon_min:
            lon_min = min(lon)
        if max(lon) > lon_max:
            lon_max = max(lon)
        if min(lat) < lat_min:
            lat_min = min(lat)
        if max(lat) > lat_max:
            lat_max = max(lat)

return lon_min, lat_min, lon_max, lat_max

おそらく最も効率的な方法ではなく、初期化手順を変更する必要があるかもしれませんが、このアイデアは同様の状況に簡単に適用できるはずです。

于 2016-02-17T10:13:36.870 に答える
0

私の最初の質問に(部分的に)答えるには、これを達成する方法は;で呼び出すreadshapefileことです。drawbounds=Falseこの場合、マップ上に境界はありませんが、選択した地域の境界はいずれにしてもパッチで描画されます。

于 2016-01-07T14:25:08.970 に答える