6

I have a lot of coordinates in the attribute table like this one:

enter image description here

I'm looking for a way how to find and select active layer duplicated points using PyQGIS. I needn't delete them but only find and show (or select).

5
  • Do your duplicate point need to have all the same attributes or only a some of them?
    – mgri
    Commented Jan 23, 2017 at 21:15
  • Yes, duplicates overlaps.
    – Artec
    Commented Jan 23, 2017 at 21:16
  • Thanks, but I don't understand if you need a spatial query or a query on the attributes.
    – mgri
    Commented Jan 23, 2017 at 21:19
  • The same attributes are only X and Y. The rest can be but not always.
    – Artec
    Commented Jan 23, 2017 at 21:20
  • In this case I need spatial query. "X,Y" in this table represents physical points wchich can be duplicated. I'm looking the way how to select points (with using geometry not attributes).
    – Artec
    Commented Jan 23, 2017 at 21:25

2 Answers 2

6

This code should do the job (you need to have your layer activated before running it from the Python Console):

layer = iface.activeLayer()

allfeatures={}
index = QgsSpatialIndex()
for ft in layer.getFeatures():
    allfeatures[ft.id()] = ft
    index.insertFeature(ft)

selection = []
for feat in layer.getFeatures():
    inGeom = feat.geometry()
    idsList = index.intersects(inGeom.boundingBox())
    if len(idsList) > 1:
        for id in idsList:
            selection.append(allfeatures[id])
layer.setSelectedFeatures([k.id() for k in selection])
6
  • Thanks for your quickly help but at last row I've got error File "<input>", line 7 layer.setSelectedFeatures([k.id() for k in selection]) ^ SyntaxError: invalid syntax
    – Artec
    Commented Jan 23, 2017 at 21:42
  • Which QGIS version are you using? It's working for me (QGIS 2.18.2)
    – mgri
    Commented Jan 23, 2017 at 21:44
  • Now I'm using 2.16.3 but sometimes use older (2.12 Lyon).
    – Artec
    Commented Jan 23, 2017 at 21:47
  • These function didn't change from your version... That's really weird, I'm pretty sure there is some problem with the copy&paste of the code.
    – mgri
    Commented Jan 23, 2017 at 21:50
  • You have right. I need to paste separately the last row layer.setSelectedFeatures([k.id() for k in selection]) and it works great !
    – Artec
    Commented Jan 23, 2017 at 21:55
3

Here is another PyQGIS solution.

Let's assume there is a polygon layer called 'polygon' with its attribute table, see the image below.

input

Note: Features with the same "id" possess the same geometry.

Proceed with Plugins > Python Console > Show Editor and paste the script below:

# imports
from qgis.core import QgsProject

def select_features_with_duplicates(layer_name: str, reference_field: str) -> None:
    """
    Selects features with duplicates in the reference field
    :param layer_name: name of the layer
    :param reference_field: name of the field to check e.g. id, fid etc.
    """
    
    # get a layer by its name
    layer = QgsProject.instance().mapLayersByName(layer_name)[0]
    
    # list of all values of the reference field
    all_values = layer.aggregate(aggregate=QgsAggregateCalculator.ArrayAggregate, fieldOrExpression=reference_field)[0]

    # make a dict with duplicate values and times each occurred 
    dict_with_duplicates = {value : all_values.count(value) for value in all_values if all_values.count(value) > 1 }
    
    # make a tuple of values from the dict keys
    values_to_select = tuple([*dict_with_duplicates])
    
    # selecting duplicate features by expression
    expression = f'"{reference_field}" in {values_to_select}'
    layer.selectByExpression(expression)
    
    return
    
select_features_with_duplicates('polygon', "id")

Change the parameters of the function in the last line. Press Run script run script and get the output that will look like this:

result

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.