Skip to content

Commit

Permalink
Add method QgsProcessingUtils::mapLayerFromString
Browse files Browse the repository at this point in the history
Algorithms and other processing code should use this method
(instead of dataobjects.getLayerFromString) to
retrieve layers from a string, as it considers the processing
context and allows resolving strings to temporarily stored layers.

This permits processing models to function correctly when
intermediate results are stored as memory layers. Subsequent
model algorithms can then access these temporary layers as inputs.
All temporary layers will be removed when the context object
is destroyed after the model algorithm is run.
  • Loading branch information
nyalldawson committed May 2, 2017
1 parent 1711a41 commit f84d703
Show file tree
Hide file tree
Showing 160 changed files with 271 additions and 320 deletions.
5 changes: 5 additions & 0 deletions python/core/processing/qgsprocessingutils.sip
Expand Up @@ -90,6 +90,11 @@ class QgsProcessingUtils
:rtype: QgsMapLayer
%End

static QgsMapLayer *mapLayerFromString( const QString &string, QgsProcessingContext &context, bool allowLoadingNewLayers = true );
%Docstring
:rtype: QgsMapLayer
%End

static QString normalizeLayerSource( const QString &source );
%Docstring
Normalizes a layer ``source`` string for safe comparison across different
Expand Down
Expand Up @@ -92,8 +92,8 @@ def processAlgorithm(self, context, feedback):
# Input layers vales are always a string with its location.
# That string can be converted into a QGIS layer (a
# QgsVectorLayer in this case) using the
# dataobjects.getLayerFromString() method.
vectorLayer = dataobjects.getLayerFromString(inputFilename)
# dataobjects.QgsProcessingUtils.mapLayerFromString() method.
vectorLayer = dataobjects.QgsProcessingUtils.mapLayerFromString(inputFilename, context)

# And now we can process

Expand Down
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/gdal/ClipByMask.py
Expand Up @@ -103,8 +103,8 @@ def defineCharacteristics(self):
def getConsoleCommands(self):
out = self.getOutputValue(self.OUTPUT)
mask = self.getParameterValue(self.MASK)
maskLayer = dataobjects.getLayerFromString(
self.getParameterValue(self.MASK))
context = dataobjects.createContext()
maskLayer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.MASK), context)
ogrMask = ogrConnectionString(mask)[1:-1]
noData = self.getParameterValue(self.NO_DATA)
opts = self.getParameterValue(self.OPTIONS)
Expand Down
5 changes: 3 additions & 2 deletions python/plugins/processing/algs/gdal/rasterize_over.py
Expand Up @@ -69,8 +69,9 @@ def defineCharacteristics(self):
self.tr('Existing raster layer'), False))

def getConsoleCommands(self):
inLayer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT))
inRasterLayer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT_RASTER))
context = dataobjects.createContext()
inLayer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
inRasterLayer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_RASTER), context)

ogrLayer = ogrConnectionString(inLayer)[1:-1]
ogrRasterLayer = ogrConnectionString(inRasterLayer)[1:-1]
Expand Down
13 changes: 8 additions & 5 deletions python/plugins/processing/algs/grass7/Grass7Algorithm.py
Expand Up @@ -219,22 +219,23 @@ def defineCharacteristicsFromFile(self):
self.addParameter(param)

def getDefaultCellsize(self):
context = dataobjects.createContext()
cellsize = 0
for param in self.parameters:
if param.value:
if isinstance(param, ParameterRaster):
if isinstance(param.value, QgsRasterLayer):
layer = param.value
else:
layer = dataobjects.getLayerFromString(param.value)
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(param.value, context)
cellsize = max(cellsize, (layer.extent().xMaximum() -
layer.extent().xMinimum()) /
layer.width())
elif isinstance(param, ParameterMultipleInput):

layers = param.value.split(';')
for layername in layers:
layer = dataobjects.getLayerFromString(layername)
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(layername, context)
if isinstance(layer, QgsRasterLayer):
cellsize = max(cellsize, (
layer.extent().xMaximum() -
Expand Down Expand Up @@ -507,16 +508,17 @@ def processOutputs(self):
self.outputCommands.append(command)

def exportVectorLayer(self, orgFilename):
context = dataobjects.createContext()

# TODO: improve this. We are now exporting if it is not a shapefile,
# but the functionality of v.in.ogr could be used for this.
# We also export if there is a selection
if not os.path.exists(orgFilename) or not orgFilename.endswith('shp'):
layer = dataobjects.getLayerFromString(orgFilename, False)
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(orgFilename, context, False)
if layer:
filename = dataobjects.exportVectorLayer(layer)
else:
layer = dataobjects.getLayerFromString(orgFilename, False)
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(orgFilename, context, False)
if layer:
useSelection = \
ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED)
Expand Down Expand Up @@ -549,8 +551,9 @@ def setSessionProjectionFromProject(self, commands):
Grass7Utils.projectionSet = True

def setSessionProjectionFromLayer(self, layer, commands):
context = dataobjects.createContext()
if not Grass7Utils.projectionSet:
qGisLayer = dataobjects.getLayerFromString(layer)
qGisLayer = dataobjects.QgsProcessingUtils.mapLayerFromString(layer, context)
if qGisLayer:
proj4 = str(qGisLayer.crs().toProj4())
command = 'g.proj'
Expand Down
5 changes: 3 additions & 2 deletions python/plugins/processing/algs/grass7/nviz7.py
Expand Up @@ -167,21 +167,22 @@ def exportRasterLayer(self, layer):

def getDefaultCellsize(self):
cellsize = 0
context = dataobjects.createContext()
for param in self.parameters:
if param.value:
if isinstance(param, ParameterRaster):
if isinstance(param.value, QgsRasterLayer):
layer = param.value
else:
layer = dataobjects.getLayerFromString(param.value)
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(param.value, context)
cellsize = max(cellsize, (layer.extent().xMaximum() -
layer.extent().xMinimum()) /
layer.width())
elif isinstance(param, ParameterMultipleInput):

layers = param.value.split(';')
for layername in layers:
layer = dataobjects.getLayerFromString(layername)
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(layername, context)
if isinstance(layer, QgsRasterLayer):
cellsize = max(cellsize, (
layer.extent().xMaximum() -
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/AddTableField.py
Expand Up @@ -91,8 +91,7 @@ def processAlgorithm(self, context, feedback):
fieldPrecision = self.getParameterValue(self.FIELD_PRECISION)
output = self.getOutputFromName(self.OUTPUT_LAYER)

layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT_LAYER))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)

fields = layer.fields()
fields.append(QgsField(fieldName, self.TYPES[fieldType], '',
Expand Down
Expand Up @@ -64,7 +64,7 @@ def defineCharacteristics(self):
def processAlgorithm(self, context, feedback):
output = self.getOutputFromName(self.OUTPUT)
vlayer = \
dataobjects.getLayerFromString(self.getParameterValue(self.INPUT))
dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
fields = vlayer.fields()
fields.append(QgsField('AUTO', QVariant.Int))
writer = output.getVectorWriter(fields, vlayer.wkbType(), vlayer.crs(), context)
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/BarPlot.py
Expand Up @@ -74,8 +74,7 @@ def defineCharacteristics(self):
self.addOutput(OutputHTML(self.OUTPUT, self.tr('Bar plot')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
namefieldname = self.getParameterValue(self.NAME_FIELD)
valuefieldname = self.getParameterValue(self.VALUE_FIELD)

Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/BasicStatistics.py
Expand Up @@ -122,8 +122,7 @@ def defineCharacteristics(self):
self.addOutput(OutputNumber(self.IQR, self.tr('Interquartile Range (IQR)')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT_LAYER))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
field_name = self.getParameterValue(self.FIELD_NAME)
field = layer.fields().at(layer.fields().lookupField(field_name))

Expand Down
Expand Up @@ -116,8 +116,7 @@ def defineCharacteristics(self):
self.addOutput(OutputNumber(self.IQR, self.tr('Interquartile Range (IQR)')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT_LAYER))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
fieldName = self.getParameterValue(self.FIELD_NAME)

outputFile = self.getOutputValue(self.OUTPUT_HTML_FILE)
Expand Down
Expand Up @@ -102,8 +102,7 @@ def defineCharacteristics(self):
self.addOutput(OutputNumber(self.MAX_VALUE, self.tr('Maximum string value')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT_LAYER))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
fieldName = self.getParameterValue(self.FIELD_NAME)

outputFile = self.getOutputValue(self.OUTPUT_HTML_FILE)
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/Boundary.py
Expand Up @@ -64,8 +64,7 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Boundary')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT_LAYER))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)

input_wkb = layer.wkbType()
if QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.LineGeometry:
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/BoundingBox.py
Expand Up @@ -63,8 +63,7 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Bounds'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT_LAYER))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)

writer = self.getOutputFromName(
self.OUTPUT_LAYER).getVectorWriter(layer.fields().toList(), QgsWkbTypes.Polygon, layer.crs(), context)
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/BoxPlot.py
Expand Up @@ -83,8 +83,7 @@ def defineCharacteristics(self):
self.addOutput(OutputHTML(self.OUTPUT, self.tr('Box plot')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
namefieldname = self.getParameterValue(self.NAME_FIELD)
valuefieldname = self.getParameterValue(self.VALUE_FIELD)

Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/Centroids.py
Expand Up @@ -65,8 +65,7 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Centroids'), datatype=[dataobjects.TYPE_VECTOR_POINT]))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT_LAYER))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)

writer = self.getOutputFromName(
self.OUTPUT_LAYER).getVectorWriter(layer.fields(), QgsWkbTypes.Point, layer.crs(), context)
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/CheckValidity.py
Expand Up @@ -100,8 +100,7 @@ def processAlgorithm(self, context, feedback):
settings.setValue(settings_method_key, initial_method_setting)

def doCheck(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT_LAYER))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)

settings = QgsSettings()
method = int(settings.value(settings_method_key, 1))
Expand Down
6 changes: 2 additions & 4 deletions python/plugins/processing/algs/qgis/Clip.py
Expand Up @@ -70,10 +70,8 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(Clip.OUTPUT, self.tr('Clipped')))

def processAlgorithm(self, context, feedback):
source_layer = dataobjects.getLayerFromString(
self.getParameterValue(Clip.INPUT))
mask_layer = dataobjects.getLayerFromString(
self.getParameterValue(Clip.OVERLAY))
source_layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Clip.INPUT), context)
mask_layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Clip.OVERLAY), context)

writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(source_layer.fields(),
QgsWkbTypes.multiType(source_layer.wkbType()),
Expand Down
6 changes: 3 additions & 3 deletions python/plugins/processing/algs/qgis/ConcaveHull.py
Expand Up @@ -79,15 +79,15 @@ def defineCharacteristics(self):
OutputVector(ConcaveHull.OUTPUT, self.tr('Concave hull'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(self.getParameterValue(ConcaveHull.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(ConcaveHull.INPUT), context)
alpha = self.getParameterValue(self.ALPHA)
holes = self.getParameterValue(self.HOLES)
no_multigeom = self.getParameterValue(self.NO_MULTIGEOMETRY)

# Delaunay triangulation from input point layer
feedback.setProgressText(self.tr('Creating Delaunay triangles...'))
delone_triangles = processing.run("qgis:delaunaytriangulation", layer, None)['OUTPUT']
delaunay_layer = dataobjects.getLayerFromString(delone_triangles)
delaunay_layer = dataobjects.QgsProcessingUtils.mapLayerFromString(delone_triangles, context)

# Get max edge length from Delaunay triangles
feedback.setProgressText(self.tr('Computing edges max length...'))
Expand Down Expand Up @@ -127,7 +127,7 @@ def processAlgorithm(self, context, feedback):
feedback.setProgressText(self.tr('Dissolving Delaunay triangles...'))
dissolved = processing.run("qgis:dissolve", delaunay_layer,
True, None, None)['OUTPUT']
dissolved_layer = dataobjects.getLayerFromString(dissolved)
dissolved_layer = dataobjects.QgsProcessingUtils.mapLayerFromString(dissolved, context)

# Save result
feedback.setProgressText(self.tr('Saving data...'))
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/ConvexHull.py
Expand Up @@ -77,8 +77,7 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(self.OUTPUT, self.tr('Convex hull'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
useField = self.getParameterValue(self.METHOD) == 1
fieldName = self.getParameterValue(self.FIELD)

Expand Down
Expand Up @@ -68,7 +68,7 @@ def defineCharacteristics(self):

def processAlgorithm(self, context, feedback):
file_name = self.getParameterValue(self.INPUT)
layer = dataobjects.getLayerFromString(file_name)
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(file_name, context)
field = self.getParameterValue(self.FIELD)
provider = layer.dataProvider()

Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/CreateConstantRaster.py
Expand Up @@ -68,8 +68,7 @@ def defineCharacteristics(self):
self.tr('Constant')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
value = self.getParameterValue(self.NUMBER)

output = self.getOutputFromName(self.OUTPUT)
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/DefineProjection.py
Expand Up @@ -75,7 +75,7 @@ def defineCharacteristics(self):

def processAlgorithm(self, context, feedback):
fileName = self.getParameterValue(self.INPUT)
layer = dataobjects.getLayerFromString(fileName)
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(fileName, context)
crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))

provider = layer.dataProvider()
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/Delaunay.py
Expand Up @@ -70,8 +70,7 @@ def defineCharacteristics(self):
datatype=[dataobjects.TYPE_VECTOR_POLYGON]))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)

fields = [QgsField('POINTA', QVariant.Double, '', 24, 15),
QgsField('POINTB', QVariant.Double, '', 24, 15),
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/DeleteColumn.py
Expand Up @@ -66,7 +66,7 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(self.OUTPUT, self.tr('Output layer')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)

fields_to_delete = self.getParameterValue(self.COLUMNS).split(';')
fields = layer.fields()
Expand Down
Expand Up @@ -60,8 +60,7 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(self.OUTPUT, self.tr('Cleaned')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)

fields = layer.fields()

Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/DeleteHoles.py
Expand Up @@ -66,8 +66,7 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(self.OUTPUT, self.tr('Cleaned'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
min_area = self.getParameterValue(self.MIN_AREA)
if min_area is not None:
try:
Expand Down
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/qgis/DensifyGeometries.py
Expand Up @@ -78,8 +78,7 @@ def defineCharacteristics(self):
self.tr('Densified')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(
self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
vertices = self.getParameterValue(self.VERTICES)

isPolygon = layer.geometryType() == QgsWkbTypes.PolygonGeometry
Expand Down
Expand Up @@ -73,7 +73,7 @@ def defineCharacteristics(self):
self.addOutput(OutputVector(self.OUTPUT, self.tr('Densified')))

def processAlgorithm(self, context, feedback):
layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT))
layer = dataobjects.QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
interval = self.getParameterValue(self.INTERVAL)

isPolygon = layer.geometryType() == QgsWkbTypes.PolygonGeometry
Expand Down

0 comments on commit f84d703

Please sign in to comment.