1

I want to calculate the nearest distance from each coordinate in a vector layer containing more than 17 000 coordinates to another vector layer. I tried the GRASS v.distance tool but it gives the following error: enter image description here

Is there any other method to do this?

  • Welcome to GIS SE. As a new user, please take the Tour. Please Edit the question to place the error message in the body of the question as ASCII text. This makes it legible on all devices and searchable by future users. – Vince Mar 6 at 18:37
  • And to further clarify: when you say 17,000 coordinate, I guess you mean 17,000 points? Also what kind of features are in the other vector layer? Polygons? How many? – Micha Mar 7 at 12:29
  • Hi Micha, yes i mean more than 17 000 points (18089 in total, actually). The other layer consists of 104612 polygons. – Erika De Keyser Mar 7 at 15:09
1

Here's the GRASS way to get the distance to nearest feature. Note that the concepts of "from" and "to" are reversed compared to what you mentioned in your question. The "to" vector is what gets the distance value added in its attribute table. Also note carefully the dmax parameter. As Gabriel De Luca mentioned, you have a huge number of comparisons, so choosing a maximum distance is critical.

  1. First add a column to the points vector to hold the distance

    v.db.addcolumn map=points column="distance DOUBLE"

  2. Now run v.distance. Choose an appropriate dmax value. Here I set 5000 m. Distance is uploaded to the distance column in the points vector

    v.distance from=polygons to=points upload=dist to_column=distance dmax=5000 output=connectors

  3. The connectors vector will hold the lines that connect each point to the nearest polygon.

1

If you are not interested in knowing which is the polygon id closest to each point, there is undoubtedly a much more simple method: Dissolve them.

Note1: I am always assuming that the geometries of your polygons are valid. This is essential for any operation you want to perform on them. Run the Check Validity tool. Invalid and Error layers must be empty. If not, run the Fix geometries tool against the polygons layer.

Note2: I would prefer to deal with single part polygons, if possible. Run the Multipart to singleparts tool.

Both previous notes apply to my other answer as well.

Now, you can run the Dissolve tool against the Single parts layer. The output is a Dissolved layer with just one multipart feature. The geometry of this feature is very complex. I was dissolved 1500 single part valid geometries without problem. I hope you have no problems with yours.

From now on, all the methods to calculate distances should work just as well. You can try it with the virtual layer approach, or you can try other methods. But the simplest way seems to me to be populate a new field in the points layer, with the expression:

distance( $geometry, geometry( get_feature_by_id( 'Dissolved', 1)))

0

To extract the minimum distance between 18 089 points against 104 612 polygons, must be necessary to compute 1 892 326 468 distances.

That can be reduced considerably if you can determine a distance threshold from each point within which to perform the calculations. If you can, comment it.

Both layers must have the same CRS assigned. Reproject them if necessary.

Test this method with a layer with one point. If it works, test it with 100 points. If you can, test it with a layer with 1 000 points. I am not sure if some limit can be reached with your data.

We will create a virtual layer. If you see that all works fine, perform the query to the original layer and export the virtual output layer to a file. Work with the saved layer instead of the virtual one.

There are probably simpler methods than this, and there are certainly better ones. From this method we do not pretend any more than to see if it is possible.


Assuming that you have a point vector layer named "points", with a column named "id" populated with a unique value for each feature.
Assuming also that you have a polygon vector layer named "polygons", also with a column named "id".

Both layers with the same CRS.

You can Create a Virtual Layer with all the point geometries, their ids, the id of their nearest polygon and the distance between them, with the following query:

WITH all_distances AS (
  SELECT 
    a.id AS point_id, 
    b.id AS polygon_id, 
    ST_Distance( a.geometry, b.geometry) AS distance 
  FROM 
    points AS a
    JOIN
      polygons AS b
), 
just_nearest AS (
  SELECT 
    c.point_id, 
    c.polygon_id, 
    MIN( c.distance) AS min_distance 
  FROM all_distances AS c 
  GROUP BY c.point_id
) 
SELECT 
  p.geometry, 
  d.point_id, 
  d.polygon_id, 
  d.min_distance AS distance
FROM 
  points AS p 
  INNER JOIN 
    just_nearest AS d 
    ON p.id = d.point_id 

With that query we are:

  • Creating a temporary table named "all_distances". With one row for each combination of point id and polygon id, and the shortest distance between them.

  • Creating a temporary table named "just_nearest". With one row for each point id, with its id, the minimum distance calculated in the previous table and its corresponding polygon id.

  • Selecting from the points layer all geometries and creating a virtual layer. With the geometry, the point id, the nearest polygon id and the distance between them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.