使用Python计算多边形shapefile中的点数

5
我有一个由各州属性值组成的美国多边形shapefile。此外,我还有存储点事件纬度和经度值的数组。本质上,我想要将点和多边形进行“空间连接”(或执行检查以查看每个点位于哪个多边形[即州]中),然后对每个州中的点数求和,以找出哪个州拥有最多的“事件”。
我认为伪代码应该是这样的:
Read in US.shp
Read in lat/lon points of events
Loop through each state in the shapefile and find number of points in each state
print 'Here is a list of the number of points in each state: '

非常感谢任何提供的库或语法。

根据我所了解的,OGR库是我需要的,但是我在语法上有些困难:

dsPolygons = ogr.Open('US.shp')  

polygonsLayer = dsPolygons.GetLayer()  


#Iterating all the polygons  
polygonFeature = polygonsLayer.GetNextFeature()  
k=0  
while polygonFeature:
    k = k + 1  
    print  "processing " + polygonFeature.GetField("STATE") + "-" + str(k) + " of " + str(polygonsLayer.GetFeatureCount())  

    geometry = polygonFeature.GetGeometryRef()          

    #Read in some points?
    geomcol = ogr.Geometry(ogr.wkbGeometryCollection)
    point = ogr.Geometry(ogr.wkbPoint)
    point.AddPoint(-122.33,47.09)
    point.AddPoint(-110.11,33.33)
    #geomcol.AddGeometry(point)
    print point.ExportToWkt()
    print point
    numCounts=0.0   
    while pointFeature:  
        if pointFeature.GetGeometryRef().Within(geometry):  
            numCounts = numCounts + 1  
        pointFeature = pointsLayer.GetNextFeature()
    polygonFeature = polygonsLayer.GetNextFeature()
    #Loop through to see how many events in each state
2个回答

11

我喜欢这个问题。我怀疑我不能给你最好的答案,也肯定不能帮助你解决OGR的问题,但 FWIW 我会告诉你我现在正在做什么。

我使用的是GeoPandas,这是 pandas 的地理空间扩展。我推荐它-它是高级别的并且功能很强大,可以免费提供 Shapelyfiona 中的所有内容。它由 twitter/@kajord 和其他人积极开发。

这是我的可工作代码版本。它假设您拥有所有的数据都是 shapefiles(形状文件),但从列表生成一个geopandas.GeoDataFrame也很容易。

import geopandas as gpd

# Read the data.
polygons = gpd.GeoDataFrame.from_file('polygons.shp')
points = gpd.GeoDataFrame.from_file('points.shp')

# Make a copy because I'm going to drop points as I
# assign them to polys, to speed up subsequent search.
pts = points.copy() 

# We're going to keep a list of how many points we find.
pts_in_polys = []

# Loop over polygons with index i.
for i, poly in polygons.iterrows():

    # Keep a list of points in this poly
    pts_in_this_poly = []

    # Now loop over all points with index j.
    for j, pt in pts.iterrows():
        if poly.geometry.contains(pt.geometry):
            # Then it's a hit! Add it to the list,
            # and drop it so we have less hunting.
            pts_in_this_poly.append(pt.geometry)
            pts = pts.drop([j])

    # We could do all sorts, like grab a property of the
    # points, but let's just append the number of them.
    pts_in_polys.append(len(pts_in_this_poly))

# Add the number of points for each poly to the dataframe.
polygons['number of points'] = gpd.GeoSeries(pts_in_polys)

开发人员告诉我,空间连接在“开发版中是新的”,如果你想要探索一下,请点击这里。我的代码主要问题是速度慢。


4
import geopandas as gpd

# Read the data.
polygons = gpd.GeoDataFrame.from_file('polygons.shp')
points = gpd.GeoDataFrame.from_file('points.shp')

# Spatial Joins
pointsInPolygon = gpd.sjoin(points, polygons, how="inner", op='intersects')

# Add a field with 1 as a constant value
pointsInPolygon['const']=1

# Group according to the column by which you want to aggregate data
pointsInPolygon.groupby(['statename']).sum()
 
**The column ['const'] will give you the count number of points in your multipolygons.**

#If you want to see others columns as well, just type something like this : 
pointsInPolygon = pointsInPolygon.groupby('statename').agg({'columnA':'first', 'columnB':'first', 'const':'sum'}).reset_index()
    
    
  [1]: https://geopandas.org/docs/user_guide/mergingdata.html#spatial-joins
  [2]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接