I would like to find a method using Geometry generator to label a point layer with the percentage of points inside another polygons layer.
I'm working on implementing a solution based on the COUNT and OVERLAY_WITHIN functions, but for the moment I can't get the solution. An approach of my failed expression is this:
count(within($geometry,collect_geometries(overlay_within('POLYGON', $geometry))))*100/num_geometries($geometry)
With this result:
The idea I am looking for is as shown in the screenshot: label point layer in the centroid of each polygon with the percentage of points:
Best Answer
From what you say, it seems like you wanted to start from the
points
layer. As you want the number of points within thepolygon
layer, it's easier to place the logic in thepolygon
layer (also allowing you to use the native label positioning features, centroid by default).You can use this formula in the
polygon
layer Label (or as a Virtual Field in thepolygon
Attribute Table)If you want this to automatically apply to any new Point layer, you can update the code to be the following :
with the
point
layer name replaced byarray_to_string( array_filter( @map_layer_ids ,@element!=@layer_id))
which is the only active layer besides the polygon one. If there are other 'static' layers you want to exclude, you can add them to the filter.Swithching to another point layer, without changing the Style in the polygon layer:
If you have static layers that you want to keep active: add them to the layer filter. Set the filter part to:
@element not in (@layer_id, 'any other layer name you need to remove', 'any other layer to remove',...)
`@layer_id' filters the polygon layer, then add a comma separated list of layers you want to keep active.
For instance I added an OtherLayer displayed on the map. Use the @map_layer_ids to identify its
id
and added it to the filter listto_string(round(array_length(overlay_intersects( array_to_string( array_filter( @map_layer_ids ,@element not in (@layer_id,'OtherLayer_a9983d8b_9323_4fac_83de_e8e24e78c8a1'))), $id)) /aggregate( array_to_string( array_filter( @map_layer_ids ,@element not in (@layer_id,'OtherLayer_a9983d8b_9323_4fac_83de_e8e24e78c8a1'))),'count',$id) ,1)*100) || ' %'