valuewidget.py

widget, taking otf projection into account - Richard Duivenvoorde, 2011-09-06 05:45 AM

Download (9.34 KB)

 
1
"""
2
/***************************************************************************
3
         Value Tool       - A QGIS plugin to get values at the mouse pointer
4
                             -------------------
5
    begin                : 2008-08-26
6
    copyright            : (C) 2008 by G. Picard
7
    email                : 
8
 ***************************************************************************/
9

10
/***************************************************************************
11
 *                                                                         *
12
 *   This program is free software; you can redistribute it and/or modify  *
13
 *   it under the terms of the GNU General Public License as published by  *
14
 *   the Free Software Foundation; either version 2 of the License, or     *
15
 *   (at your option) any later version.                                   *
16
 *                                                                         *
17
 ***************************************************************************/
18
 This script initializes the plugin, making it known to QGIS.
19
"""
20

    
21
from PyQt4.QtCore import *
22
from PyQt4.QtGui import *
23
from qgis.core import *
24

    
25
hasqwt=True
26
try:
27
    from PyQt4.Qwt5 import QwtPlot,QwtPlotCurve,QwtScaleDiv,QwtSymbol
28
except:
29
    hasqwt=False
30

    
31
from valuewidgetbase import Ui_Form
32

    
33
class ValueWidget(QWidget,Ui_Form):
34

    
35
    def __init__(self, iface, canvas):
36
        QWidget.__init__(self)
37

    
38
        
39
        Ui_Form.__init__(self)
40
        self.setupUi(self)
41

    
42
        self.iface=iface
43
        self.canvas=canvas
44

    
45
        QObject.connect(self.checkBox_2,SIGNAL("stateChanged(int)"),self.changeActive)
46
        self.changeActive(Qt.Checked)
47
        QObject.connect(self.checkBox,SIGNAL("stateChanged(int)"),self.changePage)
48
        QObject.connect(self.canvas, SIGNAL( "keyPressed( QKeyEvent * )" ), self.pauseDisplay )
49

    
50
        if (hasqwt):
51
            self.curve = QwtPlotCurve()
52
            self.curve.setSymbol(
53
                QwtSymbol(QwtSymbol.Ellipse,
54
                          QBrush(Qt.white),
55
                          QPen(Qt.red, 2),
56
                          QSize(9, 9)))
57
            self.curve.attach(self.qwtPlot)
58

    
59
    def disconnect(self):
60
        self.changeActive(False)
61
        QObject.disconnect(self.canvas, SIGNAL( "keyPressed( QKeyEvent * )" ), self.pauseDisplay )
62

    
63

    
64
    def pauseDisplay(self,e):
65
      if ( e.modifiers() == Qt.ShiftModifier or e.modifiers() == Qt.MetaModifier ) and e.key() == Qt.Key_A:
66

    
67
        self.checkBox_2.toggle()
68
        return True
69
      return False
70

    
71

    
72
    def keyPressEvent( self, e ):
73
      if ( e.modifiers() == Qt.ControlModifier or e.modifiers() == Qt.MetaModifier ) and e.key() == Qt.Key_C:
74
        items = QString()
75
        for rec in range( self.tableWidget.rowCount() ):
76
          items.append( '"' + self.tableWidget.item( rec, 0 ).text() + '",' + self.tableWidget.item( rec, 1 ).text() + "\n" )
77
        if not items.isEmpty():
78
          clipboard = QApplication.clipboard()
79
          clipboard.setText( items )
80
      elif (self.pauseDisplay(e)):
81
        pass
82
      else:
83
        QWidget.keyPressEvent( self, e )
84

    
85

    
86
    def changePage(self,state):
87
        if (state==Qt.Checked):
88
            self.stackedWidget.setCurrentIndex(1)
89
        else:
90
            self.stackedWidget.setCurrentIndex(0)
91

    
92
    def changeActive(self,state):
93
        if (state==Qt.Checked):
94
            if int(QGis.QGIS_VERSION[2]) > 2: # for QGIS >= 1.3
95
                QObject.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint &)"), self.printValue)
96
            else:
97
                QObject.connect(self.canvas, SIGNAL("xyCoordinates(QgsPoint &)"), self.printValue)
98
        else:
99
            if int(QGis.QGIS_VERSION[2]) > 2: # for QGIS >= 1.3
100
                QObject.disconnect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint &)"), self.printValue)
101
            else:
102
                QObject.disconnect(self.canvas, SIGNAL("xyCoordinates(QgsPoint &)"), self.printValue)
103

    
104

    
105
    def printValue(self,position):
106
        mapPos = position
107

    
108
        needextremum= self.checkBox.isChecked() # if plot is checked
109

    
110
        layers=self.iface
111

    
112
        # count the number of requires rows and remember the raster layers
113
        nrow=0
114
        rasterlayers=[]
115
        layersWOStatistics=[]
116

    
117
        for i in range(self.canvas.layerCount()):
118
            layer = self.canvas.layer(i)
119
            if (layer!=None and layer.isValid() and layer.type()==QgsMapLayer.RasterLayer):
120
              if layer.providerKey()=="wms":
121
                continue
122

    
123
              if layer.providerKey()=="grassraster":
124
                nrow+=1
125
                rasterlayers.append(layer)
126
              else: # normal raster layer
127
                nrow+=layer.bandCount()
128
                rasterlayers.append(layer)
129
                
130
              # check statistics for each band
131
              if needextremum:
132
                for i in range( 1,layer.bandCount()+1 ):
133
                  if not layer.hasStatistics(i):
134
                    layersWOStatistics.append((layer,i))
135

    
136
        if layersWOStatistics:
137
          self.calculateStatistics(layersWOStatistics)
138
                  
139
        # create the row if necessary
140
        self.tableWidget.setRowCount(nrow)
141

    
142
        irow=0
143
        self.values=[]
144
        self.ymin=1e38
145
        self.ymax=-1e38
146

    
147

    
148
        mapCanvasSrs = self.iface.mapCanvas().mapRenderer().destinationSrs()
149

    
150
        for layer in rasterlayers:
151

    
152
            layerSrs = layer.srs()
153
            pos = mapPos
154
            if not mapCanvasSrs == layerSrs:
155
              srsTransform = QgsCoordinateTransform(mapCanvasSrs, layerSrs)
156
              pos = srsTransform.transform(mapPos)
157

    
158
            isok,ident = layer.identify(pos)
159
            if not isok:
160
              continue
161

    
162
            layername=unicode(layer.name())
163

    
164
            if layer.providerKey()=="grassraster":
165
              if not ident.has_key(QString("value")):
166
                continue
167
              cstr = ident[QString("value")]
168
              if cstr.isNull():
169
                continue
170
              value = cstr.toDouble()
171
              if not value[1]:
172
                continue
173
              self.values.append((layername,cstr))
174
              if needextremum:
175
                self.ymin = min(self.ymin,value[0])
176
                self.ymax = max(self.ymax,value[0])
177

    
178
            else:
179
              for iband in range(1,layer.bandCount()+1): # loop over the bands
180
                bandvalue=ident[layer.bandName(iband)]
181
                layernamewithband=layername
182
                if len(ident)>1:
183
                    layernamewithband+=' '+layer.bandName(iband)
184

    
185
                self.values.append((layernamewithband,bandvalue))
186

    
187
                if needextremum:
188
                  cstr=layer.bandStatistics(iband)
189
                  self.ymin=min(self.ymin,cstr.minimumValue)
190
                  self.ymax=max(self.ymax,cstr.maximumValue)
191

    
192

    
193
        if self.checkBox.isChecked():
194
          self.plot()
195
        else:
196
          self.printInTable()
197

    
198

    
199
    def calculateStatistics(self,layersWOStatistics):
200

    
201
      lays= [l[0].name() for l in layersWOStatistics]
202
      lays = list(set( lays ))
203
      lays = QStringList() << lays
204
      res = QMessageBox.warning( self, self.tr( 'Warning' ),
205
                                 self.tr( 'There are no statistics in the following rasters:\n%1\n\nCalculate?' ).arg(lays.join('\n')),
206
                                 QMessageBox.Yes | QMessageBox.No )
207
      if res != QMessageBox.Yes:
208
        self.checkBox_2.setCheckState(Qt.Unchecked)
209
        return
210

    
211
      # calculate statistics
212
      save_state=self.checkBox_2.isChecked()
213
      self.changeActive(Qt.Unchecked) # deactivate
214

    
215
      for layerband in layersWOStatistics:
216
        layer,iband=layerband
217
        stat = layer.bandStatistics(iband)
218

    
219
      if save_state:
220
        self.changeActive(Qt.Checked) # activate if necessary
221

    
222

    
223
    def printInTable(self):
224

    
225
        irow=0
226
        for row in self.values:
227
          layername,value=row
228
          if (self.tableWidget.item(irow,0)==None):
229
              # create the item
230
              self.tableWidget.setItem(irow,0,QTableWidgetItem())
231
              self.tableWidget.setItem(irow,1,QTableWidgetItem())
232

    
233

    
234
          self.tableWidget.item(irow,0).setText(layername)
235
          self.tableWidget.item(irow,1).setText(value)
236
          irow+=1
237

    
238

    
239
    def plot(self):
240

    
241
        if (hasqwt):
242
            numvalues=[]
243
            self.qwtPlot.setAxisMaxMinor(QwtPlot.xBottom,0)
244
            #self.qwtPlot.setAxisMaxMajor(QwtPlot.xBottom,0)
245
            self.qwtPlot.setAxisScale(QwtPlot.xBottom,1,len(self.values))
246
            self.qwtPlot.setAxisScale(QwtPlot.yLeft,self.ymin,self.ymax)
247
            
248
            for row in self.values:
249
                layername,value=row
250
                try:
251
                    numvalues.append(float(value))
252
                except:
253
                    numvalues.append(0)
254
            self.curve.setData(range(1,len(numvalues)+1), numvalues)
255
            self.qwtPlot.replot()
256

    
257
        #try:
258
                #    attr = float(ident[j])
259
                #except:
260
                #    attr = 0
261
                #    print "Null cell value catched as zero!"  # For none values, profile height = 0. It's not elegant...
262

    
263
                    #nr = rastLayer.getRasterBandNumber(self.rastItems[field[1]][field[2]][0])
264

    
265
                    #print ident
266
            #for j in ident:
267
                #print j
268
                #if j.right(1) == str(nr):
269
       #attr = int(ident[j])
270
       #attr = float(ident[j])  ##### I MUST IMPLEMENT RASTER TYPE HANDLING!!!!
271
       #outFeat.addAttribute(i, QVariant(attr))