Thought it might be useful to others if I post the code that worked for me. The code posted above worked well - thanks.
In the end I decided to just find the nearest feature in two layers (in this case a layer of Parish Boundaries and another of Path Numbers). This meant a result was always returned, even if the user clicked outside the boundary.
If neither of the layers are open, it opens them up invisibly (using a style qml) then closes them down once the attribute is gained.
There is probably a neater way of doing this, but here it is:
def canvasReleaseEvent(self, event):
fx = event.pos().x()
fy = event.pos().y()
location = self.canvas.getCoordinateTransform().toMapCoordinates(fx, fy)
boundbox = QgsRectangle(4999.99,4999.69,660000.06,1225000.12)
combined = str(location)
EastingString = str(combined[1:7])
NorthingString = str(combined[8:14])
Easting = int(EastingString)
Northing = int(NorthingString)
shortestDistance = float("inf")
closestFeatureId = -1
parish_layer = None
path_layer = None
parish_close = False
path_close = False
#Checks if the Parish Layer is Open and assigns it to parish_layer
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
if "C:/MapData/QGIS/Base Maps/Other Layers/Parish Boundaries.shp" in layer.source():
parish_layer = layer
break
#If the Parish Layer is not open then it trys to open it up and assigns it to parish_layer
if str(parish_layer) == "None":
layer = QgsVectorLayer("C:/MapData/QGIS/Base Maps/Other Layers/Parish Boundaries.shp", "Parish Boundaries", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(layer)
layer.loadNamedStyle('C:/MapData/QGIS/Base Maps/Other Layers/blankparish.qml')
layer.triggerRepaint()
parish_close = True
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
if "C:/MapData/QGIS/Base Maps/Other Layers/Parish Boundaries.shp" in layer.source():
parish_layer = layer
break
#Check that the layer is open and then take the point value
if str(parish_layer) != "None":
pPnt = QgsGeometry.fromPoint(QgsPoint(Easting, Northing))
for f in parish_layer.getFeatures():
pathdist = f.geometry().distance(QgsGeometry(pPnt))
if pathdist < shortestDistance:
shortestDistance = pathdist
closestFeatureId = f.id()
testlength = str(closestFeatureId)
#Grab the first attribute as thats the Parish Name. Remove the letters CP from the end if they are present
if len(testlength) > 0:
fid = closestFeatureId
iterator = parish_layer.getFeatures(QgsFeatureRequest().setFilterFid(fid))
featuree = next(iterator)
attrs = featuree.attributes()
parishName = (attrs[0])
lastTwo = parishName[-2:]
if lastTwo == "CP":
parishName = parishName[:-3]
else:
parishName = None
if parish_close == True:
QgsMapLayerRegistry.instance().removeMapLayer(parish_layer)
#Repeat the process above for the path layer
shortestDistance = float("inf")
closestFeatureId = -1
layer = None
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
if "C:/MapData/QGIS/Rights of Way/PROW.shp" in layer.source():
path_layer = layer
break
#If the Path Layer is not open then it trys to open it up and assigns it to path_layer
if str(path_layer) == "None":
layer = QgsVectorLayer("C:/MapData/QGIS/Rights of Way/PROW.shp", "PROW", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(layer)
layer.loadNamedStyle('C:/MapData/QGIS/Base Maps/Rights of Way/blankpath.qml')
layer.triggerRepaint()
path_close = True
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
if "C:/MapData/QGIS/Rights of Way/PROW.shp" in layer.source():
path_layer = layer
break
#Check that the layer is open and then take the point value
if str(path_layer) != "None":
pPnt = QgsGeometry.fromPoint(QgsPoint(Easting, Northing))
for f in path_layer.getFeatures():
pathdist = f.geometry().distance(QgsGeometry(pPnt))
if pathdist < shortestDistance:
shortestDistance = pathdist
closestFeatureId = f.id()
testlength = str(closestFeatureId)
if len(testlength) > 0:
fid = closestFeatureId
iterator = path_layer.getFeatures(QgsFeatureRequest().setFilterFid(fid))
featuree = next(iterator)
attrs = featuree.attributes()
pathName = (attrs[0])
else:
pathName = None
if path_close == True:
QgsMapLayerRegistry.instance().removeMapLayer(path_layer)
#As a test, just display the info in a message box
if boundbox.contains(location):
QMessageBox.information(None, "Ticket Info", "Parish: " + str(parishName) + " Path: " + str(pathName) + " Easting: " + str(Easting) + " Northing: " + str(Northing))
else:
QMessageBox.information(None, "Fault Can't Be Placed", "Point out of bounds")