def loadData(self, resultFile): bLoaded = True # For information purposes layerName = self.tools.uniqueLayerName(self.processIdentifier + "_" + self.identifier) # The layername is normally defined in the comboBox for comboBox in self.complexOutputComboBoxList: if comboBox.objectName() == self.identifier: layerName = comboBox.currentText() # Vector data # TODO: Check for schema GML and KML if isMimeTypeVector(self.mimeType) != None: vlayer = QgsVectorLayer(resultFile, layerName, "ogr") try: vlayer.setCrs(self.myLayer.dataProvider().crs()) except: pass bLoaded = QgsMapLayerRegistry.instance().addMapLayer(vlayer) # Raster data elif isMimeTypeRaster(self.mimeType) != None: # We can directly attach the new layer rLayer = QgsRasterLayer(resultFile, layerName) bLoaded = QgsMapLayerRegistry.instance().addMapLayer(rLayer) # Text data elif isMimeTypeText(self.mimeType) != None: # TODO: this should be handled in a separate diaqgswps.pylog to save the text output as file' QApplication.restoreOverrideCursor() text = open(resultFile, "r").read() # TODO: This should be a text dialog with safe option self.tools.popUpMessageBox(QCoreApplication.translate("QgsWps", "Process result (text/plain)"), text) # Everything else elif isMimeTypeFile(self.mimeType) != None: # TODO: this should be handled in a separate diaqgswps.pylog to save the text output as file' QApplication.restoreOverrideCursor() text = open(resultFile, "r").read() # TODO: This should be a text dialog with safe option fileName = QFileDialog().getSaveFileName() # Everything else else: # For unsupported mime types we assume text QApplication.restoreOverrideCursor() content = open(resultFile, "r").read() # TODO: This should have a safe option self.tools.popUpMessageBox( QCoreApplication.translate("QgsWps", "Process result (unsupported mime type)"), content ) if not bLoaded: QMessageBox.information( self.iface.mainWindow(), QApplication.translate("QgsWps", "Result not loaded to the map"), QApplication.translate( "QgsWps", "It seems QGIS cannot load the result of the process. The result has a '{0}' type and can be accessed at '{1}'. \n\nYou could ask the service provider to consider changing the default data type of the result.", ).format(self.mimeType, resultFile), )
def loadData(self, resultFile, chunkId): """ Load data to the map """ if isMimeTypeVector(self.mimeType, True) != None: # Memory layer: geometryTypes = ["Point","LineString","Polygon","Unknown", "NoGeometry"] vlayer = QgsVectorLayer(resultFile, "chunk", "ogr") if self.__bFirstChunk: self.__bFirstChunk = False self.__geometryType = geometryTypes[vlayer.geometryType()] self.__bGeomMulti = vlayer.wkbType() in [4,5,6,11,12,13] self.__memoryLayer = QgsVectorLayer(self.__geometryType,"Streamed data","memory") self.__memoryLayer.dataProvider().addAttributes(vlayer.pendingFields().values()) self.__memoryLayer.updateFieldMap() provider = vlayer.dataProvider() allAttrs = provider.attributeIndexes() vlayer.select(allAttrs) # Visualize temporal geometries during the downloading process # Don't add temporal geometries if last chunk if self.DEBUG: print "Loaded chunkId:",chunkId res = self.__memoryLayer.dataProvider().addFeatures( [feat for feat in vlayer] ) self.__deliveredChunks += 1 if not self.allChunksDelivered(): inFeat = QgsFeature() inGeom = QgsGeometry() self.createTempGeometry(chunkId, self.__geometryType) while provider.nextFeature( inFeat ): inGeom = inFeat.geometry() featList = self.extractAsSingle(self.__geometryType, inGeom) if self.__bGeomMulti else [inGeom] for geom in featList: self.addTempGeometry(chunkId, self.__geometryType, geom) else: self.finishLoading() # Raster data elif isMimeTypeRaster(self.mimeType, True) != None: # We can directly attach the new layer if self.__bFirstChunk: self.__bFirstChunk = False self.__groupIndex = self.__legend.addGroup("Streamed-raster") rLayer = QgsRasterLayer(resultFile, "raster_"+str(chunkId)) bLoaded = QgsMapLayerRegistry.instance().addMapLayer(rLayer) self.stretchRaster(rLayer) self.__legend.moveLayer(rLayer, self.__groupIndex + 1) self.__deliveredChunks += 1 if self.allChunksDelivered(): self.finishLoading()
def streamingHandler(self, encoding, playlistUrl): """ Handle response form streaming based processes """ mimeTypePlaylist, self.mimeType = self.mimeType.split("+") print playlistUrl # Get number of chunks (Only for Output streaming based WPSs) chunks = 0 if isMimeTypeVector(self.mimeType) != None: for lineEdit in self.literalInputLineEditList: if lineEdit.objectName() == "NumberOfChunks": chunks = int(lineEdit.text()) elif isMimeTypeRaster(self.mimeType) != None: chunks = 1 for lineEdit in self.literalInputLineEditList: if lineEdit.objectName() == "chunksByRow" or lineEdit.objectName() == "chunksByColumn": chunks = chunks * int(lineEdit.text()) print "No. of chunks:", chunks # Streaming handler self.dataStream = Streaming(self, self.iface, chunks, playlistUrl, self.mimeType, encoding) self.dataStream.start()
def finishLoading(self): """ Finish the loading process, load the definite assembled layer """ if self.DEBUG: print "DONE!" if not self.__bFirstChunk: if isMimeTypeVector(self.mimeType, True) != None: self.removeTempGeometry(self.__geometryType) QgsMapLayerRegistry.instance().addMapLayer(self.__memoryLayer) elif isMimeTypeRaster(self.mimeType, True) != None: self.parent.lblProcess.setText("All tiles are loaded. Merging them...") # Generate gdal virtual raster # Code adapted from GdalTools (C) 2009 by L. Masini and G. Sucameli (Faunalia) self.process = QProcess(self) self.connect(self.process, SIGNAL("finished(int, QProcess::ExitStatus)"), self.loadVirtualRaster) #self.setProcessEnvironment(self.process) Required in Windows? cmd = "gdalbuildvrt" arguments = [] if platform.system() == "Windows" and cmd[-3:] == ".py": command = cmd[:-3] + ".bat" else: command = cmd tmpFile = tempfile.NamedTemporaryFile(prefix="virtual", suffix=".vrt") self.__virtualFile = tmpFile.name arguments.append(self.__virtualFile) rasters = self.getRasterFiles(self.__chunksDir, getFileExtension(self.mimeType)) for raster in rasters: arguments.append(raster) self.process.start(command, arguments, QIODevice.ReadOnly) if not self.__exceptionFound: self.parent.setStatusLabel('finished') self.parent.progressBar.setRange(0,100) self.parent.progressBar.setValue(100)
def defineProcess(self): """Create the execute request""" self.dlgProcess.close() self.dlg.close() doc = QtXml.QDomDocument() doc.setContent(self.process.processXML) QApplication.setOverrideCursor(Qt.WaitCursor) checkBoxes = self.dlgProcess.findChildren(QCheckBox) if len(checkBoxes) > 0: useSelected = checkBoxes[0].isChecked() request = ExecutionRequest(self.process) request.addExecuteRequestHeader() request.addDataInputsStart() if len(self.process.inputs) > 0: # text/plain inputs ######################################################## for textBox in self.complexInputTextBoxList: # Do not add undefined inputs if textBox == None or str(textBox.document().toPlainText()) == "": continue # TODO: Check for more types (e.g. KML, Shapefile, JSON) self.mimeType = self.inputDataTypeList[textBox.objectName()]["MimeType"] if isMimeTypePlaylist(self.mimeType) != None: schema = self.inputDataTypeList[textBox.objectName()]["Schema"] encoding = self.inputDataTypeList[textBox.objectName()]["Encoding"] # Handle 'as reference' playlist request.addReferenceInput( textBox.objectName(), self.mimeType, schema, encoding, textBox.document().toPlainText() ) else: # It's not a playlist request.addPlainTextInput(textBox.objectName(), textBox.document().toPlainText()) # Single raster and vector inputs ########################################## for comboBox in self.complexInputComboBoxList: # Do not add undefined inputs if comboBox == None or comboBox.currentText() == "<None>": continue # TODO: Check for more types (e.g. KML, Shapefile, JSON) # QMessageBox.information(None, '', str(self.inputDataTypeList[comboBox.objectName()]["MimeType"])) # QMessageBox.information(None, '', pystring(comboBox.objectName())) self.mimeType = self.inputDataTypeList[pystring(comboBox.objectName())]["MimeType"] schema = self.inputDataTypeList[pystring(comboBox.objectName())]["Schema"] encoding = self.inputDataTypeList[pystring(comboBox.objectName())]["Encoding"] self.myLayer = self.tools.getVLayer(comboBox.currentText()) # try: if isMimeTypeVector(self.mimeType) != None and encoding != "base64": gmldata = createTmpGML( self.tools.getVLayer(comboBox.currentText()), useSelected, self.process.getSupportedGMLVersion(comboBox.objectName()), ) request.addGeometryInput( comboBox.objectName(), self.mimeType, schema, encoding, gmldata, useSelected ) elif isMimeTypeVector(self.mimeType) != None or isMimeTypeRaster(self.mimeType) != None: request.addGeometryBase64Input( comboBox.objectName(), self.mimeType, self.tools.getVLayer(comboBox.currentText()) ) # except: # QApplication.restoreOverrideCursor() # QMessageBox.warning(self.iface.mainWindow(), # QApplication.translate("QgsWps","Error"), # QApplication.translate("QgsWps","Please load or select a vector layer!")) # return # Multiple raster and vector inputs ######################################## for listWidgets in self.complexInputListWidgetList: # Do not add undefined inputs if listWidgets == None: continue self.mimeType = self.inputDataTypeList[listWidgets.objectName()]["MimeType"] schema = self.inputDataTypeList[listWidgets.objectName()]["Schema"] encoding = self.inputDataTypeList[listWidgets.objectName()]["Encoding"] # Iterate over each seletced item for i in range(listWidgets.count()): listWidget = listWidgets.item(i) if listWidget == None or listWidget.isSelected() == False or str(listWidget.text()) == "<None>": continue # TODO: Check for more types if isMimeTypeVector(self.mimeType) != None and self.mimeType == "text/xml": gmldata = createTmpGML( self.tools.getVLayer(listWidget.text()), useSelected, self.process.getSupportedGMLVersion(listWidgets.objectName()), ) request.addMultipleGeometryInput( listWidgets.objectName(), self.mimeType, schema, encoding, gmldata, useSelected ) elif isMimeTypeVector(self.mimeType) != None or isMimeTypeRaster(self.mimeType) != None: request.addMultipleGeometryBase64Input( listWidgets.objectName(), self.mimeType, self.tools.getVLayer(listWidget.text()) ) # Literal data as combo box choice ######################################### for comboBox in self.literalInputComboBoxList: if comboBox == None or comboBox.currentText() == "": continue request.addLiteralDataInput(comboBox.objectName(), comboBox.currentText()) # Literal data as combo box choice ######################################### for lineEdit in self.literalInputLineEditList: if lineEdit == None or lineEdit.text() == "": continue request.addLiteralDataInput(lineEdit.objectName(), lineEdit.text()) # BBOX data as lineEdit ######################################### for bbox in self.bboxInputLineEditList: if bbox == None or bbox.text() == "": continue bboxArray = bbox.text().split(",") request.addBoundingBoxInput(bbox.objectName(), bboxArray) request.addDataInputsEnd() # Attach only defined outputs dataOutputs = doc.elementsByTagName("Output") if dataOutputs.size() > 0 or len(self.complexOutputComboBoxList) > 0: request.addResponseFormStart() # Attach ALL literal outputs ############################################# for i in range(dataOutputs.size()): f_element = dataOutputs.at(i).toElement() outputIdentifier = pystring( f_element.elementsByTagName("ows:Identifier").at(0).toElement().text() ).strip() literalOutputType = f_element.elementsByTagName("LiteralOutput") # Complex data is always requested as reference if literalOutputType.size() != 0: request.addLiteralDataOutput(outputIdentifier) # Attach selected complex outputs ######################################## for comboBox in self.complexOutputComboBoxList: # Do not add undefined outputs if comboBox == None or str(comboBox.currentText()) == "<None>": continue outputIdentifier = comboBox.objectName() self.mimeType = self.outputDataTypeList[pystring(outputIdentifier)]["MimeType"] schema = self.outputDataTypeList[pystring(outputIdentifier)]["Schema"] encoding = self.outputDataTypeList[pystring(outputIdentifier)]["Encoding"] request.addReferenceOutput(outputIdentifier, self.mimeType, schema, encoding) request.addResponseFormEnd() request.addExecuteRequestEnd() postString = request.request # This is for debug purpose only if True: # self.tools.popUpMessageBox("Execute request", postString) # Write the request into a file outFile = open("/tmp/qwps_execute_request.xml", "w") outFile.write(postString) outFile.close() QApplication.restoreOverrideCursor() self.setStatus("processing") self.wps = ExecutionResult( self.getLiteralResult, self.getResultFile, self.successResult, self.errorResult, self.streamingHandler, self.progressBar, ) self.wps.executeProcess(self.process.processUrl, postString) if len(self.process.inputs) > 0: self.wps.thePostReply.uploadProgress.connect(lambda done, total: self.setStatus("upload", done, total)) self.wps.fetchingResult.connect(self.fetchingResult)