3

I have a polygon and a point layer. The polygons contains buildings, the points should be the edges of the buildings. A building is "good" as much as points are touching or in the near (buffer 0.2 meter) of the building. There are no other references between the layers.

enter image description here

I need the number of touching or intersecting points and points within a near of 20cm. With that result I'm able to say, which building have got the best quality...

The result could be written into a virtual field of the building-polygon.

I know, SQL could do the thing easily. But I need a QGIS (aggregate?) way because the input data will be provided as shapefile or GeoJSON.

5
  • 4
    So what's going on in the above example? You've got three red points that are right on the corners of the polygon, two that are close (one in and one out), two that are right outside and one that is right inside. Or is that inside point a label you've generated according to that expression? What answer do you expect given the diagram you've shown?
    – Spacedman
    May 13, 2019 at 8:49
  • on board means QGIS, no python, no SQL. There are no references between the shapes.
    – MartinMap
    May 13, 2019 at 8:55
  • of course! Lets go the virtual layer way!
    – MartinMap
    May 13, 2019 at 8:58
  • 2
    If I get you right you want to count the points that are less than 20cm away from the polygon boundary (for a statement on one of your layers "quality" you should take points inside and outside into account), so shouldn't you buffer 20 cm outside, 20 cm inside and count the points withing the difference of both? Or would it be a better approch to test points within a 20 cm distance around the polygons vertices? May 15, 2019 at 7:11
  • Yes, of course, it would be better to count the points next to the polygon vertices. If a (buffered) point fits completely inside a polygon, it would not be counted by intersect (because it's within).
    – MartinMap
    May 15, 2019 at 7:24

4 Answers 4

8

In QGIS there is a possibility using a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer....

Let's assume there are three features in 'buildings' and 12 in 'point_layer' accordingly, see image below.

Example

With the following query, it is possible to get the number of touching or intersecting points and points within a near of 20cm.

SELECT
    b.*,
    SUM(ST_Touches(b.geometry, p.geometry)) AS touch,
    SUM(PtDistWithin(b.geometry, p.geometry, 20)) AS near
FROM
    point_layer AS p,
    buildings AS b
GROUP BY
    b.id

The output Virtual Layer will maintain initial attributes and geometries and additional fields 'touch' and 'near'.

Result


References:

4
  • 2
    Did I get him wromg or wasn't the challenge NO sql? May 15, 2019 at 6:59
  • I think he wanted to check solutions besides SQL. Perhaps I am wrong.
    – Taras
    May 15, 2019 at 7:03
  • At first I did not think about to use virtual layers. So SQL wasn't a option to me (because I can't use a database). But now, with the use of virtual layers, SQL becomes interesting. Taras solution is working, but it takes a very long time, to calculate (200k points)
    – MartinMap
    May 15, 2019 at 7:29
  • It's nice, but it counts similarly a point on a vertice and a point anywhere on an edge, as shown for instance in this comment.
    – Legisey
    Jun 6, 2019 at 13:38
5

Also an expression example:

aggregate(layer:='point_layer', aggregate:='count', expression:="fid",  filter:=intersects(buffer($geometry, 0.2), geometry(@parent)))
  • 'point_layer' is your points
  • "fid" can be any field (e.g. "id")
5

Thanks to @Kazuhito and @Taras I found a aggregate way to check the intersection with the edges (nodes) of the buildings and the (control-) points, while the points will be buffered with 1m (green):

aggregate( 'point', 'count',"fid",intersects(buffer($geometry,1),nodes_to_points(geometry(@parent))))

enter image description here

As you can see: The building in the center have got 6 nodes (edges) and 7 control points around - 5 of them intersecting the edges of the building within 1m. The other ones are not in the near of an edge.

4

Note that this is more an enhanced comment, but will likely be edited to a qualified answer. I tried drawing a scetch of what is desired, with some resulting questions related to it (cp. my comment above):

enter image description here

For me, the question is what points are taken into account to gain a qualified statement on the "building quality".

  • point A is surely within the 20cm buffer, but for me it does contribute nothing to a statement on the buiding quality (I think only the point "near the vertices" should be taken into account)
  • points B1 and B2 are within the buffer, but should be counted only once, because they mean the same building edge
  • using a buffer with sharp edges, point B1 is inside the buffer but obviuosly more than the buffer distance away from its related building edge, so the result depens on what kind of buffer is generated (buffer with round eged should be preferred).
  • I recommend counting only the points in a 20 cm neighborhood of the buildings vertices, and furthermore only 1 point per neighborhood.

So with all these considerations, the point count lies somewhat between 5 (without A, either B1 or B2) and 7 (all points within buffer).

So if we can get clarified on all this, one could provide a QGIS process/model (or SQL?)

4
  • Great work! Lets take another approach according to your graphic: 1. Extracting the nodes from polygon, 2. make a 20 cm buffer of them, 3. look for intersection with the "control points"
    – MartinMap
    May 15, 2019 at 8:54
  • @MAP, Will you ask it as a new question? Or shall I extend my answer?
    – Taras
    May 15, 2019 at 8:57
  • 2
    @Taras I think you should extend your answer, all agree? May 15, 2019 at 9:01
  • Yes, please extend your answer.
    – MartinMap
    May 15, 2019 at 9:05

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.