4

I am making a map where I want to label two points with only one label. How can I do that? I've attached the image of my map.

enter image description here

3
  • I know you are using QGIS but in ArcGIS you would dissolve the point by the field that has the label values. Then label them and remove duplicates. That may give you insight on what to do in Q. Commented May 12, 2021 at 23:28
  • This would work in QGIS as well. However, two shortcomings to consider: 1. this approach is static, if you add or change geometries, you have to dissolve again. 2. Dissolving, you loose information. The solution I proposed overcomes these problems: once set, it works automatically and dynamically, even when changing geometries, attributes etc. It also affects only visualization and does not change data. In the same way, you could also hide symbolization (point rendering).
    – Babel
    Commented May 13, 2021 at 8:38
  • Check out gis.stackexchange.com/questions/299788/…
    – MrXsquared
    Commented May 14, 2021 at 9:08

2 Answers 2

11

A different aproach (than @Babel's) is to use the geometry generator which is available also in the label-engine. Just collect the geometries with the same name, building a multipoint geometry and then using the boundingbox to label all points with the same name with one Label:

enter image description here

The expression is (where "name" is the id for same objects which should be labeled together):

bounds(collect($geometry, group_by:="name"))

To make callouts to all points I used also the geometry generator for symbols. The labelpositions are stored in the auxiliary storage and can be used then to produce the callouts to all parts with the expression:

make_line($geometry,
  make_point( "auxiliary_storage_labeling_positionx" , 
            "auxiliary_storage_labeling_positiony") 
          )

enter image description here

3
  • A nice solution, indeed!
    – Babel
    Commented May 13, 2021 at 8:47
  • Thank you so much! Both @Babel and eurojam ! I got it to work on my project now! However now my callouts only reached one of the points where the label is assigned to two points, how did you make two callouts?
    – anneke
    Commented May 17, 2021 at 9:26
  • see the edited answer above.
    – eurojam
    Commented May 17, 2021 at 14:20
4

In the label settings, go to the last tab called rendering and next to show label select data driven override and select edit (see screenshot below). Paste the following expression (overlay_nearest() function is available since QGIS 3.16, array_min() since QGIS 3.18). It returns true (=show label) only if the point has a certain minimum distance (change that manually, see below) from it's nearest neighbor:

if (
    array_length (
        overlay_nearest( 
            @layer, 
            $geometry, 
            max_distance:=10000
        )
    ) >0,
    if (
        $id > array_min(
            overlay_nearest( 
                @layer, 
                $id,
                max_distance:=10000,
                limit:=100
            )
        ),
        0,
        1
    ),
    1
)

You can change the max_distance:=10000 in line 6: only if points are closer to each other than this distance will labels be skipped. If two or more points are closer than this distance, still one (but just one) label will be rendered: the one of the point with the smallest id value in this group (cluster od points).

Screenshot: as you see, where points are "clustered" (closer than 10.000 m), only one label is retained. Points a bit farther away will be labeled, however. For each of the three name, you have 3 "clusters" of points close together that illustrate how the expression works: in each cluster, only one point is labeled: enter image description here

2
  • Thank you! However it gives me some errors: Function is not known syntax error, unexpected COMMA, expecting end of file syntax error, unexpected ')', expecting end of file syntax error, unexpected ')', expecting end of file Can you help me with those?
    – anneke
    Commented May 13, 2021 at 10:25
  • What QGIS version do you use? This expression works with the current version 3.18. array_min function was only introduced in this latest release. Will update my answer accordingly.
    – Babel
    Commented May 13, 2021 at 10:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.