Sunday 9 October 2016

labeling - Removing duplicate point labels in QGIS


I am working on a protected areas map. The label layer is from the mapping authority. The one I am using is point based.


Unfortunately some of the points carry the same name leading to duplicate names for mountain areas, glaciers and other. I am for several reasons bound to use this layer, so finding a different layer or making changes to the layer is not within the scope of this question.


Result of duplicate label names, point layer



Is there a way to remove duplicate labels when labels are within a certain distance of each other?


If so, can such a rule be enforced within one of the categories when rule-based labelling is used?


enter image description here



Answer



If you do not want to build a different layer just for labeling and do not want to make changes to the layer, then data defined properties may be what you need.


The idea: get the feature to be labeled and create a geometry collection of all features having the same attribute value (no matter which attributes). Retrieve the centroid of this collection, get its x and y coordinate, and use this for labeling.


In default setting QGIS doesn't show colliding labels. This way you see all labels only once, right in the center of objects with same names.


To use this approach, you need to use data defined overriding of y and y coordinate, on tab Layer Properties -> Labeling -> Placement.


Define following function in functions editor, and press Load.


@qgsfunction(args='auto', group='Custom')

def getAgglomerationCenter(layername, attribute, feature, parent):
layer = QgsMapLayerRegistry.instance().mapLayersByName(layername)[0]
geom = QgsGeometry().fromWkt('GEOMETRYCOLLECTION()')
for feat in layer.getFeatures():
if feat[attribute] == feature[attribute]:
geom.addPart(QgsPointV2(feat.geometry().asPoint()))
return geom.centroid()

As expression in case of x coordinate give:


x(getAgglomerationCenter( 'YOUR LAYER NAME', 'ATTRIBUTE NAME' ))


and for y coordinate:


y(getAgglomerationCenter( 'YOUR LAYER NAME', 'ATTRIBUTE NAME' ))

Tested situation:


Test case


Disclaimer: this implementation is not optimized in any way, eg instead of looping over all features, using QgsFeatureRequest() is preferable. And probably memoizing results is possible, to prevent build the same collection several times.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...