~ubuntu-branches/ubuntu/utopic/qgis/utopic

« back to all changes in this revision

Viewing changes to python/plugins/fTools/tools/doSubsetSelect.py

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-04-24 15:12:20 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120424151220-r88g00af5fpn5fc3
Tags: 1.7.4+1.7.5~20120320-1
The "Sometimes they come back" release.

* Branching from Qgis tree and adapting to current Debian Policy and
  standards. The target tree is currently set to release-1.7.
  (closes: #661491, #606304, #615683, #616182, #600308)
* Policy bumped to 3.9.3.
* Moving to debhelper compatibility level 9.
* Source format is now 3.0 with quilt support.
* Merged with 2bf42287 upstream git snapshot.
* Migrated to dh_python2 instead of python-central.
  (closes: #617048)
* Snapshot in qgis.org release-1.7: c936d031
* Added an automagic creation of a lintian override for sqlite embedding.
  This is required for uploading currently.
* Added missing ${misc:Depends} to make lintian happy.
* Copyright notes updated and debian/copyright moved to format 1.0.
* More licenses notices now reported in debian/copyright. Thanks ftpmasters.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
1
2
#-----------------------------------------------------------
2
 
3
 
# Random Selection Within Subsets
4
 
#
5
 
# A QGIS plugin for randomly selecting features from 
6
 
# within multiple user defined subsets based on an input field.
7
 
#
8
 
# Copyright (C) 2008  Carson Farmer
9
 
#
 
3
#
 
4
# fTools
 
5
# Copyright (C) 2008-2011  Carson Farmer
10
6
# EMAIL: carson.farmer (at) gmail.com
11
 
# WEB  : www.geog.uvic.ca/spar/carson
 
7
# WEB  : http://www.ftools.ca/fTools.html
 
8
#
 
9
# A collection of data management and analysis tools for vector data
12
10
#
13
11
#-----------------------------------------------------------
14
 
 
12
#
15
13
# licensed under the terms of GNU GPL 2
16
 
 
14
#
17
15
# This program is free software; you can redistribute it and/or modify
18
16
# it under the terms of the GNU General Public License as published by
19
17
# the Free Software Foundation; either version 2 of the License, or
20
18
# (at your option) any later version.
21
 
 
19
#
22
20
# This program is distributed in the hope that it will be useful,
23
21
# but WITHOUT ANY WARRANTY; without even the implied warranty of
24
22
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
23
# GNU General Public License for more details.
26
 
 
24
#
27
25
# You should have received a copy of the GNU General Public License along
28
26
# with this program; if not, write to the Free Software Foundation, Inc.,
29
27
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30
 
31
 
#--------------------------------------------------------------------
 
28
#
 
29
#---------------------------------------------------------------------
 
30
 
32
31
from PyQt4.QtCore import *
33
32
from PyQt4.QtGui import *
34
 
import random
 
33
import random, ftools_utils
35
34
from qgis.core import *
36
35
from ui_frmSubsetSelect import Ui_Dialog
37
36
 
38
37
class Dialog(QDialog, Ui_Dialog):
39
38
 
40
 
        def __init__(self, iface):
41
 
                QDialog.__init__(self)
42
 
                self.iface = iface
43
 
                # Set up the user interface from Designer.
44
 
                self.setupUi(self)
45
 
                QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.update)              
46
 
                self.setWindowTitle("Random selection within subsets")
47
 
                # populate layer list
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())
54
 
 
55
 
        def update(self, inputLayer):
56
 
                self.inField.clear()
57
 
                changedLayer = self.getVectorLayerByName(inputLayer)
58
 
                changedField = self.getFieldList(changedLayer)
59
 
                for i in changedField:
60
 
                        self.inField.addItem(unicode(changedField[i].name()))
61
 
 
62
 
        def accept(self):
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")
67
 
                else:
68
 
                        inVect = self.inShape.currentText()
69
 
                        uidField = self.inField.currentText()
70
 
                        if self.rdoNumber.isChecked():
71
 
                                value = self.spnNumber.value()
72
 
                                perc = False
73
 
                        else:
74
 
                                value = self.spnPercent.value()
75
 
                                perc = True
76
 
                        self.compute(inVect, uidField, value, perc, self.progressBar)
77
 
                        self.progressBar.setValue(100)
78
 
                self.progressBar.setValue(0)
79
 
 
80
 
        def outFile(self):
81
 
                self.outShape.clear()
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...")
88
 
                else:
89
 
                        filePath = QFileInfo(outName).absoluteFilePath()
90
 
                        if filePath.right(4) != ".shp": filePath = filePath + ".shp"
91
 
                        if not outName.isEmpty():
92
 
                                self.outShape.clear()
93
 
                                self.outShape.insert(filePath)
94
 
 
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)
102
 
                #unique = []
103
 
                #vprovider.uniqueValues(index, unique)
104
 
                unique = self.getUniqueValues(vprovider, int(index))
105
 
                inFeat = QgsFeature()
106
 
                selran = []
107
 
                mlayer.removeSelection(True)
108
 
                nFeat = vprovider.featureCount() * len(unique)
109
 
                nElement = 0
110
 
                self.progressBar.setValue(0)
111
 
                self.progressBar.setRange(0, nFeat)
112
 
                if not len(unique) == mlayer.featureCount():
113
 
                        for i in unique:
114
 
                                vprovider.rewind()
115
 
                                FIDs= []
116
 
                                while vprovider.nextFeature(inFeat):
117
 
                                        atMap = inFeat.attributeMap()
118
 
                                        if atMap[index] == QVariant(i):
119
 
                                                FID = inFeat.id()
120
 
                                                FIDs.append(FID)
121
 
                                        nElement += 1
122
 
                                        self.progressBar.setValue(nElement)
123
 
                                if perc: selVal = int(round((value / 100.0000) * len(FIDs), 0))
124
 
                                else: selVal = value
125
 
                                if selVal >= len(FIDs): selran = FIDs
126
 
                                else: selran = random.sample(FIDs, selVal)
127
 
                                selran.extend(mlayer.selectedFeaturesIds())
128
 
                                mlayer.setSelectedFeatures(selran)
129
 
                else:
130
 
                        mlayer.setSelectedFeatures(range(0, mlayer.featureCount()))
131
 
 
132
 
        def getVectorLayerByName(self, myName):
133
 
                mc = self.iface.mapCanvas()
134
 
                nLayers = mc.layerCount()
135
 
                for l in range(nLayers):
136
 
                        layer = mc.layer(l)
137
 
                        if layer.name() == unicode(myName,'latin1'):
138
 
                                vlayer = QgsVectorLayer(unicode(layer.source()),  unicode(myName),  unicode(layer.dataProvider().name()))
139
 
                                if vlayer.isValid():
140
 
                                        return vlayer
141
 
                                else:
142
 
                                        QMessageBox.information(self, "Random Selection Within Subsets", "Vector layer is not valid")
143
 
 
144
 
        def getMapLayerByName(self, myName):
145
 
                mc = self.iface.mapCanvas()
146
 
                nLayers = mc.layerCount()
147
 
                for l in range(nLayers):
148
 
                        layer = mc.layer(l)
149
 
                        if layer.name() == unicode(myName,'latin1'):
150
 
                                return layer
151
 
 
152
 
        def getFieldList(self, vlayer):
153
 
                fProvider = vlayer.dataProvider()
154
 
                feat = QgsFeature()
155
 
                allAttrs = fProvider.attributeIndexes()
156
 
                fProvider.select(allAttrs)
157
 
                myFields = fProvider.fields()
158
 
                return myFields
159
 
 
160
 
        def getUniqueValues(self, provider, index):
161
 
                allAttrs = provider.attributeIndexes()    
162
 
                provider.select(allAttrs)
163
 
                feat = QgsFeature()
164
 
                values = []
165
 
                check = []
166
 
                provider.rewind()
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() )
171
 
                return values
 
39
    def __init__(self, iface):
 
40
        QDialog.__init__(self)
 
41
        self.iface = iface
 
42
        # Set up the user interface from Designer.
 
43
        self.setupUi(self)
 
44
        QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.update)
 
45
        self.setWindowTitle(self.tr("Random selection within subsets"))
 
46
        self.buttonOk = self.buttonBox_2.button( QDialogButtonBox.Ok )
 
47
        # populate layer list
 
48
        self.progressBar.setValue(0)
 
49
        mapCanvas = self.iface.mapCanvas()
 
50
        layers = ftools_utils.getLayerNames([QGis.Point, QGis.Line, QGis.Polygon])
 
51
        self.inShape.addItems(layers)
 
52
 
 
53
    def update(self, inputLayer):
 
54
        self.inField.clear()
 
55
        changedLayer = ftools_utils.getVectorLayerByName(inputLayer)
 
56
        changedField = ftools_utils.getFieldList(changedLayer)
 
57
        for i in changedField:
 
58
            self.inField.addItem(unicode(changedField[i].name()))
 
59
        maxFeatures = changedLayer.dataProvider().featureCount()
 
60
        self.spnNumber.setMaximum( maxFeatures )
 
61
 
 
62
    def accept(self):
 
63
        self.buttonOk.setEnabled( False )
 
64
        if self.inShape.currentText() == "":
 
65
            QMessageBox.information(self, self.tr("Random selection within subsets"), self.tr("Please specify input vector layer"))
 
66
        elif self.inField.currentText() == "":
 
67
            QMessageBox.information(self, self.tr("Random selection within subsets"), self.tr("Please specify an input field"))
 
68
        else:
 
69
            inVect = self.inShape.currentText()
 
70
            uidField = self.inField.currentText()
 
71
            if self.rdoNumber.isChecked():
 
72
                value = self.spnNumber.value()
 
73
                perc = False
 
74
            else:
 
75
                value = self.spnPercent.value()
 
76
                perc = True
 
77
            self.compute(inVect, uidField, value, perc, self.progressBar)
 
78
            self.progressBar.setValue(100)
 
79
        self.progressBar.setValue(0)
 
80
        self.buttonOk.setEnabled( True )
 
81
 
 
82
    def compute(self, inVect, inField, value, perc, progressBar):
 
83
        mlayer = ftools_utils.getMapLayerByName(inVect)
 
84
        mlayer.removeSelection(True)
 
85
        vlayer = ftools_utils.getVectorLayerByName(inVect)
 
86
        vprovider = vlayer.dataProvider()
 
87
        allAttrs = vprovider.attributeIndexes()
 
88
        vprovider.select(allAttrs)
 
89
        index = vprovider.fieldNameIndex(inField)
 
90
        #unique = []
 
91
        #vprovider.uniqueValues(index, unique)
 
92
        unique = ftools_utils.getUniqueValues(vprovider, int(index))
 
93
        inFeat = QgsFeature()
 
94
        selran = []
 
95
        nFeat = vprovider.featureCount() * len(unique)
 
96
        nElement = 0
 
97
        self.progressBar.setValue(0)
 
98
        self.progressBar.setRange(0, nFeat)
 
99
        if not len(unique) == mlayer.featureCount():
 
100
            for i in unique:
 
101
                vprovider.rewind()
 
102
                FIDs= []
 
103
                while vprovider.nextFeature(inFeat):
 
104
                    atMap = inFeat.attributeMap()
 
105
                    if atMap[index] == QVariant(i):
 
106
                        FID = inFeat.id()
 
107
                        FIDs.append(FID)
 
108
                    nElement += 1
 
109
                    self.progressBar.setValue(nElement)
 
110
                if perc: selVal = int(round((value / 100.0000) * len(FIDs), 0))
 
111
                else: selVal = value
 
112
                if selVal >= len(FIDs): selFeat = FIDs
 
113
                else: selFeat = random.sample(FIDs, selVal)
 
114
                selran.extend(selFeat)
 
115
            mlayer.setSelectedFeatures(selran)
 
116
        else:
 
117
            mlayer.setSelectedFeatures(range(0, mlayer.featureCount()))