def joinattributesbylocation(self, input, join, inputonlyselected=False, joinonlyselected=False, joinfiels=[], method=0, predicate=[0], prefix='', discardnomatching=False, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'qgis:joinattributesbylocation' inputsource = input joinsource = join if inputonlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) if joinonlyselected: joinsource = QgsProcessingFeatureSourceDefinition(join, True) params = dict( INPUT=inputsource, JOIN=joinsource, JOIN_FIELDS=joinfiels, METHOD=method, # 0 — (one-to-many), 1 — (one - to - one) PREDICATE= predicate, # 0 — intersects, 1 — contains, 2 — equals, 3 — touches, 4 — overlaps, 5 — within, 6 — crosses PREFIX=prefix, DISCARD_NONMATCHING=discardnomatching, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def joinattributetable(self, input1, input1onlyselected, input2, input2onlyselected, field1, field2, prefix='M_', output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'native:joinattributestable' inputsource1 = input1 inputsource2 = input2 if input1onlyselected: inputsource1 = QgsProcessingFeatureSourceDefinition(input1, True) if input2onlyselected: inputsource2 = QgsProcessingFeatureSourceDefinition(input2, True) params = dict(INPUT=inputsource1, FIELD=field1, INPUT_2=inputsource2, FIELD_2=field2, FIELDS_TO_COPY=[], METHOD=1, PREFIX=prefix, DISCARD_NONMATCHING=False, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def distancematrix(self, input, inputonlyselected, inputfield, target, targetonlyseleted, targetfield, matrixtype=2, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'qgis:distancematrix' inputsource = input tarsource = target if inputonlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) if targetonlyseleted: tarsource = QgsProcessingFeatureSourceDefinition(target, True) params = dict(INPUT=inputsource, INPUT_FIELD=inputfield, TARGET=tarsource, TARGET_FIELD=targetfield, MATRIX_TYPE=matrixtype, NEAREST_POINTS=0, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def countpointsinpolygon(self, polygons, points, field, polyonlyselected=False, pointonlyseleced=False, weight=None, classfield=None, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'qgis:countpointsinpolygon' polyinputsource = polygons if polyonlyselected: polyinputsource = QgsProcessingFeatureSourceDefinition( polygons, True) pointinputsource = points if pointonlyseleced: pointinputsource = QgsProcessingFeatureSourceDefinition( points, True) params = dict(POLYGONS=polyinputsource, POINTS=pointinputsource, FIELD=field, WEIGHT=weight, CLASSFIELD=classfield, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def intersection(self, input, inputonlyseleceted, inputfields, overlay, overayprefix, overonlyselected=False, overlayer_fields=None, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'native:intersection' inputsource = input if inputonlyseleceted: inputsource = QgsProcessingFeatureSourceDefinition(input, True) overlaysource = overlay if overonlyselected: overlaysource = QgsProcessingFeatureSourceDefinition(overlay, True) params = dict(INPUT=inputsource, INPUT_FIELDS=inputfields, OVERLAY=overlaysource, OVERLAY_FIELDS_PREFIX=overayprefix, OVERLAY_FIELDS=overlayer_fields, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def execute_in_place(alg, parameters, context=None, feedback=None): """Executes an algorithm modifying features in-place in the active layer. The input layer must be editable or an exception is raised. :param alg: algorithm to run :type alg: QgsProcessingAlgorithm :param parameters: parameters of the algorithm :type parameters: dict :param context: context, defaults to None :param context: QgsProcessingContext, optional :param feedback: feedback, defaults to None :param feedback: QgsProcessingFeedback, optional :raises QgsProcessingException: raised when the layer is not editable or the layer cannot be found in the current project :return: a tuple with true if success and results :rtype: tuple """ parameters['INPUT'] = QgsProcessingFeatureSourceDefinition( iface.activeLayer().id(), True) ok, results = execute_in_place_run(alg, iface.activeLayer(), parameters, context=context, feedback=feedback) if ok: iface.activeLayer().triggerRepaint() return ok, results
def nearesthubpoints(self, input, onlyselected, sf_hub, hubfield, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = "qgis:distancetonearesthubpoints" inputsource = input if onlyselected: # self.feedback.pushInfo('onlyselected') inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, HUBS=sf_hub, FIELD=hubfield, UNIT=0, OUTPUT=output) result = self.run_algprocessing(algname=algname, params=params)['OUTPUT'] if output.find('TEMPORARY_OUTPUT') < 0: basename = 'output' result = self.renameField(layer=result, fromName='HubName', toName=hubfield, baseName=basename) else: result.startEditing() idx = result.fields().indexFromName('HubName') result.renameAttribute(idx, hubfield) result.commitChanges() return result
def createCentroidsLayer(self, layer, filt, name): #Dato un layer di tipo poligonale, ne crea una copia utilizzandone i centroidi; #In base al filtro scelto utilizza solo le features selezionate (o tutte le features se non esiste un filtro): #aggiunge i campi prob, ruolo e probRuolo if filt: QueryLayer().selectionByExpr(layer, filt) else: layer.selectAll() context = dataobjects.createContext() context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck) params = { 'INPUT': QgsProcessingFeatureSourceDefinition(layer.id(), True), 'ALL_PARTS': False, 'OUTPUT': 'memory:' } newLayer = processing.run("native:centroids", params, context=context) layerOutput = newLayer['OUTPUT'] data_provider = layerOutput.dataProvider() data_provider.addAttributes([QgsField('prob', QVariant.Int)]) data_provider.addAttributes([QgsField('ruolo', QVariant.String)]) data_provider.addAttributes([QgsField('probRuolo', QVariant.String)]) layerOutput.updateFields() layerOutput.setName(name) QgsProject.instance().addMapLayer(layerOutput) QgsProject.instance().layerTreeRoot().findLayer( layerOutput.id()).setItemVisibilityChecked(False) layer.removeSelection() iface.setActiveLayer(layerOutput) return layerOutput
def testGetOgrCompatibleSourceFromOgrLayer(self): p = QgsProject() source = os.path.join(testDataPath, 'points.gml') vl = QgsVectorLayer(source) self.assertTrue(vl.isValid()) p.addMapLayer(vl) context = QgsProcessingContext() context.setProject(p) feedback = QgsProcessingFeedback() alg = ogr2ogr() alg.initAlgorithm() path, layer = alg.getOgrCompatibleSource('INPUT', {'INPUT': vl.id()}, context, feedback, True) self.assertEqual(path, source) path, layer = alg.getOgrCompatibleSource('INPUT', {'INPUT': vl.id()}, context, feedback, False) self.assertEqual(path, source) # with selected features only - if not executing, the 'selected features only' setting # should be ignored (because it has no meaning for the gdal command outside of QGIS!) parameters = { 'INPUT': QgsProcessingFeatureSourceDefinition(vl.id(), True) } path, layer = alg.getOgrCompatibleSource('INPUT', parameters, context, feedback, False) self.assertEqual(path, source) # with subset string vl.setSubsetString('x') path, layer = alg.getOgrCompatibleSource('INPUT', parameters, context, feedback, False) self.assertEqual(path, source) # subset of layer must be exported path, layer = alg.getOgrCompatibleSource('INPUT', parameters, context, feedback, True) self.assertNotEqual(path, source) self.assertTrue(path) self.assertTrue(path.endswith('.gpkg')) self.assertTrue(os.path.exists(path)) self.assertTrue(layer) # geopackage with layer source = os.path.join(testDataPath, 'custom', 'circular_strings.gpkg') vl2 = QgsVectorLayer(source + '|layername=circular_strings') self.assertTrue(vl2.isValid()) p.addMapLayer(vl2) path, layer = alg.getOgrCompatibleSource('INPUT', {'INPUT': vl2.id()}, context, feedback, True) self.assertEqual(path, source) self.assertEqual(layer, 'circular_strings') vl3 = QgsVectorLayer(source + '|layername=circular_strings_with_line') self.assertTrue(vl3.isValid()) p.addMapLayer(vl3) path, layer = alg.getOgrCompatibleSource('INPUT', {'INPUT': vl3.id()}, context, feedback, True) self.assertEqual(path, source) self.assertEqual(layer, 'circular_strings_with_line')
def testFeatureSourceInput(self): # create a memory layer and add to project and context layer = QgsVectorLayer("Point?crs=epsg:3857&field=fldtxt:string&field=fldint:integer", "testmem", "memory") self.assertTrue(layer.isValid()) pr = layer.dataProvider() f = QgsFeature() f.setAttributes(["test", 123]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) f2 = QgsFeature() f2.setAttributes(["test2", 457]) f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(110, 200))) self.assertTrue(pr.addFeatures([f, f2])) self.assertEqual(layer.featureCount(), 2) # select first feature layer.selectByIds([next(layer.getFeatures()).id()]) self.assertEqual(len(layer.selectedFeatureIds()), 1) QgsProject.instance().addMapLayer(layer) context = QgsProcessingContext() context.setProject(QgsProject.instance()) alg = QgsApplication.processingRegistry().createAlgorithmById('grass7:v.buffer') self.assertIsNotNone(alg) temp_file = os.path.join(self.temp_dir, 'grass_output_sel.shp') parameters = {'input': QgsProcessingFeatureSourceDefinition('testmem', True), 'cats': '', 'where': '', 'type': [0, 1, 4], 'distance': 1, 'minordistance': None, 'angle': 0, 'column': None, 'scale': 1, 'tolerance': 0.01, '-s': False, '-c': False, '-t': False, 'output': temp_file, 'GRASS_REGION_PARAMETER': None, 'GRASS_SNAP_TOLERANCE_PARAMETER': -1, 'GRASS_MIN_AREA_PARAMETER': 0.0001, 'GRASS_OUTPUT_TYPE_PARAMETER': 0, 'GRASS_VECTOR_DSCO': '', 'GRASS_VECTOR_LCO': ''} feedback = QgsProcessingFeedback() results, ok = alg.run(parameters, context, feedback) self.assertTrue(ok) self.assertTrue(os.path.exists(temp_file)) # make sure that layer has correct features res = QgsVectorLayer(temp_file, 'res') self.assertTrue(res.isValid()) self.assertEqual(res.featureCount(), 1) QgsProject.instance().removeMapLayer(layer)
def differencelayer(self, input, onlyselected, overlay, overonlyselected, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = "native:difference" inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) oversource = overlay if overonlyselected: oversource = QgsProcessingFeatureSourceDefinition(overlay, True) params = dict(INPUT=inputsource, OVERLAY=oversource, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def get_processing_value(param: QgsProcessingParameterDefinition, inp: WPSInput, context: ProcessingContext) -> Any: """ Return processing values from WPS input data """ if isinstance(param, DESTINATION_LAYER_TYPES): # # Destination layer: a new layer is created as file with the input name. # Do not supports memory layer because we need persistence # param.setSupportsNonFileBasedOutput(False) # # Enforce pushing created layers to layersToLoadOnCompletion list # i.e layer will be stored in the destination project # get extension from input metadata (should always exist for destination) extension = get_metadata(inp[0], 'processing:extension')[0] destination = inp[0].data if confservice.getboolean('processing', 'unsafe.raw_destination_input_sink'): sink, destination = parse_root_destination_path( param, destination, extension) else: # Use canonical file name sink = "./%s.%s" % (get_valid_filename(param.name()), extension) value = QgsProcessingOutputLayerDefinition(sink, context.destination_project) value.destinationName = destination LOGGER.debug("Handling destination layer: %s, details name: %s", param.name(), value.destinationName) elif isinstance(param, QgsProcessingParameterFeatureSource): # # Support feature selection # value, has_selection = parse_layer_spec(inp[0].data, context, allow_selection=True) value = QgsProcessingFeatureSourceDefinition( value, selectedFeaturesOnly=has_selection) elif isinstance(param, INPUT_LAYER_TYPES): if len(inp) > 1: value = [parse_layer_spec(i.data, context)[0] for i in inp] else: value, _ = parse_layer_spec(inp[0].data, context) else: value = None return value
def recherche(self): # Paramètres en entrée: # { 'INPUT' : 'C:/Olivier/Documents/Carto/References/Vecteur/communes-20140629-5m-shp/communes-20140629-5m.shp', # 'INTERSECT' : QgsProcessingFeatureSourceDefinition('TraceMatin20160930224546251', True), # 'OUTPUT' : 'C:/Olivier/Documents/Collectif/Telethon 2018/Cartes/Enduro/SuiviValidation.shp', # 'PREDICATE' : [0] } ss = False ll = self.parent.dlg.MasqueLignePoint.currentData() if (self.parent.dlg.selectionSeulement.isChecked()): self.parent.iface.messageBar().pushMessage( "Selection seulement dans {0}".format(ll.name()), Qgis.MessageLevel.Info) self.parent.iface.messageBar().update() ss = True print(ll.selectedFeatureCount()) if (ll.selectedFeatureCount() == 0): self.parent.iface.messageBar().pushCritical( "Erreur", "Pas d entite selectionnee dans {0}".format(ll.name())) self.parent.message("Recherche ...") QGuiApplication.setOverrideCursor(Qt.WaitCursor) paramin = { 'INPUT': self.parent.dlg.MasqueListeCouches.currentData().id(), 'INTERSECT': QgsProcessingFeatureSourceDefinition(ll.id(), ss), 'OUTPUT': 'memory:', 'PREDICATE': [0] } res = processing.run('native:extractbylocation', paramin) # verifier si erreur print(res['OUTPUT']) l = res['OUTPUT'] # Ajout des champs res=l.dataProvider().addAttributes([QgsField("valide", QVariant.Date), QgsField("note", QVariant.String), \ QgsField("supprime", QVariant.Date), QgsField("ajoute", QVariant.Date)]) l.updateFields() if (not res): print("Erreur creation attributs") self.parent.iface.messageBar().pushCritical( "Erreur", "Erreur de creation des attributs") if (len(self.parent.dlg.MasqueNomCouche.displayText().strip()) > 0): l.setName(self.parent.dlg.MasqueNomCouche.displayText().strip()) self.defStyle(l) QgsProject.instance().addMapLayer(l) QGuiApplication.restoreOverrideCursor() self.parent.message("Done")
def runSplitLinesWithLines(self, inputLyr, linesLyr, context, feedback=None, onlySelected=False, outputLyr=None): usedInput = inputLyr if not onlySelected else \ QgsProcessingFeatureSourceDefinition(inputLyr.id(), True) usedLines = linesLyr if not onlySelected else \ QgsProcessingFeatureSourceDefinition(linesLyr.id(), True) outputLyr = 'memory:' if outputLyr is None else outputLyr parameters = { 'INPUT': usedInput, 'LINES': usedLines, 'OUTPUT': outputLyr } output = processing.run("native:splitwithlines", parameters, context=context, feedback=feedback) return output['OUTPUT']
def multiparttosingleparts(self, input, onlyselected, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'native:multiparttosingleparts' #algname = 'qgis:multiparttosingleparts' inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def centroidlayer(self, input, onlyselected, allparts=False, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'native:centroids' inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, ALL_PARTS=allparts, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def runAddCount(self, inputLyr, boolVar): output = processing.run( "native:addautoincrementalfield", { 'INPUT':QgsProcessingFeatureSourceDefinition(inputLyr.sourceName(), not boolVar), # boolVar recebe o contrario da checkbox de feições selecionadas 'FIELD_NAME':'AUTO', 'START':0, 'GROUP_FIELDS':[], 'SORT_EXPRESSION':'', 'SORT_ASCENDING':False, 'SORT_NULLS_FIRST':False, 'OUTPUT':'TEMPORARY_OUTPUT' } ) return output['OUTPUT']
def dissolvewithQgis2(self, input, onlyselected, field=None, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'qgis:dissolve' inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, FIELD=field, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def clipwithQgis(self, input, onlyselected, overlay, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = "native:clip" inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, OVERLAY=overlay, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def createConvexHull(self, lBeni, b1, b2): #Data una lista di beni calcola il convexhull corrispondente; #utilizza l'algoritmo minimumboundinggeometry; #setta il context affinchè non ci sia il check sulle geometrie invalide layer = Utils().getLayerBeni() layerOutput = False for feat in layer.getFeatures(): if feat['ident'] in lBeni: beneId = str(feat['id']) dipendentiIds = QueryLayer().getDependenciesList( beneId, b1, b2) if len(dipendentiIds) > 2: expr = QueryLayer().IdListToExpr(dipendentiIds) QueryLayer().selectionByExpr(layer, expr) context = dataobjects.createContext() context.setInvalidGeometryCheck( QgsFeatureRequest.GeometryNoCheck) params = { 'INPUT': QgsProcessingFeatureSourceDefinition(layer.id(), True), 'TYPE': 3, 'OUTPUT': 'memory:' } newconvexhulllayer = processing.run( "qgis:minimumboundinggeometry", params, context=context) layerOutput = newconvexhulllayer['OUTPUT'] layerOutput.setName('areaBene' + beneId) layerOutput.startEditing() for feat in layerOutput.getFeatures(): feat['id'] = beneId layerOutput.updateFeature(feat) layerOutput.commitChanges() Utils().setStyle("buffer", layerOutput) QgsProject.instance().addMapLayer(layerOutput) if layerOutput != False: if len(lBeni) > 1: Utils().zoomToLayer(Utils().getLayerBeni()) else: Utils().zoomToLayer(layerOutput) else: iface.messageBar().pushMessage( 'Attenzione', 'Non esistono beni o relazioni con queste caratteristiche', level=Qgis.Critical)
def _alg_tester(self, alg_name, input_layer, parameters): alg = self.registry.createAlgorithmById(alg_name) self.assertIsNotNone(alg) parameters['INPUT'] = QgsProcessingFeatureSourceDefinition( input_layer.id(), True) parameters['OUTPUT'] = 'memory:' old_features = [f for f in input_layer.getFeatures()] input_layer.selectByIds([old_features[0].id()]) # Check selected self.assertEqual(input_layer.selectedFeatureIds(), [old_features[0].id()], alg_name) context = QgsProcessingContext() context.setProject(QgsProject.instance()) feedback = ConsoleFeedBack() input_layer.rollBack() with self.assertRaises(QgsProcessingException) as cm: execute_in_place_run(alg, input_layer, parameters, context=context, feedback=feedback, raise_exceptions=True) ok = False input_layer.startEditing() ok, _ = execute_in_place_run(alg, input_layer, parameters, context=context, feedback=feedback, raise_exceptions=True) new_features = [f for f in input_layer.getFeatures()] # Check ret values self.assertTrue(ok, alg_name) # Check geometry types (drop Z or M) self.assertEqual(new_features[0].geometry().wkbType(), old_features[0].geometry().wkbType()) return old_features, new_features
def bufferwithQgis(self, input, onlyselected, distance, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'native:multiringconstantbuffer' inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, DISTANCE=distance, OUTPUT=output, RINGS=1) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def testGetOgrCompatibleSourceFromFeatureSource(self): # create a memory layer and add to project and context layer = QgsVectorLayer( "Point?field=fldtxt:string&field=fldint:integer", "testmem", "memory") self.assertTrue(layer.isValid()) pr = layer.dataProvider() f = QgsFeature() f.setAttributes(["test", 123]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) f2 = QgsFeature() f2.setAttributes(["test2", 457]) f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) self.assertTrue(pr.addFeatures([f, f2])) self.assertEqual(layer.featureCount(), 2) # select first feature layer.selectByIds([next(layer.getFeatures()).id()]) self.assertEqual(len(layer.selectedFeatureIds()), 1) QgsProject.instance().addMapLayer(layer) context = QgsProcessingContext() context.setProject(QgsProject.instance()) alg = QgsApplication.processingRegistry().createAlgorithmById( 'gdal:buffervectors') self.assertIsNotNone(alg) parameters = { 'INPUT': QgsProcessingFeatureSourceDefinition('testmem', True) } feedback = QgsProcessingFeedback() # check that memory layer is automatically saved out to geopackage when required by GDAL algorithms ogr_data_path, ogr_layer_name = alg.getOgrCompatibleSource( 'INPUT', parameters, context, feedback, executing=True) self.assertTrue(ogr_data_path) self.assertTrue(ogr_data_path.endswith('.gpkg')) self.assertTrue(os.path.exists(ogr_data_path)) self.assertTrue(ogr_layer_name) # make sure that layer has only selected feature res = QgsVectorLayer(ogr_data_path, 'res') self.assertTrue(res.isValid()) self.assertEqual(res.featureCount(), 1) QgsProject.instance().removeMapLayer(layer)
def statisticsbycategories(self, input, onlyselected, categoriesfields, valuefield, output='TEMPORARY_OUTPUT'): if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = 'qgis:statisticsbycategories' inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, CATEGORIES_FIELD_NAME=categoriesfields, METHOD=0, VALUES_FIELD_NAME=valuefield, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def refactorfields(self, input, onlyselected, refieldmapping, output='TEMPORARY_OUTPUT'): # qgis:refactorfields # {'FIELDS_MAPPING': [{'expression': '"NEAR_FID"', 'length': 10, 'name': 'NEAR_FID', 'precision': 0, 'type': 4}, # {'expression': '"pop_all"', 'length': 18, 'name': 'pop_all', 'precision': 11, 'type': 6}], # 'INPUT': '/Users/song-ansup/Desktop/KoALA_data/logfile/cliped_pop.shp', 'OUTPUT': 'TEMPORARY_OUTPUT'} if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = "qgis:refactorfields" inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, FIELDS_MAPPING=refieldmapping, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def rectanglesovalsdiamonds(self, input, onlyselected=False, shape=0, width=1.0, height=1.0, rotation=None, segment=36, output='TEMPORARY_OUTPUT'): # 0 — Rectangles # 1 — Ovals # 2 — Diamonds if output is None or output == '': output = 'TEMPORARY_OUTPUT' algname = "" if algname == "": algname = self.checkAlgname("qgis:rectanglesovalsdiamondsfixed") if algname == "": algname = self.checkAlgname("native:rectanglesovalsdiamondsfixed") if algname == "": algname = self.checkAlgname("qgis:rectanglesovalsdiamonds") if algname == "": algname = self.checkAlgname("native:rectanglesovalsdiamonds") self.feedback.pushInfo("************ checkAlgname %s : " % algname) inputsource = input if onlyselected: inputsource = QgsProcessingFeatureSourceDefinition(input, True) params = dict(INPUT=inputsource, SHAPE=shape, WIDTH=width, HEIGHT=height, ROTATION=rotation, SEGMENTS=segment, OUTPUT=output) return self.run_algprocessing(algname=algname, params=params)['OUTPUT']
def _test_copy_selected(self, input_layer_name, output_layer_name, select_id=1): print("### ", input_layer_name, output_layer_name) gpkg = get_test_file_copy_path('insert_features_to_layer_test.gpkg') input_layer_path = "{}|layername={}".format(gpkg, input_layer_name) output_layer_path = "{}|layername={}".format(gpkg, output_layer_name) input_layer = QgsVectorLayer(input_layer_path, 'layer name', 'ogr') self.assertTrue(input_layer.isValid()) output_layer = QgsVectorLayer(output_layer_path, 'layer name', 'ogr') self.assertTrue(output_layer.isValid()) QgsProject.instance().addMapLayers([input_layer, output_layer]) input_layer.select(select_id) # fid=1 res = processing.run( "etl_load:appendfeaturestolayer", { 'SOURCE_LAYER': QgsProcessingFeatureSourceDefinition(input_layer_path, True), 'SOURCE_FIELD': None, 'TARGET_LAYER': output_layer, 'TARGET_FIELD': None, 'ACTION_ON_DUPLICATE': 0 }) # No action self.assertIsNone( res[UPDATED_COUNT] ) # These are None because ACTION_ON_DUPLICATE is None self.assertIsNone(res[SKIPPED_COUNT]) return res
def test_feature_source_definition(self): """ Test that QgsProcessingFeatureSourceDefinition values are correctly loaded and written """ doc = QDomDocument("properties") definition = QgsProcessingFeatureSourceDefinition(QgsProperty.fromValue('my source')) definition.selectedFeaturesOnly = True definition.featureLimit = 27 definition.flags = QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature definition.geometryCheck = QgsFeatureRequest.GeometrySkipInvalid elem = QgsXmlUtils.writeVariant(definition, doc) c = QgsXmlUtils.readVariant(elem) self.assertEqual(c.source.staticValue(), 'my source') self.assertTrue(c.selectedFeaturesOnly) self.assertEqual(c.featureLimit, 27) self.assertEqual(c.flags, QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature) self.assertEqual(c.geometryCheck, QgsFeatureRequest.GeometrySkipInvalid)
def execute_in_place_run(alg, parameters, context=None, feedback=None, raise_exceptions=False): """Executes an algorithm modifying features in-place in the input layer. :param alg: algorithm to run :type alg: QgsProcessingAlgorithm :param parameters: parameters of the algorithm :type parameters: dict :param context: context, defaults to None :type context: QgsProcessingContext, optional :param feedback: feedback, defaults to None :type feedback: QgsProcessingFeedback, optional :param raise_exceptions: useful for testing, if True exceptions are raised, normally exceptions will be forwarded to the feedback :type raise_exceptions: boo, default to False :raises QgsProcessingException: raised when there is no active layer, or it cannot be made editable :return: a tuple with true if success and results :rtype: tuple """ if feedback is None: feedback = QgsProcessingFeedback() if context is None: context = dataobjects.createContext(feedback) # Only feature based algs have sourceFlags try: if alg.sourceFlags( ) & QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks: context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck) except AttributeError: pass active_layer = parameters['INPUT'] # Run some checks and prepare the layer for in-place execution by: # - getting the active layer and checking that it is a vector # - making the layer editable if it was not already # - selecting all features if none was selected # - checking in-place support for the active layer/alg/parameters # If one of the check fails and raise_exceptions is True an exception # is raised, else the execution is aborted and the error reported in # the feedback try: if active_layer is None: raise QgsProcessingException(tr("There is not active layer.")) if not isinstance(active_layer, QgsVectorLayer): raise QgsProcessingException( tr("Active layer is not a vector layer.")) if not active_layer.isEditable(): if not active_layer.startEditing(): raise QgsProcessingException( tr("Active layer is not editable (and editing could not be turned on)." )) if not alg.supportInPlaceEdit(active_layer): raise QgsProcessingException( tr("Selected algorithm and parameter configuration are not compatible with in-place modifications." )) except QgsProcessingException as e: if raise_exceptions: raise e QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical) if feedback is not None: feedback.reportError(getattr(e, 'msg', str(e)), fatalError=True) return False, {} if not active_layer.selectedFeatureIds(): active_layer.selectAll() # Make sure we are working on selected features only parameters['INPUT'] = QgsProcessingFeatureSourceDefinition( active_layer.id(), True) parameters['OUTPUT'] = 'memory:' req = QgsFeatureRequest(QgsExpression(r"$id < 0")) req.setFlags(QgsFeatureRequest.NoGeometry) req.setSubsetOfAttributes([]) # Start the execution # If anything goes wrong and raise_exceptions is True an exception # is raised, else the execution is aborted and the error reported in # the feedback try: new_feature_ids = [] active_layer.beginEditCommand(alg.displayName()) # Checks whether the algorithm has a processFeature method if hasattr(alg, 'processFeature'): # in-place feature editing # Make a clone or it will crash the second time the dialog # is opened and run alg = alg.create() if not alg.prepare(parameters, context, feedback): raise QgsProcessingException( tr("Could not prepare selected algorithm.")) # Check again for compatibility after prepare if not alg.supportInPlaceEdit(active_layer): raise QgsProcessingException( tr("Selected algorithm and parameter configuration are not compatible with in-place modifications." )) field_idxs = range(len(active_layer.fields())) iterator_req = QgsFeatureRequest(active_layer.selectedFeatureIds()) iterator_req.setInvalidGeometryCheck( context.invalidGeometryCheck()) feature_iterator = active_layer.getFeatures(iterator_req) step = 100 / len(active_layer.selectedFeatureIds() ) if active_layer.selectedFeatureIds() else 1 for current, f in enumerate(feature_iterator): feedback.setProgress(current * step) if feedback.isCanceled(): break # need a deep copy, because python processFeature implementations may return # a shallow copy from processFeature input_feature = QgsFeature(f) new_features = alg.processFeature(input_feature, context, feedback) new_features = QgsVectorLayerUtils.makeFeaturesCompatible( new_features, active_layer) if len(new_features) == 0: active_layer.deleteFeature(f.id()) elif len(new_features) == 1: new_f = new_features[0] if not f.geometry().equals(new_f.geometry()): active_layer.changeGeometry(f.id(), new_f.geometry()) if f.attributes() != new_f.attributes(): active_layer.changeAttributeValues( f.id(), dict(zip(field_idxs, new_f.attributes())), dict(zip(field_idxs, f.attributes()))) new_feature_ids.append(f.id()) else: active_layer.deleteFeature(f.id()) # Get the new ids old_ids = set( [f.id() for f in active_layer.getFeatures(req)]) if not active_layer.addFeatures(new_features): raise QgsProcessingException( tr("Error adding processed features back into the layer." )) new_ids = set( [f.id() for f in active_layer.getFeatures(req)]) new_feature_ids += list(new_ids - old_ids) results, ok = {}, True else: # Traditional 'run' with delete and add features cycle # There is no way to know if some features have been skipped # due to invalid geometries if context.invalidGeometryCheck( ) == QgsFeatureRequest.GeometrySkipInvalid: selected_ids = active_layer.selectedFeatureIds() else: selected_ids = [] results, ok = alg.run(parameters, context, feedback) if ok: result_layer = QgsProcessingUtils.mapLayerFromString( results['OUTPUT'], context) # TODO: check if features have changed before delete/add cycle new_features = [] # Check if there are any skipped features if context.invalidGeometryCheck( ) == QgsFeatureRequest.GeometrySkipInvalid: missing_ids = list( set(selected_ids) - set(result_layer.allFeatureIds())) if missing_ids: for f in active_layer.getFeatures( QgsFeatureRequest(missing_ids)): if not f.geometry().isGeosValid(): new_features.append(f) active_layer.deleteFeatures(active_layer.selectedFeatureIds()) for f in result_layer.getFeatures(): new_features.extend( QgsVectorLayerUtils.makeFeaturesCompatible( [f], active_layer)) # Get the new ids old_ids = set([f.id() for f in active_layer.getFeatures(req)]) if not active_layer.addFeatures(new_features): raise QgsProcessingException( tr("Error adding processed features back into the layer." )) new_ids = set([f.id() for f in active_layer.getFeatures(req)]) new_feature_ids += list(new_ids - old_ids) active_layer.endEditCommand() if ok and new_feature_ids: active_layer.selectByIds(new_feature_ids) elif not ok: active_layer.rollBack() return ok, results except QgsProcessingException as e: active_layer.endEditCommand() active_layer.rollBack() if raise_exceptions: raise e QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical) if feedback is not None: feedback.reportError(getattr(e, 'msg', str(e)), fatalError=True) return False, {}
def fill_right_of_way_relations(self, db): layers = { db.names.LC_ADMINISTRATIVE_SOURCE_T: None, db.names.LC_PARCEL_T: None, db.names.LC_PLOT_T: None, db.names.LC_RESTRICTION_T: None, db.names.LC_RESTRICTION_TYPE_D: None, db.names.LC_RIGHT_OF_WAY_T: None, db.names.COL_RRR_SOURCE_T: None, db.names.LC_SURVEY_POINT_T: None, db.names.COL_UE_BAUNIT_T: None } # Load layers self.app.core.get_layers(db, layers, load=True) if not layers: return None exp = "\"{}\" = '{}'".format( db.names.ILICODE_F, LADMNames.RESTRICTION_TYPE_D_RIGHT_OF_WAY_ILICODE_VALUE) restriction_right_of_way_t_id = [ feature for feature in layers[ db.names.LC_RESTRICTION_TYPE_D].getFeatures(exp) ][0][db.names.T_ID_F] if layers[db.names.LC_PLOT_T].selectedFeatureCount() == 0 or layers[ db.names.LC_RIGHT_OF_WAY_T].selectedFeatureCount( ) == 0 or layers[ db.names.LC_ADMINISTRATIVE_SOURCE_T].selectedFeatureCount( ) == 0: if self.app.core.get_ladm_layer_from_qgis( db, db.names.LC_PLOT_T, EnumLayerRegistryType.IN_LAYER_TREE) is None: self.logger.message_with_button_load_layer_emitted.emit( QCoreApplication.translate( "RightOfWay", "First load the layer {} into QGIS and select at least one plot!" ).format(db.names.LC_PLOT_T), QCoreApplication.translate("RightOfWay", "Load layer {} now").format( db.names.LC_PLOT_T), db.names.LC_PLOT_T, Qgis.Warning) else: self.logger.warning_msg( __name__, QCoreApplication.translate( "RightOfWay", "Select at least one benefited plot, one right of way and at least one administrative source to create relations!" )) return else: ue_baunit_features = layers[db.names.COL_UE_BAUNIT_T].getFeatures() # Get unique pairs id_right_of_way-id_parcel existing_pairs = [ (ue_baunit_feature[db.names.COL_UE_BAUNIT_T_PARCEL_F], ue_baunit_feature[db.names.COL_UE_BAUNIT_T_LC_RIGHT_OF_WAY_F]) for ue_baunit_feature in ue_baunit_features ] existing_pairs = set(existing_pairs) plot_ids = [ f[db.names.T_ID_F] for f in layers[db.names.LC_PLOT_T].selectedFeatures() ] right_of_way_id = layers[ db.names.LC_RIGHT_OF_WAY_T].selectedFeatures()[0].attribute( db.names.T_ID_F) id_pairs = list() for plot in plot_ids: exp = "\"{uebaunit}\" = {plot}".format( uebaunit=db.names.COL_UE_BAUNIT_T_LC_PLOT_F, plot=plot) parcels = layers[db.names.COL_UE_BAUNIT_T].getFeatures(exp) for parcel in parcels: id_pair = (parcel.attribute( db.names.COL_UE_BAUNIT_T_PARCEL_F), right_of_way_id) id_pairs.append(id_pair) if len(id_pairs) < len(plot_ids): # If any relationship plot-parcel is not found, we don't need to continue self.logger.warning_msg( __name__, QCoreApplication.translate( "RightOfWay", "One or more pairs id_plot-id_parcel weren't found, this is needed to create benefited and restriction relations." )) return if id_pairs: new_features = list() for id_pair in id_pairs: if not id_pair in existing_pairs: #Create feature new_feature = QgsVectorLayerUtils().createFeature( layers[db.names.COL_UE_BAUNIT_T]) new_feature.setAttribute( db.names.COL_UE_BAUNIT_T_PARCEL_F, id_pair[0]) new_feature.setAttribute( db.names.COL_UE_BAUNIT_T_LC_RIGHT_OF_WAY_F, id_pair[1]) self.logger.info( __name__, "Saving RightOfWay-Parcel: {}-{}".format( id_pair[1], id_pair[0])) new_features.append(new_feature) layers[db.names.COL_UE_BAUNIT_T].dataProvider().addFeatures( new_features) self.logger.info_msg( __name__, QCoreApplication.translate( "RightOfWay", "{} out of {} records were saved into {}! {} out of {} records already existed in the database." ).format(len(new_features), len(id_pairs), db.names.COL_UE_BAUNIT_T, len(id_pairs) - len(new_features), len(id_pairs))) spatial_join_layer = processing.run( "qgis:joinattributesbylocation", { 'INPUT': layers[db.names.LC_PLOT_T], 'JOIN': QgsProcessingFeatureSourceDefinition( layers[db.names.LC_RIGHT_OF_WAY_T].id(), True), 'PREDICATE': [0], 'JOIN_FIELDS': [db.names.T_ID_F], 'METHOD': 0, 'DISCARD_NONMATCHING': True, 'PREFIX': '', 'OUTPUT': 'memory:' })['OUTPUT'] restriction_features = layers[ db.names.LC_RESTRICTION_T].getFeatures() existing_restriction_pairs = [ (restriction_feature[db.names.COL_BAUNIT_RRR_T_UNIT_F], restriction_feature[db.names.COL_RRR_T_DESCRIPTION_F]) for restriction_feature in restriction_features ] existing_restriction_pairs = set(existing_restriction_pairs) id_pairs_restriction = list() plot_ids = spatial_join_layer.getFeatures() for plot in plot_ids: exp = "\"uebaunit\" = {plot}".format( uebaunit=db.names.COL_UE_BAUNIT_T_LC_PLOT_F, plot=plot.attribute(db.names.T_ID_F)) parcels = layers[db.names.COL_UE_BAUNIT_T].getFeatures(exp) for parcel in parcels: id_pair_restriction = (parcel.attribute( db.names.COL_UE_BAUNIT_T_PARCEL_F), QCoreApplication.translate( "RightOfWay", "Right of way")) id_pairs_restriction.append(id_pair_restriction) new_restriction_features = list() if id_pairs_restriction: for id_pair in id_pairs_restriction: if not id_pair in existing_restriction_pairs: #Create feature new_feature = QgsVectorLayerUtils().createFeature( layers[db.names.LC_RESTRICTION_T]) new_feature.setAttribute( db.names.COL_BAUNIT_RRR_T_UNIT_F, id_pair[0]) new_feature.setAttribute( db.names.COL_RRR_T_DESCRIPTION_F, id_pair[1]) new_feature.setAttribute( db.names.LC_RESTRICTION_T_TYPE_F, restriction_right_of_way_t_id) self.logger.info( __name__, "Saving RightOfWay-Parcel: {}-{}".format( id_pair[1], id_pair[0])) new_restriction_features.append(new_feature) layers[db.names.LC_RESTRICTION_T].dataProvider().addFeatures( new_restriction_features) self.logger.info_msg( __name__, QCoreApplication.translate( "RightOfWay", "{} out of {} records were saved into {}! {} out of {} records already existed in the database." ).format( len(new_restriction_features), len(id_pairs_restriction), db.names.LC_RESTRICTION_T, len(id_pairs_restriction) - len(new_restriction_features), len(id_pairs_restriction))) administrative_source_ids = [ f[db.names.T_ID_F] for f in layers[ db.names.LC_ADMINISTRATIVE_SOURCE_T].selectedFeatures() ] source_relation_features = layers[ db.names.COL_RRR_SOURCE_T].getFeatures() existing_source_pairs = [ (source_relation_feature[db.names.COL_RRR_SOURCE_T_SOURCE_F], source_relation_feature[ db.names.COL_RRR_SOURCE_T_LC_RESTRICTION_F]) for source_relation_feature in source_relation_features ] existing_source_pairs = set(existing_source_pairs) rrr_source_relation_pairs = list() for administrative_source_id in administrative_source_ids: for restriction_feature in new_restriction_features: rrr_source_relation_pair = (administrative_source_id, restriction_feature.attribute( db.names.T_ID_F)) rrr_source_relation_pairs.append(rrr_source_relation_pair) new_rrr_source_relation_features = list() if rrr_source_relation_pairs: for id_pair in rrr_source_relation_pairs: if not id_pair in existing_source_pairs: new_feature = QgsVectorLayerUtils().createFeature( layers[db.names.COL_RRR_SOURCE_T]) new_feature.setAttribute( db.names.COL_RRR_SOURCE_T_SOURCE_F, id_pair[0]) new_feature.setAttribute( db.names.COL_RRR_SOURCE_T_LC_RESTRICTION_F, id_pair[1]) self.logger.info( __name__, "Saving Restriction-Source: {}-{}".format( id_pair[1], id_pair[0])) new_rrr_source_relation_features.append(new_feature) layers[db.names.COL_RRR_SOURCE_T].dataProvider().addFeatures( new_rrr_source_relation_features) self.logger.info_msg( __name__, QCoreApplication.translate( "RightOfWay", "{} out of {} records were saved into {}! {} out of {} records already existed in the database." ).format( len(new_rrr_source_relation_features), len(rrr_source_relation_pairs), db.names.COL_RRR_SOURCE_T, len(rrr_source_relation_pairs) - len(new_rrr_source_relation_features), len(rrr_source_relation_pairs)))