1

Is there a way in QGIS to either put in coordinates or select a point using the needle, and then finding the closest features to that point?

I have tried in DB Manager and it works where I can return the closest points from a set of coordinates. However I would like to do it through the QGIS interface so I can actually see which points are closest on the map.

I have not been able to find anything so far about it. I was thinking there might be a way in PyQGIS however I am still very new to that so it is difficult to start out there.

Al110
  • 35
  • 3
  • Which tool is the needle? – BERA Sep 22 '21 at 07:07
  • I can't remember the specific name for it, but when you for example use the Service Area(from point) tool you can select a start point anywhere on the map using it. – Al110 Sep 22 '21 at 07:13
  • 1
    There was a blogpost from lutraconsulting about how to write such a plugin but it's still written for QGIS2: https://www.lutraconsulting.co.uk/blog/2014/10/17/getting-started-writing-qgis-python-plugins/ . ( https://github.com/brylie/qgis-closest-feature ) So you could port this plugin to QGIS3 for example. – Thomas B Sep 22 '21 at 07:53
  • Thank you! Do you have any good resources on how exactly to port a plug-in? I don't have that much experience with it and I am not following the instructions I have found online very well so far :/ – Al110 Sep 22 '21 at 08:59
  • you can use qgis2to3 from opengis.ch. great tool. just upgraded the plugin with qgis2to3. just two lines had to be changed manually after this. working proof of concept plugin for qgis3 you can find here: https://github.com/thbaumann/qgis_closest_feature. Could be used to merge the nicer code from MrXsquared's answer (including transform and indexing) into a plugin... – Thomas B Sep 22 '21 at 13:04

1 Answers1

2

You can adapt these two answers:

and build a PyQGIS tool such as:

def display_point(pointTool): 
    #print ('({:.4f}, {:.4f})'.format(pointTool[0], pointTool[1]))
    point = QgsPointXY(pointTool) # convert QgsPoint to QgsPointXY
    reprojectedpoint = tr.transform(point) # Reproject the clicked point from canvas CRS to layers CRS
    nearestneighbors = spatial_idx.nearestNeighbor(reprojectedpoint, neighbors=1) # build a list of the nearest 1 neigbors
    layer.selectByIds(nearestneighbors) # select the x nearest neighbors

canvas = iface.mapCanvas() # a reference to our map canvas layer = iface.activeLayer() # get layer to select features from sourceCrs = QgsCoordinateReferenceSystem(canvas.mapSettings().destinationCrs().authid()) # get CRS of map canvas destCrs = QgsCoordinateReferenceSystem(layer.crs()) # get CRS of layer tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance()) # setup reprojection spatial_idx = QgsSpatialIndex(layer.getFeatures()) # build a spatial index for the layer

this QGIS tool emits as QgsPoint after each click on the map canvas

pointTool = QgsMapToolEmitPoint(canvas) pointTool.canvasClicked.connect(display_point) canvas.setMapTool(pointTool)

which selects the nearest point of the clicked point on canvas in the currently selected layer:

enter image description here

MrXsquared
  • 34,292
  • 21
  • 67
  • 117