def initializeSettings(self): AlgorithmProvider.initializeSettings(self) ProcessingConfig.addSetting( Setting(self.getDescription(), GPFUtils.BEAM_FOLDER, "BEAM install directory", GPFUtils.programPath(GPFUtils.beamKey()))) ProcessingConfig.addSetting( Setting(self.getDescription(), GPFUtils.BEAM_THREADS, "Maximum number of parallel (native) threads", 4))
def processAlgorithm(self, progress): gpfXml = self.toXml(forExecution=True) loglines = [] loglines.append("GPF Graph") for line in gpfXml.splitlines(): loglines.append(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) GPFUtils.executeGpf( GPFUtils.getKeyFromProviderName(self.provider.getName()), gpfXml, progress)
def _loadAlgorithms(self): self.createAlgsList(GPFUtils.snapKey(), SNAPAlgorithm) self.algs = self.preloadedAlgs if ProcessingConfig.getSetting(GPFUtils.S1TBX_ACTIVATE) == True: self.createAlgsList(GPFUtils.s1tbxKey(), S1TbxAlgorithm) for alg in self.preloadedAlgs: self.algs.append(alg) if ProcessingConfig.getSetting(GPFUtils.S2TBX_ACTIVATE) == True: self.createAlgsList(GPFUtils.s2tbxKey(), S2TbxAlgorithm) for alg in self.preloadedAlgs: self.algs.append(alg) # Also load models self.loadGpfModels(GPFUtils.modelsFolder())
def addWriteNode(self, graph, output, key): # add write node nodeID = self.nodeID+"_write_"+str(GPFAlgorithm.nodeIDNum) GPFAlgorithm.nodeIDNum +=1 node = ET.SubElement(graph, "node", {"id":nodeID}) operator = ET.SubElement(node, "operator") operator.text = "Write" # add source sources = ET.SubElement(node, "sources") ET.SubElement(sources, "sourceProduct", {"refid":self.nodeID}) # add some options parametersNode = ET.SubElement(node, "parameters") parameter = ET.SubElement(parametersNode, "file") parameter.text = str(output.value) parameter = ET.SubElement(parametersNode, "formatName") if output.value.lower().endswith(".dim"): parameter.text = "BEAM-DIMAP" elif output.value.lower().endswith(".hdr"): parameter.text = "ENVI" else: if key == GPFUtils.beamKey(): parameter.text = "GeoTIFF" else: parameter.text = "GeoTIFF-BigTIFF" return graph
def initializeSettings(self): AlgorithmProvider.initializeSettings(self) ProcessingConfig.addSetting( Setting(self.getDescription(), GPFUtils.SNAP_FOLDER, "SNAP install directory", GPFUtils.programPath(GPFUtils.snapKey()))) ProcessingConfig.addSetting( Setting(self.getDescription(), GPFUtils.SNAP_THREADS, "Maximum number of parallel (native) threads", 4)) ProcessingConfig.addSetting( Setting(self.getDescription(), GPFUtils.GPF_MODELS_FOLDER, "GPF models' directory", GPFUtils.modelsFolder())) ProcessingConfig.addSetting( Setting(self.getDescription(), GPFUtils.S1TBX_ACTIVATE, "Activate Sentinel-1 toolbox", False)) ProcessingConfig.addSetting( Setting(self.getDescription(), GPFUtils.S2TBX_ACTIVATE, "Activate Sentinel-2 toolbox", False))
def createAlgsList(self): self.preloadedAlgs = [] folder = GPFUtils.gpfDescriptionPath(GPFUtils.beamKey()) for descriptionFile in os.listdir(folder): if descriptionFile.endswith("txt"): try: alg = BEAMAlgorithm(os.path.join(folder, descriptionFile)) if alg.name.strip() != "": self.preloadedAlgs.append(alg) else: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, "Could not open BEAM algorithm: " + descriptionFile) except Exception, e: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, "Could not open BEAM algorithm: " + descriptionFile)
def processAlgorithm(self, key, progress): # Create a GFP for execution with SNAP's GPT graph = ET.Element("graph", {'id':self.operator+'_gpf'}) version = ET.SubElement(graph, "version") version.text = "1.0" # Add node with this algorithm's operator graph = self.addGPFNode(graph) # Add outputs as write nodes (except for Write operator) if self.operator != "Write" and len(self.outputs) >= 1: for output in self.outputs: graph = self.addWriteNode(graph, output, key) # Log the GPF loglines = [] loglines.append("GPF Graph") GPFUtils.indentXML(graph) for line in ET.tostring(graph).splitlines(): loglines.append(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) # Execute the GPF GPFUtils.executeGpf(key, ET.tostring(graph), progress)
def createAlgsList(self, key, gpfAlgorithm): self.preloadedAlgs = [] folder = GPFUtils.gpfDescriptionPath(key) for descriptionFile in os.listdir(folder): if descriptionFile.endswith("txt"): try: alg = gpfAlgorithm(os.path.join(folder, descriptionFile)) if alg.name.strip() != "": alg.provider = self self.preloadedAlgs.append(alg) else: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, "Could not open " + key + " SNAP generic algorithm: " + descriptionFile) except Exception, e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, str(e)) ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, "Could not open " + key + " generic algorithm: " + descriptionFile)
def __init__(self, gpfAlgorithmProvider): self.name = self.tr('GpfModel', 'GpfModelerAlgorithm') # The dialog where this model is being edited self.modelerdialog = None self.descriptionFile = None self.helpContent = {} # Geoalgorithms in this model. A dict of Algorithm objects, with names as keys self.algs = {} #Input parameters. A dict of Input objects, with names as keys self.inputs = {} # NOTE: # This doesn't seem used so remove it later from BEAMParmetersPanel and S1TbxAlgorithm self.multipleRasterInput = False GeoAlgorithm.__init__(self) self.provider = gpfAlgorithmProvider self.programKey = GPFUtils.getKeyFromProviderName( self.provider.getName())
def toXml(self, forExecution=False): graph = ET.Element("graph", {'id': "Graph"}) version = ET.SubElement(graph, "version") version.text = "1.0" # If the XML is made to be saved then set parameters and outputs. # If it is made for execution then parameters and outputs are already set. if not forExecution: self.defineCharacteristics() # Set the connections between nodes for alg in self.algs.values(): for param in alg.params.values(): if isinstance(param, ValueFromOutput): alg.algorithm.getParameterFromName( "sourceProduct").setValue( self.algs[param.alg].algorithm.nodeID) # Save model algorithms for alg in self.algs.values(): self.prepareAlgorithm(alg) # Only Write operators can save raster outputs for out in alg.algorithm.outputs: if alg.algorithm.operator != "Write" and isinstance( out, OutputRaster): if out.name in alg.outputs: QMessageBox.warning( None, self.tr('Unable to save model'), self. tr('Output rasters can only be saved by Write operator. Remove the value of raster output in %s algorithm or add a Write operator' % (alg.algorithm.operator, ))) return graph = alg.algorithm.addGPFNode(graph) # Save also the position and settings of model inputs. # They are saved as attributes of relevant parameter XML nodes. # This way they do not interfere with the model when it's opened # in SNAP. if alg.algorithm.operator != "Read": for param in alg.params.keys(): paramValue = str(alg.params[param]) if paramValue in self.inputs.keys(): # Only Read operators can read raster inputs if param == "sourceProduct": QMessageBox.warning( None, self.tr('Unable to save model'), self. tr('Input rasters can only be loaded by Read operator. Change the value of raster input in %s algorithm to an output of another algorithm' % (alg.algorithm.operator, ))) return paramTag = graph.find('node[@id="' + alg.algorithm.nodeID + '"]/parameters/' + param) if paramTag is not None: pos = self.inputs[paramValue].pos paramTag.attrib["qgisModelInputPos"] = str( pos.x()) + "," + str(pos.y()) paramTag.attrib["qgisModelInputVars"] = str( self.inputs[paramValue].param.todict()) # Save model layout presentation = ET.SubElement(graph, "applicationData", { "id": "Presentation", "name": self.name, "group": self.group }) ET.SubElement(presentation, "Description") for alg in self.algs.values(): node = ET.SubElement(presentation, "node", {"id": alg.algorithm.nodeID}) ET.SubElement(node, "displayPosition", { "x": str(alg.pos.x()), "y": str(alg.pos.y()) }) # Make it look nice in text file GPFUtils.indentXML(graph) return ET.tostring(graph)
def helpFile(self, key): folder = GPFUtils.gpfDocPath(key) if str(folder).strip() != "": helpfile = os.path.join( str(folder), self.operator + ".html" ) return helpfile return None
def addGPFNode(self, graph): # if there are previous nodes that should be added to the graph, recursively go backwards and add them if self.previousAlgInGraph != None: self.previousAlgInGraph.addGPFNode(graph) # now create and add the current node node = ET.Element("node", {"id":self.nodeID}) operator = ET.SubElement(node, "operator") operator.text = self.operator # sources are added in the parameters loop below sources = ET.SubElement(node, "sources") parametersNode = ET.SubElement(node, "parameters") for param in self.parameters: # add a source product if isinstance(param, ParameterRaster): if param.value: param.value, dataFormat = GPFUtils.gdalPathToSnapPath(param.value) if param.value.startswith("Error:"): raise GeoAlgorithmExecutionException(param.value) # if the source is a file, then add an external "source product" file if os.path.isfile(param.value): # check if the file should be added individually or through the # ProductSet-Reader used sometimes by S1 Toolbox match = re.match("^\d*ProductSet-Reader>(.*)",param.name) if match: paramName = match.group(1) sourceNodeId = self.addProductSetReaderNode(graph, param.value) else: paramName = param.name if operator.text == "Read": sourceNodeId = self.addReadNode(graph, param.value, dataFormat, self.nodeID) return graph else: sourceNodeId = self.addReadNode(graph, param.value, dataFormat) if sources.find(paramName) == None: source = ET.SubElement(sources, paramName) source.set("refid",sourceNodeId) # else assume its a reference to a previous node and add a "source" element elif param.value: source = ET.SubElement(sources, param.name, {"refid":param.value}) # add parameters else: # Set the name of the parameter # First check if there are nested tags tagList = param.name.split(">") parentElement = parametersNode parameter = None for tag in tagList: # if this is the last tag or there are no nested tags create the parameter element if tag == tagList[-1]: # special treatment for geoRegionExtent parameter in Subset operator if tag == "geoRegionExtent": tag = "geoRegion" # there can be only one parameter element in each parent element if len(parentElement.findall(tag)) > 0: parameter = parentElement.findall(tag)[0] else: parameter = ET.SubElement(parentElement, tag) # "!" means that a new element in the graph should be created as child of the parent element and set as a parent elif tag.startswith("!"): parentElement = ET.SubElement(parentElement, tag[1:]) # otherwise just find the last element with required name and set it as parent of the parameter element # or create a new one if it can't be found else: if len(parentElement.findall(tag)) > 0: parentElement = (parentElement.findall(tag))[-1] else: parentElement = ET.SubElement(parentElement, tag) # Set the value of the parameter if param.value == None or param.value == GPFAlgorithm.NOVALUEINT or param.value == GPFAlgorithm.NOVALUEDOUBLE: pass elif isinstance(param, ParameterBoolean): if param.value: parameter.text = "True" else: parameter.text = "False" elif isinstance(param, ParameterSelection): idx = int(param.value) parameter.text = str(param.options[idx]) # create at WKT polygon from the extent values, used in Subset Operator elif isinstance(param, ParameterExtent): values = param.value.split(",") if len(values) == 4: parameter.text = "POLYGON((" parameter.text += values[0] + ' ' + values[2] +", " parameter.text += values[0] + ' ' + values[3] +", " parameter.text += values[1] + ' ' + values[3] +", " parameter.text += values[1] + ' ' + values[2] +", " parameter.text += values[0] + ' ' + values[2] +"))" elif isinstance(param, ParameterFile): if param.value is None or param.value == "None": parameter.text = "" else: parameter.text = str(param.value) else: parameter.text = str(param.value) # For "Write" operator also save the output raster as a parameter if self.operator == "Write": fileParameter = ET.SubElement(parametersNode, "file") fileParameter.text = str((self.outputs[0]).value) graph.append(node) return graph
def showBandsDialog(self): polarisations = GPFUtils.getPolarisations(self.getFilePath()) dlg = GPFPolarisationsListDialog(polarisations, self.getFilePath(), self) dlg.show()
def showBandsDialog(self): bands = GPFUtils.getBeamBandNames(self.getFilePath(), self.programKey, self.appendProductName) dlg = GPFBandsListDialog(bands, self.getFilePath(), self) dlg.show()
def showMetadataDialog(self): sourceProduct = self.parent.getRasterParamPath("sourceProduct") pixelSizes = GPFUtils.getS1TbxPixelSize(sourceProduct, self.programKey) dlg = S1TbxPixelSizeInputDialog(pixelSizes, sourceProduct, self.parent) dlg.show()
def helpFile(self): GPFAlgorithm.helpFile(self, GPFUtils.beamKey())
def processAlgorithm(self, progress): GPFAlgorithm.processAlgorithm(self, GPFUtils.beamKey(), progress)
def __init__(self, descriptionfile): GPFAlgorithm.__init__(self, descriptionfile) self.programKey = GPFUtils.beamKey()
def __init__(self, descriptionfile): SNAPAlgorithm.__init__(self, descriptionfile) #self.programKey = GPFUtils.s1tbxKey() self.programKey = GPFUtils.snapKey()
def getDescription(self): return GPFUtils.providerDescription()