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.
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!
-
@Joseph :) Any thoughts?Vijay Ramesh– Vijay Ramesh2016年07月13日 20:06:44 +00:00Commented Jul 13, 2016 at 20:06
-
Would first merging them all into one file be an option?bugmenot123– bugmenot1232016年07月13日 22:19:18 +00:00Commented 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.Vijay Ramesh– Vijay Ramesh2016年07月13日 22:43:47 +00:00Commented Jul 13, 2016 at 22:43
-
It is preferable to use itertools module to avoid repeated indexes (see my answer).xunilk– xunilk2016年07月14日 07:42:27 +00:00Commented Jul 14, 2016 at 7:42
-
I am also currently obtaining this error : IndexError: list index out of rangeVijay Ramesh– Vijay Ramesh2016年07月25日 13:28:22 +00:00Commented Jul 25, 2016 at 13:28
1 Answer 1
In this case, it is preferable to use itertools module to avoid repeated indexes. I assumed one feature for each shapefile in next situation:
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:
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:
and results at Python Console of QGIS were as expected.
-
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.Vijay Ramesh– Vijay Ramesh2016年07月14日 14:06:58 +00:00Commented Jul 14, 2016 at 14:06
-
Basically, if there are multiple features per shapefile.Vijay Ramesh– Vijay Ramesh2016年07月14日 14:49:51 +00:00Commented 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.Vijay Ramesh– Vijay Ramesh2016年07月14日 19:27:32 +00:00Commented 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– xunilk2016年07月15日 09:37:37 +00:00Commented 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?Vijay Ramesh– Vijay Ramesh2016年07月21日 20:11:09 +00:00Commented Jul 21, 2016 at 20:11