Skip to content

Commit 7e93081

Browse files
author
volayaf@gmail.com
committed
Improvements in R Connection (more or less working now)
added R toolbox actions git-svn-id: http://sextante.googlecode.com/svn/trunk/soft/bindings/qgis-plugin@31 881b9c09-3ef8-f3c2-ec3d-21d735c97f4d
1 parent 1b68f20 commit 7e93081

10 files changed

+226
-33
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from sextante.core.GeoAlgorithm import GeoAlgorithm
2+
import os.path
3+
from PyQt4 import QtGui
4+
from PyQt4.QtCore import *
5+
from PyQt4.QtGui import *
6+
from qgis.core import *
7+
from sextante.parameters.ParameterVector import ParameterVector
8+
from sextante.core.QGisLayers import QGisLayers
9+
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
10+
from sextante.outputs.OutputVector import OutputVector
11+
12+
class LayerFromExtent(GeoAlgorithm):
13+
14+
INPUT = "INPUT"
15+
OUTPUT = "OUTPUT"
16+
17+
def getIcon(self):
18+
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/layer_extent.png")
19+
20+
def processAlgorithm(self, progress):
21+
settings = QSettings()
22+
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
23+
output = self.getOutputValue(LayerFromExtent.OUTPUT)
24+
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(LayerFromExtent.INPUT))
25+
fields = {
26+
0 : QgsField( "MINX", QVariant.Double ),
27+
1 : QgsField( "MINY", QVariant.Double ),
28+
2 : QgsField( "MAXX", QVariant.Double ),
29+
3 : QgsField( "MAXY", QVariant.Double ),
30+
4 : QgsField( "CNTX", QVariant.Double ),
31+
5 : QgsField( "CNTY", QVariant.Double ),
32+
6 : QgsField( "AREA", QVariant.Double ),
33+
7 : QgsField( "PERIM", QVariant.Double ),
34+
8 : QgsField( "HEIGHT", QVariant.Double ),
35+
9 : QgsField( "WIDTH", QVariant.Double ) }
36+
37+
writer = QgsVectorFileWriter( output, systemEncoding, fields, QGis.WKBPolygon, self.vlayer.crs() )
38+
rect = vlayer.extent()
39+
minx = rect.xMinimum()
40+
miny = rect.yMinimum()
41+
maxx = rect.xMaximum()
42+
maxy = rect.yMaximum()
43+
height = rect.height()
44+
width = rect.width()
45+
cntx = minx + ( width / 2.0 )
46+
cnty = miny + ( height / 2.0 )
47+
area = width * height
48+
perim = ( 2 * width ) + (2 * height )
49+
rect = [
50+
QgsPoint( minx, miny ),
51+
QgsPoint( minx, maxy ),
52+
QgsPoint( maxx, maxy ),
53+
QgsPoint( maxx, miny ),
54+
QgsPoint( minx, miny ) ]
55+
geometry = QgsGeometry().fromPolygon( [ rect ] )
56+
feat = QgsFeature()
57+
feat.setGeometry( geometry )
58+
feat.setAttributeMap( {
59+
0 : QVariant( minx ),
60+
1 : QVariant( miny ),
61+
2 : QVariant( maxx ),
62+
3 : QVariant( maxy ),
63+
4 : QVariant( cntx ),
64+
5 : QVariant( cnty ),
65+
6 : QVariant( area ),
66+
7 : QVariant( perim ),
67+
8 : QVariant( height ),
68+
9 : QVariant( width ) } )
69+
writer.addFeature( feat )
70+
del writer
71+
72+
def defineCharacteristics(self):
73+
self.name = "Layer from layer extent"
74+
self.group = "Geometry tools"
75+
self.addParameter(ParameterVector(LayerFromExtent.INPUT, "Input layer", ParameterVector.VECTOR_TYPE_ANY))
76+
self.addOutput(OutputVector(LayerFromExtent.OUTPUT, "Output layer"))
77+
#=========================================================

src/sextante/gui/SextanteToolbox.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ def executeAlgorithm(self):
8989
alg = copy.deepcopy(alg)
9090
dlg = ParametersDialog(alg)
9191
dlg.exec_()
92-
9392
if isinstance(item, TreeActionItem):
9493
action = item.action
9594
action.setData(self)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from sextante.script.EditScriptDialog import EditScriptDialog
2+
from sextante.gui.ToolboxAction import ToolboxAction
3+
import os
4+
from PyQt4 import QtGui
5+
from sextante.r.EditRScriptDialog import EditRScriptDialog
6+
7+
class CreateNewRScriptAction(ToolboxAction):
8+
9+
def __init__(self):
10+
self.name="Create new R script"
11+
self.group="Tools"
12+
13+
def getIcon(self):
14+
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/r.png")
15+
16+
def execute(self):
17+
dlg = EditRScriptDialog(None)
18+
dlg.exec_()
19+
if dlg.update:
20+
self.toolbox.updateTree()

src/sextante/r/EditRScriptAction.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from sextante.gui.ContextAction import ContextAction
2+
from sextante.r.RAlgorithm import RAlgorithm
3+
from sextante.r.EditRScriptDialog import EditRScriptDialog
4+
5+
class EditRScriptAction(ContextAction):
6+
7+
def __init__(self):
8+
self.name="Edit R script"
9+
10+
def isEnabled(self):
11+
return isinstance(self.alg, RAlgorithm)
12+
13+
def execute(self):
14+
dlg = EditRScriptDialog(self.alg)
15+
dlg.exec_()
16+
if dlg.update:
17+
self.toolbox.updateTree()

src/sextante/r/EditRScriptDialog.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from PyQt4 import QtCore, QtGui
2+
from PyQt4.QtCore import *
3+
from PyQt4.QtGui import *
4+
from sextante.r.RUtils import RUtils
5+
6+
class EditRScriptDialog(QtGui.QDialog):
7+
def __init__(self, alg):
8+
self.alg = alg
9+
QtGui.QDialog.__init__(self)
10+
self.setModal(True)
11+
self.setupUi()
12+
self.update = False
13+
14+
def setupUi(self):
15+
self.setObjectName("Dialog")
16+
self.resize(655, 360)
17+
self.setWindowTitle("Edit script")
18+
self.text = QtGui.QTextEdit(self)
19+
self.text.setGeometry(QtCore.QRect(5, 5, 550, 350))
20+
self.text.setObjectName("text")
21+
self.text.setEnabled(True)
22+
if self.alg != None:
23+
self.text.setText(self.alg.script)
24+
self.saveButton = QtGui.QPushButton(self)
25+
self.saveButton.setGeometry(QtCore.QRect(570, 300, 80, 23))
26+
self.saveButton.setObjectName("saveButton")
27+
self.saveButton.setText("Save")
28+
self.cancelButton = QtGui.QPushButton(self)
29+
self.cancelButton.setGeometry(QtCore.QRect(570, 327, 80, 23))
30+
self.cancelButton.setObjectName("cancelButton")
31+
self.cancelButton.setText("Cancel")
32+
QObject.connect(self.saveButton, QtCore.SIGNAL("clicked()"), self.saveAlgorithm)
33+
QObject.connect(self.cancelButton, QtCore.SIGNAL("clicked()"), self.cancel)
34+
QtCore.QMetaObject.connectSlotsByName(self)
35+
36+
def saveAlgorithm(self):
37+
if self.alg!=None:
38+
filename = self.alg.descriptionFile
39+
else:
40+
filename = QtGui.QFileDialog.getSaveFileName(self, "Save Script", RUtils.RScriptsFolder(), "R-SEXTANTE scripts (*.rsx)")
41+
if filename:
42+
text = self.text.toPlainText()
43+
fout = open(filename, "w")
44+
fout.write(text)
45+
fout.close()
46+
self.update = True
47+
self.close()
48+
49+
def cancel(self):
50+
self.update = False
51+
self.close()

src/sextante/r/RAlgorithm.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def getIcon(self):
3232
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/script.png")
3333

3434
def defineCharacteristicsFromFile(self):
35-
self.commands=""
35+
self.script = ""
36+
self.commands=[]
3637
self.showPlots = False
3738
self.showConsoleOutput = False
3839
self.verboseCommands = []
@@ -45,13 +46,14 @@ def defineCharacteristicsFromFile(self):
4546
if line.startswith("##"):
4647
self.processParameterLine(line)
4748
elif line.startswith(">"):
48-
self.commands += line[1:]
49+
self.commands.append(line[1:])
4950
self.verboseCommands.append(line[1:])
5051
if not self.showConsoleOutput:
5152
self.addOutput(OutputHTML(RAlgorithm.R_CONSOLE_OUTPUT, "R Console Output"))
5253
self.showConsoleOutput = True
5354
else:
54-
self.commands += line
55+
self.commands.append(line)
56+
self.script += line + "\n"
5557
line = lines.readline().strip("\n")
5658
lines.close()
5759

@@ -146,8 +148,8 @@ def getFullSetOfRCommands(self):
146148

147149
commands = []
148150
commands += self.getImportCommands()
149-
commands += self.getExportCommands()
150151
commands += self.getRCommands()
152+
commands += self.getExportCommands()
151153

152154
return commands
153155

@@ -168,7 +170,7 @@ def getExportCommands(self):
168170
value = value + ".shp"
169171
value = value.replace("\\", "/")
170172
filename = os.path.basename(value)
171-
filename = filename[-4]
173+
filename = filename[:-4]
172174
commands.append("writeOGR(" + out.name + ",\"" + value + "\",\""
173175
+ filename + "\", driver=\"ESRI Shapefile\")");
174176

@@ -178,8 +180,6 @@ def getExportCommands(self):
178180
return commands
179181

180182

181-
182-
183183
def getImportCommands(self):
184184

185185
commands = []
@@ -197,7 +197,7 @@ def getImportCommands(self):
197197
raise GeoAlgorithmExecutionException("Unsupported input file format.\n" + value)
198198
value = value.replace("\\", "/")
199199
filename = os.path.basename(value)
200-
filename = filename[-4]
200+
filename = filename[:-4]
201201
commands.append(param.name + " = " + "readOGR(\"" + value + "\",layer=\"" + filename + "\")")
202202
if isinstance(param, (ParameterTableField, ParameterString)):
203203
commands.append(param.name + "=\"" + param.value + "\"")
@@ -225,7 +225,7 @@ def getImportCommands(self):
225225
raise GeoAlgorithmExecutionException("Unsupported input file format.\n" + layer)
226226
layer = layer.replace("\\", "/")
227227
filename = os.path.basename(layer)
228-
filename = filename[-4]
228+
filename = filename[:-4]
229229
commands.append("tempvar" + str(iLayer) + " = " + "readOGR(\"" + layer + "\",layer=\"" + filename + "\")")
230230
iLayer+=1
231231
s = ""

src/sextante/r/RAlgorithmProvider.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@
88
from PyQt4 import QtGui
99
from sextante.r.RUtils import RUtils
1010
from sextante.r.RAlgorithm import RAlgorithm
11+
from sextante.r.CreateNewRScriptAction import CreateNewRScriptAction
12+
from sextante.r.EditRScriptAction import EditRScriptAction
1113

1214
class RAlgorithmProvider(AlgorithmProvider):
1315

1416
def __init__(self):
1517
AlgorithmProvider.__init__(self)
1618
SextanteConfig.addSetting(Setting("R", RUtils.RSCRIPTS_FOLDER, "R Scripts folder", RUtils.RScriptsFolder()))
1719
SextanteConfig.addSetting(Setting("R", RUtils.R_FOLDER, "R folder", RUtils.RFolder()))
18-
#self.actions = []
19-
#self.actions.append(CreateNewScriptAction())
20-
self.contextMenuActions = []#EditScriptAction(), DeleteScriptAction()]
20+
self.actions = []
21+
self.actions.append(CreateNewRScriptAction())
22+
self.contextMenuActions = [EditRScriptAction()]
2123

2224
def getIcon(self):
2325
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/r.png")

src/sextante/r/RUtils.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,23 @@ def executeRAlgorithm(alg):
4949
RUtils.verboseCommands = alg.getVerboseCommands();
5050
RUtils.createRScriptFromRCommands(alg.getFullSetOfRCommands())
5151
if SextanteUtils.isWindows():
52-
command = ["\"" + RUtils.RFolder() + os.sep + "bin" + os.sep + "R.exe\"", "CMD", "BATCH", "--vanilla",
53-
"\"" + RUtils.getRScriptFilename() + "\""]
52+
command = [RUtils.RFolder() + os.sep + "bin" + os.sep + "R.exe", "CMD", "BATCH", "--vanilla", RUtils.getRScriptFilename()]
5453
else:#TODO***********
5554
pass
5655

57-
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=True).stdout
56+
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=True)
57+
5858
RUtils.createConsoleOutput()
5959

6060

6161
@staticmethod
6262
def createConsoleOutput():
63+
add = False
6364
lines = open(RUtils.getConsoleOutputFilename())
6465
line = lines.readline().strip("\n").strip(" ")
6566
while line != "":
6667
if line.startswith(">"):
67-
line = line[1:]
68+
line = line[1:].strip(" ")
6869
if line in RUtils.verboseCommands:
6970
add = True
7071
else:

src/sextante/saga/SagaAlgorithm.py

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from sextante.parameters.ParameterFactory import ParameterFactory
3030
from sextante.outputs.OutputFactory import OutputFactory
3131
from sextante.core.SextanteConfig import SextanteConfig
32+
import math
3233

3334
class SagaAlgorithm(GeoAlgorithm):
3435

@@ -174,14 +175,48 @@ def defineCharacteristicsFromFileSagaFormat(self):
174175
line = lines.readline()
175176
lines.close()
176177

177-
def processAlgorithm(self, progress):
178178

179+
def calculateResamplingExtent(self):
180+
auto = SextanteConfig.getSetting(SagaUtils.SAGA_AUTO_RESAMPLING)
181+
if auto:
182+
first = True;
183+
for param in self.parameters:
184+
if isinstance(param, ParameterRaster):
185+
if isinstance(param.value, QgsRasterLayer):
186+
value = param.value
187+
else:
188+
value = QGisLayers.getObjectFromUri(param.value)
189+
if first:
190+
self.xmin = value.extent().xMinimum()
191+
self.xmax = value.extent().xMaximum()
192+
self.ymin = value.extent().yMinimum()
193+
self.ymax = value.extent().yMaximum()
194+
self.cellsize = (value.extent().xMaximum() - value.extent().xMinimum())/value.getRasterXDim()
195+
first = False
196+
else:
197+
self.xmin = min(self.xmin, value.extent().xMinimum())
198+
self.xmax = max(self.xmax, value.extent().xMaximum())
199+
self.ymin = min(self.ymin, value.extent().yMinimum())
200+
self.ymax = max(self.ymax, value.extent().yMaximum())
201+
self.cellsize = max(self.cellsize, (value.extent().xMaximum() - value.extent().xMinimum())/value.getRasterXDim())
202+
else:
203+
self.xmin = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMIN)
204+
self.xmax = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMAX)
205+
self.ymin = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMIN)
206+
self.ymax = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMAX)
207+
self.cellsize = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_CELLSIZE)
208+
209+
210+
211+
def processAlgorithm(self, progress):
179212
commands = list()
180213
self.exportedLayers = {}
181214
self.numExportedLayers = 0;
182215

183-
#1: Export rasters to sgrd. only ASC and TIF are supported.
184-
# Vector layers must be in shapefile format and tables in dbf format. We check that.
216+
#1: Export rasters to sgrd. only ASC and TIF are supported.
217+
# Vector layers must be in shapefile format and tables in dbf format. We check that.
218+
if self.resample:
219+
self.calculateResamplingExtent()
185220
for param in self.parameters:
186221
if isinstance(param, ParameterRaster):
187222
if param.value == None:
@@ -305,18 +340,10 @@ def resampleRasterLayer(self,layer):
305340
inputFilename = layer
306341
destFilename = self.getTempFilename()
307342
self.exportedLayers[layer]= destFilename
308-
auto = SextanteConfig.getSetting(SagaUtils.SAGA_AUTO_RESAMPLING)
309-
if auto:
310-
pass
311-
else:
312-
xmin = auto = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMIN)
313-
xmax = auto = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMAX)
314-
ymin = auto = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMIN)
315-
ymax = auto = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMAX)
316-
cellsize = auto = SextanteConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_CELLSIZE)
317-
s = "grid_tools \"Resampling\" -INPUT " + inputFilename + "-TARGET 0 -SCALE_UP_METHOD 4 -SCALE_DOWN_METHOD 4 -USER_XMIN " +\
318-
xmin + " -USER_XMAX " + xmax + " -USER_YMIN " + ymin + " -USER_YMAX " + ymax +\
319-
" -USER_SIZE " + str(cellsize) + " -USER_GRID " + destFilename
343+
s = "grid_tools \"Resampling\" -INPUT " + inputFilename + "-TARGET 0 -SCALE_UP_METHOD 4 -SCALE_DOWN_METHOD 4 -USER_XMIN " +\
344+
self.xmin + " -USER_XMAX " + self.xmax + " -USER_YMIN " + self.ymin + " -USER_YMAX " + self.ymax +\
345+
" -USER_SIZE " + str(self.cellsize) + " -USER_GRID " + destFilename
346+
return s
320347

321348
def exportRasterLayer(self,layer):
322349
if not layer.lower().endswith("tif") and not layer.lower().endswith("asc"):

src/sextante/script/ScriptAlgorithm.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ def createDescriptiveName(self, s):
4646
return s.replace("_", " ")
4747

4848
def processParameterLine(self,line):
49-
5049
param = None
5150
out = None
5251
line = line.replace("#", "");

0 commit comments

Comments
 (0)