TransWikia.com

Filter symbols in QGIS similar to labels for anti-collision?

Geographic Information Systems Asked by Bytor on March 23, 2021

I am using the GeoNames data in a PostGIS 2.5 table to populate cities on a map in QGIS, but with millions of entries it is very crowded with overapping making it useless without some sort of filtering. The QGIS layer is points only, and I have various symbols symbols for hamlet, village, etc… classified by population size, and they are all 1mm to 3mm in diameter.

portion of map with overlapping symbols

I would like to some how filter the items that get shown in a way analogous to how QGIS draws labels for a layer, with some symbols not getting drawn if they would collide with other symbols. I would also like that to be done with priority for population size rather than the seemingly random way QGIS does it for labels of equal priority in the same layer.

At first I though that scale-based rendering would work, but that means in order to filter out nearby cities like Mississauga or Hoboken so they don’t overlap with Toronto and New York at smaller scales, smaller cities like Red Deer or Rapid City would not get shown even though there is plenty of room for their symbols.

I’m imagining the algorithm go something like this:

for each place in list of places in order of most population to least
  get map location where place would be drawn
  have any other symbols already been rendered within a 5mm diameter of that map location?
  if no then
    render this symbol
  else
    skip to next place

In that map portion shown above you can see how there is a chain of six overlapping circles extending out to the left and down from the back dot like a backwards ‘J’- large, large, large, small, large, small. Only the large circle between the two small ones would get rendered even though the other large circles indicate cities of larger population since it’s the first one to be far enough away from the back dot. If I zoom in to a higher scale, this hypothetical algorithm would let all six circles get rendered once the symbols would no longer be inside each other’s 5mm diameter.

I know I can control rendering order in QGIS, but can’t seem to figure out the "render or not" part. I found various functions in plugins that do overlaps, but since this is a point layer nothing ever actually overlaps to do it that way. Even if it did, those functions look at all features and I need it too look at only the already rendered stuff to make the decision.

I suspect that this will require Python, but I don’t know it that well or what the QGIS internal Python API offers to have an idea of how to go about this. Is this variable rendering even possible in QGIS?

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP