import geopandas
#path = "F:\\shapefile\\Detroit\\Detroit_height.shp"
path="F:\\shapefile\\Xian\\Xian\\Xian.shp"
# 读取shapefile文件,可设置bbox选定区域
gdf = geopandas.read_file(path)
gdf=gdf[gdf.boundary.is_simple]
gdf.reset_index(drop=True,inplace=True)
print(len(gdf))
polygon1=gdf.loc[0,'geometry']
polygon2=gdf.loc[0,'geometry']
print(polygon1.overlaps(polygon2)) #自己和自己不算overlaps
spatial_index = gdf.sindex
#建立R树索引. gdf,geopandas dataframe 数据
for i in range(len(gdf)):
polygon=gdf.loc[i,'geometry']
possible_matches_index = list(spatial_index.intersection(polygon.bounds))
possible_matches = gdf.iloc[possible_matches_index]
#通过R树进行简单包含查询
precise_matches = possible_matches[possible_matches.overlaps(polygon)]
#将简单查询结果进行进行匹配,得到精确查询结果
if len(precise_matches)>0:
print("detect overlaps :{}".format(i))
else:
print("not detect overlaps :{}".format(i))
注意,进行拓扑检查之前,先要进行自相交检查(gdf.boundary.is_simple),且删除掉不符合的Polygon之后,还是进行索引重置(当然这不是必须的,但是本次代码需要)。利用Rtree建立空间索引之后,进行暴力相交检测。注意,两个完全相同的polygon不算overlaps.
之前的方法由于重复判断,因此会产生过多的overlay的polygon,而事实上没必要删除这么多,因此,采用了一下的方法(flag=0)
import geopandas
import time
#path = "F:\\shapefile\\Detroit\\Detroit_height.shp"
path="F:\\shapefile\\Xian\\Xian\\Xian.shp"
gdf = geopandas.read_file(path)
gdf=gdf[gdf.boundary.is_simple]
gdf.reset_index(drop=True,inplace=True)
print(len(gdf))
polygon1=gdf.loc[0,'geometry']
polygon2=gdf.loc[0,'geometry']
print(polygon1.overlaps(polygon2)) #自己和自己不算overlaps
gdf_copy=gdf.copy(deep=True)
def check_overlay(gdf,flag):
spatial_index = gdf.sindex
#建立R树索引.
drop_list=[]
for i in range(len(gdf)):
polygon=gdf.loc[i,'geometry']
possible_matches_index = list(spatial_index.intersection(polygon.bounds))
possible_matches = gdf.iloc[possible_matches_index]
#通过R树进行简单包含查询
precise_matches = possible_matches[possible_matches.overlaps(polygon)]
#将简单查询结果进行进行匹配,得到精确查询结果
if flag==0:
spatial_index.delete(i, polygon.bounds)
if len(precise_matches)>0:
drop_list.append(i)
return drop_list
start=time.time()
drop_list=check_overlay(gdf,0)
stop=time.time()
print(len(drop_list))
print(len(gdf))
print(stop-start)
gdf.drop(axis=0,index=drop_list,inplace=True)
gdf.reset_index(drop=True,inplace=True)
start=time.time()
drop_list=check_overlay(gdf,1)
stop=time.time()
print(len(drop_list))
print(len(gdf))
print(stop-start)
运行结果:
(第一次检查,第二次测试第一次的检查是否成功)
上面的拓扑检查无法检查出相等以及包含这种情况,因此,更正如下(相交(intersects)-边界相交(touches)=内部相交)
import geopandas
def check_overlap(gdf):
spatial_index = gdf.sindex
#建立R树索引.
drop_list=[]
for i in range(len(gdf)):
polygon=gdf.loc[i,'geometry']
possible_matches_index = list(spatial_index.intersection(polygon.bounds))
possible_matches = gdf.iloc[possible_matches_index]
#通过R树进行简单包含查询
precise_matches_intersects = possible_matches[possible_matches.intersects(polygon)]
precise_matches_touches = possible_matches[possible_matches.touches(polygon)]
#将简单查询结果进行进行匹配,得到精确查询结果
spatial_index.delete(i, polygon.bounds)
if (len(precise_matches_intersects)-len(precise_matches_touches))>1:
drop_list.append(i)
return drop_list
if __name__=='__main__':
path="f:\\shapefile\\Xian\\Xian\\Xian.shp"
gdf=geopandas.read_file(path)
gdf=gdf[gdf.boundary.is_simple]
gdf.reset_index(drop=True,inplace=True)
drop_list=check_overlap(gdf)
print(len(gdf))
print(len(drop_list))
gdf.drop(axis=0,index=drop_list,inplace=True)
gdf.reset_index(drop=True,inplace=True)
print(len(gdf))
gdf.to_file("F:\\shapefile\\1.shp")