Check this code for your answer:
https://github.com/dsgoficial/DsgTools/blob/master/ProductionTools/CopyPasteTool/multiLayerSelect.py
On DSGTools, there is a tool called Generic Selector which among other stuff, does exactly what you want. The selection using a polygon is achieved by using the shift modifier in the tool. The tool on the link above is a child of QgsMapTool and we have to reimplement some methods in order to get things done. Explaining the code in a general way, you have to reimplement 3 methods: the canvasPressEvent, canvasReleaseEvent and the canvasMoveEvent.
Let's break the problem into 2 smaller ones:
- Build the search polygon
- Get the features.
To build the polygon, you have to click, drag and release. The click event is the canvasPressEvent. In this method, you have to get the coordinate of the beginning of the rectangle, then you have to let the canvasMoveEvent that you have to build the rubberband (polygon that is shown on screen). The code snippet bellow shows you what you can do:
def canvasPressEvent(self, e):
"""
Method used to build rectangle if shift is held, otherwise, feature select/deselect and identify is done.
"""
if QtGui.QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier:
self.isEmittingPoint = True
self.startPoint = self.toMapCoordinates(e.pos())
self.endPoint = self.startPoint
self.isEmittingPoint = True
self.showRect(self.startPoint, self.endPoint)
else:
self.isEmittingPoint = False
self.createContextMenu(e)
The variable self.isEmittingPoint is used to build the rubberband on the method onCanvasMoveEvent:
def canvasMoveEvent(self, e):
"""
Used only on rectangle select.
"""
if not self.isEmittingPoint:
return
self.endPoint = self.toMapCoordinates( e.pos() )
self.showRect(self.startPoint, self.endPoint)
The method self.showRect resets and draws the rubberband:
def showRect(self, startPoint, endPoint):
"""
Builds rubberband rect.
"""
self.rubberBand.reset(QGis.Polygon)
if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():
return
point1 = QgsPoint(startPoint.x(), startPoint.y())
point2 = QgsPoint(startPoint.x(), endPoint.y())
point3 = QgsPoint(endPoint.x(), endPoint.y())
point4 = QgsPoint(endPoint.x(), startPoint.y())
self.rubberBand.addPoint(point1, False)
self.rubberBand.addPoint(point2, False)
self.rubberBand.addPoint(point3, False)
self.rubberBand.addPoint(point4, True) # true to update canvas
self.rubberBand.show()
Then, when you release the click, the canvasReleaseEvent is emitted:
def canvasReleaseEvent(self, e):
"""
After the rectangle is built, here features are selected.
"""
if QtGui.QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier:
self.isEmittingPoint = False
r = self.rectangle()
layers = self.canvas.layers()
for layer in layers:
#ignore layers on black list and features that are not vector layers
if layer.type() != QgsMapLayer.VectorLayer or (self.layerHasPartInBlackList(layer.name())):
continue
if r is not None:
#builds bbRect and select from layer, adding selection
bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, r)
layer.select(bbRect, True)
self.rubberBand.hide()
On this method, we can achieve the second step, the selection. This tool on DSGTools selects from every layer loaded. To do so, first we have to get the search rectangle, transforming the rubberband into a QgsRectangle. We have implemented a method called rectangle to do so:
def rectangle(self):
"""
Builds rectangle from self.startPoint and self.endPoint
"""
if self.startPoint is None or self.endPoint is None:
return None
elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y():
return None
return QgsRectangle(self.startPoint, self.endPoint)
After getting the rectangle, we iterate on every layer, get the bbRect and finally select the features using layer.select
I hope I was clear on my answer!
Maybe something like
ogr2ogr -f 'ESRI Shapefile' -dialect sqlite -sql "SELECT a.* FROM bergs a,
AOI_buffered100 b WHERE ST_Intersects(a.geometry, b.geometry)" -overwrite
bergs_testborderrem.shp sub_directory
where the shapefiles are in sub_directory
. Also you may want ST_Touches
or something instead of ST_Intersects
.
The key seems to be the specification of the directory as the source, though relative directories appear to be possible, at least for the second shapefile, as long as there are shapefiles in sub_directory
. Finally, make sure that the name of the geometry columns are correct.
Also, see here.
Best Answer
Two possible solutions:
Vector > Research tools > Select by Location
and tick the "Use selected features only" checkbox.Vector > Geopressing tools > Intersection
and again tick the "Use only selected features" checkbox. The input layer will be your points layer, and the select layer will be your polygon layer.