1
#-----------------------------------------------------------
3
# Random Selection Within Subsets
5
# A QGIS plugin for randomly selecting features from
6
# within multiple user defined subsets based on an input field.
8
# Copyright (C) 2008 Carson Farmer
10
# EMAIL: carson.farmer (at) gmail.com
11
# WEB : www.geog.uvic.ca/spar/carson
13
#-----------------------------------------------------------
15
# licensed under the terms of GNU GPL 2
17
# This program is free software; you can redistribute it and/or modify
18
# it under the terms of the GNU General Public License as published by
19
# the Free Software Foundation; either version 2 of the License, or
20
# (at your option) any later version.
22
# This program is distributed in the hope that it will be useful,
23
# but WITHOUT ANY WARRANTY; without even the implied warranty of
24
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
# GNU General Public License for more details.
27
# You should have received a copy of the GNU General Public License along
28
# with this program; if not, write to the Free Software Foundation, Inc.,
29
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31
#--------------------------------------------------------------------
32
from PyQt4.QtCore import *
33
from PyQt4.QtGui import *
35
from qgis.core import *
36
from ui_frmSubsetSelect import Ui_Dialog
38
class Dialog(QDialog, Ui_Dialog):
40
def __init__(self, iface):
41
QDialog.__init__(self)
43
# Set up the user interface from Designer.
45
QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.update)
46
self.setWindowTitle("Random selection within subsets")
48
self.progressBar.setValue(0)
49
mapCanvas = self.iface.mapCanvas()
50
for i in range(mapCanvas.layerCount()):
51
layer = mapCanvas.layer(i)
52
if layer.type() == layer.VectorLayer:
53
self.inShape.addItem(layer.name())
55
def update(self, inputLayer):
57
changedLayer = self.getVectorLayerByName(inputLayer)
58
changedField = self.getFieldList(changedLayer)
59
for i in changedField:
60
self.inField.addItem(unicode(changedField[i].name()))
63
if self.inShape.currentText() == "":
64
QMessageBox.information(self, "Random Selection Within Subsets", "Please specify input vector layer")
65
elif self.inField.currentText() == "":
66
QMessageBox.information(self, "Random Selection Within Subsets", "Please specify an input field")
68
inVect = self.inShape.currentText()
69
uidField = self.inField.currentText()
70
if self.rdoNumber.isChecked():
71
value = self.spnNumber.value()
74
value = self.spnPercent.value()
76
self.compute(inVect, uidField, value, perc, self.progressBar)
77
self.progressBar.setValue(100)
78
self.progressBar.setValue(0)
82
fileDialog = QFileDialog()
83
fileDialog.setConfirmOverwrite(False)
84
outName = fileDialog.getSaveFileName(self, "Output Shapefile",".", "Shapefiles (*.shp)")
85
fileCheck = QFile(outName)
86
if fileCheck.exists():
87
QMessageBox.warning(self, "Random Selection Within Subsets", "Cannot overwrite existing shapefile...")
89
filePath = QFileInfo(outName).absoluteFilePath()
90
if filePath.right(4) != ".shp": filePath = filePath + ".shp"
91
if not outName.isEmpty():
93
self.outShape.insert(filePath)
95
def compute(self, inVect, inField, value, perc, progressBar):
96
vlayer = self.getVectorLayerByName(inVect)
97
vprovider = vlayer.dataProvider()
98
mlayer = self.getMapLayerByName(inVect)
99
allAttrs = vprovider.attributeIndexes()
100
vprovider.select(allAttrs)
101
index = vprovider.fieldNameIndex(inField)
103
#vprovider.uniqueValues(index, unique)
104
unique = self.getUniqueValues(vprovider, int(index))
105
inFeat = QgsFeature()
107
mlayer.removeSelection(True)
108
nFeat = vprovider.featureCount() * len(unique)
110
self.progressBar.setValue(0)
111
self.progressBar.setRange(0, nFeat)
112
if not len(unique) == mlayer.featureCount():
116
while vprovider.nextFeature(inFeat):
117
atMap = inFeat.attributeMap()
118
if atMap[index] == QVariant(i):
122
self.progressBar.setValue(nElement)
123
if perc: selVal = int(round((value / 100.0000) * len(FIDs), 0))
125
if selVal >= len(FIDs): selran = FIDs
126
else: selran = random.sample(FIDs, selVal)
127
selran.extend(mlayer.selectedFeaturesIds())
128
mlayer.setSelectedFeatures(selran)
130
mlayer.setSelectedFeatures(range(0, mlayer.featureCount()))
132
def getVectorLayerByName(self, myName):
133
mc = self.iface.mapCanvas()
134
nLayers = mc.layerCount()
135
for l in range(nLayers):
137
if layer.name() == unicode(myName,'latin1'):
138
vlayer = QgsVectorLayer(unicode(layer.source()), unicode(myName), unicode(layer.dataProvider().name()))
142
QMessageBox.information(self, "Random Selection Within Subsets", "Vector layer is not valid")
144
def getMapLayerByName(self, myName):
145
mc = self.iface.mapCanvas()
146
nLayers = mc.layerCount()
147
for l in range(nLayers):
149
if layer.name() == unicode(myName,'latin1'):
152
def getFieldList(self, vlayer):
153
fProvider = vlayer.dataProvider()
155
allAttrs = fProvider.attributeIndexes()
156
fProvider.select(allAttrs)
157
myFields = fProvider.fields()
160
def getUniqueValues(self, provider, index):
161
allAttrs = provider.attributeIndexes()
162
provider.select(allAttrs)
167
while provider.nextFeature(feat):
168
if not feat.attributeMap()[index].toString() in check:
169
values.append( feat.attributeMap()[index] )
170
check.append( feat.attributeMap()[index].toString() )