Skip to main content
I updated code based on the indentation comment. My error has changed to the nearestNeighor issue
Source Link
Pat
  • 189
  • 1
  • 12
#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 = c.QgsSpatialIndexp.nearestNeighbor(sGeometry.asPoint(),1)
        
       if sDist < sDistMin and s.attribute(point_attribute_to_match) == c.attribute(Chainage_attribute_to_match):
                    sDistMin = sDist
                    sourceId = cp.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 { unexpected indent (, line 58)'QgsFeature' object has no attribute 'nearestNeighbor' See log for more details } which corresponds to the If statement under the Nearest Neighbor i am trying to figure out. see below. I am not sure why its concentrating on that section as the issue.

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 58
       50, in <module>
       if sDist < sDistMin and s.attribute(point_attribute_to_match) == c.attribute(Chainage_attribute_to_match)AttributeError:
           'QgsFeature' object has no attribute ^'nearestNeighbor'
            IndentationError: unexpected indent


#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 = c.QgsSpatialIndex.nearestNeighbor(sGeometry,1)
        
       if sDist < sDistMin and s.attribute(point_attribute_to_match) == c.attribute(Chainage_attribute_to_match):
                    sDistMin = sDist
                    sourceId = c.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 { unexpected indent (, line 58) See log for more details } which corresponds to the If statement under the Nearest Neighbor i am trying to figure out. see below. I am not sure why its concentrating on that section as the issue.

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 58
                if sDist < sDistMin and s.attribute(point_attribute_to_match) == c.attribute(Chainage_attribute_to_match):
                ^
            IndentationError: unexpected indent


#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'
            


Source Link
Pat
  • 189
  • 1
  • 12

Find the closest Point from a Point which contains the same attribute

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 https://gis.stackexchange.com/questions/250528/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 = c.QgsSpatialIndex.nearestNeighbor(sGeometry,1)
        
       if sDist < sDistMin and s.attribute(point_attribute_to_match) == c.attribute(Chainage_attribute_to_match):
                    sDistMin = sDist
                    sourceId = c.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 { unexpected indent (, line 58) See log for more details } which corresponds to the If statement under the Nearest Neighbor i am trying to figure out. see below. I am not sure why its concentrating on that section as the issue.

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 58
                if sDist < sDistMin and s.attribute(point_attribute_to_match) == c.attribute(Chainage_attribute_to_match):
                ^
            IndentationError: unexpected indent