我也想知道是否有可能对所有落点的属性(即总体)求和在多边形中并将该数量连接到多边形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
评论
我认为您应该从这里开始编辑第二个问题,以便使这个问题集中在我认为对您来说更重要的问题上。另一个可以单独研究/询问。