6

After reading through the following question (which is kinda related but not quite what I need):

How can I show points on the same coordinate as e.g. a bigger symbol in QGIS?

I found out that there might be a need to label these locations that have multiple points with same lat/long values. For example, if a location has 20 features in it, I want the label to say 20. Or even more useful: if a location has 20 features in the location, and 15 fulfill a condition (string = abc), I want the label to say 15.

Is there a way of doing so in QGIS?

3 Answers 3

10

If I understand, you want aggregate a layer by location. You will need SQL for that, so create a virtual layer (Qgis >= 2.14) with a query like :

SELECT geometry, count(*) AS count FROM your_layer GROUP BY geometry

You can now use the "count" field of the virtual layer as label.

For adding the filter by the text field :

SELECT 
  geometry, 
  count(*) AS count_total,
  count(CASE WHEN filter_field = "abc" THEN 1 ELSE NULL END) as count_filter
FROM your_layer GROUP BY geometry

Adapt words to your layer : your_layer, filter_field and "abc".

5
  • I can't click ok on that filter query. My error is Parser Error: syntax error, unexpected FUNCTION, expecting $end Eval Error: No root node! Parsing failed?
    – Luffydude
    Commented May 26, 2016 at 10:03
  • 1
    @Pierma, how have you managed to use a SQL statement within QGIS? Commented May 26, 2016 at 15:28
  • 2
    Go to Layer --> Add Layer --> Add Virtual Layer... It's a very recent functionality! Commented May 26, 2016 at 17:21
  • Yes, sorry, don't use the filter query (no support of sql functions). The query only work for a virtual layer. Do as Germán Carrillo explain. It will create a new layer in your project. This new layer is dynamic, so if your data change, the virtral layer will update (as a virtual field).
    – Pierma
    Commented May 26, 2016 at 21:44
  • This is a very elegant solution. Thanks!
    – DotPi
    Commented Apr 19, 2022 at 17:34
9

Nice question! PyQGIS to the rescue!

Follow these steps to get a new field (in your original layer) called label with the number of points that lie in the same location:

  1. Active (select) your layer in the QGIS ToC.
  2. Run this code snippet in the QGIS Python console:

    from PyQt4.QtCore import QVariant
    
    lyr = iface.activeLayer()
    
    # Create New Field
    lyr.dataProvider().addAttributes([QgsField("label", QVariant.Int)])
    lyr.updateFields()
    fIdx = lyr.fieldNameIndex( 'label' )
    
    # Create Spatial Index
    idx = QgsSpatialIndex()
    for f in lyr.getFeatures():
      idx.insertFeature(f)
    
    # Use the Spatial Index
    attrFeatMap = {}
    for f in lyr.getFeatures():
      if not f.id() in attrFeatMap:
        res = idx.intersects( f.geometry().boundingBox() )
        for id in res:
           attrFeatMap[id] = { fIdx : len(res) }
    
    # Write calculated count to the label field
    lyr.dataProvider().changeAttributeValues( attrFeatMap )
    
  3. Open layer properties and configure labels selecting the label field we've just populated.

  4. This is the result:

    enter image description here


EDIT:

As you would also like to filter by an attribute, you can define an expression in the beginning of the code (for example, after the Create New Field block):

expr = QgsExpression( '"string"=\'{}\''.format("abc") )

and replace the two calls to lyr.getFeatures() by:

lyr.getFeatures( QgsFeatureRequest( expr ) )

That way you'll only get the count of the points with the same coordinates that fulfill the string=abc condition.

1
  • 1
    Seems exactly what I've needed, will test tomorrow
    – Luffydude
    Commented May 26, 2016 at 16:13
4

you can use Rule-based labeling

shapefile point before the rule fig_1

all the points they label.

fig_2

after the rule:

fig_3

using rules you can specify which labels to show, even using conditional statements

4
  • Could you please elaborate on what you've done in your filtro? Also I can't seem to get it labeling the number of points
    – Luffydude
    Commented May 25, 2016 at 14:50
  • sorry, I remedied!
    – pigreco
    Commented May 25, 2016 at 15:30
  • sorry, I misread the question. I agree with the use of the virtual layer.
    – pigreco
    Commented May 27, 2016 at 11:47
  • Your answer is useful but not for this very particular case. Thanks anyway
    – Luffydude
    Commented May 27, 2016 at 12:06

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.