I have a database of fire hydrants (HYD). The positions aren't very exact, the other fields are very useful. I also have a database of GPS'd fire hydrants (GPS). We are manually moving the HYD points to snap to the GPS points, and will then do a join on spatially equal features.

Being manual, this gets tedious, and it can be helpful if a visual indication shows you have actually successfully snapped the HYD to the GPS point. (lets say the HYD point goes from red to yellow, for instance, or changes size/shape, etc)

I've come at this from different angles, but can't seem to find a good way with PostGIS or QGIS to make this visual change happen.

Help? Also, note, we are doing this with approx 40 features types, and some will involve lines touching points. Similar enough concept, though.

  • If the "GPS'd" hydrants are in the "right" locations, why not simply use them instead of the other set? – Paulo Raposo Nov 14 '15 at 4:06
  • Because the HYD points have a bunch of data besides just the geometry that the GPS points should copy over and we can delete the HYD points. – Jim N May 5 '16 at 18:44
  • Apologies, I was taken off this project shortly after posting the question, and forgot about it. I can't say for sure that one of the answers is right, but I upvoted those I thought were along the right lines. The key was having a visual signal that you successfully snapped a given point in the HYD layer, and thereby signal the user that HYD no longer needs attention. – Jim N May 5 '16 at 21:07

To visually identify points at the same location, you might want to look at rendering your layer with Point Displacement.

This screenshot shows a set of postcodes in the UK. Normally the point layer style gives no indication when two or more points are at the same location. With this style on, however, you can see the locations where there are more than one point feature.

example of qgis point displacement

Here, a single point shows as a blue dot. Multiple points at the same location are shown as a red dot at the correct location, and blue dots spread around in concentric rings. You can of course style this to your liking - this is just a quick example using the defaults.

You can experiment with the settings to set the snapping tolerance (how close together two points must be to be merged). This can be done in map units, mm or pixels.

In your case, you're only likely to have two points matching, so you'd end up with two blue points 'orbiting' around a red point when you've snapped them to the same location... like the ones in the top-right of the screenshot.


There may be a much simpler approach if you come at this from a different direction. Instead of manually moving the points - join the attributes. A spatial join is of limited use as your points are not coincident (which is why you are manually moving them).

I assume that your GPS'ed hydrants don't have an id compatible with the original data because, if they do, you'd have already done a standard table join and not be asking this question. So the question is how can you manufacture an id that will allow you to perform the join (and thereby transfer all the attributes to the GPS points)?

  1. Make sure all your GPS points have a unique id of some sort and likewise your hydrants
  2. Use the Distance Matrix tool to find the nearest neighbour between the two layers (Vector->Analysis Tools->Distance Matrix). I recommend you set a limit on number of nearest points perhaps to 1 in the first instance (Use only the nearest (k) target points)
  3. Step 2 will give you a table from which you can select the nearest hydrant. Join the output table to your GPS points. Now you have a reference id of the nearest hydrant in your GPS points data. Use this to join the Hydrant attributes to your GPS points.
  4. Verify that the join is correct by a visual check (labeling the data on screen) and by checking a sample of points. There may be some instance where the nearest hydrant to a GPS point is not the correct one. Only you will know that, but you can edit the join table to correct any anomalies and rejoin.

There might be more ways to achieve your goal. One of them could be using ST_SnapToGrid. Note that this would result in the shift in the data, probably not what you want.

My favourite way to solve this sort of task is as follows:

// select distinct hydrant ids with their counterpart geometry from snap_layer
SELECT DISTINCT ON (id) h.id,  s.wkb_geometry
FROM hydrants h
-- find all the points you want to snap to within the given distance in units of crs
LEFT JOIN snap_layer s ON (ST_DWithin(h.wkb_geometry, s.wkb_geometry, 150))
-- order by distance (see spatal operators, mainly <#>, st_distance might be handy as well, though not that efficient)
ORDER BY id, h.wkb_geometry <-> s.wkb_geometry;

Is this of any help?


If I understand you correctly, you're manually editing the locations of these hydrants, using snapping. If that's the case, a spatial join will find spatially-coincident points, since their coordinate sets will be an exact match; similarly with lines, since the point coordinates should lay perfectly along the line - again, having used snapping.

So, you could perform a spatial join when you're done a batch of editing, between the edited and "GPS'd" points. Manually-adjusted points that are coincident with the "GPS'd" ones will have join attributes that other ones will not. You can use those attributes to differentiate these, and symbolize them differently.

The above could also be done using some specified search radius when you perform the spatial join, if for some reason exact coincidence isn't happening in your data.

The following walks through performing spatial joins using the GUI: http://www.qgistutorials.com/en/docs/performing_spatial_joins.html

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.