3

I have a list of 34 shapefiles. These shapefiles are range maps for different species. I would like to take 4 of these shapefiles and document a list of those shapefiles (within the 30 shapefiles), whose ranges overlap with these 4 shapefiles. I wouldn't mind comparing them one at a time ie. Shapefile 1 with the other 30 shapefiles; Shapefile2 with the other 30 shapefile..

Is there a way to do this in QGIS/PyQGIS?

I tried using the Intersect tool, but that would only give me the features that are common to both the files chosen.

I basically need a table that gives me : shapefile1 and all the names of the shapefiles that overlap with shapefile1

EDIT: Following @xunik's suggestion:

ISSUE I am having right now is that the script is not picking up every possible combination(even if they are slightly touching each other). Attached is an image that shows the script being written to a csv file.

enter image description here

EDIT 2

The script suggested by @xunilk below is not working and is actually showing incorrect information. Any suggestions?

See Image below. The output is showing that these two features intersect, when in reality, they dont. Please Help!

enter image description here

5
  • @Joseph :) Any thoughts? Jul 13, 2016 at 20:06
  • Would first merging them all into one file be an option? Jul 13, 2016 at 22:19
  • I believe they could be merged into a single file (since most of these shape files have the same attribute fields. (Note: Most of the shapefiles are composed of a single polygon, however, some of them have 2 or 3 polygons defining the species range). Let me know. Jul 13, 2016 at 22:43
  • It is preferable to use itertools module to avoid repeated indexes (see my answer).
    – xunilk
    Jul 14, 2016 at 7:42
  • I am also currently obtaining this error : IndexError: list index out of range Jul 25, 2016 at 13:28

1 Answer 1

3

In this case, it is preferable to use itertools module to avoid repeated indexes. I assumed one feature for each shapefile in next situation:

enter image description here

Next code prints all the names of the shapefiles that overlap with each other.

import itertools

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

feats = []

for layer in layers:
    for feat in layer.getFeatures():
        feats.append(feat)

n = len(layers)

comb = range(n)

for i, j in itertools.combinations(comb, 2):
    if feats[i].geometry().intersects(feats[j].geometry()):
        print layers[i].name() + " intersects with " + layers[j].name()

After running the code at the Python Console of QGIS I got:

enter image description here

It works as expected.

Editing Note:

When each layer can have more than one feature, next version of former script works:

import itertools

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

n = len(layers)

feats = [ [] for i in range(n) ]

idx_layers = []

for i, layer in enumerate(layers):
    for feat in layer.getFeatures():
        feats[i].append( feat )
        idx_layers.append(i)

len_feats = [ len(item) for item in feats ]

idx_feats = []

for item in len_feats:
    idx_feats.append(range(item))

#flattened list
idx_feats = [ item for element in idx_feats for item in element ]

n = sum(len_feats)

comb = range(n)

#flattened list
feats = [ item for element in feats for item in element ]

for i, j in itertools.combinations(comb, 2):
    if feats[i].geometry().intersects(feats[j].geometry()):
        print "feature:", idx_feats[i] , "from layer:", idx_layers[i], " intersects feature:", idx_feats[j], "from layer:", idx_layers[j]

I tried out with these new shapefiles:

enter image description here

and results at Python Console of QGIS were as expected.

enter image description here

7
  • Thanks @xunilk. It works as you suggested. I have a question: Some shapefiles, that have different attribute fields are not being taken by the script above and shown to intersect. Any suggestions for the same. Jul 14, 2016 at 14:06
  • Basically, if there are multiple features per shapefile. Jul 14, 2016 at 14:49
  • Hey @xunilk, I am presently having issues with the same, as the script is not checking for every possible combination as well. I would like a result, even if the edges of polygons from two shapefiles are touching each other. Jul 14, 2016 at 19:27
  • Obviously, former version of my script only works for shapefiles with only one feature. New version (editing note) can handle more than one feature.
    – xunilk
    Jul 15, 2016 at 9:37
  • I am still having an issue where all shapefiles that even overlap or touch each other are not being picked up by the script you wrote. Any ideas? Jul 21, 2016 at 20:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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