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.
def getAgglomerationCenter(layername, attribute, feature, parent):
layer = QgsMapLayerRegistry.instance().mapLayersByName(layername)
geom = QgsGeometry().fromWkt('GEOMETRYCOLLECTION()')
for feat in layer.getFeatures():
if feat[attribute] == feature[attribute]:
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' ))
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.