9

I have two layers: a point layer defining properties (95 objects), and a polygon layer defining plots of land associated with the properties (211 objects). Each point relates to one or more polygons. What I would like to produce is a table of distances of each point to ALL of the polygons associated with that point (nearest edge or centroid of polygon -- either will do). Calculating the nearest distance is relatively easy in QGIS and ArcGIS, but those calculations omit all distant polygons, at least by the methods I have been employing. Ideally I would like an output of

Point_ID | distance to polygon 1 | distance to polygon 2 | distance to polygon 3 | etc.

Any pointers in ArcGIS 10 or QGIS 2.2+ would be most helpful.

closed as too broad by PolyGeo Dec 12 '16 at 12:14

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • This can be done with near analysis in ArcGIS, but to do it for each point will require a little automation. Are you familiar with python scripting? – Emil Brundage Dec 15 '14 at 17:00
  • Emil - No, I'm not familiar with Python, but maybe I should learn. – NickN Dec 17 '14 at 9:06
1

You can use the Distance Matrix in QGIS to achieve this. You would first need to convert your polygons into centroid points by either Vector > Geometry Tools > Polygon centroids or via the SAGA version of polygon centroids. Reason for this is the Distance Matrix function can only analyse between 2 point layers. Also, the output would be like this:

Point_1 | PolygonCentroid_1 | Distance
Point_1 | PolygonCentroid_2 | Distance
Point_1 | PolygonCentroid_3 | Distance
Point_2 | PolygonCentroid_1 | Distance
Point_2 | PolygonCentroid_2 | Distance

The output would be a .csv file so you could manually edit the layout using another software such as Microsoft Excel.

  • Thanks Joseph -- For a newcomer to GIS like me, this is the simplest way of getting the answers I wanted. – NickN Jan 30 '15 at 9:06
  • Most welcome mate! This procedure (and the results) are basic but when you become more familiar with GIS software, you can try using more advanced procedures which are described in the other answers. – Joseph Jan 30 '15 at 10:24
  • 1
    @nickN Just a very minor note to this method, centroids don't always fall within a polygon depending on its shape. It's possible you could get some incorrect distances/rankings, but it depends on your data and requirements as to whether it would be an issue. Otherwise this is essentially the QGIS version of ArcGIS's GNT, except the latter can handle more than points and I'm not sure how QGIS handles the names/IDs in the result. – Chris W Jan 30 '15 at 21:08
5

This is fairly simple to achieve using QGIS (I think any version will do) and a very simple SQL statement in DB manager. But for that your that must be in some kind of spatial database (Postgis or spatialite). Since it's more accessible to most people, I will assume using spatialite, but the SQL statements are the same for Postgis.

  1. Create a new Spatialite database;
  2. Import your point and polygons layers into the new database;
  3. Open DB manager plugin, select the database and run one of the following SQL statements:

Distance from all points to all polygons boundaries

SELECT 
  f.point_id,
  g.polygon_id,
  st_distance(g.geom, f.geom) AS distance
FROM
  points_table AS f, 
  polygons_table AS g

Distance to all points to related polygons boundaries (assuming that a common field exists)

SELECT 
  f.point_id,
  g.polygon_id,
  st_distance(g.geom, f.geom) AS distance
FROM
  points_table AS f JOIN 
  polygons_table AS g ON (g.common_field = f.common_field)

Distance to all points to related polygons centroids:

SELECT 
  f.point_id,
  g.polygon_id,
  st_distance(f.geom, st_centroid(g.geom)) AS distance
FROM
  points_table AS f JOIN 
  polygons_table AS g ON (g.common_field = f.common_field)

Notice that you can add any field from your layers to the result:

SELECT 
  f.point_id,
  f.point_number,
  g.polygon_id,
  g.parcel_name,
  st_distance(f.geom, st_centroid(g.geom)) AS distance
FROM
  points_table AS f JOIN 
  polygons_table AS g ON (g.common_field = f.common_field)

Or even all fields:

SELECT 
  f.*,
  g.*,
  st_distance(f.geom, st_centroid(g.geom)) AS distance
FROM
  points_table AS f JOIN 
  polygons_table AS g ON (g.common_field = f.common_field)
  • If you need more input about how to create the spatialite database and import the layer, let me know and I will edit the answer. – Alexandre Neto Dec 19 '14 at 1:17
  • Hi Alexandre, why join and not a simple WHERE? – Luigi Pirelli Dec 19 '14 at 8:52
  • Well, It's something I caught from one of Paul Ramsey's presentations. Can't remember the reason why he advocate the explicit use of Join, but if he says it... :-P I will try to run EXPLAIN over both queries to see if there is any difference. – Alexandre Neto Dec 23 '14 at 15:07
  • I'm new to SpatialLite - this answer seems to address a problem I'm working on. My table is blank. Perhaps I'm not understanding this. I have a polygon layer called "Pothole VRI" and another point layer called "Grid Pothole Center". I add the following code using your instructions as above: SELECT f.id, g.id, st_distance(f.geom, st_centroid(g.geom)) AS distance FROM 'Grid Pothole Center' AS f, 'Pothole VRI' AS g __ I get an empty table x with these headings: id, id:1, distance What have I done wrong here? Using QGIS 3.6 – Mark Thompson May 24 at 22:06
4

The Generate Near Table tool in ArcGIS will do what you want, but it requires an Advanced license and will do it for all points/polygons - not just those associated with each other. This means for each of your 95 objects you will get the ranked distance for all 211 properties, so 20,045 rows in the table. You'd either have to filter the resulting table or as Emil suggests automate the task to create selections based on the association and only run it on those groups.

As far as filtering, yes, a join (followed by a definition query or selection) is all you'd need. The tool result gives you IN_FID and NEAR_FID. Depending on how you run the tool (properties near point, or point near property) determine which FID is which. You'd then join your point and property tables (both) to the tool result based on the appropriate FID.

This assumes each of your 211 property records has an attribute that says which of the 95 points they belong to, because the next step is to select (or definition query) all records in the joined table(s) where two fields of one record should match - point name field = property associated point name field. The cases where they don't match are polygons that aren't associated with that point, so you don't care about their distance from that point.

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