3

I have been trying for 2 days to join points representing addresses (in Paris region) to the closest polygon (parcel of land).

The problems:

  • The parcels of land are contiguous, sometimes a point related to the next parcel could actually be closer to the next parcel's centerpoint/vertice midpoint than to its own
  • There are sometimes several points (addresses) by land parcel
  • Some points are located quite close to the vertice of "their" parcel, sometimes further away (depending also on the street width) so it is difficult to use a buffer strategy (plus the buffers would overlap over each other since land parcels are adjacent)
  • I tried "NNJoin" but it doesn't move forward at all (I have a large database) and I am not sure how to specifiy how many points I want to select
  • I tried "Join attributes by nearest" but some dots are equally distant to the polygon and then all included, which is ok but the distance problem means it sometimes include some dots it shouldn't include
  • I tried a space matrix with vertices extracted from the polygons, but it froze...
  • My guess is that ideally, I should establish a kind of perpendicular projection of the parcels on the street side only, that would stop at the median line of the street. This way I would be sure not to include the points of adjacent parcels or parcels on the other side of the street. But I have no idea if and how to do this... Otherwise, my less ideal solution would be to use "Join attributes by nearest", specify 3 or 4 as maximum possible addresses and a maximum distance of 1 or 2 m, and hope to get the majority of points without too many of the neighbouring points. Not so great as you see...

Below is a screenshot + what I envision with the median line of the streets and the perpendicular projection.

screenshot of problem + possible solution

Now I have tried to use Voronoi (the SAGA one the other ones seem to take a lot of time) around the Pole of Inaccessibility of the land parcels, but the result is a kind of disaster.

enter image description here

I think I am onto something though, @Bruce Xiaolong Liu is already developing a plugin for Voronoi for polygons: Calculating Voronoi Diagrams for polygons I didn't manage to install it, but maybe I can find some workaround to achieve something a bit similar. I first thought about applying Voronoi to extracted vertices from the polygons, then combining each polygon from the same parcel into one larger polygon, but it seems a bit complicated. I will see if I find something else.

Another idea: replacing the polygons with points, then using the simple region growing tool by SAGA. But I am not an advanced user and unsure how to do it.

Taras
  • 32,823
  • 4
  • 66
  • 137
Philippe Morgan
  • 633
  • 4
  • 11
  • I just thought that another solution would be to create large buffers that would "crop" each other at their intersection and thus reach my result in an easier way. I will give it a try, although I am not really sure how to do that either beyond the initial buffer part... – Philippe Morgan Sep 06 '20 at 19:40
  • Basically a tool to "grow" the polygons until they find each other's limits. Not sure if this exists. – Philippe Morgan Sep 06 '20 at 19:52
  • I think I could use something called Thiessen polygons if this applies also to polygons and not just to points. – Philippe Morgan Sep 06 '20 at 20:13
  • This might be worth a look - PostGIS, but essentially the same problem. https://gis.stackexchange.com/questions/338312/find-closest-polygon-from-point-and-get-its-attributes – Tom Brennan Sep 06 '20 at 22:38
  • You can deal with expressions, in geometry there is the expression segments_to_line that decomposes a polygon in its segments, locating the segment to which the point of interest is closer or in front, you can calculate the perpendicular to that line segment. – Luis Perez Sep 07 '20 at 01:49
  • Another option, is to use PyQGis, and for each point, locate the nearest polygon for a tolerance, if you find more than one (for example the point is near a boundary), apply some decision rules. Defined the polygon of interest you can go through its points, evaluate the segment that is in front of the point, and locate it on the line or draw a perpendicular – Luis Perez Sep 07 '20 at 01:50

2 Answers2

3

Not a pure solution, just couple of ideas how this task can be tackled

Idea #1

  1. Geocode each point, i.e. convert address into a x,y-tuple and it as a layer into QGIS. As you said that "points representing addresses (in Paris region)" apparently means for me, that each point has a street and a building number. IMHO each address will be geocoded and perhaps placed inside a parcel or hopefully close to.
    For geocoding in QGIS, see these artciles:

  2. Then migrate address values from new points into polygons

  3. Spatially join attributes from points to polygons via an address field


Idea #2

  1. Convert polygons to lines step_21

  2. Delete intersections, so only the outer edges will remain step_22

  3. Generate points along those lines sections step_23

  4. Spatially join attributes from points to points on edges step_24

    A pitfall: neighbour parcels will have a vertex in common, so the spatial join may not work properly in that case


Idea #3

  1. Create buffers on the outer parcels' borders OR enlarge those polygons on their open edges

    Check for implementation this thread Enlarge a Polygon without changing its shape or position

    step_31

  2. Spatially join attributes from points to extended polygons

Taras
  • 32,823
  • 4
  • 66
  • 137
  • Thank you, unless I misunderstand what you said the first one would not work because most of these points are not located inside the land they refer to, but just in front on the street (go figure) and outside of the land polygons (not touching them). They are already georeferenced. – Philippe Morgan Sep 07 '20 at 08:10
  • The second option might work to some extent, but since land parcels are adjacent it means the vertex of one might also include a dot related to the adjacent parcel, just because it is within the specified radius, and thus be joined with the address of the next building (same street but wrong building number). I really think the "region growing" or "voronoi" (based on polygons, not points) might be the best solution. – Philippe Morgan Sep 07 '20 at 08:10
  • The problem is that dots are roughly placed in front of each polygon, but not always at the same distance and also not always in front of the midpoint of the street facing vertice. So if I use nearest neighbour and my specified distance is too big I will end up "catching" points (addresses) from other pieces of land either adjacent or on the other side of the street. But if my distance is too small I will also miss some address points. – Philippe Morgan Sep 07 '20 at 08:13
  • Not an ideal solution, but since most of the points are within 1 or 2 m of the parcel boundary I can just try to join as many of them as possible like that and check the remaining addresses manually, although it is just a workaround and not an ideal one. – Philippe Morgan Sep 07 '20 at 08:14
  • Just a quick idea: if I could calculate the midpoint of the street facing vertice I could use nearest neighbour with this and at least avoid using corner vertex which will each time also catch address points from adjacent land parcels. – Philippe Morgan Sep 07 '20 at 08:17
  • Thank you it's much clearer now with the links and pictures! I will have a look at both and tell you what/if something worked for me. Thank you again, appreciate it! – Philippe Morgan Sep 07 '20 at 09:32
  • Taras, I tried geocoding with OSM but my file is too big. I am trying your option 2 now which seems like a good idea, especially if I try to join the closest neighbouring land boundary point to each address point. Right now I am trying to delete the inside intersecting lines (overlapping lines), should I use check geometry for this or is there another way? Thank you! – Philippe Morgan Sep 07 '20 at 10:53
  • 1
    How big is your data? For geoecoding you will probably need some GeoPy. To get edges I think it can be separatelly asked, nevertheless I will follow this workflow: (1) Convert original parcels into polylines (2) Dissolve original parcels (3) Convert the result of 2. into polylines (4) Intersection between 1. and 3. – Taras Sep 07 '20 at 11:47
  • I had about 250 000 land parcels so it's pretty big. But in the end I found two successful methods (one related to yours although even simpler but I wouldn't have gotten the idea without you). I'm going to explain them in an answer. – Philippe Morgan Sep 09 '20 at 17:31
0

There are two ways (at least) to solve this (and probably a third one as shown by @Taras) Both times the key point is to see things from the perspective of adresses (points), not parcels (polygons). Because while 1 polygon may have several addresses, addresses are only related to 1 specific polygon (parcel/plot/lot/piece of land).

Method 1 :

Use "Join attributes by nearest" and specify as first input layer the address points, and as second input layer the parcel polygons. Also specify that they can only have 1 nearest neighbour (as one address can only be linked to one parcel, while 1 parcel may have two or three addresses). No need to convert the polygon to polylines and the polylines to points, because while they might be further away or closer, near the vertex or near the midpoint of the parcel boundary, the address A related to parcel A will always be positioned closer to it than to parcel B (unless a mistake has been made when creating the point).

Test + attribute table showing correct match (same letter).

Join attributes by nearest

Method 2

I actually found this method before the first one although the first one is even easier. In this case, you can create a wide even buffer around each address point which will necessarily catch its related land polygon (for instance a 8m radius buffer is more than enough). Then I use "Join attributes by location". Like in method 1, it is critical to choose (unlike the usual choice) the buffered address points as "Base Layer", and the polygon layer as "Join Layer". You can then choose "intersects" and "overlaps" as geometric predicate (still unsure of the difference so I checked both boxes) and then (key point) specify "Take attributes of the feature with largest overlap only (one-to-one) as Join type, because addresses are only related to one piece of land (while parcels can be related to several addresses). Since the polygon which will be closer to an address point will be covered by the largest overlap from this address point buffer, it will be joined with this address.

Voilà !

buffered address points

Philippe Morgan
  • 633
  • 4
  • 11
  • The only issue with method 1 (but it might be an issue in my own dataset) is that I get many "Multiple matching features found at same distance from search feature, found 2 features instead of 1" (2 or more, up to 9 features) even if I only want 1 matching feature. It seems unlikely in reality to have features at exactly the same distance, I will investigate this, maybe there is a tolerance level which can be defined somewhere and is currently too permissive (e.g. 1,5 m being seen as the same as 1.8 m). – Philippe Morgan Sep 09 '20 at 18:12
  • Problem solved: several copies of the same polygon were on top of each other. – Philippe Morgan Sep 09 '20 at 18:26
  • Why do you put comments under yours answer, edit it instead – Taras Sep 09 '20 at 18:38
  • In fact I didn't know if it was related to my method or something related to my dataset so I didn't want to include it in the answer. it turned out I had multiple geometries (polygons here) over one another, so I should probably even delete the comments as it turns out to be unrelated to the issue I was trying to solve :-) – Philippe Morgan Sep 09 '20 at 19:08