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?

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
    Seems exactly what I've needed, will test tomorrow – Luffydude May 26 '16 at 16:13
8

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".

  • 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 May 26 '16 at 10:03
  • 1
    @Pierma, how have you managed to use a SQL statement within QGIS? – Knightshound May 26 '16 at 15:28
  • 2
    Go to Layer --> Add Layer --> Add Virtual Layer... It's a very recent functionality! – Germán Carrillo May 26 '16 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 May 26 '16 at 21:44
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

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

  • 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 May 25 '16 at 14:50
  • sorry, I remedied! – pigreco May 25 '16 at 15:30
  • sorry, I misread the question. I agree with the use of the virtual layer. – pigreco May 27 '16 at 11:47
  • Your answer is useful but not for this very particular case. Thanks anyway – Luffydude May 27 '16 at 12:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.