为QGIS 2空间连接创建空间索引(PyQGIS)
我写了一段代码,用于在QGIS 2和2.2中进行简单的空间连接(就是找出那些在某个缓冲区内的点,并获取这个缓冲区的属性)。不过,我想使用QgsSpatialIndex来加快这个过程。接下来我该怎么做呢:
pointProvider = self.pointLayer.dataProvider()
rotateProvider = self.rotateBUFF.dataProvider()
all_point = pointProvider.getFeatures()
point_spIndex = QgsSpatialIndex()
for feat in all_point:
point_spIndex.insertFeature(feat)
all_line = rotateProvider.getFeatures()
line_spIndex = QgsSpatialIndex()
for feat in all_line:
line_spIndex.insertFeature(feat)
rotate_IDX = self.rotateBUFF.fieldNameIndex('bearing')
point_IDX = self.pointLayer.fieldNameIndex('bearing')
self.pointLayer.startEditing()
for rotatefeat in self.rotateBUFF.getFeatures():
for pointfeat in self.pointLayer.getFeatures():
if pointfeat.geometry().intersects(rotatefeat.geometry()) == True:
pointID = pointfeat.id()
bearing = rotatefeat.attributes()[rotate_IDX]
self.pointLayer.changeAttributeValue(pointID, point_IDX, bearing)
self.pointLayer.commitChanges()
1 个回答
1
要进行这种空间连接,你可以使用QgsSpatialIndex中的intersects(QgsRectangle)函数,这个函数可以帮你找到符合条件的特征ID列表,或者使用nearestNeighbor(QgsPoint,n)函数来获取离某个点最近的n个邻居的特征ID列表。
因为你只想要那些在缓冲区内的点,所以intersects函数看起来最合适。我还没有测试过如果用一个退化的边界框(就是一个点)是否可以。如果不行的话,你可以在你的点周围创建一个非常小的边界框。
intersects函数会返回所有与给定矩形相交的特征,所以你需要对这些候选特征进行进一步的测试,以确认它们是否真的相交。
你的外层循环应该是针对这些点的(你想要从它们所在的缓冲区中添加属性值到每个点上)。
# If degenerate rectangles are allowed, delta could be 0,
# if not, choose a suitable, small value
delta = 0.1
# Loop through the points
for point in all_point:
# Create a search rectangle
# Assuming that all_point consist of QgsPoint
searchRectangle = QgsRectangle(point.x() - delta, point.y() - delta, point.x() + delta, point.y() + delta)
# Use the search rectangle to get candidate buffers from the buffer index
candidateIDs = line_index.intesects(searchRectangle)
# Loop through the candidate buffers to find the first one that contains the point
for candidateID in candidateIDs:
candFeature == rotateProvider.getFeatures(QgsFeatureRequest(candidateID)).next()
if candFeature.geometry().contains(point):
# Do something useful with the point - buffer pair
# No need to look further, so break
break