The main problem I see there is that the collect()
function creates a part for each original feature, that is: it returns a 7-parts feature for the collection of plots (parcelas) 19 to 25.
The trick of making a buffer generates a false union of the parts: unites them in an attempt to generate valid geometries, because a feature with parts that partially overlap implies an invalid geometry. I don't think we can trust that after the buffer the geometries will always be merged and valid.
In addition, there are still parts for groups that do not overlap. Which brought you here.
I don't know how to cast single-part geometries dynamically from an expression.
So my proposal is that you create a virtual layer with the single-part geometries, all valid and merged. And that you use that layer to label the sides of the groups.
Since the problem of dumping geometries in a virtual layer is not completely solved I will focus on that problem, seeing that you have already solved how to label it.
You should create a virtual layer with the following SQL query:
WITH RECURSIVE parts AS (
SELECT t.fid, t.total, 1 AS part
FROM totals AS t
UNION ALL
SELECT t.fid, t.total, part + 1 AS part
FROM totals AS t
INNER JOIN parts AS p ON t.fid = p.fid AND p.part < t.total
),
totals AS (
SELECT fid, NumGeometries( geom) AS total
FROM merged
),
merged AS (
SELECT fid , MZNA, REGLABEL, ST_Buffer(ST_Union(ST_Buffer(geometry, 0.1)), -0.1) AS geom
FROM plots
GROUP BY MZNA, REGLABEL
)
--SELECT * from merged;
--SELECT * from totals;
--SELECT * from parts;
-- to debug, comment on the following lines and uncomment the previous SELECT clause of your interest.
SELECT p.fid, m.MZNA, m.REGLABEL, p.part, GeometryN( m.geom, p.part) as geom
FROM parts AS p
INNER JOIN merged AS m ON p.fid = m.fid;
I am assuming that the source layer is called plots and that all its features have a unique fid value.
The virtual layer has been saved in the project, it is not a separate file. It has the advantage that any modification in the original layer should be immediately reflected in the virtual layer, each time those changes are saved and the canvas re-freshed / re-rendered.
About the query:
I came to it as a first solution to the problem of dumping geometries in the environment of a virtual layer, of which I did not find a previous solution. (It can surely be improved.)
The merged Common Table Expression (CTE) performs the union of the original geometries, grouped by the values of the MZNA and REGLABEL fields. A buffer and anti-buffer is performed as a precision threshold of the digitization of the plots. This table returns fields of interest and (multi-parts if distant) merged geometries.
The totals CTE just returns the fid and total (number of parts) fields.
The parts RECURSIVE CTE performs an iterative addition for each fid of multiple rows, starting with part 1 until part is equal to total.
Finally, for each row of the parts CTE, we select the fields from merged and each part of any geometry, following the parts rows. The part value is returned just to debugging purposes.
collect
is one of the aggregate functions. There's no "dis-aggregate" category of functions. There are the@geometry_part_num
and@geometry_part_count
variables, but I'm not sure how to use them for that.