4

Using QGIS, I have polygons with data for multiple individuals. The individuals do not have x,y location data; they are simply located somewhere within the polygon, and the exact location is not important. Using the symbology, I set it to turn each individual into a centroid. However, the centroids for each individual are now stacked upon each other, so that only one is visible. I want to use the points displacement function to put space between each centroid so that each individual is visible. But I have found no instructions on how to convert markers of a polygon layer into a points layer. I have found instructions for turning points into a polygon layer, but not the opposite. I need to convert centroid markers of a polygon layer into a points layer. (Or, theoretically, find a different symbology besides centroids that will create a distinct marker for each individual within the polygon.)

4 Answers 4

4

Are you looking for something like Vector > Geometry Tools > Centroid to generate centroids from polygons that you can then run the points displacement tool on?

Alternatively if you want a dynamic points symbology layer linked to your source layer perhaps write a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer... with a query like:

SELECT
    unique_id_column,
    centroid(geometry) AS geometry
FROM
    polygon_layer

This will then generate an actual points layer - that still updates if you make changes to your source layer - and you can use the native Points Displacement symbology (which is not available for generated points a la centroid fill or geometry generator).

See example below where 1, 2, and 4 are separate polygons with the same geometry but different "ID"s. I have generated centroids using a virtual layer and used the id as a label and used the point displacement symbology to automatically offset the centroids from each other.

enter image description here

4

Use the tool "Geometry by expression" with the following settings:

enter image description here

4

I see that you are asking for how to make a point layer from centroids - but as far as I understand your question, you are just going to use the point layer for display purposes, then I would prefer to get what I want out of the existing layers rather than making a new one.

You can use the centroid fill using simple markers and in the "simple marker" part of the Symbol selector, you can rotate and / or make an offset so that the symbols are distinguashable. You may also even a lookuptable with one entry per individ and x and y offsets and rotation for that individ, join that table to your data table and set those parts as calculated fields (the drop down icon on the right) for each individ (or use any other information on that individ to calculate individual placements and / or rotations of the symbols)

Another possibility is to set the symbol layer type as "Geometry generator" and geometry type to Point / multipoint. If you type in centroid($geometry), you'll get the centroid, that can be used to define a new point:

make_point(x(centroid($geometry))+200,y(centroid($geometry)-200),0)

Will make a point that is 200 map units east and 200 units south of the centroid. You may type in one formula for each individ, or again, make a look up table, if that is linked in so that you have the points ind_dx and ind_dy, the formula would be:

make_point(x(centroid($geometry))+"ind_dx",y(centroid($geometry)+"ind_dy"),0)

Depending on how you make the map, you can define dx and dy to be either in (real world) map units or some unit defined on the map you are making.

3

Basic idea

There is a way to imitate the point displacement symbology with geometry generator, based on polygons. You can use the centroid, then project (shift) it a ceratin distance and with a certain azimuth. If you have 10 points to represent, every point should have an increasing azimuth of one thenth of 360 degrees: 36, 72 etc.

A bit more sophisticated

Instead of centroid, use point_on_surface or pole_of_inaccessibility: a centroid can fall outside of the polygon (e.g. C-shaped polygons). Let's call this point (from where we project (shift/displace) the points the central point.

For the radius to displace the point, use a variable value in a way that all displaced points fall inside the polygon: a larger one for large polygons, a smaller for small polygons. Use the distance of the central point to the nearest point of the polygon's boundary. Multiply this by a value between 0 and 1 to get all points inside the polygon.

The expression to use with Geometry generator

  • In line 6, change to number of points you want to create (here: 12). Of course, this could also be an attribute value to get a varying number of points per polygon.
  • In line 20 replace 0.7 by any other factor to adapt the radius of the point displacement. As long as the value is smaller than 1, all points will be inside the polygon
  • As a variant, replace line 3 by point_on_surface( $geometry), or centroid( $geometry),
  • To get a constant radius, replace lines 12 to 20 with the radius length value in numerical form (like 100)
with_variable (
    'point',
    pole_of_inaccessibility ( $geometry, 1),
    with_variable(
        'no',
        12,
        collect_geometries(
            array_foreach (
                generate_series (0,@no),
                project (
                    @point,
                    length (
                        make_line (
                            @point,
                            closest_point( 
                                boundary ($geometry),
                                @point
                            )
                        )
                    )*0.7,
                    radians (360) / @no * @element
                 )
            )
        )
    )
)

Screenshot

enter image description here

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.