Skip to content

Commit 401aea2

Browse files
committed
Merge pull request #111 from etiennesky/ftools1
Ftools vector grid improvements
2 parents be4d125 + 8966899 commit 401aea2

File tree

2 files changed

+132
-15
lines changed

2 files changed

+132
-15
lines changed

python/plugins/fTools/tools/doVectorGrid.py

+109-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import ftools_utils
3434
from qgis.core import *
3535
from ui_frmVectorGrid import Ui_Dialog
36+
import math
3637

3738
class Dialog(QDialog, Ui_Dialog):
3839
def __init__(self, iface):
@@ -44,6 +45,7 @@ def __init__(self, iface):
4445
#QObject.connect(self.inShape, SIGNAL("currentIndexChanged(QString)"), self.updateInput)
4546
QObject.connect(self.btnUpdate, SIGNAL("clicked()"), self.updateLayer)
4647
QObject.connect(self.btnCanvas, SIGNAL("clicked()"), self.updateCanvas)
48+
QObject.connect(self.chkAlign, SIGNAL("toggled(bool)"), self.chkAlignToggled)
4749
self.buttonOk = self.buttonBox_2.button( QDialogButtonBox.Ok )
4850
self.setWindowTitle(self.tr("Vector grid"))
4951
self.xMin.setValidator(QDoubleValidator(self.xMin))
@@ -57,6 +59,8 @@ def populateLayers( self ):
5759
layermap = QgsMapLayerRegistry.instance().mapLayers()
5860
for name, layer in layermap.iteritems():
5961
self.inShape.addItem( unicode( layer.name() ) )
62+
if layer == self.iface.activeLayer():
63+
self.inShape.setCurrentIndex( self.inShape.count() -1 )
6064

6165
def offset(self, value):
6266
if self.chkLock.isChecked():
@@ -66,12 +70,50 @@ def updateLayer( self ):
6670
mLayerName = self.inShape.currentText()
6771
if not mLayerName == "":
6872
mLayer = ftools_utils.getMapLayerByName( unicode( mLayerName ) )
73+
# get layer extents
6974
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)
7084
self.updateExtents( boundBox )
7185

7286
def updateCanvas( self ):
7387
canvas = self.iface.mapCanvas()
7488
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"))
75117
self.updateExtents( boundBox )
76118

77119
def updateExtents( self, boundBox ):
@@ -100,7 +142,9 @@ def accept(self):
100142
if self.rdoPolygons.isChecked(): polygon = True
101143
else: polygon = False
102144
self.outShape.clear()
145+
QApplication.setOverrideCursor(Qt.WaitCursor)
103146
self.compute( boundBox, xSpace, ySpace, polygon )
147+
QApplication.restoreOverrideCursor()
104148
addToTOC = QMessageBox.question(self, self.tr("Generate Vector Grid"), self.tr("Created output shapefile:\n%1\n\nWould you like to add the new layer to the TOC?").arg(unicode(self.shapefileName)), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton)
105149
if addToTOC == QMessageBox.Yes:
106150
ftools_utils.addShapeToCanvas( self.shapefileName )
@@ -131,8 +175,13 @@ def compute( self, bound, xOffset, yOffset, polygon ):
131175
outFeat = QgsFeature()
132176
outGeom = QgsGeometry()
133177
idVar = 0
134-
self.progressBar.setRange( 0, 0 )
178+
# self.progressBar.setRange( 0, 0 )
179+
self.progressBar.setValue( 0 )
135180
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
136185
y = bound.yMaximum()
137186
while y >= bound.yMinimum():
138187
pt1 = QgsPoint(bound.xMinimum(), y)
@@ -144,6 +193,15 @@ def compute( self, bound, xOffset, yOffset, polygon ):
144193
writer.addFeature(outFeat)
145194
y = y - yOffset
146195
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
147205
x = bound.xMinimum()
148206
while x <= bound.xMaximum():
149207
pt1 = QgsPoint(x, bound.yMaximum())
@@ -155,7 +213,15 @@ def compute( self, bound, xOffset, yOffset, polygon ):
155213
writer.addFeature(outFeat)
156214
x = x + xOffset
157215
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 )
158220
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
159225
y = bound.yMaximum()
160226
while y >= bound.yMinimum():
161227
x = bound.xMinimum()
@@ -176,7 +242,12 @@ def compute( self, bound, xOffset, yOffset, polygon ):
176242
idVar = idVar + 1
177243
x = x + xOffset
178244
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 )
180251
del writer
181252

182253
def outFile(self):
@@ -185,3 +256,39 @@ def outFile(self):
185256
if self.shapefileName is None or self.encoding is None:
186257
return
187258
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+

python/plugins/fTools/tools/frmVectorGrid.ui

+23-13
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
<rect>
1010
<x>0</x>
1111
<y>0</y>
12-
<width>438</width>
13-
<height>459</height>
12+
<width>489</width>
13+
<height>475</height>
1414
</rect>
1515
</property>
1616
<property name="windowTitle">
@@ -29,7 +29,7 @@
2929
<item row="0" column="0" colspan="2">
3030
<widget class="QComboBox" name="inShape"/>
3131
</item>
32-
<item row="1" column="0">
32+
<item row="2" column="0">
3333
<widget class="QToolButton" name="btnUpdate">
3434
<property name="minimumSize">
3535
<size>
@@ -42,7 +42,7 @@
4242
</property>
4343
</widget>
4444
</item>
45-
<item row="1" column="1">
45+
<item row="2" column="1">
4646
<widget class="QToolButton" name="btnCanvas">
4747
<property name="minimumSize">
4848
<size>
@@ -55,7 +55,7 @@
5555
</property>
5656
</widget>
5757
</item>
58-
<item row="2" column="0">
58+
<item row="3" column="0">
5959
<layout class="QHBoxLayout">
6060
<item>
6161
<widget class="QLabel" name="label">
@@ -82,7 +82,7 @@
8282
</item>
8383
</layout>
8484
</item>
85-
<item row="2" column="1">
85+
<item row="3" column="1">
8686
<layout class="QHBoxLayout">
8787
<item>
8888
<widget class="QLabel" name="label_4">
@@ -109,7 +109,7 @@
109109
</item>
110110
</layout>
111111
</item>
112-
<item row="3" column="0">
112+
<item row="4" column="0">
113113
<layout class="QHBoxLayout">
114114
<item>
115115
<widget class="QLabel" name="label_3">
@@ -136,7 +136,7 @@
136136
</item>
137137
</layout>
138138
</item>
139-
<item row="3" column="1">
139+
<item row="4" column="1">
140140
<layout class="QHBoxLayout">
141141
<item>
142142
<widget class="QLabel" name="label_5">
@@ -163,6 +163,13 @@
163163
</item>
164164
</layout>
165165
</item>
166+
<item row="1" column="0" colspan="2">
167+
<widget class="QCheckBox" name="chkAlign">
168+
<property name="text">
169+
<string>Align extents and resolution to selected raster layer</string>
170+
</property>
171+
</widget>
172+
</item>
166173
</layout>
167174
</widget>
168175
</item>
@@ -186,7 +193,7 @@
186193
</spacer>
187194
</item>
188195
<item row="0" column="1">
189-
<widget class="QLabel" name="label_7">
196+
<widget class="QLabel" name="lblX">
190197
<property name="text">
191198
<string>X</string>
192199
</property>
@@ -245,7 +252,7 @@
245252
</spacer>
246253
</item>
247254
<item row="1" column="1">
248-
<widget class="QLabel" name="label_8">
255+
<widget class="QLabel" name="lblY">
249256
<property name="enabled">
250257
<bool>false</bool>
251258
</property>
@@ -279,7 +286,7 @@
279286
<string>Output grid as polygons</string>
280287
</property>
281288
<property name="checked">
282-
<bool>true</bool>
289+
<bool>false</bool>
283290
</property>
284291
</widget>
285292
</item>
@@ -288,6 +295,9 @@
288295
<property name="text">
289296
<string>Output grid as lines</string>
290297
</property>
298+
<property name="checked">
299+
<bool>true</bool>
300+
</property>
291301
</widget>
292302
</item>
293303
</layout>
@@ -385,7 +395,7 @@
385395
</connection>
386396
<connection>
387397
<sender>chkLock</sender>
388-
<signal>clicked(bool)</signal>
398+
<signal>toggled(bool)</signal>
389399
<receiver>spnY</receiver>
390400
<slot>setDisabled(bool)</slot>
391401
<hints>
@@ -402,7 +412,7 @@
402412
<connection>
403413
<sender>chkLock</sender>
404414
<signal>toggled(bool)</signal>
405-
<receiver>label_8</receiver>
415+
<receiver>lblY</receiver>
406416
<slot>setDisabled(bool)</slot>
407417
<hints>
408418
<hint type="sourcelabel">

0 commit comments

Comments
 (0)