0

Data set (shapefile) contains polygons. How can I calculate the distance to the nearest five polygons in the data set in QGIS?

3
  • dataset is a shapefile? Sep 2, 2015 at 15:40
  • 1
    how you want to measure the distance? Is it centroid to centroid? Closest vertices? Shortest line between edges?
    – Steven Kay
    Sep 2, 2015 at 15:53
  • shortest line between edges
    – Amy Deane
    Jan 26, 2016 at 18:50

1 Answer 1

1

Here's an example of how you can do this, using postgresql and qgis. It finds the closest 5 polygons to each polygon in the dataset. The screenshot should show how it establishes distances.

N nearest polygons

Note that I'm using British National Grid (27700) - this a local UTM projection in meters, so over these relatively short distances the results will be quite accurate. You'll need to project your data into a similar CRS for your locale. If you're using longer distances - such as between countries or regions - you'll need to use ::geography.

  • imported polygons from OpenStreetMap into PostgreSQL using shp2pgsql. This tool also sets up spatial indexes to speed things up.
  • ran the query below
  • exported to CSV, then imported as delimited layer
  • set CRS of new layer to my local projection (27700)

Query:-

select * from (
    select
        a.gid as from_gid, -- this is an ID created on import
        b.gid as to_gid, 
        a.full_id as from_originalid, -- this was original unique ID in shapefile
        b.full_id as to_originalid,
        st_asewkt(st_shortestline(a.geom,b.geom)), 
        st_distance(a.geom,b.geom) as distance,
        RANK() OVER(PARTITION BY a.gid ORDER BY st_distance(a.geom,b.geom)) as rk
    from
        my_table as a,
        my_table as b
    where 
        st_dwithin(a.geom,b.geom,4000) and a.gid!=b.gid -- must be < 4km
    group by
        a.gid, 
        b.gid
    order by
        a.gid,
        st_distance(a.geom,b.geom) ASC
) as res
where rk<=5 -- how many neighbours you want

Now, I have a table which links each patch to its 5 closest neighbours...

"from_gid","to_gid","from_originalid","to_originalid","?column?","distance","rk"
1,90,"w33458756","w233167579","geometry",0.8228431343271,1
1,91,"w33458756","w233167992","geometry",21.1914264821244,2
1,92,"w33458756","w233168011","geometry",44.5356828699015,3
1,88,"w33458756","w233167212","geometry",86.986670207639,4
1,89,"w33458756","w233167528","geometry",109.008710565124,5
2,140,"w33458843","w307855181","geometry",41.0315108912926,1
2,11,"w33458843","w232374434","geometry",123.281434892635,2
2,10,"w33458843","w232373705","geometry",184.603505248759,3
...etc...

Note that the st_dwithin() is used to speed up the query. This means that if a line is longer than 4km, it's not used. You'll need to tweak that for your dataset.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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