OSM Toner style town labels explained
The point table of the Spatialite database created from OSM north-eastern Austria contains more than 500,000 points. This post shows how the style works which – when applied to the point layer – wil make sure that only towns and (when zoomed in) villages will be marked and labeled.
In the attribute table, we can see that there are two tags which provide context for populated places: the place
and the population
tag. The place
tag has it’s own column created by ogr2ogr when converting from OSM to Spatialite. The population
tag on the other hand is listed in the other_tags
column.
for example
"opengeodb:lat"=>"47.5000237","opengeodb:lon"=>"16.0334769","population"=>"623"
Overview maps would be much too crowded if we simply labeled all cities and towns. Therefore, it is necessary to filter towns based on their population and only label the bigger ones. I used limits of 5,000 and 10,000 inhabitants depending on the scale.
At the core of these rules is an expression which extracts the population value from the other_tags
attribute: The strpos()
function is used to locate the text "population"=>"
within the string attribute value. The population value is then extracted using the left()
function to get the characters between "population"=>"
and the next occurrence of "
. This value can ten be cast to integer using toint()
and then compared to the population limit:
5000 < toint( left ( substr( "other_tags", strpos("other_tags" ,'"population"=>"')+16, 8 ), strpos( substr( "other_tags", strpos("other_tags" ,'"population"=>"')+16, 8 ), '"' ) ) )
There is also one additional detail concerning label placement in this style: When zoomed in closer than 1:400,000 the labels are placed on top of the points but when zoomed out further, the labels are put right of the point symbol. This is controlled using a scale-based expression in the label placement:
As usual, you can find the style on Github: https://github.com/anitagraser/QGIS-resources/blob/master/qgis2/osm_spatialite/osm_spatialite_tonerlite_point.qml