27

I have two layers, a line and a point layer.

I need to make a line layer which connects all the points to the nearest line feature. How can I do that?

Is there a plugin available for QGIS? This is a very important tool which is missing in QGIS.

ArcView has this tool: "Nearest Features"

Taras
  • 32,823
  • 4
  • 66
  • 137
Frodo
  • 2,407
  • 1
  • 18
  • 36
  • I dont remember there is a plugin for this (but i might be wrong), but it is easily solvable with a SQL query or a few python lines of code (and preferably a spatial index!). – mgc Feb 21 '16 at 19:09
  • I dont know to write a python code, I am beginner – Frodo Feb 21 '16 at 19:24
  • Look at this questions, maybe it will help you: [1]: http://gis.stackexchange.com/questions/59169/how-to-draw-perpendicular-lines-in-qgis, [2]: http://gis.stackexchange.com/questions/73584/shortest-distance-from-point-to-line-big-dataset, [3]: http://gis.stackexchange.com/questions/107227/calculate-distance-between-point-and-linestring-and-how-to-represent-that-on-qgi/107230 – Artec Feb 21 '16 at 19:42
  • I've already looked at these posts, the first is ok, but how to make a module with this code. Where do I put this code? – Frodo Feb 21 '16 at 20:01

5 Answers5

29

As an alternative, you could:

  1. Use the Convert Lines to Points tool from:

    Processing Toolbox > SAGA > Shapes - Points > Convert Lines to Points

    (Add points over small distances. E.g. add a point every 1m if the overall line is 100m)

    Convert lines to points

  2. Use the Distance to nearest hub from:

    Processing Toolbox > QGIS geoalgorithms > Vector analysis tools > Distance to nearest hub

    (Set the parameters, using the output layer of the Convert Lines to Points tool as the Destination hubs layer and setting the Output shape type as Line to hub)

    Distance to nearest hub

  3. Final result should be a line layer which connects the original points layer with the original line layer (with line-converted points):

    Final result with points

    (without line-converted points):

    Final result without points

I used QGIS 2.12.3-Lyon.

Joseph
  • 75,746
  • 7
  • 171
  • 282
  • There is now a tool called "Points along geometry" in the Vector geometry menu in QGIS which does the same as the SAGA tool. – Jens Jul 06 '20 at 09:24
11

In QGIS I can suggest using a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer....

Let's assume we have two layers 'points' and 'river' with their corresponding attribute tables, see image below.

input

With the following query, it is possible to create new lines that will represent the connection between points to the nearest line features.

SELECT
    ST_ShortestLine(r.geometry, p.geometry),
    p.id AS pid,
    r.id AS rid,
    ROUND(ST_Length(ST_ShortestLine(r.geometry, p.geometry)), 6) AS distance
FROM
    points AS p, river AS r
WHERE
    distance < 0.5
GROUP BY
    p.id
ORDER BY
    MIN(distance)

Note:

  • WHERE distance < 0.5 specifies the longest acceptable distance between point to the line feature

The output Virtual Layer with its Attribute table will look as following

output

Taras
  • 32,823
  • 4
  • 66
  • 137
  • Note - This is a PostGIS query... – Erich Purpur Jul 16 '21 at 13:57
  • 1
    Exactly what I'm looking. however, QGIS freezes, and no layer is added after it is working again. I have a point layer with about 22.000 points. Is this probably too big? For both files I created a spatial index and for the adding I used the provider OGR data provider. Is this correct so far? I'm not sure, if I actually have Postgre with PostGIS configured. Could this be the problem? – i.i.k. Apr 03 '23 at 12:37
5

Meanwhile (since QGIS 3.16), there is the new overlay_nearest() function you can use for that with QGIS expressions. For each point, 1) get the nearest line with overlay_nearest(), 2) get the closest point on this line to the point using closest_point().

The expression to be used with Geometry generator or Geometry by expression (see here for details) look like:

make_line (
    $geometry,
    closest_point (
        overlay_nearest ('line', $geometry)[0],
        $geometry
    )
)
  • Replace line in line 4 with the name of your line layer.

Dotted lines to connect points to nearest lines are created with the above expression:

enter image description here

Taras
  • 32,823
  • 4
  • 66
  • 137
Babel
  • 71,072
  • 14
  • 78
  • 208
  • Is there a way to get the actual distances added to the point geometries as a new attribute? – i.i.k. Apr 03 '23 at 11:44
  • 1
    Yes. Add length() funtion to it and enclose the expression above: length ( make_line [...] )` – Babel Apr 03 '23 at 11:54
  • 1
    However, be aware of the CRS you use to get meaningful values. E.g. don't use any mercator projections - or reproject your results using transform() function. See here, solution 3 for details: https://gis.stackexchange.com/a/438809/88814 – Babel Apr 03 '23 at 11:56
  • 1
    Hi @Babel, I did try to enclose my code in the length function, however, then it doesn't work anymore, meaning, it doesn't even create the line anymore. – i.i.k. Apr 03 '23 at 13:07
  • My code is:
    make_line (
    $geometry,
    closest_point (overlay_nearest ('clipped_mainstreets', $geometry)[0],$geometry))
    )```
    
    – i.i.k. Apr 03 '23 at 13:09
  • Oh, and my CRS is a projected EPSG:25832 – i.i.k. Apr 03 '23 at 13:15
  • I just thought, maybe it is a problem that one of my attributes has already the name 'length' (comes from OSM). – i.i.k. Apr 03 '23 at 13:17
  • i checked it out, by renaming the 'length' attribute to 'length_osm' but this did not change anything in the result. – i.i.k. Apr 03 '23 at 13:25
  • If you add length, of course there will no line be created. length calculates a measurement value, not a geometry (line - for this use the solution above). If you use the expression to create a new attribute with field calclulator, it should work. If not, please add this as a new question as here in the comments, it is not the right place. Add as many information as you have and what doesn't work - you might link to this question for context – Babel Apr 03 '23 at 14:01
2

The ClosestPoint does what you are looking for, currently limited to selected features only. You can take a look at the code and modify it for your needs

miln40
  • 1,111
  • 12
  • 20
-2

If you find the point over the line, the shortest point, with the coordinate 3D (X,Y,Z) you need an algorithm to calc the position over the shortest line. You can using this tool https://github.com/rafaelduartenom/findpointonline. You need postgres to execute this tool and shapefiles.