Skip to content
Permalink
Browse files
improved table usage.Added better transparent layer handling for exte…
…rnal apps.Started gdal bindings

git-svn-id: http://sextante.googlecode.com/svn/trunk/soft/bindings/qgis-plugin@65 881b9c09-3ef8-f3c2-ec3d-21d735c97f4d
  • Loading branch information
volayaf committed Apr 6, 2012
1 parent afdbb21 commit f499c85821271a48e300930bcd81fe24da98933b
Showing with 672 additions and 361 deletions.
  1. +1 −1 src/sextante/SextantePlugin.py
  2. +1 −1 src/sextante/__init__.py
  3. +5 −7 src/sextante/core/AlgorithmProvider.py
  4. +49 −0 src/sextante/core/LayerExporter.py
  5. +36 −39 src/sextante/core/QGisLayers.py
  6. +4 −3 src/sextante/core/Sextante.py
  7. +2 −0 src/sextante/core/SextanteConfig.py
  8. +10 −0 src/sextante/core/SextanteUtils.py
  9. +0 −2 src/sextante/ftools/FToolsAlgorithmProvider.py
  10. +1 −1 src/sextante/ftools/FixedDistanceBuffer.py
  11. +1 −1 src/sextante/ftools/VariableDistanceBuffer.py
  12. +12 −0 src/sextante/gdal/GdalAlgorithm.py
  13. +57 −0 src/sextante/gdal/GdalAlgorithmProvider.py
  14. +28 −0 src/sextante/gdal/GdalUtils.py
  15. 0 src/sextante/gdal/__init__.py
  16. BIN src/sextante/gdal/icons/24-to-8-bits.png
  17. BIN src/sextante/gdal/icons/8-to-24-bits.png
  18. BIN src/sextante/gdal/icons/about.png
  19. BIN src/sextante/gdal/icons/contour.png
  20. BIN src/sextante/gdal/icons/dem.png
  21. BIN src/sextante/gdal/icons/edit.png
  22. BIN src/sextante/gdal/icons/gdalicon.png
  23. BIN src/sextante/gdal/icons/grid.png
  24. BIN src/sextante/gdal/icons/merge.png
  25. BIN src/sextante/gdal/icons/nearblack.png
  26. BIN src/sextante/gdal/icons/polygonize.png
  27. BIN src/sextante/gdal/icons/projection-add.png
  28. BIN src/sextante/gdal/icons/proximity.png
  29. BIN src/sextante/gdal/icons/raster-clip.png
  30. BIN src/sextante/gdal/icons/raster-info.png
  31. BIN src/sextante/gdal/icons/raster-overview.png
  32. BIN src/sextante/gdal/icons/raster-rgb.png
  33. BIN src/sextante/gdal/icons/rasterize.png
  34. BIN src/sextante/gdal/icons/reset.png
  35. BIN src/sextante/gdal/icons/sieve.png
  36. BIN src/sextante/gdal/icons/tileindex.png
  37. BIN src/sextante/gdal/icons/tooltip.png
  38. BIN src/sextante/gdal/icons/translate.png
  39. BIN src/sextante/gdal/icons/vrt.png
  40. BIN src/sextante/gdal/icons/warp.png
  41. +40 −0 src/sextante/gdal/information.py
  42. +38 −0 src/sextante/gdal/nearblack.py
  43. +51 −0 src/sextante/gdal/scripts/fillnodata.py
  44. +78 −0 src/sextante/gdal/scripts/proximity.py
  45. +47 −0 src/sextante/gdal/scripts/sieve.py
  46. +27 −17 src/sextante/grass/GrassAlgorithm.py
  47. +0 −2 src/sextante/grass/GrassAlgorithmProvider.py
  48. +2 −1 src/sextante/grass/GrassUtils.py
  49. +2 −2 src/sextante/grass/description/alg_123.txt
  50. +0 −3 src/sextante/grass/description/alg_152.txt
  51. +1 −1 src/sextante/grass/description/alg_153.txt
  52. +0 −4 src/sextante/grass/description/alg_154.txt
  53. +1 −1 src/sextante/grass/description/alg_156.txt
  54. +1 −5 src/sextante/grass/description/alg_157.txt
  55. +1 −2 src/sextante/grass/description/alg_158.txt
  56. +5 −5 src/sextante/grass/description/alg_159.txt
  57. +2 −3 src/sextante/grass/description/alg_160.txt
  58. +3 −3 src/sextante/grass/description/alg_162.txt
  59. +0 −11 src/sextante/grass/description/alg_163.txt
  60. +0 −14 src/sextante/grass/description/alg_164.txt
  61. +4 −4 src/sextante/grass/description/alg_165.txt
  62. +0 −8 src/sextante/grass/description/alg_166.txt
  63. +0 −4 src/sextante/grass/description/alg_167.txt
  64. +0 −4 src/sextante/grass/description/alg_168.txt
  65. +0 −6 src/sextante/grass/description/alg_170.txt
  66. +1 −1 src/sextante/grass/description/alg_171.txt
  67. +2 −2 src/sextante/grass/description/alg_172.txt
  68. +0 −10 src/sextante/grass/description/alg_173.txt
  69. +1 −1 src/sextante/grass/description/alg_174.txt
  70. +0 −5 src/sextante/grass/description/alg_175.txt
  71. +1 −2 src/sextante/grass/description/alg_176.txt
  72. +2 −2 src/sextante/grass/description/alg_177.txt
  73. +0 −1 src/sextante/grass/description/alg_178.txt
  74. +0 −18 src/sextante/grass/description/alg_22.txt
  75. +0 −12 src/sextante/grass/description/alg_27.txt
  76. +1 −1 src/sextante/grass/description/alg_3.txt
  77. +0 −5 src/sextante/grass/description/alg_32.txt
  78. +0 −7 src/sextante/grass/description/alg_5.txt
  79. +7 −7 src/sextante/grass/description/alg_67.txt
  80. +7 −7 src/sextante/grass/description/alg_70.txt
  81. +2 −3 src/sextante/grass/description/alg_75.txt
  82. +1 −1 src/sextante/grass/description/alg_91.txt
  83. +2 −2 src/sextante/grass/description/alg_94.txt
  84. +0 −5 src/sextante/gui/AlgorithmExecutor.py
  85. +0 −1 src/sextante/gui/BatchProcessingDialog.py
  86. +1 −1 src/sextante/gui/HTMLViewerDialog.py
  87. +5 −10 src/sextante/gui/ParametersDialog.py
  88. +6 −4 src/sextante/gui/SextantePostprocessing.py
  89. BIN src/sextante/manual.pdf
  90. +1 −1 src/sextante/metadata.txt
  91. +4 −1 src/sextante/mmqgis/MMQGISAlgorithmProvider.py
  92. +0 −3 src/sextante/modeler/ModelerAlgorithm.py
  93. +1 −1 src/sextante/modeler/ModelerParametersDialog.py
  94. +6 −0 src/sextante/parameters/Parameter.py
  95. +36 −4 src/sextante/parameters/ParameterMultipleInput.py
  96. +12 −10 src/sextante/parameters/ParameterTable.py
  97. +23 −0 src/sextante/parameters/ParameterVector.py
  98. +11 −8 src/sextante/r/RAlgorithm.py
  99. +0 −1 src/sextante/r/RAlgorithmProvider.py
  100. +4 −2 src/sextante/r/RUtils.py
  101. +22 −60 src/sextante/saga/SagaAlgorithm.py
  102. +0 −3 src/sextante/saga/SagaAlgorithmProvider.py
  103. +1 −1 src/sextante/saga/SagaUtils.py
  104. +2 −2 src/sextante/script/ScriptAlgorithm.py
  105. +0 −1 src/sextante/script/ScriptAlgorithmProvider.py
@@ -123,7 +123,7 @@ def openHelp(self):
if os.name == "nt":
os.startfile(filename)
elif sys.platform == "darwin":
subprocess.call(('open', filename))
subprocess.Popen(('open', filename))
else:
subprocess.call(('xdg-open', filename))

@@ -5,7 +5,7 @@ def name():
def description():
return "SEXTANTE Geoprocessing platform for QGIS"
def version():
return "Version 1.0.1"
return "Version 1.0.2"
def icon():
return "icon.png"
def qgisMinimumVersion():
@@ -19,21 +19,21 @@ def loadAlgorithms(self):
return
else:
self._loadAlgorithms()
for alg in self.algs:
alg.provider = self

#methods to be overridden.
#==============================


def _loadAlgorithms(self):
'''Algorithm loading should take place here, filling self.algs, which is a list of
elements of class GeoAlgorithm. Use that class to create your own algorithms
Since algorithms should have a reference to the provider they come
from, this is also the place to set the 'provider' variable of each algorithm'''
elements of class GeoAlgorithm. Use that class to create your own algorithms'''
pass

def initializeSettings(self):
'''this is the place where you should add config parameters to sextante using the SextanteConfig class.
this method is called when a provider is added to Sextante.
'''this is the place where you should add config parameters to SEXTANTE using the SextanteConfig class.
this method is called when a provider is added to SEXTANTE.
By default it just adds a setting to activate or deactivate algorithms from the provider'''
name = "ACTIVATE_" + self.getName().upper().replace(" ", "_")
SextanteConfig.addSetting(Setting(self.getName(), name, "Activate", True))
@@ -49,8 +49,6 @@ def getName(self):
return "Generic algorithm provider"




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

@@ -0,0 +1,49 @@
from sextante.core.SextanteConfig import SextanteConfig
from sextante.core.SextanteUtils import SextanteUtils
from qgis.core import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class LayerExporter():

'''This class provides method to export layers so they can be used by third party applications.
These method are used by the GeoAlgorithm class and allow the developer to use transparently
any layer that is loaded into QGIS, without having to worry about its origin'''

@staticmethod
def exportVectorLayer(layer):
'''Takes a QgsVectorLayer and returns the filename to refer to it, which allows external
apps which support only file-based layers to use it. It performs the necessary export
in case the input layer is not in a standard format suitable for most appplications, it is
a remote one or db-based (non-file based) one, or if there is a selection and it should be
used, exporting just the selected features.
Currently, the output is restricted to shapefiles, so anything that is not in a shapefile
will get exported'''
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = SextanteUtils.getTempFilename("shp")
provider = layer.dataProvider()
allAttrs = provider.attributeIndexes()
provider.select( allAttrs )
useSelection = SextanteConfig.getSetting(SextanteConfig.USE_SELECTED)
if useSelection and layer.selectedFeatureCount() != 0:
writer = QgsVectorFileWriter( output, systemEncoding,provider.fields(), provider.geometryType(), provider.crs() )
selection = layer.selectedFeatures()
for feat in selection:
writer.addFeature(feat)
del writer
return output
else:
if (not str(layer.source()).endswith("shp")):
writer = QgsVectorFileWriter( output, systemEncoding,provider.fields(), provider.geometryType(), provider.crs() )
feat = QgsFeature()
while provider.nextFeature(feat):
writer.addFeature(feat)
del writer
return output
else:
return str(layer.source())




@@ -20,7 +20,7 @@ def getRasterLayers():

for layer in layers:
if layer.type() == layer.RasterLayer:
if os.path.exists(layer.source()):#only file-based layers
if layer.usesProvider() and layer.providerKey() == 'gdal':#only gdal file-based layers
raster.append(layer)
return raster

@@ -31,27 +31,25 @@ def getVectorLayers(shapetype=-1):
for layer in layers:
if layer.type() == layer.VectorLayer:
if shapetype == QGisLayers.ALL_TYPES or layer.geometryType() == shapetype:
if os.path.exists(layer.source()):
vector.append(layer)
#if os.path.exists(layer.source()):
vector.append(layer)
return vector

@staticmethod
def getAllLayers():
layers = QGisLayers.iface.legendInterface().layers()
layerslist = list()
for layer in layers:
if os.path.exists(layer.source()):
layerslist.append(layer)
return layerslist
layers = []
layers += QGisLayers.getRasterLayers();
layers += QGisLayers.getVectorLayers();
return layers

@staticmethod
def getTables():
layers = QGisLayers.iface.legendInterface().layers()
tables = list()
for layer in layers:
if layer.type() == layer.VectorLayer :
uri = str(layer.dataProvider().dataSourceUri())
if (uri.endswith("shp")):
uri = str(layer.source())
if uri.endswith("csv") or uri.endswith("dbf"):
tables.append(layer)
return tables

@@ -71,42 +69,41 @@ def load(layer, name = None, crs = None, style = None):
return
prjSetting = None
settings = QSettings()
try:
if crs != None:
prjSetting = settings.value("/Projections/defaultBehaviour")
settings.setValue("/Projections/defaultBehaviour", QVariant(""))
if name == None:
name = path.split(layer)[1]
qgslayer = QgsVectorLayer(layer, name , 'ogr')
if qgslayer.isValid():
if crs != None:
prjSetting = settings.value("/Projections/defaultBehaviour")
settings.setValue("/Projections/defaultBehaviour", QVariant(""))
if name == None:
name = path.split(layer)[1]
qgslayer = QgsVectorLayer(layer, name , 'ogr')
qgslayer.setCrs(crs,False)
if style == None:
if qgslayer.geometryType == 0:
style = SextanteConfig.getSetting(SextanteConfig.VECTOR_POINT_STYLE)
elif qgslayer.geometryType == 1:
style = SextanteConfig.getSetting(SextanteConfig.VECTOR_LINE_STYLE)
else:
style = SextanteConfig.getSetting(SextanteConfig.VECTOR_POLYGON_STYLE)
qgslayer.loadNamedStyle(style)
QgsMapLayerRegistry.instance().addMapLayer(qgslayer)
else:
qgslayer = QgsRasterLayer(layer, name)
if qgslayer.isValid():
if crs != None:
qgslayer.setCrs(crs,False)
if style == None:
if qgslayer.geometryType == 0:
style = SextanteConfig.getSetting(SextanteConfig.VECTOR_POINT_STYLE)
elif qgslayer.geometryType == 1:
style = SextanteConfig.getSetting(SextanteConfig.VECTOR_LINE_STYLE)
else:
style = SextanteConfig.getSetting(SextanteConfig.VECTOR_POLYGON_STYLE)
style = SextanteConfig.getSetting(SextanteConfig.RASTER_STYLE)
qgslayer.loadNamedStyle(style)
QgsMapLayerRegistry.instance().addMapLayer(qgslayer)
QGisLayers.iface.legendInterface().refreshLayerSymbology(qgslayer)
else:
qgslayer = QgsRasterLayer(layer, name)
if qgslayer.isValid():
if crs != None:
qgslayer.setCrs(crs,False)
if style == None:
style = SextanteConfig.getSetting(SextanteConfig.RASTER_STYLE)
qgslayer.loadNamedStyle(style)
QgsMapLayerRegistry.instance().addMapLayer(qgslayer)
QGisLayers.iface.legendInterface().refreshLayerSymbology(qgslayer)
else:
QtGui.QMessageBox.critical(None, "Error", "Could not load layer: " + str(layer))
except Exception, e:
QtGui.QMessageBox.critical(None, "Error", "Could not load layer: " + str(layer))
finally:
if prjSetting:
settings.setValue("/Projections/defaultBehaviour", prjSetting)
if prjSetting:
settings.setValue("/Projections/defaultBehaviour", prjSetting)
raise RuntimeError("Could not load layer: " + str(layer)
+"\nCheck the SEXTANTE log to look for errors in algorithm execution")
if prjSetting:
settings.setValue("/Projections/defaultBehaviour", prjSetting)


@staticmethod
@@ -5,7 +5,6 @@
import copy
from sextante.core.QGisLayers import QGisLayers
from sextante.gui.AlgorithmExecutor import AlgorithmExecutor, SilentProgress
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from sextante.core.SextanteConfig import SextanteConfig
from sextante.core.SextanteLog import SextanteLog
from sextante.modeler.ModelerAlgorithmProvider import ModelerAlgorithmProvider
@@ -18,6 +17,7 @@
from sextante.grass.GrassAlgorithmProvider import GrassAlgorithmProvider
from sextante.gui.RenderingStyles import RenderingStyles
from sextante.modeler.ModelerOnlyAlgorithmProvider import ModelerOnlyAlgorithmProvider
from sextante.gdal.GdalAlgorithmProvider import GdalAlgorithmProvider

class Sextante:

@@ -83,6 +83,7 @@ def initialize():
Sextante.addProvider(RAlgorithmProvider())
Sextante.addProvider(SagaAlgorithmProvider())
Sextante.addProvider(GrassAlgorithmProvider())
Sextante.addProvider(GdalAlgorithmProvider())
Sextante.modeler.initializeSettings();
#and initialize
SextanteLog.startLogging()
@@ -269,12 +270,12 @@ def runalg(name, *args):

@staticmethod
def load(layer):
'''loads a layer into QGIS'''
'''Loads a layer into QGIS'''
QGisLayers.load(layer)

@staticmethod
def loadFromAlg(layersdict):
'''load all layer resulting from a given algorithm.
'''Load all layer resulting from a given algorithm.
Layers are passed as a dictionary, obtained from alg.getOutputValuesAsDictionary()'''
QGisLayers.loadFromDict(layersdict)

@@ -9,11 +9,13 @@ class SextanteConfig():
VECTOR_LINE_STYLE = "VECTOR_LINE_STYLE"
VECTOR_POLYGON_STYLE = "VECTOR_POLYGON_STYLE"
SHOW_RECENT_ALGORITHMS = "SHOW_RECENT_ALGORITHMS"
USE_SELECTED = "USE_SELECTED"

settings = {}

@staticmethod
def initialize():
SextanteConfig.addSetting(Setting("General", SextanteConfig.USE_SELECTED, "Use only selected features in external application", True))
SextanteConfig.addSetting(Setting("General", SextanteConfig.SHOW_RECENT_ALGORITHMS, "Show recently executed algorithms", True))
SextanteConfig.addSetting(Setting("General", SextanteConfig.OUTPUT_FOLDER,
"Output folder", os.path.join(SextanteUtils.userFolder(),"outputs" )))
@@ -36,6 +36,16 @@ def setTempOutput(out, alg):
out.value = filename
SextanteUtils.NUM_EXPORTED += 1

@staticmethod
def getTempFilename(ext):
path = SextanteUtils.tempFolder()
filename = path + os.sep + str(time.time()) + str(SextanteUtils.getNumExportedLayers()) + "." + ext
return filename

@staticmethod
def getNumExportedLayers():
SextanteUtils.NUM_EXPORTED += 1
return SextanteUtils.NUM_EXPORTED

def mkdir(newdir):
if os.path.isdir(newdir):
@@ -42,8 +42,6 @@ def __init__(self):
ConvexHull(), FixedDistanceBuffer(), VariableDistanceBuffer(),
Dissolve(), Difference(), Intersection(), Union(), Clip(), ExtentFromLayer(),
RandomSelection(), RandomSelectionWithinSubsets(), SelectByLocation()]
for alg in self.alglist:
alg.provider = self

def getName(self):
return "ftools"
@@ -9,7 +9,7 @@
from sextante.outputs.OutputVector import OutputVector
from sextante.parameters.ParameterBoolean import ParameterBoolean
from sextante.parameters.ParameterNumber import ParameterNumber
import sextante.ftools.Buffer as buff
from sextante.ftools import Buffer as buff

class FixedDistanceBuffer(GeoAlgorithm):

@@ -9,7 +9,7 @@
from sextante.outputs.OutputVector import OutputVector
from sextante.parameters.ParameterBoolean import ParameterBoolean
from sextante.parameters.ParameterNumber import ParameterNumber
import sextante.ftools.Buffer as buff
from sextante.ftools import Buffer as buff
from sextante.parameters.ParameterTableField import ParameterTableField

class VariableDistanceBuffer(GeoAlgorithm):
@@ -0,0 +1,12 @@
from sextante.script.ScriptAlgorithm import ScriptAlgorithm
from PyQt4 import QtGui
import os

class GdalAlgorithm(ScriptAlgorithm):
'''Just a ScriptAlgorithm that automatically takes its icon
filename for the script filename'''

def getIcon(self):
filename = os.path.basename(self.descriptionFile[:-2] + "png")
filepath = os.path.dirname(__file__) + "/icons/" + filename
return QtGui.QIcon(filepath)
@@ -0,0 +1,57 @@
import os
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from sextante.core.AlgorithmProvider import AlgorithmProvider
from sextante.script.WrongScriptException import WrongScriptException
from sextante.core.SextanteLog import SextanteLog
from sextante.gdal.GdalAlgorithm import GdalAlgorithm
from sextante.gdal.nearblack import nearblack
from sextante.gdal.information import information

class GdalAlgorithmProvider(AlgorithmProvider):

'''This provider incorporates GDAL-based algorithms into SEXTANTE.
Algorithms have been implemented using two different mechanisms,
which should serve as an example of different ways of extending
SEXTANTE:
1)when a python script exist for a given process, it has been adapted
as a SEXTANTE python script and loaded using the ScriptAlgorithm class.
This algorithms call GDAL using its Python bindings
2)Other algorithms are called directly using the command line interface,
These have been implemented individually extending the GeoAlgorithm class'''

def __init__(self):
AlgorithmProvider.__init__(self)
self.createAlgsList()

def scriptsFolder(self):
'''The folder where script algorithms are stored'''
return os.path.dirname(__file__) + "/scripts"

def getName(self):
return "Gdal"

def getIcon(self):
return QIcon(os.path.dirname(__file__) + "/icons/gdalicon.png")

def _loadAlgorithms(self):
'''This is called each time there is a change in the SEXTANTE set of algorithm,
for instance, when the users adds a new model or script. Since this provider
cannot be extended by the user, we create the list in advance and then just
assign it to self.algs'''
self.algs = self.preloadedAlgs

def createAlgsList(self):
#First we populate the list of algorihtms with those created extending
#GeoAlgorithm directly (those that execute GDAL using the console)
self.preloadedAlgs = [nearblack(), information()]
#And then we add those that are created as python scripts
folder = self.scriptsFolder()
for descriptionFile in os.listdir(folder):
if descriptionFile.endswith("py"):
try:
fullpath = os.path.join(self.scriptsFolder(), descriptionFile)
alg = GdalAlgorithm(fullpath)
self.preloadedAlgs.append(alg)
except WrongScriptException,e:
SextanteLog.addToLog(SextanteLog.LOG_ERROR,e.msg)

0 comments on commit f499c85

Please sign in to comment.