3

I have a point layer with the z attribute (and there is a field with the same z value). I have digitised a polygon, snapping to the point layer. How can I transfer the z value from the point layer to each polygon vertex?

Edit

They're a bunch of points surveyed with a total station of the outline of a building, so I have connected the dots to make the actual footprint polygon, but each polygon vertex has a 0 Z attribute, and I want to transfer the Z attribute from each point to each corresponding vertex.

she_weeds
  • 12,488
  • 1
  • 28
  • 58
MerseyViking
  • 14,543
  • 1
  • 41
  • 75

3 Answers3

3

Assuming your polygons are quite simple, you could do it all in one step in Virtual Layer by combining @Gabriel De Luca's multipart-to-singlepart query here and this neat shortcut for rebuilding polygons from points here.

Replace pts_z with your points layer name and poly with your polygon layer name.

WITH RECURSIVE parts AS (
  SELECT t.id, t.total, 1 AS part
  FROM totals AS t
  UNION ALL
  SELECT t.id, t.total, part + 1 AS part
  FROM totals AS t
  INNER JOIN parts AS p ON t.id = p.id AND p.part < t.total
  ),

totals AS (
  SELECT id, num_points(geometry) AS total
  FROM multipoints
  ),

multipoints AS (
  SELECT id, nodes_to_points(geometry) AS geometry
  FROM poly
  ),

polypoints AS (
  SELECT p.id, p.part, geometry_n(m.geometry,p.part) AS geometry
  FROM parts AS p
  INNER JOIN multipoints AS m ON p.id = m.id
),

polypoints_z AS (
  SELECT pp.id, pp.part, st_translate(pp.geometry,0,0,st_z(pz.geometry)) AS geometry, st_z(pz.geometry) AS zval 
  FROM polypoints AS pp
  INNER JOIN pts_z AS pz ON intersects(pp.geometry,pz.geometry)
  ORDER BY id, part
)

SELECT id, st_convexhull(st_collect(geometry)) AS geometry
FROM polypoints_z
GROUP BY id

Step 1 (multipoints): Extract the nodes from the polygon features along with the original polygon id

Step 2 (totals and recursive function parts): Figure out how many nodes each polygon has and generate a series of numbers accordingly per polygon (5 nodes = 1, 2, 3, 4, 5; 3 nodes = 1, 2, 3...)

Step 3 (polypoints): Convert multipoints to single points by iterating over each geometry part using step 2

Step 4 (polypoints_z): Then as @snaileater suggested you perform a spatial join on polypoints and your points layer, joining the points' z value and adding it to the polygon nodes using ST_Translate()

Step 5: Finally, use ST_Collect() to regroup all the points in polypoints_z by the original polygon id, resulting in a multipoint geometry, and use ST_ConvexHull() to create the polygon by 'shrink-wrapping' around that geometry.

Step 5 won't work properly if you have more complex polygons - where you have a point sticking inwards, for example.

I'm sure there is a way to rebuild the polygon using id and part, rather than Convex Hull, but I can't get Make_Line() to work on multipointZs in QGIS Virtual Layer...


Example:

Polygons with id 1 and 2 and point layer with z values shown.

example1

Result from Virtual Layer query - does not recreate polygon accurately for id 2 due to more complex geometry.

example2

However Z-values have been transferred across to polygon vertices if you inspect the geometry (here in DB Manager).

example3

Taras
  • 32,823
  • 4
  • 66
  • 137
she_weeds
  • 12,488
  • 1
  • 28
  • 58
2

Not sure of an easy out of the box way of doing this but I have one idea. You could firstly convert your points (which contain the Z value) to a raster, ensuring you choose a suitable scale. Then use the Drape tool over your newly created building outline to set the Z value for each of the polygons vertices.

AWGIS
  • 3,220
  • 1
  • 21
  • 36
  • 1
    Thanks @AWGIS. I thought about that, but it seems a bit messy. I'll give it a go though and see if it works. Otherwise I see a day of plugin development ahead of me :) – MerseyViking Apr 24 '20 at 08:50
  • @MerseyViking there is definitely a good use case for a tool that achieves this – AWGIS Apr 24 '20 at 12:15
  • @MerseyViking Hi did you managed to do it? I have a same problem – LEI Feb 02 '23 at 15:48
  • @LEI I've moved on to other things since then, but I don't think I ever got a satisfactory way of doing it. IIRC, I just did it manually in the end. – MerseyViking Feb 06 '23 at 12:54
2

Can't you try the following 'vector-only' three steps process :

1) Extract vertices (by any means, u can use Vector geometry/Extract vertices in the Processing toolbox

2) Make a spatial join between these vertices and your point layer, that will enable you to retrieve your z values

3) Rebuild the polygons (that should not be hard with the table generated by the Extract vertices treatment) ...

Tell me if it works ...

Snaileater
  • 5,743
  • 1
  • 15
  • 26