【发布时间】:2016-01-16 08:36:28
【问题描述】:
这是我的问题。
1。简介
- 多边形类型的 shapefile 代表研究区域
http://i8.tietuku.com/08fdccbb7e11c0a9.png
- 某个点位于整个矩形地图中
http://i8.tietuku.com/877f87022bf817b8.png
我想测试每个点是否位于多边形内/外并做一些进一步的操作(例如,对研究区域内的网格点数量求和)
2。我的想法
由于堆栈溢出的信息,我有两种方法。
2.1 想法A将shapefile光栅化成光栅文件,然后进行测试。
我还没有这样做,但我已经问了一个问题here 并得到了答案。
2.2 想法 B我曾尝试使用poly.contain()测试散点位置,但结果与实际不符。
3。我的代码基于想法 B:
例如:
- 原始数据由pt(一个熊猫数据框)表示,其中包含 1000 个网格 X、Y。
- 我已经显示的 shapefile 是研究区域,我想过滤原始数据,只留下该区域内的点。
# map four boundaries
xc1,xc2,yc1,yc2 = 113.49805889531724,115.5030664238035,37.39995194888143,38.789235929357105
# grid definition
lon_grid = np.linspace(x_map1,x_map2,38)
lat_grid = np.linspace(y_map1,y_map2,32)
3.1 准备工作
# generate (lon,lat)
xx = lon_grid[pt.X.iloc[:].as_matrix()]
yy = lat_grid[pt.Y.iloc[:].as_matrix()]
sh = (len(xx),2)
data = np.zeros(len(xx)*2).reshape(*sh)
for i in range(0,len(xx),1):
data[i] = np.array([xx[i],yy[i]])
# reading the shapefile
map = Basemap(llcrnrlon=x_map1,llcrnrlat=y_map1,urcrnrlon=x_map2,\
urcrnrlat=y_map2)
map.readshapefile('/xx,'xx')
3.2 测试
patches=[]
for info, shape in zip(map.xxx_info, map.xxx):
x,y=zip(*shape)
patches.append(Polygon(np.array(shape), True) )
for poly in patches:
mask = np.array([poly.contains_point(xy) for xy in data])
- 然后,我有一个 numpy 数组掩码,其值为 0,1 代表内/外。
- 将掩码组合成pt ==> pt = pt[[pt.mask == 1]],我可以过滤点
我的想法 2 的一个例子但问题在于使用
poly,contains_point(xy),我无法得到与我的尝试匹配的结果。
对值 0,1 求和:
unique, counts = np.unique(mask, return_counts=True)
print np.asarray((unique, counts)).T
#result:
> [[0 7]
[1 3]]
http://i4.tietuku.com/7d156db62c564a30.png
从唯一值来看,shapefile区域内必须有3个点,但结果显示多了一个点。
40分的另一个测试
http://i4.tietuku.com/5fc12514265b5a50.png
4。我的问题
结果是错误的,我还没弄明白。
但我认为问题的发生可能有两个原因:
- 多边形 shapefile 错误(一个简单的多边形,我不认为问题仍然存在)。
- 使用
poly.contains_point(xy)不正确。
添加 2016-01-16
感谢您的回答,我发现的原因是 shapefile 本身。
当我把它改成 shapely.polygon 时,效果很好。
这是我的代码和结果
c = fiona.open("xxx.shp")
pol = c.next()
geom = shape(pol['geometry'])
poly_data = pol["geometry"]["coordinates"][0]
poly = Polygon(poly_data)
ax.add_patch(plt.Polygon(poly_data))
xx = lon_grid[pt_select.X.iloc[:].as_matrix()]
yy = lat_grid[pt_select.Y.iloc[:].as_matrix()]
sh = (len(xx),2)
points = np.zeros(len(xx)*2).reshape(*sh)
for i in range(0,len(xx),1):
points[i] = np.array([xx[i],yy[i]])
mask = np.array([poly.contains(Point(x, y)) for x, y in points])
ax.plot(points[:, 0], points[:, 1], "rx")
ax.plot(points[mask, 0], points[mask, 1], "ro")
【问题讨论】:
-
对不起,我正在编辑它。
标签: python numpy matplotlib shapefile matplotlib-basemap