import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import Polygon
import geopandas as gpd
import math
def make_mesh(box,w,h): #按照w,h对box进行网格划分
[xmin,ymin,xmax,ymax]=box
list_x=np.arange(xmin,xmax,w)
list_y=np.arange(ymin,ymax,h)
polygon_list=[]
for i in range(len(list_x)):
for j in range(len(list_y)):
xleft=list_x[i]
ydown=list_y[j]
if i==len(list_x)-1:
xright=xmax
else:
xright=list_x[i+1]
if j==len(list_y)-1:
yup=ymax
else:
yup=list_y[j+1]
rectangle=Polygon([(xleft, ydown), (xright, ydown), (xright, yup), (xleft, yup)])
polygon_list.append(rectangle)
return gpd.GeoSeries(polygon_list)
path="f:\\shapefile\\OUTPUT\\test.shp"
gdf=gpd.read_file(path)
print(gdf.total_bounds)
[xmin,ymin,xmax,ymax]=gdf.total_bounds
w=(xmax-xmin)/10
h=(ymax-ymin)/10
#[xmin,ymin,xmax,ymax]=eval(input("输入box:"))
#[w,h]=eval(input("输入网格宽和高:"))
rect=make_mesh([xmin,ymin,xmax,ymax],w,h)
ax=gdf.plot()
rect.boundary.plot(ax=ax,color='yellow')
plt.show()
rectangles=gpd.GeoDataFrame(geometry=rect)
rectangles['RectangleID']=range(len(rectangles))
res=gpd.sjoin(left_df=rectangles,
right_df=gdf,
how='right',
op='intersects')
g=res.groupby('RectangleID')
g=dict(list(g))
count=0
ax=gdf.plot()
color=['yellow','green','blue','black','purple','red']
mean_heights=[]
for k,v in g.items():
row=k//10
col=k%10
mean_heights.append((row,col,v['height'].mean()))
print("row={},col={},mean height={}".format(row,col,v["height"].mean()))
gpd.GeoSeries(rectangles['geometry'][k]).boundary.plot(ax=ax,color=color[(row%6+col)%6])
v.plot(ax=ax,color=color[(row%6+col)%6])
plt.show()
print(res.columns.tolist())
print(res.loc[:,['index_left','RectangleID']])
for mean_height in mean_heights:
print(mean_height)
这里需要关注的是geopandas.sjoin这个函数的使用,这个函数非常强大,详细使用方法见链接 上述代码实现了: 对地图文件按照矩形进行分割,得到一个网状结构,然后统计每个网格内建筑物的平均高度。 以下是运行结果: 这是对网络的分割,下面是获取每个网格内的建筑物:
这是每个网格内建筑物的平均高度(每个网格以元祖存储):