Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fine grain control over select by location tools #1495

Merged
merged 3 commits into from
Jul 1, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 48 additions & 32 deletions python/plugins/fTools/tools/doSelectByLocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#-----------------------------------------------------------
#
# fTools
# Copyright (C) 2008-2011 Carson Farmer
# Copyright (C) 2008-2011 Carson Farmer, edited and improved by Giovanni Allegri (2014)
# EMAIL: carson.farmer (at) gmail.com
# WEB : http://www.ftools.ca/fTools.html
#
Expand Down Expand Up @@ -32,12 +32,16 @@
from PyQt4.QtGui import *
import ftools_utils
from qgis.core import *
from ui_frmPointsInPolygon import Ui_Dialog
from ui_frmSelectByLocation import Ui_Dialog

class Dialog(QDialog, Ui_Dialog):
TOUCH = 1
OVERLAP = 2
WITHIN = 4

def __init__(self, iface):
QDialog.__init__(self, iface.mainWindow())
self.opFlags = 0
self.iface = iface
# Set up the user interface from Designer.
self.setupUi(self)
Expand All @@ -48,7 +52,6 @@ def __init__(self, iface):
layers = ftools_utils.getLayerNames([QGis.Point, QGis.Line, QGis.Polygon])
self.inPolygon.addItems(layers)
self.inPoint.addItems(layers)
self.updateUI()
self.connect(self.inPoint, SIGNAL("currentIndexChanged(QString)"), self.updateCheck)
self.cmbModify.addItems([self.tr("creating new selection"), self.tr("adding to current selection"), self.tr("removing from current selection")])

Expand All @@ -59,50 +62,63 @@ def updateCheck(self, text):
else:
self.chkSelected.setChecked(False)

def updateUI(self):
self.label_5.setVisible(False)
self.lnField.setVisible(False)
self.outShape.setVisible(False)
self.toolOut.setVisible(False)
self.label_2.setVisible(False)
self.setWindowTitle(self.tr("Select by location"))
self.label_3.setText(self.tr("Select features in:"))
self.label_4.setText(self.tr("that intersect features in:"))
self.label_mod = QLabel(self)
self.label_mod.setObjectName("label_mod")
self.label_mod.setText(self.tr("Modify current selection by:"))
self.cmbModify = QComboBox(self)
self.cmbModify.setObjectName("cmbModify")
self.chkSelected = QCheckBox(self.tr("Use selected features only"), self)
self.chkSelected.setObjectName("chkSelected")
self.gridLayout.addWidget(self.chkSelected,2,0,1,1)
self.gridLayout.addWidget(self.label_mod,3,0,1,1)
self.gridLayout.addWidget(self.cmbModify,4,0,1,1)
self.resize(381, 100)

def accept(self):
self.buttonOk.setEnabled( False )
if self.inPolygon.currentText() == "":
QMessageBox.information(self, self.tr("Select by location"), self.tr( "Please specify input layer"))
elif self.inPoint.currentText() == "":
QMessageBox.information(self, self.tr("Select by location"), self.tr("Please specify select layer"))
else:
inPoly = self.inPolygon.currentText()
inPts = self.inPoint.currentText()
self.compute(inPoly, inPts, self.cmbModify.currentText(), self.chkSelected.isChecked())
inLayer = self.inPolygon.currentText()
selLayer = self.inPoint.currentText()
self.compute(inLayer, selLayer, self.cmbModify.currentText(), self.chkSelected.isChecked())
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )

def compute(self, inPoly, inPts, modify, selection):
inputLayer = ftools_utils.getVectorLayerByName(inPoly)
selectLayer = ftools_utils.getVectorLayerByName(inPts)
def compute(self, inLayer, selLayer, modify, selection):
inputLayer = ftools_utils.getVectorLayerByName(inLayer)
selectLayer = ftools_utils.getVectorLayerByName(selLayer)
inputProvider = inputLayer.dataProvider()
selectProvider = selectLayer.dataProvider()
feat = QgsFeature()
infeat = QgsFeature()
geom = QgsGeometry()
selectedSet = []
index = ftools_utils.createIndex(inputProvider)

def _points_op(geomA,geomB):
return geomA.intersects(geomB)

def _poly_lines_op(geomA,geomB):
if geomA.disjoint(geomB):
return False
intersects = False
if self.opFlags & self.TOUCH:
intersects |= geomA.touches(geomB)
if not intersects and (self.opFlags & self.OVERLAP):
if geomB.type() == QGis.Line or geomA.type() == QGis.Line:
intersects |= geomA.crosses(geomB)
else:
intersects |= geomA.overlaps(geomB)
if not intersects and (self.opFlags & self.WITHIN):
intersects |= geomA.contains(geomB)
return intersects

def _sp_operator():
if inputLayer.geometryType() == QGis.Point:
return _points_op
else:
return _poly_lines_op

self.opFlags = 0
if self.chkTouches.checkState() == Qt.Checked:
self.opFlags |= self.TOUCH
if self.chkOverlaps.checkState() == Qt.Checked:
self.opFlags |= self.OVERLAP
if self.chkContains.checkState() == Qt.Checked:
self.opFlags |= self.WITHIN

sp_operator = _sp_operator()

if selection:
features = selectLayer.selectedFeatures()
Expand All @@ -113,7 +129,7 @@ def compute(self, inPoly, inPts, modify, selection):
for id in intersects:
inputProvider.getFeatures( QgsFeatureRequest().setFilterFid( int(id) ) ).nextFeature( infeat )
tmpGeom = QgsGeometry(infeat.geometry())
if geom.intersects(tmpGeom):
if sp_operator(geom,tmpGeom):
selectedSet.append(infeat.id())
self.progressBar.setValue(self.progressBar.value()+1)
else:
Expand All @@ -125,7 +141,7 @@ def compute(self, inPoly, inPts, modify, selection):
for id in intersects:
inputProvider.getFeatures( QgsFeatureRequest().setFilterFid( int(id) ) ).nextFeature( infeat )
tmpGeom = QgsGeometry( infeat.geometry() )
if geom.intersects(tmpGeom):
if sp_operator(geom,tmpGeom):
selectedSet.append(infeat.id())
self.progressBar.setValue(self.progressBar.value()+1)
if modify == self.tr("adding to current selection"):
Expand Down
167 changes: 167 additions & 0 deletions python/plugins/fTools/tools/frmSelectByLocation.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>423</width>
<height>308</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>308</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>308</height>
</size>
</property>
<property name="windowTitle">
<string>Select by location</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Select features in:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="inPolygon"/>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>that intersect features in:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="inPoint"/>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="chkTouches">
<property name="text">
<string>Include input features that touch the selection features</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="chkOverlaps">
<property name="text">
<string>Include input features that overlap/cross the selection features</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="chkContains">
<property name="text">
<string>Include input features completely within the selection features</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="chkSelected">
<property name="text">
<string>Only selected features</string>
</property>
</widget>
</item>
<item row="7" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="textVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<widget class="QComboBox" name="cmbModify"/>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Loading