33
33
import ftools_utils
34
34
from qgis .core import *
35
35
from ui_frmVectorGrid import Ui_Dialog
36
+ import math
36
37
37
38
class Dialog (QDialog , Ui_Dialog ):
38
39
def __init__ (self , iface ):
@@ -44,6 +45,7 @@ def __init__(self, iface):
44
45
#QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.updateInput)
45
46
QObject .connect (self .btnUpdate , SIGNAL ("clicked()" ), self .updateLayer )
46
47
QObject .connect (self .btnCanvas , SIGNAL ("clicked()" ), self .updateCanvas )
48
+ QObject .connect (self .chkAlign , SIGNAL ("toggled(bool)" ), self .chkAlignToggled )
47
49
self .buttonOk = self .buttonBox_2 .button ( QDialogButtonBox .Ok )
48
50
self .setWindowTitle (self .tr ("Vector grid" ))
49
51
self .xMin .setValidator (QDoubleValidator (self .xMin ))
@@ -57,6 +59,8 @@ def populateLayers( self ):
57
59
layermap = QgsMapLayerRegistry .instance ().mapLayers ()
58
60
for name , layer in layermap .iteritems ():
59
61
self .inShape .addItem ( unicode ( layer .name () ) )
62
+ if layer == self .iface .activeLayer ():
63
+ self .inShape .setCurrentIndex ( self .inShape .count () - 1 )
60
64
61
65
def offset (self , value ):
62
66
if self .chkLock .isChecked ():
@@ -66,12 +70,50 @@ def updateLayer( self ):
66
70
mLayerName = self .inShape .currentText ()
67
71
if not mLayerName == "" :
68
72
mLayer = ftools_utils .getMapLayerByName ( unicode ( mLayerName ) )
73
+ # get layer extents
69
74
boundBox = mLayer .extent ()
75
+ # if "align extents and resolution..." button is checked
76
+ if self .chkAlign .isChecked ():
77
+ if not mLayer .type () == QgsMapLayer .RasterLayer :
78
+ QMessageBox .information (self , self .tr ("Vector grid" ), self .tr ("Please select a raster layer" ))
79
+ else :
80
+ dx = math .fabs (boundBox .xMaximum ()- boundBox .xMinimum ()) / mLayer .width ()
81
+ dy = math .fabs (boundBox .yMaximum ()- boundBox .yMinimum ()) / mLayer .height ()
82
+ self .spnX .setValue (dx )
83
+ self .spnY .setValue (dy )
70
84
self .updateExtents ( boundBox )
71
85
72
86
def updateCanvas ( self ):
73
87
canvas = self .iface .mapCanvas ()
74
88
boundBox = canvas .extent ()
89
+ # if "align extents and resolution..." button is checked
90
+ if self .chkAlign .isChecked ():
91
+ mLayerName = self .inShape .currentText ()
92
+ if not mLayerName == "" :
93
+ mLayer = ftools_utils .getMapLayerByName ( unicode ( mLayerName ) )
94
+ if not mLayer .type () == QgsMapLayer .RasterLayer :
95
+ QMessageBox .information (self , self .tr ("Vector grid" ), self .tr ("Please select a raster layer" ))
96
+ else :
97
+ # get extents and pixel size
98
+ xMin = boundBox .xMinimum ()
99
+ yMin = boundBox .yMinimum ()
100
+ xMax = boundBox .xMaximum ()
101
+ yMax = boundBox .yMaximum ()
102
+ boundBox2 = mLayer .extent ()
103
+ dx = math .fabs (boundBox2 .xMaximum ()- boundBox2 .xMinimum ()) / mLayer .width ()
104
+ dy = math .fabs (boundBox2 .yMaximum ()- boundBox2 .yMinimum ()) / mLayer .height ()
105
+ # get pixels from the raster that are closest to the desired extent
106
+ newXMin = self .getClosestPixel ( boundBox2 .xMinimum (), boundBox .xMinimum (), dx , True )
107
+ newXMax = self .getClosestPixel ( boundBox2 .xMaximum (), boundBox .xMaximum (), dx , False )
108
+ newYMin = self .getClosestPixel ( boundBox2 .yMinimum (), boundBox .yMinimum (), dy , True )
109
+ newYMax = self .getClosestPixel ( boundBox2 .yMaximum (), boundBox .yMaximum (), dy , False )
110
+ # apply new values if found all min/max
111
+ if newXMin is not None and newXMax is not None and newYMin is not None and newYMax is not None :
112
+ boundBox .set ( newXMin , newYMin , newXMax , newYMax )
113
+ self .spnX .setValue (dx )
114
+ self .spnY .setValue (dy )
115
+ else :
116
+ QMessageBox .information (self , self .tr ("Vector grid" ), self .tr ("Unable to compute extents aligned on selected raster layer" ))
75
117
self .updateExtents ( boundBox )
76
118
77
119
def updateExtents ( self , boundBox ):
@@ -100,7 +142,9 @@ def accept(self):
100
142
if self .rdoPolygons .isChecked (): polygon = True
101
143
else : polygon = False
102
144
self .outShape .clear ()
145
+ QApplication .setOverrideCursor (Qt .WaitCursor )
103
146
self .compute ( boundBox , xSpace , ySpace , polygon )
147
+ QApplication .restoreOverrideCursor ()
104
148
addToTOC = QMessageBox .question (self , self .tr ("Generate Vector Grid" ), self .tr ("Created output shapefile:\n %1\n \n Would you like to add the new layer to the TOC?" ).arg (unicode (self .shapefileName )), QMessageBox .Yes , QMessageBox .No , QMessageBox .NoButton )
105
149
if addToTOC == QMessageBox .Yes :
106
150
ftools_utils .addShapeToCanvas ( self .shapefileName )
@@ -131,8 +175,13 @@ def compute( self, bound, xOffset, yOffset, polygon ):
131
175
outFeat = QgsFeature ()
132
176
outGeom = QgsGeometry ()
133
177
idVar = 0
134
- self .progressBar .setRange ( 0 , 0 )
178
+ # self.progressBar.setRange( 0, 0 )
179
+ self .progressBar .setValue ( 0 )
135
180
if not polygon :
181
+ # counters for progressbar - update every 5%
182
+ count = 0
183
+ count_max = (bound .yMaximum () - bound .yMinimum ()) / yOffset
184
+ count_update = count_max * 0.10
136
185
y = bound .yMaximum ()
137
186
while y >= bound .yMinimum ():
138
187
pt1 = QgsPoint (bound .xMinimum (), y )
@@ -144,6 +193,15 @@ def compute( self, bound, xOffset, yOffset, polygon ):
144
193
writer .addFeature (outFeat )
145
194
y = y - yOffset
146
195
idVar = idVar + 1
196
+ count += 1
197
+ if int ( math .fmod ( count , count_update ) ) == 0 :
198
+ prog = int ( count / count_max * 50 )
199
+ self .progressBar .setValue ( prog )
200
+ self .progressBar .setValue ( 50 )
201
+ # counters for progressbar - update every 5%
202
+ count = 0
203
+ count_max = (bound .xMaximum () - bound .xMinimum ()) / xOffset
204
+ count_update = count_max * 0.10
147
205
x = bound .xMinimum ()
148
206
while x <= bound .xMaximum ():
149
207
pt1 = QgsPoint (x , bound .yMaximum ())
@@ -155,7 +213,15 @@ def compute( self, bound, xOffset, yOffset, polygon ):
155
213
writer .addFeature (outFeat )
156
214
x = x + xOffset
157
215
idVar = idVar + 1
216
+ count += 1
217
+ if int ( math .fmod ( count , count_update ) ) == 0 :
218
+ prog = 50 + int ( count / count_max * 50 )
219
+ self .progressBar .setValue ( prog )
158
220
else :
221
+ # counters for progressbar - update every 5%
222
+ count = 0
223
+ count_max = (bound .yMaximum () - bound .yMinimum ()) / yOffset
224
+ count_update = count_max * 0.05
159
225
y = bound .yMaximum ()
160
226
while y >= bound .yMinimum ():
161
227
x = bound .xMinimum ()
@@ -176,7 +242,12 @@ def compute( self, bound, xOffset, yOffset, polygon ):
176
242
idVar = idVar + 1
177
243
x = x + xOffset
178
244
y = y - yOffset
179
- self .progressBar .setRange ( 0 , 100 )
245
+ count += 1
246
+ if int ( math .fmod ( count , count_update ) ) == 0 :
247
+ prog = int ( count / count_max * 100 )
248
+
249
+ self .progressBar .setValue ( 100 )
250
+ #self.progressBar.setRange( 0, 100 )
180
251
del writer
181
252
182
253
def outFile (self ):
@@ -185,3 +256,39 @@ def outFile(self):
185
256
if self .shapefileName is None or self .encoding is None :
186
257
return
187
258
self .outShape .setText ( QString ( self .shapefileName ) )
259
+
260
+ def chkAlignToggled (self ):
261
+ if self .chkAlign .isChecked ():
262
+ self .spnX .setEnabled ( False )
263
+ self .lblX .setEnabled ( False )
264
+ self .spnY .setEnabled ( False )
265
+ self .lblY .setEnabled ( False )
266
+ else :
267
+ self .spnX .setEnabled ( True )
268
+ self .lblX .setEnabled ( True )
269
+ self .spnY .setEnabled ( not self .chkLock .isChecked () )
270
+ self .lblY .setEnabled ( not self .chkLock .isChecked () )
271
+
272
+ def getClosestPixel (self , startVal , targetVal , step , isMin ):
273
+ foundVal = None
274
+ tmpVal = startVal
275
+ # find pixels covering the extent - slighlyt inneficient b/c loop on all elements before xMin
276
+ if targetVal < startVal :
277
+ backOneStep = not isMin
278
+ step = - step
279
+ while foundVal is None :
280
+ if tmpVal <= targetVal :
281
+ if backOneStep :
282
+ tmpVal -= step
283
+ foundVal = tmpVal
284
+ tmpVal += step
285
+ else :
286
+ backOneStep = isMin
287
+ while foundVal is None :
288
+ if tmpVal >= targetVal :
289
+ if backOneStep :
290
+ tmpVal -= step
291
+ foundVal = tmpVal
292
+ tmpVal += step
293
+ return foundVal
294
+
0 commit comments