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

Taras
  • 32,823
  • 4
  • 66
  • 137
Artec
  • 982
  • 5
  • 14
  • Do your duplicate point need to have all the same attributes or only a some of them? – mgri Jan 23 '17 at 21:15
  • Yes, duplicates overlaps. – Artec Jan 23 '17 at 21:16
  • Thanks, but I don't understand if you need a spatial query or a query on the attributes. – mgri Jan 23 '17 at 21:19
  • The same attributes are only X and Y. The rest can be but not always. – Artec Jan 23 '17 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 Jan 23 '17 at 21:25

2 Answers2

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])
mgri
  • 16,159
  • 6
  • 47
  • 80
  • 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 Jan 23 '17 at 21:42
  • Which QGIS version are you using? It's working for me (QGIS 2.18.2) – mgri Jan 23 '17 at 21:44
  • Now I'm using 2.16.3 but sometimes use older (2.12 Lyon). – Artec Jan 23 '17 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 Jan 23 '17 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 Jan 23 '17 at 21:55
  • I'm glad it worked also for you! =) – mgri Jan 23 '17 at 21:56
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) &gt; 1 }

# make a tuple of values from the dict keys
values_to_select = tuple([*dict_with_duplicates])

# selecting duplicate features by expression
expression = f'&quot;{reference_field}&quot; 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

Taras
  • 32,823
  • 4
  • 66
  • 137