I am trying to render cities on the map, using Geonames’ dataset (source). I have downloaded the top 10000 cities as a GeoJSON file, and loaded it into QGIS. However, when I zoom out, this shows too many points: they completely fill the map.

I have enabled labels, and there is the option under Layer Properties › Labels › Rendering › Feature Options to limit the number of features rendered. This way, only the largest cities in an area will be labelled (I have set render priority to be based on population), but when I zoom in I can see more city names appear.

Is it possible to apply a similar limit to the symbols themselves? Can I hide all but the largest 100 cities within the viewport? I do not want to hard-code limits for population and zoom level, because I would like cities in less populous areas to appear sooner when zooming in there.

2 Answers 2


There are several ways I can think of to address this situation using the Expression Builder, or even using a custom python function. Because of the size of the layer, however, these can be incredibly resource-intensive.

There is, thankfully, an easier, sneakier way, using the label settings you've already established. This will result in label text which is fixed in its position, but this can be addressed with a few extra steps. Here's how it works:

  1. On the Background tab, enable label backgrounds.
  2. Choose Marker Symbol as the background type.
  3. Adjust the symbology of the marker as necessary.
  4. Adjust symbol placement and offsets so that marker symbol is properly placed.
    • You'll want to choose "offset from point" under Placement, and choose for the label to be placed directly on top of the point.
    • If you're labeling the city name using the same layer, make sure that whatever offset you choose to move the text off of the point, that the inverse of that offset is applied to the background marker symbol.
  5. (Optional) Get dynamic label text back.
    1. Set the label text to a single whitespace character.
    2. Duplicate the layer.
    3. On the new layer, remove the marker symbol, and re-set the label text to the "name" field, or whichever you are using.
    4. Adjust the labeling properties on the new layer to get the text to your liking. You may need to change some of the labeling priority weights between the two layers.

background marker symbol

In my map, I offset the "label" by -4. By offsetting the background marker symbol by +4, the point will render directly on top of the geometry feature.


And here are the results. I've left the actual feature layer being rendered just to show that it is highlighting the larger population points correctly. With this label setting, I can actually opt to uncheck the Enable symbol layer box on the symbology tab, and let the label points take their place entirely.

full extent

And here's the same setup at a much broader scale, with the point features no longer being rendered.


In fact, the rendering style cluster does something similar, only that points that are too close are not suppressed, but clustered in a separate symbol. However, you can use this at least as a workaround by adapting to your needs.

Choose clustering as rendering style for your points layer. Than define your cluster symbol and set it as completely transparent. Define the distance for clustering, so all points that are closer than this value will be clustered - and thus be transparent.

Alternatively, you could also use a date-driven size for the cluster, defining in an expression the conditions when size should be 0 (thus invisible). Also play around with Control feature rendering order, see: https://docs.qgis.org/3.10/en/docs/user_manual/working_with_vector/vector_properties.html#layer-rendering

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.