我试图做一个空间连接,就像这里的例子:是否有一个python选项来“按位置连接属性”?但是,这种方法似乎效率低下/缓慢。即使仅以250点的分数运行它,也要花费近2分钟的时间,而对于> 1,000点的shapefile,它完全会失败。有没有更好的方法?我想完全在Python中完成此操作,而无需使用ArcGIS,QGIS等。

我也想知道是否有可能对所有落点的属性(即总体)求和在多边形中并将该数量连接到多边形shapefile。

这是我要转换的代码。我在第9行收到错误消息:

poly['properties']['score'] += point['properties']['score']

它说:


TypeError:+不支持的操作数类型=:“ NoneType”和“ float”。


如果我将“ + =”替换为“ =”,它可以正常运行,但不会对字段求和。我也尝试过将它们设置为整数,但也会失败。

with fiona.open(poly_shp, 'r') as n: 
  with fiona.open(point_shp,'r') as s:
    outSchema = {'geometry': 'Polygon','properties':{'region':'str','score':'float'}}
    with fiona.open (out_shp, 'w', 'ESRI Shapefile', outSchema, crs) as output:
        for point in s:
            for poly in n:
                if shape(point['geometry']).within(shape(poly['geometry'])):  
                    poly['properties']['score']) += point['properties']['score'])
                    output.write({
                        'properties':{
                            'region':poly['properties']['NAME'],
                            'score':poly['properties']['score']},
                        'geometry':poly['geometry']})


评论

我认为您应该从这里开始编辑第二个问题,以便使这个问题集中在我认为对您来说更重要的问题上。另一个可以单独研究/询问。

#1 楼

Fiona返回Python字典,您不能将 poly['properties']['score']) += point['properties']['score'])与字典一起使用。
使用Mike T给出的引用对属性求和的示例:带有或不带有空间索引的方法:


不带
通过点迭代
对于i,在枚举中的pt(点):
point = shape (pt ['geometry'])
对多边形进行迭代
对于j,poly枚举(多边形):
if point.within(shape(poly ['geometry']))):
#属性值的总和
多边形[j] ['properties'] ['score'] =多边形[j] ['properties'] ['score'] +点[i] ['properties '] ['score']

具有R-tree索引(可以使用pyrtree或rtree)
创建R-tree索引并将功能存储在其中(边界框)
来自rtree导入索引
idx = index.Index()
用于pos,枚举(多边形)中的多边形:
idx.insert(pos,shape(poly [ 'geometry'])。bounds)
通过点迭代
用于枚举的i,pt(点s):
point = shape(pt ['geometry'])
通过空间索引进行迭代
idx.intersection(point.coords [0])中的j进行迭代:
if point.within(shape(polygons [j] ['geometry']))):
polygons [j] ['properties'] ['score'] =多边形[j] ['properties'] ['score' ] + points [i] ['properties'] ['score']


两种解决方案的结果:
# read the shapefiles 
import fiona
from shapely.geometry import shape
polygons = [pol for pol in fiona.open('poly.shp')]
points = [pt for pt in fiona.open('point.shp')]
# attributes of the polygons
for poly in polygons:
   print poly['properties'] 
OrderedDict([(u'score', 0)])
OrderedDict([(u'score', 0)])
OrderedDict([(u'score', 0)])

# attributes of the points
for pt in points:
    print i['properties']
 OrderedDict([(u'score', 1)]) 
 .... # (same for the 8 points)

有什么区别?

没有索引,您必须遍历所有几何(多边形和点)。
使用边界空间索引(空间索引RTree),仅遍历有可能相交的几何使用您当前的几何形状(“过滤器”可以节省大量计算和时间...)
,但空间索引并不是魔杖。当必须检索数据集的很大一部分时,空间索引不能提供任何速度优势。

之后:使用OGR进行索引,Shapely,Fiona

#2 楼

另外-geopandas现在可以选择将rtree作为依赖项,请参见github repo

因此,除了遵循上面所有(非常好的)代码之外,您还可以执行以下操作: />
import geopandas
from geopandas.tools import sjoin
point = geopandas.GeoDataFrame.from_file('point.shp') # or geojson etc
poly = geopandas.GeoDataFrame.from_file('poly.shp')
pointInPolys = sjoin(point, poly, how='left')
pointSumByPoly = pointInPolys.groupby('PolyGroupByField')['fields', 'in', 'grouped', 'output'].agg(['sum'])


要获得此时髦的功能,请务必先安装C库libspatialindex

编辑:更正的程序包导入

评论


我的印象是rtree是可选的。这是否意味着您需要安装rtree以及libspatialindex C库?

– Kuanb
17年2月10日在1:54

已经有一段时间了,但是我想当我从github安装geopandas时,当我第一次安装libspatialindex时会自动添加rtree……自从他们做了相当重要的发行以来,所以我确定情况已经有所改变

– claytonrsh
17-2-27在15:16

我刚刚从pypa安装了geopandas,并且需要安装rtree才能正常工作。看到这个答案:stackoverflow.com/a/60014884/868724

–aboutaaron
20 Mar 10 '20 at 18:01

#3 楼

使用Rtree作为索引来执行更快的联接,然后使用Shapely进行空间谓词以确定点是否确实在多边形内。如果做得正确,这可能比大多数其他GIS更快。

在此处或此处查看示例。

关于“ SUM”的问题的第二部分,请使用dict对象以多边形ID为键来累积人口。虽然,使用PostGIS可以更好地完成这种事情。

评论


谢谢@Mike T ...使用dict对象或PostGIS是很好的建议。但是,我仍然对在哪里可以将Rtree合并到我的代码中感到有些困惑(包括上面的代码)。

– jburrfischer
2014年6月24日在2:45



#4 楼

此网页显示了如何在Shapely的空间查询更昂贵之前使用边界框多边形内搜索。

http://rexdouglass.com/fast-spatial-joins-in- python-with-a-spatial-index /

评论


感谢@klewis ...您是否有机会为第二部分提供帮助?为了对落在多边形内的点属性(例如总体)求和,我尝试了类似于以下代码的操作,但是它引发了错误。如果shape(school ['geometry'])。within(shape(neighborhood ['geometry'])):inside ['properties'] ['population'] + = school ['properties'] ['population']

– jburrfischer
2014年6月23日20:10

如果以“ r”模式打开邻居,则该邻居可能是只读的。两个shapefile是否都具有字段填充?哪条线抛出错误?祝好运。

– klewis
2014年6月23日在23:22

再次感谢您@klewis ...我已经在上面添加了代码并解释了错误。另外,我一直在玩rtree,我对将其添加到上面的代码中仍然感到困惑。对不起,真麻烦。

– jburrfischer
14年6月24日在2:35

尝试此操作,似乎将None添加到int会导致错误。 poly_score = poly ['properties'] ['score'])point_score = point ['properties'] ['score'])if point_score:if poly_score poly ['properties'] ['score'])+ = point_score else: poly ['properties'] ['score'])= point_score

– klewis
2014年6月24日13:25