""" *************************************************************************** v_net.py -------- Date : December 2015 Copyright : (C) 2015 by Médéric Ribreux Email : medspx at medspx dot fr *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * *************************************************************************** This Python module handles pre-treatment operations for v.net.* GRASS modules. Before using a v.net module you often have to incorporate a points layer into the network vector map. """ __author__ = "Médéric Ribreux" __date__ = "December 2015" __copyright__ = "(C) 2015, Médéric Ribreux" import os from qgis.core import QgsProcessingException from processing.tools.system import getTempFilename from qgis.PyQt.QtCore import QCoreApplication def incorporatePoints( alg, parameters, context, feedback, pointLayerName="points", networkLayerName="input", ): """ incorporate points with lines to form a GRASS network """ # Grab the point layer and delete this parameter pointLayer = alg.parameterAsVectorLayer(parameters, pointLayerName, context) if pointLayer: # Create an intermediate GRASS layer which is the combination of network + centers intLayer = "net" + os.path.basename(getTempFilename(context=context)) pointLayer = alg.exportedLayers[pointLayerName] # Grab the network layer lineLayer = alg.parameterAsVectorLayer(parameters, networkLayerName, context) if lineLayer: lineLayer = alg.exportedLayers[networkLayerName] else: raise QgsProcessingException( QCoreApplication.translate( "GrassAlgorithmExt", "GRASS GIS v.net requires a lines layer!" ) ) threshold = alg.parameterAsDouble(parameters, "threshold", context) # Create the v.net connect command for point layer integration command = "v.net -s input={} points={} output={} operation=connect threshold={}".format( lineLayer, pointLayer, intLayer, threshold ) alg.commands.append(command) # Connect the point layer database to the layer 2 of the network command = f"v.db.connect -o map={intLayer} table={pointLayer} layer=2" alg.commands.append(command) # remove undesired parameters alg.removeParameter(pointLayerName) # Use temp layer for input alg.exportedLayers[networkLayerName] = intLayer # Process the command if "threshold" in parameters: alg.removeParameter("threshold") alg.processCommand(parameters, context, feedback) def variableOutput(alg, layers, parameters, context, nocats=True): """Handle variable data output for v.net modules: :param layers: layers is a dict of outputs: { 'outputName': ['srcLayer', 'output_type', output_layer_number, nocats], ... } where: - outputName is the name of the output in the description file. - srcLayer is the grass name of the layer to export. - output_type is the GRASS datatype (point/line/area/etc.). - output_layer_number is the GRASS layer number for multiple layers datasets. - nocats indicates weither we need to also export without categories items. :param parameters: :param context: :param nocats: do not add categories. """ for outputName, typeList in layers.items(): if not isinstance(typeList, list): continue file_name = alg.parameterAsOutputLayer(parameters, outputName, context) src_layer = typeList[0] output_type = typeList[1] output_layer_number = typeList[2] no_cats = typeList[3] grass_name = f"{src_layer}{alg.uniqueSuffix}" alg.exportVectorLayer( grassName=grass_name, fileName=file_name, layer=output_layer_number, exportnocat=no_cats, dataType=output_type, ) def processOutputs(alg, parameters, context, feedback): idx = alg.parameterAsInt(parameters, "operation", context) operations = alg.parameterDefinition("operation").options() operation = operations[idx] if operation == "nodes": outputParameter = {"output": ["output", "point", 2, True]} elif operation == "connect": outputParameter = {"output": ["output", "line", 1, False]} elif operation == "arcs": outputParameter = {"output": ["output", "line", 1, True]} variableOutput(alg, outputParameter, parameters, context)