I am trying to create python code to iterate through points on 1 layer and find the closest point on another layer (Road Chainages) based on attribute values. I need to limit the search to < 20m maximum distance between both matching attribute values.
I utilised code from Find the closest segment to a point which contains the same attribute and amended to suit point layers but i get stuck at the nearestNeighbor code. I believe i need to try to implement something similar to whats on this website Finding nearest line to point in QGIS? and somehow include the QgsSpatialIndex.nearestNeighbor (QgsPoint point, int neighbors)
I am using QGIS 2.18, but will look to update code to 3+ once i improve my skills.
#Based on
#https://gis.stackexchange.com/questions/250528/find-the-closest-segment-to-a-point-which-contains-the-same-attribute
from qgis.core import *
from PyQt4.QtCore import QVariant
##in development=group
##points=vector point
##point_attribute_to_match=field points
##Chainages=vector point
##Chainage_attribute_to_match=field Chainages
##Chainage_attribute_to_transfer=field Chainages
##tolerance=number 50
#get source and target objects
sources = processing.getObject(points)
linksLayer = processing.getObject(Chainages)
#add new field
sources.startEditing()
newField = QgsField('Chain', QVariant.Int)
sources.addAttribute(newField)
sources.updateFields()
sourceIndex = sources.fieldNameIndex('Chain')
#variables for progress bar
percentMax = sources.featureCount()
p = 1
for s in sources.getFeatures():
#get geometry
if s.geometry():
sGeometry = s.geometry().asPoint()
if sGeometry == [0,0]:
sGeometry = s.geometry().asMultiPoint()[0]
else:
progress.setText("no geometry found")
#get nearest feature and write source attribute out
sDistMin = 1000
sourceId = -1
for c in linksLayer.getFeatures(QgsFeatureRequest().setFilterRect(s.geometry().buffer(tolerance,5).boundingBox())):
# print c.attribute(Chainage_attribute_to_match) - Research why this is failing.
# Tried sDist = c.QgsSpatialIndex.nearestNeighbor(sGeometry,1)
# Tried sDist = c.geometry().nearestNeighbor(sGeometry,1) .
# Tried sDist = c.nearestNeighbor(sGeometry,1)
sDist = p.nearestNeighbor(sGeometry.asPoint(),1)
if sDist < sDistMin and s.attribute(point_attribute_to_match) == c.attribute(Chainage_attribute_to_match):
sDistMin = sDist
sourceId = p.attribute(Chainage_attribute_to_transfer)
progress.setText("Marker")
if sourceId != -1:
sources.changeAttributeValue(s.id(), sourceIndex, sourceId)
sourceId = -1
else:
progress.setText("no matching source found for: " + point_attribute_to_match)
#set progress
progress.setPercentage(p/(float(percentMax))*100)
p += 1
sources.commitChanges()
In my log i get { 'QgsFeature' object has no attribute 'nearestNeighbor' See log for more details }. see below.
2019-01-18T08:47:13 2 Uncaught error while executing algorithm
Traceback (most recent call last):
File "C:/PROGRA~1/QGIS2~1.18/apps/qgis-ltr/./python/plugins\processing\core\GeoAlgorithm.py", line 203, in execute
self.processAlgorithm(progress)
File "C:/PROGRA~1/QGIS2~1.18/apps/qgis-ltr/./python/plugins\processing\script\ScriptAlgorithm.py", line 381, in processAlgorithm
exec((script), ns)
File "<string>", line 50, in <module>
AttributeError: 'QgsFeature' object has no attribute 'nearestNeighbor'
sDist = ...
to match theif sDist ...
line. note that I have not checked your code for anything else!