def update_variables_gui(self): variables_scope = QgsExpressionContextScope(self.tr('Model Variables')) for k, v in self.model.variables().items(): variables_scope.setVariable(k, v) variables_context = QgsExpressionContext() variables_context.appendScope(variables_scope) self.variables_editor.setContext(variables_context) self.variables_editor.setEditableScopeIndex(0)
def _expressionContext(alg): context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope()) processingScope = QgsExpressionContextScope() for param in alg.parameters: processingScope.setVariable('%s_value' % param.name, '') context.appendScope(processingScope) return context
def expressionContext(self): context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope()) processingScope = QgsExpressionContextScope() for param in self.alg.parameters: processingScope.setVariable("%s_value" % param.name, "") context.appendScope(processingScope) return context
def check_for_update_events(self, widget, value): if not self.feature: return from qgis.core import QgsExpression, QgsExpressionContext, QgsExpressionContextScope # If we don't have any events for this widgets just get out now if not widget.id in self.events: return events = self.events[widget.id] events = [event for event in events if event['event'].lower() == 'update'] if not events: return feature = self.to_feature(no_defaults=True) for event in events: action = event['action'].lower() targetid = event['target'] if targetid == widget.id: utils.log("Can't connect events to the same widget. ID {}".format(targetid)) continue widget = self.get_widget_from_id(targetid) if not widget: utils.log("Can't find widget for id {} in form".format(targetid)) continue condition = event['condition'] expression = event['value'] context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable("value", value) scope.setVariable("field", widget.field) context.setFeature(feature) context.appendScope(scope) conditionexp = QgsExpression(condition) exp = QgsExpression(expression) if action.lower() == "show": widget.hidden = not conditionexp.evaluate(context) if action.lower() == "hide": widget.hidden = conditionexp.evaluate(context) if action == 'widget expression': if conditionexp.evaluate(context): newvalue = self.widget_default(field, feature=feature) widget.setvalue(newvalue) if action == 'set value': if conditionexp.evaluate(context): newvalue = exp.evaluate(context) widget.setvalue(newvalue)
def createExpressionContext(): context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope(QgsProject.instance())) if iface.mapCanvas(): context.appendScope(QgsExpressionContextUtils.mapSettingsScope(iface.mapCanvas().mapSettings())) processingScope = QgsExpressionContextScope() extent = iface.mapCanvas().fullExtent() processingScope.setVariable('fullextent_minx', extent.xMinimum()) processingScope.setVariable('fullextent_miny', extent.yMinimum()) processingScope.setVariable('fullextent_maxx', extent.xMaximum()) processingScope.setVariable('fullextent_maxy', extent.yMaximum()) context.appendScope(processingScope) return context
def runGetFeatureTests(self, source): FeatureSourceTestCase.runGetFeatureTests(self, source) # combination of an uncompilable expression and limit feature = next(self.vl.getFeatures('pk=4')) context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable('parent', feature) context.appendScope(scope) request = QgsFeatureRequest() request.setExpressionContext(context) request.setFilterExpression('"pk" = attribute(@parent, \'pk\')') request.setLimit(1) values = [f['pk'] for f in self.vl.getFeatures(request)] self.assertEqual(values, [4])
def testVariables(self): """ check through widget model to ensure it is populated with variables """ w = QgsExpressionBuilderWidget() m = w.model() s = QgsExpressionContextScope() s.setVariable('my_var1', 'x') s.setVariable('my_var2', 'y') c = QgsExpressionContext() c.appendScope(s) # check that variables are added when setting context w.setExpressionContext(c) items = m.findItems('my_var1', Qt.MatchRecursive) self.assertEqual(len(items), 1) items = m.findItems('my_var2', Qt.MatchRecursive) self.assertEqual(len(items), 1) items = m.findItems('not_my_var', Qt.MatchRecursive) self.assertEqual(len(items), 0) # double check that functions are still only there once items = m.findItems('lower', Qt.MatchRecursive) self.assertEqual(len(items), 1) items = m.findItems('upper', Qt.MatchRecursive) self.assertEqual(len(items), 1)
def __init__(self, dialog): super(ExecuteSQLWidget, self).__init__(None) self.setupUi(self) self.dialog = dialog self.dialogType = dialogTypes[dialog.__class__.__name__] self.mExpressionWidget = QgsFieldExpressionWidget() # add model parameters in context scope if called from modeler if self.dialogType == DIALOG_MODELER: strings = dialog.getAvailableValuesOfType( [QgsProcessingParameterString, QgsProcessingParameterNumber], []) model_params = [dialog.resolveValueDescription(s) for s in strings] scope = QgsExpressionContextScope() for param in model_params: var = QgsExpressionContextScope.StaticVariable(param) scope.addVariable(var) self.mExpressionWidget.appendScope(scope) self.mHLayout.insertWidget(0, self.mExpressionWidget) self.mInsert.clicked.connect(self.insert)
def createExpressionContext(): context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope( QgsExpressionContextUtils.projectScope(QgsProject.instance())) if iface and iface.mapCanvas(): context.appendScope( QgsExpressionContextUtils.mapSettingsScope( iface.mapCanvas().mapSettings())) processingScope = QgsExpressionContextScope() if iface and iface.mapCanvas(): extent = iface.mapCanvas().fullExtent() processingScope.setVariable('fullextent_minx', extent.xMinimum()) processingScope.setVariable('fullextent_miny', extent.yMinimum()) processingScope.setVariable('fullextent_maxx', extent.xMaximum()) processingScope.setVariable('fullextent_maxy', extent.yMaximum()) context.appendScope(processingScope) return context
def createExpressionContext(self) -> QgsExpressionContext: # pylint: disable=missing-docstring, no-self-use context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable('some_var', 10) context.appendScope(scope) return context
def addRowInLayer(row, errTable, table_codif): """ Rows will be converted in a geometry thanks to codification. All attributes will be added thanks to QgsExpressionContext. Parameters ---------- row: list of list A row contains one or many list of points. errTable: list of list Contains points in error. Some points can be added after the end of this function. table_codif: dictionnary The codification file. See the information about qlsc format. """ # TODO: assert? code = row[CODE_POSITION][0] parameters = row[PARAM_POSITION] codif = table_codif['Codification'][code] layerName = codif['Layer'] layer = QgsVectorLayer(layerName) dim = 4 if QgsWkbTypes.hasZ(layer.dataProvider().wkbType()) else 3 geom = geomFromType(list(zip(*row[1:dim])), parameters, codif['GeometryType'], layer.geometryType()) if geom: layer.startEditing() fields = layer.fields() newFeature = QgsFeature(fields) newFeature.setGeometry(geom) for e in codif['Attributes']: # print(e, e[1], e[1].startswith('_att')) if e[1].startswith('_att'): # len('_att') == 4 try: nb = int(e[1][4:]) - 1 assert(nb >= 0) val = row[ATTRS_POSITION + nb][0] newFeature[e[0]] = val except: # print("attributes error") pass else: context = QgsExpressionContext() scope = QgsExpressionContextScope() try: exp = QgsExpression(e[1]) scope.setFeature(newFeature) context.appendScope(scope) newFeature[e[0]] = exp.evaluate(context) except: # print('key error') pass ret = layer.addFeature(newFeature) # if not ret: # print(ret) layer.commitChanges() layer.updateExtents() else: # can it happen? errTable.append(row)
def expressionContext(self): context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope()) processingScope = QgsExpressionContextScope() layers = dataobjects.getAllLayers() for layer in layers: name = layer.name() processingScope.setVariable('%s_minx' % name, layer.extent().xMinimum()) processingScope.setVariable('%s_miny' % name, layer.extent().yMinimum()) processingScope.setVariable('%s_maxx' % name, layer.extent().xMaximum()) processingScope.setVariable('%s_maxy' % name, layer.extent().yMaximum()) if isinstance(layer, QgsRasterLayer): cellsize = (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width() processingScope.setVariable('%s_cellsize' % name, cellsize) layers = dataobjects.getRasterLayers() for layer in layers: for i in range(layer.bandCount()): stats = layer.dataProvider().bandStatistics(i + 1) processingScope.setVariable('%s_band%i_avg' % (name, i + 1), stats.mean) processingScope.setVariable('%s_band%i_stddev' % (name, i + 1), stats.stdDev) processingScope.setVariable('%s_band%i_min' % (name, i + 1), stats.minimumValue) processingScope.setVariable('%s_band%i_max' % (name, i + 1), stats.maximumValue) extent = iface.mapCanvas().extent() processingScope.setVariable('canvasextent_minx', extent.xMinimum()) processingScope.setVariable('canvasextent_miny', extent.yMinimum()) processingScope.setVariable('canvasextent_maxx', extent.xMaximum()) processingScope.setVariable('canvasextent_maxy', extent.yMaximum()) extent = iface.mapCanvas().fullExtent() processingScope.setVariable('fullextent_minx', extent.xMinimum()) processingScope.setVariable('fullextent_miny', extent.yMinimum()) processingScope.setVariable('fullextent_maxx', extent.xMaximum()) processingScope.setVariable('fullextent_maxy', extent.yMaximum()) context.appendScope(processingScope) return context
def runGetFeatureTests(self, provider): assert len([f for f in provider.getFeatures()]) == 5 self.assert_query(provider, 'name ILIKE \'QGIS\'', []) self.assert_query(provider, '"name" IS NULL', [5]) self.assert_query(provider, '"name" IS NOT NULL', [1, 2, 3, 4]) self.assert_query(provider, '"name" NOT LIKE \'Ap%\'', [1, 3, 4]) self.assert_query(provider, '"name" NOT ILIKE \'QGIS\'', [1, 2, 3, 4]) self.assert_query(provider, '"name" NOT ILIKE \'pEAR\'', [1, 2, 4]) self.assert_query(provider, 'name = \'Apple\'', [2]) self.assert_query(provider, 'name <> \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'name = \'apple\'', []) self.assert_query(provider, '"name" <> \'apple\'', [1, 2, 3, 4]) self.assert_query(provider, '(name = \'Apple\') is not null', [1, 2, 3, 4]) self.assert_query(provider, 'name LIKE \'Apple\'', [2]) self.assert_query(provider, 'name LIKE \'aPple\'', []) self.assert_query(provider, 'name ILIKE \'aPple\'', [2]) self.assert_query(provider, 'name ILIKE \'%pp%\'', [2]) self.assert_query(provider, 'cnt > 0', [1, 2, 3, 4]) self.assert_query(provider, '-cnt > 0', [5]) self.assert_query(provider, 'cnt < 0', [5]) self.assert_query(provider, '-cnt < 0', [1, 2, 3, 4]) self.assert_query(provider, 'cnt >= 100', [1, 2, 3, 4]) self.assert_query(provider, 'cnt <= 100', [1, 5]) self.assert_query(provider, 'pk IN (1, 2, 4, 8)', [1, 2, 4]) self.assert_query(provider, 'cnt = 50 * 2', [1]) self.assert_query(provider, 'cnt = 99 + 1', [1]) self.assert_query(provider, 'cnt = 101 - 1', [1]) self.assert_query(provider, 'cnt - 1 = 99', [1]) self.assert_query(provider, '-cnt - 1 = -101', [1]) self.assert_query(provider, '-(-cnt) = 100', [1]) self.assert_query(provider, '-(cnt) = -(100)', [1]) self.assert_query(provider, 'cnt + 1 = 101', [1]) self.assert_query(provider, 'cnt = 1100 % 1000', [1]) self.assert_query(provider, '"name" || \' \' || "name" = \'Orange Orange\'', [1]) self.assert_query(provider, '"name" || \' \' || "cnt" = \'Orange 100\'', [1]) self.assert_query(provider, '\'x\' || "name" IS NOT NULL', [1, 2, 3, 4]) self.assert_query(provider, '\'x\' || "name" IS NULL', [5]) self.assert_query(provider, 'cnt = 10 ^ 2', [1]) self.assert_query(provider, '"name" ~ \'[OP]ra[gne]+\'', [1]) self.assert_query(provider, '"name"="name2"', [2, 4]) # mix of matched and non-matched case sensitive names self.assert_query(provider, 'true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'false', []) # Three value logic self.assert_query(provider, 'false and false', []) self.assert_query(provider, 'false and true', []) self.assert_query(provider, 'false and NULL', []) self.assert_query(provider, 'true and false', []) self.assert_query(provider, 'true and true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true and NULL', []) self.assert_query(provider, 'NULL and false', []) self.assert_query(provider, 'NULL and true', []) self.assert_query(provider, 'NULL and NULL', []) self.assert_query(provider, 'false or false', []) self.assert_query(provider, 'false or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'false or NULL', []) self.assert_query(provider, 'true or false', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true or NULL', [1, 2, 3, 4, 5]) self.assert_query(provider, 'NULL or false', []) self.assert_query(provider, 'NULL or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'NULL or NULL', []) self.assert_query(provider, 'not true', []) self.assert_query(provider, 'not false', [1, 2, 3, 4, 5]) self.assert_query(provider, 'not null', []) # not self.assert_query(provider, 'not name = \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'not name IS NULL', [1, 2, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' or name = \'Apple\'', [1, 2, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' or not name = \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' and pk = 4', [4]) self.assert_query(provider, 'not name = \'Apple\' and not pk = 4', [1, 3]) self.assert_query(provider, 'not pk IN (1, 2, 4, 8)', [3, 5]) # type conversion - QGIS expressions do not mind that we are comparing a string # against numeric literals self.assert_query(provider, 'num_char IN (2, 4, 5)', [2, 4, 5]) # geometry self.assert_query(provider, 'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))', [1, 2]) # combination of an uncompilable expression and limit feature = next(self.vl.getFeatures('pk=4')) context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable('parent', feature) context.appendScope(scope) request = QgsFeatureRequest() request.setExpressionContext(context) request.setFilterExpression('"pk" = attribute(@parent, \'pk\')') request.setLimit(1) values = [f['pk'] for f in self.vl.getFeatures(request)] self.assertEqual(values, [4])
def doStart(self): # first see if we can pull data from the predictions layer startTime = self.datetime endTime = self.datetime.addDays(1) featureRequest = QgsFeatureRequest() stationPt = QgsPointXY(self.stationFeature.geometry().vertexAt(0)) searchRect = QgsRectangle(stationPt, stationPt) searchRect.grow( 0.01 / 60 ) # in the neighborhood of .01 nm as 1/60 = 1 arc minute in this proj. featureRequest.setFilterRect(searchRect) # Create a time based query ctx = featureRequest.expressionContext() scope = QgsExpressionContextScope() scope.setVariable('startTime', startTime) scope.setVariable('endTime', endTime) scope.setVariable('station', self.stationFeature['station']) ctx.appendScope(scope) featureRequest.setFilterExpression( "station = @station and time >= @startTime and time < @endTime") featureRequest.addOrderBy('time') savedFeatureIterator = self.manager.predictionsLayer.getFeatures( featureRequest) savedFeatures = list(savedFeatureIterator) if len(savedFeatures) > 0: # We have some features, so go ahead and stash them in the layer and resolve this promise print('{}: retrieved {} features from layer'.format( self.stationFeature['station'], len(savedFeatures))) self.predictions = savedFeatures self.resolve() else: # The layer didn't have what we wanted, so we must request the data we need. # At this point, the situation falls into several possible cases. # Case 1: A Harmonic station with known flood/ebb directions. Here # we need two requests which can simply be combined and sorted: # 1a: EventType, i.e. slack, flood and ebb # 1b: SpeedDirType, as velocity can be calculated by projecting along flood/ebb # # Case 2: A Harmonic station with unknown flood and/or ebb. # We actually need to combine 3 requests: # 2a: EventType # 2b: SpeedDirType, which only provides vector magnitude/angle # 2c: VelocityMajorType, which only provides current velocity (but for same times as 2b) # Here we set up requests for cases 1 and 2 if self.stationFeature['type'] == 'H': self.speedDirRequest = CurrentPredictionRequest( self.manager, self.stationFeature, startTime, endTime, CurrentPredictionRequest.SpeedDirectionType) self.addDependency(self.speedDirRequest) self.eventRequest = CurrentPredictionRequest( self.manager, self.stationFeature, startTime, endTime, CurrentPredictionRequest.EventType) self.addDependency(self.eventRequest) floodDir = self.stationFeature['meanFloodDir'] ebbDir = self.stationFeature['meanEbbDir'] if floodDir == NULL or ebbDir == NULL: self.velocityRequest = CurrentPredictionRequest( self.manager, self.stationFeature, startTime, endTime, CurrentPredictionRequest.VelocityMajorType) self.addDependency(self.velocityRequest) else: self.velocityRequest = None # Case 3: A Subordinate station which only knows its events. Here we need the following: # 3a: PredictionEventPromises for this station in a 3-day window surrounding the date of interest # 3b: PredictionDataPromises for the reference station in the same 3-day window. else: self.eventPromises = [] self.refPromises = [] refStation = self.manager.getStation( self.stationFeature['refStation']) if refStation is None: print("Could not find ref station {} for {}".format( self.stationFeature['refStation'], self.stationFeature['station'])) else: for dayOffset in [-1, 0, 1]: windowDate = self.localDate.addDays(dayOffset) dataPromise = self.manager.getDataPromise( refStation, windowDate) self.refPromises.append(dataPromise) self.addDependency(dataPromise) eventPromise = self.manager.getEventPromise( self.stationFeature, windowDate) self.eventPromises.append(eventPromise) self.addDependency(eventPromise)
def runGetFeatureTests(self, provider): assert len([f for f in provider.getFeatures()]) == 5 self.assert_query(provider, 'name ILIKE \'QGIS\'', []) self.assert_query(provider, '"name" IS NULL', [5]) self.assert_query(provider, '"name" IS NOT NULL', [1, 2, 3, 4]) self.assert_query(provider, '"name" NOT LIKE \'Ap%\'', [1, 3, 4]) self.assert_query(provider, '"name" NOT ILIKE \'QGIS\'', [1, 2, 3, 4]) self.assert_query(provider, '"name" NOT ILIKE \'pEAR\'', [1, 2, 4]) self.assert_query(provider, 'name = \'Apple\'', [2]) self.assert_query(provider, 'name <> \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'name = \'apple\'', []) self.assert_query(provider, '"name" <> \'apple\'', [1, 2, 3, 4]) self.assert_query(provider, '(name = \'Apple\') is not null', [1, 2, 3, 4]) self.assert_query(provider, 'name LIKE \'Apple\'', [2]) self.assert_query(provider, 'name LIKE \'aPple\'', []) self.assert_query(provider, 'name ILIKE \'aPple\'', [2]) self.assert_query(provider, 'name ILIKE \'%pp%\'', [2]) self.assert_query(provider, 'cnt > 0', [1, 2, 3, 4]) self.assert_query(provider, '-cnt > 0', [5]) self.assert_query(provider, 'cnt < 0', [5]) self.assert_query(provider, '-cnt < 0', [1, 2, 3, 4]) self.assert_query(provider, 'cnt >= 100', [1, 2, 3, 4]) self.assert_query(provider, 'cnt <= 100', [1, 5]) self.assert_query(provider, 'pk IN (1, 2, 4, 8)', [1, 2, 4]) self.assert_query(provider, 'cnt = 50 * 2', [1]) self.assert_query(provider, 'cnt = 99 + 1', [1]) self.assert_query(provider, 'cnt = 101 - 1', [1]) self.assert_query(provider, 'cnt - 1 = 99', [1]) self.assert_query(provider, '-cnt - 1 = -101', [1]) self.assert_query(provider, '-(-cnt) = 100', [1]) self.assert_query(provider, '-(cnt) = -(100)', [1]) self.assert_query(provider, 'cnt + 1 = 101', [1]) self.assert_query(provider, 'cnt = 1100 % 1000', [1]) self.assert_query(provider, '"name" || \' \' || "name" = \'Orange Orange\'', [1]) self.assert_query(provider, '"name" || \' \' || "cnt" = \'Orange 100\'', [1]) self.assert_query(provider, '\'x\' || "name" IS NOT NULL', [1, 2, 3, 4]) self.assert_query(provider, '\'x\' || "name" IS NULL', [5]) self.assert_query(provider, 'cnt = 10 ^ 2', [1]) self.assert_query(provider, '"name" ~ \'[OP]ra[gne]+\'', [1]) self.assert_query( provider, '"name"="name2"', [2, 4]) # mix of matched and non-matched case sensitive names self.assert_query(provider, 'true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'false', []) # Three value logic self.assert_query(provider, 'false and false', []) self.assert_query(provider, 'false and true', []) self.assert_query(provider, 'false and NULL', []) self.assert_query(provider, 'true and false', []) self.assert_query(provider, 'true and true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true and NULL', []) self.assert_query(provider, 'NULL and false', []) self.assert_query(provider, 'NULL and true', []) self.assert_query(provider, 'NULL and NULL', []) self.assert_query(provider, 'false or false', []) self.assert_query(provider, 'false or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'false or NULL', []) self.assert_query(provider, 'true or false', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true or NULL', [1, 2, 3, 4, 5]) self.assert_query(provider, 'NULL or false', []) self.assert_query(provider, 'NULL or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'NULL or NULL', []) self.assert_query(provider, 'not true', []) self.assert_query(provider, 'not false', [1, 2, 3, 4, 5]) self.assert_query(provider, 'not null', []) # not self.assert_query(provider, 'not name = \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'not name IS NULL', [1, 2, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' or name = \'Apple\'', [1, 2, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' or not name = \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' and pk = 4', [4]) self.assert_query(provider, 'not name = \'Apple\' and not pk = 4', [1, 3]) self.assert_query(provider, 'not pk IN (1, 2, 4, 8)', [3, 5]) # type conversion - QGIS expressions do not mind that we are comparing a string # against numeric literals self.assert_query(provider, 'num_char IN (2, 4, 5)', [2, 4, 5]) # geometry self.assert_query( provider, 'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))', [1, 2]) # combination of an uncompilable expression and limit feature = next(self.vl.getFeatures('pk=4')) context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable('parent', feature) context.appendScope(scope) request = QgsFeatureRequest() request.setExpressionContext(context) request.setFilterExpression('"pk" = attribute(@parent, \'pk\')') request.setLimit(1) values = [f['pk'] for f in self.vl.getFeatures(request)] self.assertEqual(values, [4])
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsRasterLayer(parameters, self.INPUT, context) if source is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) band = self.parameterAsInt(parameters, self.BAND, context) expression = self.parameterAsString(parameters, self.EXPRESSION, context).replace('\n', '') feedback.pushInfo('Expression = {}'.format(expression)) if len(expression.strip()) == 0: raise QgsProcessingException('Expression values required!') output_raster = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) # create raster dataset inputDs = gdal.Open(unicode(source.source()), GA_ReadOnly) inputBand = inputDs.GetRasterBand(band) dataType = inputBand.DataType; nodata = int(inputBand.GetNoDataValue()) if dataType < 6 else inputBand.GetNoDataValue() feedback.pushInfo('NoData Value = {0}'.format(nodata)) feedback.pushInfo('DataType = {0}'.format(dataType)) feedback.pushInfo('DataType = {0}'.format(self.RASTER_TYPES[gdal.GetDataTypeName(dataType)])) driver = gdal.GetDriverByName('GTiff') outputDs = driver.Create(output_raster, inputDs.RasterXSize, inputDs.RasterYSize, 1, dataType) outputDs.SetProjection(inputDs.GetProjection()) outputDs.SetGeoTransform(inputDs.GetGeoTransform()) outputBand = outputDs.GetRasterBand(1) outputBand.SetNoDataValue(nodata) # prepare feature for expression fields = QgsFields() fields.append(QgsField('value', QVariant.Double)) fields.append(QgsField(source.name(), QVariant.Double)) exp = QgsExpression(expression) context = QgsExpressionContext() scope = QgsExpressionContextScope() context.appendScope(scope) feature = QgsFeature(fields) # extrace by attributes data_type = self.RASTER_TYPES[gdal.GetDataTypeName(dataType)] for y in range(inputBand.YSize): if feedback.isCanceled(): break feedback.setProgress(int(y / float(inputBand.YSize) * 100)) scanline = inputBand.ReadRaster(0, y, inputBand.XSize, 1, inputBand.XSize, 1, dataType) values = struct.unpack(data_type * inputBand.XSize, scanline) output = ''.encode() for value in values: raster_value = nodata if value != nodata: feature.setAttribute(0, value) feature.setAttribute(1, value) scope.setFeature(feature) if bool(exp.evaluate(context)): raster_value = value else: raster_value = nodata output = output + struct.pack(data_type, raster_value) # write line outputBand.WriteRaster(0, y, inputBand.XSize, 1, output, buf_xsize=inputBand.XSize, buf_ysize=1, buf_type=dataType) del output outputDs.FlushCache() outputDs = None inputDs = None return {self.OUTPUT: output_raster}
def testExpression(self): """ test aggregate calculation using an expression """ # numeric layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory") pr = layer.dataProvider() int_values = [4, 2, 3, 2, 5, None, 8] features = [] for v in int_values: f = QgsFeature() f.setFields(layer.fields()) f.setAttributes([v]) features.append(f) assert pr.addFeatures(features) #int agg = QgsAggregateCalculator(layer) val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint * 2') self.assertTrue(ok) self.assertEqual(val, 48) # double val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint * 1.5') self.assertTrue(ok) self.assertEqual(val, 36) # datetime val, ok = agg.calculate(QgsAggregateCalculator.Max, "to_date('2012-05-04') + to_interval( fldint || ' day' )") self.assertTrue(ok) self.assertEqual(val, QDateTime(QDate(2012, 5, 12), QTime(0, 0, 0))) # date val, ok = agg.calculate(QgsAggregateCalculator.Min, "to_date(to_date('2012-05-04') + to_interval( fldint || ' day' ))") self.assertTrue(ok) self.assertEqual(val, QDateTime(QDate(2012, 5, 6), QTime(0, 0, 0))) # string val, ok = agg.calculate(QgsAggregateCalculator.Max, "fldint || ' oranges'") self.assertTrue(ok) self.assertEqual(val, '8 oranges') # geometry val, ok = agg.calculate(QgsAggregateCalculator.GeometryCollect, "make_point( coalesce(fldint,0), 2 )") self.assertTrue(ok) self.assertTrue(val.exportToWkt(), 'MultiPoint((4 2, 2 2, 3 2, 2 2,5 2, 0 2,8 2))') # try a bad expression val, ok = agg.calculate(QgsAggregateCalculator.Max, "not_a_field || ' oranges'") self.assertFalse(ok) val, ok = agg.calculate(QgsAggregateCalculator.Max, "5+") self.assertFalse(ok) # test expression context # check default context first # should have layer variables: val, ok = agg.calculate(QgsAggregateCalculator.Min, "@layer_name") self.assertTrue(ok) self.assertEqual(val, 'layer') # but not custom variables: val, ok = agg.calculate(QgsAggregateCalculator.Min, "@my_var") self.assertTrue(ok) self.assertEqual(val, NULL) # test with manual expression context scope = QgsExpressionContextScope() scope.setVariable('my_var', 5) context = QgsExpressionContext() context.appendScope(scope) val, ok = agg.calculate(QgsAggregateCalculator.Min, "@my_var", context) self.assertTrue(ok) self.assertEqual(val, 5)
def runGetFeatureTests(self, provider): assert len([f for f in provider.getFeatures()]) == 5 self.assert_query(provider, 'name ILIKE \'QGIS\'', []) self.assert_query(provider, '"name" IS NULL', [5]) self.assert_query(provider, '"name" IS NOT NULL', [1, 2, 3, 4]) self.assert_query(provider, '"name" NOT LIKE \'Ap%\'', [1, 3, 4]) self.assert_query(provider, '"name" NOT ILIKE \'QGIS\'', [1, 2, 3, 4]) self.assert_query(provider, '"name" NOT ILIKE \'pEAR\'', [1, 2, 4]) self.assert_query(provider, 'name = \'Apple\'', [2]) self.assert_query(provider, 'name <> \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'name = \'apple\'', []) self.assert_query(provider, '"name" <> \'apple\'', [1, 2, 3, 4]) self.assert_query(provider, '(name = \'Apple\') is not null', [1, 2, 3, 4]) self.assert_query(provider, 'name LIKE \'Apple\'', [2]) self.assert_query(provider, 'name LIKE \'aPple\'', []) self.assert_query(provider, 'name ILIKE \'aPple\'', [2]) self.assert_query(provider, 'name ILIKE \'%pp%\'', [2]) self.assert_query(provider, 'cnt > 0', [1, 2, 3, 4]) self.assert_query(provider, '-cnt > 0', [5]) self.assert_query(provider, 'cnt < 0', [5]) self.assert_query(provider, '-cnt < 0', [1, 2, 3, 4]) self.assert_query(provider, 'cnt >= 100', [1, 2, 3, 4]) self.assert_query(provider, 'cnt <= 100', [1, 5]) self.assert_query(provider, 'pk IN (1, 2, 4, 8)', [1, 2, 4]) self.assert_query(provider, 'cnt = 50 * 2', [1]) self.assert_query(provider, 'cnt = 150 / 1.5', [1]) self.assert_query(provider, 'cnt = 1000 / 10', [1]) self.assert_query(provider, 'cnt = 1000/11+10', []) # checks that provider isn't rounding int/int self.assert_query(provider, 'pk = 9 // 4', [2]) # int division self.assert_query(provider, 'cnt = 99 + 1', [1]) self.assert_query(provider, 'cnt = 101 - 1', [1]) self.assert_query(provider, 'cnt - 1 = 99', [1]) self.assert_query(provider, '-cnt - 1 = -101', [1]) self.assert_query(provider, '-(-cnt) = 100', [1]) self.assert_query(provider, '-(cnt) = -(100)', [1]) self.assert_query(provider, 'cnt + 1 = 101', [1]) self.assert_query(provider, 'cnt = 1100 % 1000', [1]) self.assert_query(provider, '"name" || \' \' || "name" = \'Orange Orange\'', [1]) self.assert_query(provider, '"name" || \' \' || "cnt" = \'Orange 100\'', [1]) self.assert_query(provider, '\'x\' || "name" IS NOT NULL', [1, 2, 3, 4]) self.assert_query(provider, '\'x\' || "name" IS NULL', [5]) self.assert_query(provider, 'cnt = 10 ^ 2', [1]) self.assert_query(provider, '"name" ~ \'[OP]ra[gne]+\'', [1]) self.assert_query(provider, '"name"="name2"', [2, 4]) # mix of matched and non-matched case sensitive names self.assert_query(provider, 'true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'false', []) # Three value logic self.assert_query(provider, 'false and false', []) self.assert_query(provider, 'false and true', []) self.assert_query(provider, 'false and NULL', []) self.assert_query(provider, 'true and false', []) self.assert_query(provider, 'true and true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true and NULL', []) self.assert_query(provider, 'NULL and false', []) self.assert_query(provider, 'NULL and true', []) self.assert_query(provider, 'NULL and NULL', []) self.assert_query(provider, 'false or false', []) self.assert_query(provider, 'false or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'false or NULL', []) self.assert_query(provider, 'true or false', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'true or NULL', [1, 2, 3, 4, 5]) self.assert_query(provider, 'NULL or false', []) self.assert_query(provider, 'NULL or true', [1, 2, 3, 4, 5]) self.assert_query(provider, 'NULL or NULL', []) self.assert_query(provider, 'not true', []) self.assert_query(provider, 'not false', [1, 2, 3, 4, 5]) self.assert_query(provider, 'not null', []) # not self.assert_query(provider, 'not name = \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'not name IS NULL', [1, 2, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' or name = \'Apple\'', [1, 2, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' or not name = \'Apple\'', [1, 3, 4]) self.assert_query(provider, 'not name = \'Apple\' and pk = 4', [4]) self.assert_query(provider, 'not name = \'Apple\' and not pk = 4', [1, 3]) self.assert_query(provider, 'not pk IN (1, 2, 4, 8)', [3, 5]) # type conversion - QGIS expressions do not mind that we are comparing a string # against numeric literals self.assert_query(provider, 'num_char IN (2, 4, 5)', [2, 4, 5]) #function self.assert_query(provider, 'sqrt(pk) >= 2', [4, 5]) self.assert_query(provider, 'radians(cnt) < 2', [1, 5]) self.assert_query(provider, 'degrees(pk) <= 200', [1, 2, 3]) self.assert_query(provider, 'abs(cnt) <= 200', [1, 2, 5]) self.assert_query(provider, 'cos(pk) < 0', [2, 3, 4]) self.assert_query(provider, 'sin(pk) < 0', [4, 5]) self.assert_query(provider, 'tan(pk) < 0', [2, 3, 5]) self.assert_query(provider, 'acos(-1) < pk', [4, 5]) self.assert_query(provider, 'asin(1) < pk', [2, 3, 4, 5]) self.assert_query(provider, 'atan(3.14) < pk', [2, 3, 4, 5]) self.assert_query(provider, 'atan2(3.14, pk) < 1', [3, 4, 5]) self.assert_query(provider, 'exp(pk) < 10', [1, 2]) self.assert_query(provider, 'ln(pk) <= 1', [1, 2]) self.assert_query(provider, 'log(3, pk) <= 1', [1, 2, 3]) self.assert_query(provider, 'log10(pk) < 0.5', [1, 2, 3]) self.assert_query(provider, 'round(3.14) <= pk', [3, 4, 5]) self.assert_query(provider, 'round(0.314,1) * 10 = pk', [3]) self.assert_query(provider, 'floor(3.14) <= pk', [3, 4, 5]) self.assert_query(provider, 'ceil(3.14) <= pk', [4, 5]) self.assert_query(provider, 'pk < pi()', [1, 2, 3]) self.assert_query(provider, 'round(cnt / 66.67) <= 2', [1, 5]) self.assert_query(provider, 'floor(cnt / 66.67) <= 2', [1, 2, 5]) self.assert_query(provider, 'ceil(cnt / 66.67) <= 2', [1, 5]) self.assert_query(provider, 'pk < pi() / 2', [1]) self.assert_query(provider, 'pk = char(51)', [3]) self.assert_query(provider, 'pk = coalesce(NULL,3,4)', [3]) self.assert_query(provider, 'lower(name) = \'apple\'', [2]) self.assert_query(provider, 'upper(name) = \'APPLE\'', [2]) self.assert_query(provider, 'name = trim(\' Apple \')', [2]) # geometry # azimuth and touches tests are deactivated because they do not pass for WFS provider #self.assert_query(provider, 'azimuth($geometry,geom_from_wkt( \'Point (-70 70)\')) < pi()', [1, 5]) self.assert_query(provider, 'x($geometry) < -70', [1, 5]) self.assert_query(provider, 'y($geometry) > 70', [2, 4, 5]) self.assert_query(provider, 'xmin($geometry) < -70', [1, 5]) self.assert_query(provider, 'ymin($geometry) > 70', [2, 4, 5]) self.assert_query(provider, 'xmax($geometry) < -70', [1, 5]) self.assert_query(provider, 'ymax($geometry) > 70', [2, 4, 5]) self.assert_query(provider, 'disjoint($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))', [4, 5]) self.assert_query(provider, 'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))', [1, 2]) #self.assert_query(provider, 'touches($geometry,geom_from_wkt( \'Polygon ((-70.332 66.33, -65.32 66.33, -65.32 78.3, -70.332 78.3, -70.332 66.33))\'))', [1, 4]) self.assert_query(provider, 'contains(geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'),$geometry)', [1, 2]) self.assert_query(provider, 'distance($geometry,geom_from_wkt( \'Point (-70 70)\')) > 7', [4, 5]) self.assert_query(provider, 'intersects($geometry,geom_from_gml( \'<gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-72.2,66.1 -65.2,66.1 -65.2,72.0 -72.2,72.0 -72.2,66.1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>\'))', [1, 2]) # combination of an uncompilable expression and limit feature = next(self.vl.getFeatures('pk=4')) context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable('parent', feature) context.appendScope(scope) request = QgsFeatureRequest() request.setExpressionContext(context) request.setFilterExpression('"pk" = attribute(@parent, \'pk\')') request.setLimit(1) values = [f['pk'] for f in self.vl.getFeatures(request)] self.assertEqual(values, [4])
def testRemappingSink(self): """ Test remapping features """ fields = QgsFields() fields.append(QgsField('fldtxt', QVariant.String)) fields.append(QgsField('fldint', QVariant.Int)) fields.append(QgsField('fldtxt2', QVariant.String)) store = QgsFeatureStore(fields, QgsCoordinateReferenceSystem('EPSG:3857')) mapping_def = QgsRemappingSinkDefinition() mapping_def.setDestinationWkbType(QgsWkbTypes.Point) mapping_def.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:4326')) mapping_def.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:3857')) mapping_def.setDestinationFields(fields) mapping_def.addMappedField('fldtxt2', QgsProperty.fromField('fld1')) mapping_def.addMappedField( 'fldint', QgsProperty.fromExpression('@myval * fldint')) proxy = QgsRemappingProxyFeatureSink(mapping_def, store) self.assertEqual(proxy.destinationSink(), store) self.assertEqual(len(store), 0) incoming_fields = QgsFields() incoming_fields.append(QgsField('fld1', QVariant.String)) incoming_fields.append(QgsField('fldint', QVariant.Int)) context = QgsExpressionContext() scope = QgsExpressionContextScope() scope.setVariable('myval', 2) context.appendScope(scope) context.setFields(incoming_fields) proxy.setExpressionContext(context) proxy.setTransformContext(QgsProject.instance().transformContext()) f = QgsFeature() f.setFields(incoming_fields) f.setAttributes(["test", 123]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2))) self.assertTrue(proxy.addFeature(f)) self.assertEqual(len(store), 1) self.assertEqual(store.features()[0].geometry().asWkt(1), 'Point (111319.5 222684.2)') self.assertEqual(store.features()[0].attributes(), [None, 246, 'test']) f2 = QgsFeature() f2.setAttributes(["test2", 457]) f2.setGeometry(QgsGeometry.fromWkt('LineString( 1 1, 2 2)')) f3 = QgsFeature() f3.setAttributes(["test3", 888]) f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(3, 4))) self.assertTrue(proxy.addFeatures([f2, f3])) self.assertEqual(len(store), 4) self.assertEqual(store.features()[1].attributes(), [None, 914, 'test2']) self.assertEqual(store.features()[2].attributes(), [None, 914, 'test2']) self.assertEqual(store.features()[3].attributes(), [None, 1776, 'test3']) self.assertEqual(store.features()[1].geometry().asWkt(1), 'Point (111319.5 111325.1)') self.assertEqual(store.features()[2].geometry().asWkt(1), 'Point (222639 222684.2)') self.assertEqual(store.features()[3].geometry().asWkt(1), 'Point (333958.5 445640.1)')
def layer_value(feature, layer, defaultconfig): if not canvas: roam.utils.warning( "No canvas set for using layer_values default function") return None layers = [] # layer name can also be a list of layers to search layername = defaultconfig['layer'] if isinstance(layername, basestring): layers.append(layername) else: layers = layername expression = defaultconfig['expression'] field = defaultconfig['field'] for searchlayer in layers: try: searchlayer = QgsMapLayerRegistry.instance().mapLayersByName( searchlayer)[0] except IndexError: RoamEvents.raisemessage( "Missing layer", "Unable to find layer used in widget expression {}".format( searchlayer), level=1) roam.utils.warning( "Unable to find expression layer {}".format(searchlayer)) return if feature.geometry(): rect = feature.geometry().boundingBox() if layer.geometryType() == QGis.Point: point = feature.geometry().asPoint() rect = QgsRectangle(point.x(), point.y(), point.x() + 10, point.y() + 10) rect.scale(20) rect = canvas.mapRenderer().mapToLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect) \ .setFlags(QgsFeatureRequest.ExactIntersect) features = searchlayer.getFeatures(rq) else: features = searchlayer.getFeatures() expression = expression.replace("$roamgeometry", "@roamgeometry") exp = QgsExpression(expression) exp.prepare(searchlayer.pendingFields()) if exp.hasParserError(): error = exp.parserErrorString() roam.utils.warning(error) context = QgsExpressionContext() scope = QgsExpressionContextScope() context.appendScope(scope) scope.setVariable("roamgeometry", feature.geometry()) for f in features: context.setFeature(f) value = exp.evaluate(context) if exp.hasEvalError(): error = exp.evalErrorString() roam.utils.warning(error) if value: return f[field] raise DefaultError('No features found')
def layer_value(feature, layer, defaultconfig): if not canvas: roam.utils.warning("No canvas set for using layer_values default function") return None layers = [] # layer name can also be a list of layers to search layername = defaultconfig['layer'] if isinstance(layername, basestring): layers.append(layername) else: layers = layername expression = defaultconfig['expression'] field = defaultconfig['field'] for searchlayer in layers: try: searchlayer = QgsMapLayerRegistry.instance().mapLayersByName(searchlayer)[0] except IndexError: RoamEvents.raisemessage("Missing layer", "Unable to find layer used in widget expression {}".format(searchlayer), level=1) roam.utils.warning("Unable to find expression layer {}".format(searchlayer)) return if feature.geometry(): rect = feature.geometry().boundingBox() if layer.geometryType() == QGis.Point: point = feature.geometry().asPoint() rect = QgsRectangle(point.x(), point.y(), point.x() + 10, point.y() + 10) rect.scale(20) rect = canvas.mapRenderer().mapToLayerCoordinates(layer, rect) rq = QgsFeatureRequest().setFilterRect(rect)\ .setFlags(QgsFeatureRequest.ExactIntersect) features = searchlayer.getFeatures(rq) else: features = searchlayer.getFeatures() expression = expression.replace("$roamgeometry", "@roamgeometry") exp = QgsExpression(expression) exp.prepare(searchlayer.pendingFields()) if exp.hasParserError(): error = exp.parserErrorString() roam.utils.warning(error) context = QgsExpressionContext() scope = QgsExpressionContextScope() context.appendScope(scope) scope.setVariable("roamgeometry", feature.geometry()) for f in features: context.setFeature(f) value = exp.evaluate(context) if exp.hasEvalError(): error = exp.evalErrorString() roam.utils.warning(error) if value: return f[field] raise DefaultError('No features found')
def handleAlgorithmResults(alg, context, feedback=None, showResults=True, parameters={}): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText( QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress( 100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString( l, context, typeHint=details.layerTypeHint) if layer is not None: set_layer_name(layer, details) '''If running a model, the execution will arrive here when an algorithm that is part of that model is executed. We check if its output is a final otuput of the model, and adapt the output name accordingly''' outputName = details.outputName expcontext = QgsExpressionContext() scope = QgsExpressionContextScope() expcontext.appendScope(scope) for out in alg.outputDefinitions(): if out.name() not in parameters: continue outValue = parameters[out.name()] if hasattr(outValue, "sink"): outValue = outValue.sink.valueAsString(expcontext)[0] else: outValue = str(outValue) if outValue == l: outputName = out.name() break style = None if outputName: style = RenderingStyles.getStyle(alg.id(), outputName) if style is None: if layer.type() == QgsMapLayerType.RasterLayer: style = ProcessingConfig.getSetting( ProcessingConfig.RASTER_STYLE) else: if layer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POINT_STYLE) elif layer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POLYGON_STYLE) if style: layer.loadNamedStyle(style) details.project.addMapLayer( context.temporaryLayerStore().takeMapLayer(layer)) if details.postProcessor(): details.postProcessor().postProcessLayer( layer, context, feedback) else: wrongLayers.append(str(l)) except Exception: QgsMessageLog.logMessage( QCoreApplication.translate( 'Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', Qgis.Critical) wrongLayers.append(str(l)) i += 1 feedback.setProgress(100) if wrongLayers: msg = QCoreApplication.translate( 'Postprocessing', "The following layers were not correctly generated.") msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += QCoreApplication.translate( 'Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm." ) feedback.reportError(msg) return len(wrongLayers) == 0
def createExpressionContext(self) -> QgsExpressionContext: # pylint: disable=missing-docstring, no-self-use context = QgsExpressionContext() scope = QgsExpressionContextScope() context.appendScope(scope) context.appendScope(vl1.createExpressionContextScope()) return context
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) insee_com = self.parameterAsExpression(parameters, self.INSEE_COM, context) adresse = self.parameterAsExpression(parameters, self.ADRESSE, context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) fields = source.fields() fields.append(QgsField( 'ban_label', QVariant.String, len=6)) or feedback.reportError( 'Le champs ban_label existe deja, son contenu sera remplacé') fields.append(QgsField( 'ban_citycode', QVariant.String, len=100)) or feedback.reportError( 'Le champs ban_citycode existe deja, son contenu sera remplacé' ) fields.append(QgsField( 'ban_score', QVariant.Double, len=10, prec=5)) or feedback.reportError( 'Le champs ban_score existe deja, son contenu sera remplacé') fields.append(QgsField( 'ban_type', QVariant.String, len=20)) or feedback.reportError( 'Le champs ban_type existe deja, son contenu sera remplacé') (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(2154)) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) total = 100.0 / source.featureCount() if source.featureCount() else 0 features = source.getFeatures() citycode_expr = QgsExpression(insee_com) adresse_expr = QgsExpression(adresse) context = self.createExpressionContext(parameters, context, source) scope = QgsExpressionContextScope() citycode_expr.prepare(context) adresse_expr.prepare(context) for current, feature in enumerate(features): if feedback.isCanceled(): break scope.setFeature(feature) context.appendScope(scope) citycode = citycode_expr.evaluate(context) adresse = adresse_expr.evaluate(context) response = geocode(adresse, citycode=citycode) if response: #feedback.pushDebugInfo(str(response['properties'].get('score'))) attr = feature.attributes() for i in range(fields.count() - len(attr)): attr.append(None) feature.setFields(fields) feature.setAttributes(attr) feature.setAttribute('ban_label', response['properties'].get('label', '')) feature.setAttribute( 'ban_citycode', response['properties'].get('citycode', '')) feature.setAttribute('ban_score', response['properties'].get('score', '')) feature.setAttribute('ban_type', response['properties'].get('type', '')) x = response['properties'].get('x') y = response['properties'].get('y') #feature.setAttributes(attr) geom = QgsGeometry().fromPointXY(QgsPointXY(x, y)) #t=QgsCoordinateTransform(QgsCoordinateReferenceSystem(2154),source.sourceCrs(),QgsProject.instance()) #geom.transform(t) feature.setGeometry(geom) # Add a feature in the sink sink.addFeature(feature, QgsFeatureSink.FastInsert) # Update the progress bar feedback.setProgress(int(current * total)) sleep(0.11) return {self.OUTPUT: dest_id}
def testExpression(self): """ test aggregate calculation using an expression """ # numeric layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory") pr = layer.dataProvider() int_values = [4, 2, 3, 2, 5, None, 8] features = [] for v in int_values: f = QgsFeature() f.setFields(layer.fields()) f.setAttributes([v]) features.append(f) assert pr.addFeatures(features) #int agg = QgsAggregateCalculator(layer) val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint * 2') self.assertTrue(ok) self.assertEqual(val, 48) # double val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint * 1.5') self.assertTrue(ok) self.assertEqual(val, 36) # datetime val, ok = agg.calculate( QgsAggregateCalculator.Max, "to_date('2012-05-04') + to_interval( fldint || ' day' )") self.assertTrue(ok) self.assertEqual(val, QDateTime(QDate(2012, 5, 12), QTime(0, 0, 0))) # date val, ok = agg.calculate( QgsAggregateCalculator.Min, "to_date(to_date('2012-05-04') + to_interval( fldint || ' day' ))") self.assertTrue(ok) self.assertEqual(val, QDateTime(QDate(2012, 5, 6), QTime(0, 0, 0))) # string val, ok = agg.calculate(QgsAggregateCalculator.Max, "fldint || ' oranges'") self.assertTrue(ok) self.assertEqual(val, '8 oranges') # geometry val, ok = agg.calculate(QgsAggregateCalculator.GeometryCollect, "make_point( coalesce(fldint,0), 2 )") self.assertTrue(ok) self.assertTrue(val.exportToWkt(), 'MultiPoint((4 2, 2 2, 3 2, 2 2,5 2, 0 2,8 2))') # try a bad expression val, ok = agg.calculate(QgsAggregateCalculator.Max, "not_a_field || ' oranges'") self.assertFalse(ok) val, ok = agg.calculate(QgsAggregateCalculator.Max, "5+") self.assertFalse(ok) # test expression context # check default context first # should have layer variables: val, ok = agg.calculate(QgsAggregateCalculator.Min, "@layer_name") self.assertTrue(ok) self.assertEqual(val, 'layer') # but not custom variables: val, ok = agg.calculate(QgsAggregateCalculator.Min, "@my_var") self.assertTrue(ok) self.assertEqual(val, NULL) # test with manual expression context scope = QgsExpressionContextScope() scope.setVariable('my_var', 5) context = QgsExpressionContext() context.appendScope(scope) val, ok = agg.calculate(QgsAggregateCalculator.Min, "@my_var", context) self.assertTrue(ok) self.assertEqual(val, 5)
def updateVariables(self): context = self.mItem.createExpressionContext(); self.mVariableEditor.setContext( context ); editableIndex = context.indexOfScope( QgsExpressionContextScope("Composer Item" )); if ( editableIndex >= 0 ): self.mVariableEditor.setEditableScopeIndex( editableIndex );