def __init__(self, parent, plugin): QDialog.__init__(self, parent) self.setupUi(self) self.plugin = plugin self.mResult = "" self.progressBar.setRange(0, 0) self.progressBar.setFormat("%p%") self.labelName.setText(plugin["name"]) self.buttonBox.clicked.connect(self.abort) url = QUrl(plugin["download_url"]) fileName = plugin["filename"] tmpDir = QDir.tempPath() tmpPath = QDir.cleanPath(tmpDir + "/" + fileName) self.file = QFile(tmpPath) self.request = QNetworkRequest(url) authcfg = repositories.all()[plugin["zip_repository"]]["authcfg"] if authcfg and isinstance(authcfg, str): if not QgsAuthManager.instance().updateNetworkRequest( self.request, authcfg.strip()): self.mResult = self.tr( "Update of network request with authentication " "credentials FAILED for configuration '{0}'").format(authcfg) self.request = None if self.request is not None: self.reply = QgsNetworkAccessManager.instance().get(self.request) self.reply.downloadProgress.connect(self.readProgress) self.reply.finished.connect(self.requestFinished) self.stateChanged(4)
def testLayout(self, page=0, pixelDiff=0): if self.layout is None: myMessage = "Layout not valid" return False, myMessage # load expected image self.setControlName("expected_" + self.test_name) # get width/height, create image and render the composition to it outputImage = QImage(self.size, QImage.Format_RGB32) outputImage.setDotsPerMeterX(self.dots_per_meter) outputImage.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(outputImage) p = QPainter(outputImage) self.layout.exporter().renderPage(p, page) p.end() renderedFilePath = QDir.tempPath() + QDir.separator() + QFileInfo(self.test_name).baseName() + "_rendered.png" outputImage.save(renderedFilePath, "PNG") self.setRenderedImage(renderedFilePath) testResult = self.runTest(self.test_name, pixelDiff) return testResult, self.report()
def getAllInstalled(self): """ Build the localCache """ self.localCache = {} # reversed list of the plugin paths: first system plugins -> then user plugins -> finally custom path(s) pluginPaths = list(plugin_paths) pluginPaths.reverse() for pluginsPath in pluginPaths: isTheSystemDir = (pluginPaths.index(pluginsPath) == 0) # The current dir is the system plugins dir if isTheSystemDir: # temporarily add the system path as the first element to force loading the readonly plugins, even if masked by user ones. sys.path = [pluginsPath] + sys.path try: pluginDir = QDir(pluginsPath) pluginDir.setFilter(QDir.AllDirs) for key in pluginDir.entryList(): if key not in [".", ".."]: path = QDir.toNativeSeparators(pluginsPath + "/" + key) # readOnly = not QFileInfo(pluginsPath).isWritable() # On windows testing the writable status isn't reliable. readOnly = isTheSystemDir # Assume only the system plugins are not writable. # failedToLoad = settings.value("/PythonPlugins/watchDog/" + key) is not None plugin = self.getInstalledPlugin(key, path=path, readOnly=readOnly) if key in list(self.localCache.keys()) and compareVersions(self.localCache[key]["version_installed"], plugin["version_installed"]) == 1: # An obsolete plugin in the "user" location is masking a newer one in the "system" location! self.obsoletePlugins += [key] self.localCache[key] = plugin except: # it's not necessary to stop if one of the dirs is inaccessible pass if isTheSystemDir: # remove the temporarily added path sys.path.remove(pluginsPath)
def copyFile(alg, fromFile, toFile): """ Generates a copy command for GRASS7 script """ createDestDir(alg, toFile) command = "{} \"{}\" \"{}\"".format( "COPY /Y" if isWindows() else "cp -f", QDir.toNativeSeparators(fromFile), QDir.toNativeSeparators(toFile)) alg.commands.append(command)
def moveFile(alg, fromFile, toFile): """ Generates a move command for GRASS7 script """ createDestDir(alg, toFile) command = "{} \"{}\" \"{}\"".format( "MOVE /Y" if isWindows() else "mv -f", QDir.toNativeSeparators(fromFile), QDir.toNativeSeparators(toFile) ) alg.commands.append(command)
def requestFinished(self): reply = self.sender() self.buttonBox.setEnabled(False) if reply.error() != QNetworkReply.NoError: self.mResult = reply.errorString() if reply.error() == QNetworkReply.OperationCanceledError: self.mResult += "<br/><br/>" + QCoreApplication.translate("QgsPluginInstaller", "If you haven't canceled the download manually, it might be caused by a timeout. In this case consider increasing the connection timeout value in QGIS options.") self.reject() reply.deleteLater() return elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) in (301, 302): redirectionUrl = reply.attribute(QNetworkRequest.RedirectionTargetAttribute) self.redirectionCounter += 1 if self.redirectionCounter > 4: self.mResult = QCoreApplication.translate("QgsPluginInstaller", "Too many redirections") self.reject() reply.deleteLater() return else: if redirectionUrl.isRelative(): redirectionUrl = reply.url().resolved(redirectionUrl) # Fire a new request and exit immediately in order to quietly destroy the old one self.url = redirectionUrl self.requestDownloading() reply.deleteLater() return self.file.open(QFile.WriteOnly) self.file.write(reply.readAll()) self.file.close() self.stateChanged(0) reply.deleteLater() pluginDir = qgis.utils.home_plugin_path tmpPath = self.file.fileName() # make sure that the parent directory exists if not QDir(pluginDir).exists(): QDir().mkpath(pluginDir) # if the target directory already exists as a link, remove the link without resolving: QFile(pluginDir + str(QDir.separator()) + self.plugin["id"]).remove() try: unzip(str(tmpPath), str(pluginDir)) # test extract. If fails, then exception will be raised and no removing occurs # removing old plugin files if exist removeDir(QDir.cleanPath(pluginDir + "/" + self.plugin["id"])) # remove old plugin if exists unzip(str(tmpPath), str(pluginDir)) # final extract. except: self.mResult = self.tr("Failed to unzip the plugin package. Probably it's broken or missing from the repository. You may also want to make sure that you have write permission to the plugin directory:") + "\n" + pluginDir self.reject() return try: # cleaning: removing the temporary zip file QFile(tmpPath).remove() except: pass self.close()
def selectDirectory(self): lastDir = self.leText.text() settings = QgsSettings() if not lastDir: lastDir = settings.value("/Processing/LastOutputPath", QDir.homePath()) dirName = QFileDialog.getExistingDirectory(self, self.tr('Select directory'), lastDir, QFileDialog.ShowDirsOnly) if dirName: self.leText.setText(QDir.toNativeSeparators(dirName)) settings.setValue('/Processing/LastOutputPath', dirName)
def selectDirectory(self): lastDir = self.leText.text() settings = QgsSettings() if not lastDir: lastDir = settings.value("/Processing/LastOutputPath", QDir.homePath()) dirName = QFileDialog.getExistingDirectory(self, self.tr('Select Directory'), lastDir, QFileDialog.ShowDirsOnly) if dirName: self.leText.setText(QDir.toNativeSeparators(dirName)) settings.setValue('/Processing/LastOutputPath', dirName) self.use_temporary = False self.skipOutputChanged.emit(False) self.destinationChanged.emit()
def on_btnSave_clicked(self): fileName, _ = QFileDialog.getSaveFileName(None, self.tr('Export Colors and elevations as XML'), QDir.homePath(), self.tr('XML files (*.xml *.XML)')) if fileName == '': return if not fileName.lower().endswith('.xml'): fileName += '.xml' doc = QDomDocument() colorsElem = doc.createElement('ReliefColors') doc.appendChild(colorsElem) colors = self.reliefColors() for c in colors: elem = doc.createElement('ReliefColor') elem.setAttribute('MinElevation', str(c.minElevation)) elem.setAttribute('MaxElevation', str(c.maxElevation)) elem.setAttribute('red', str(c.color.red())) elem.setAttribute('green', str(c.color.green())) elem.setAttribute('blue', str(c.color.blue())) colorsElem.appendChild(elem) with codecs.open(fileName, 'w', encoding='utf-8') as f: f.write(doc.toString(2))
def testQgsCentroidFillSymbolLayerV2(self): """ Create a new style from a .sld file and match test """ mTestName = 'QgsCentroidFillSymbolLayerV2' mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.sld' % (unitTestDataPath(), mTestName)) mDoc = QDomDocument(mTestName) mFile = QFile(mFilePath) mFile.open(QIODevice.ReadOnly) mDoc.setContent(mFile, True) mFile.close() mSymbolLayer = QgsCentroidFillSymbolLayerV2.createFromSld( mDoc.elementsByTagName('PointSymbolizer').item(0).toElement()) mExpectedValue = type(QgsCentroidFillSymbolLayerV2()) mValue = type(mSymbolLayer) mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = u'regular_star' mValue = mSymbolLayer.subSymbol().symbolLayer(0).name() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = u'#55aaff' mValue = mSymbolLayer.subSymbol().symbolLayer(0).color().name() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = u'#00ff00' mValue = mSymbolLayer.subSymbol().symbolLayer(0).borderColor().name() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage
def testValueConverter(self): """Tests writing a layer with a field value converter.""" ml = QgsVectorLayer(("Point?field=nonconv:int&field=ignored:string&field=converted:int"), "test", "memory") self.assertIsNotNone(ml, "Provider not initialized") self.assertTrue(ml.isValid(), "Source layer not valid") provider = ml.dataProvider() self.assertIsNotNone(provider) self.assertEqual(ml.fields().count(), 3) ft = QgsFeature() ft.setAttributes([1, "ignored", 3]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), "value_converter.shp") converter = TestFieldValueConverter(ml) write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, "utf-8", QgsCoordinateReferenceSystem(), "ESRI Shapefile", attributes=[0, 2], fieldValueConverter=converter, ) self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer("{}|layerid=0".format(dest_file_name), "test", "ogr") self.assertEqual(created_layer.fields().count(), 2) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f["nonconv"], 1) self.assertEqual(f["conv_attr"], "converted_val")
def testWriteShapefileWithMultiConversion(self): """Check writing geometries to an ESRI shapefile with conversion to multi.""" ml = QgsVectorLayer(("Point?crs=epsg:4326&field=id:int"), "test", "memory") self.assertIsNotNone(ml, "Provider not initialized") self.assertTrue(ml.isValid(), "Source layer not valid") provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt("Point (1 2)")) ft.setAttributes([1]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), "to_multi.shp") crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, "utf-8", crs, "ESRI Shapefile", forceMulti=True ) self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer("{}|layerid=0".format(dest_file_name), "test", "ogr") f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.exportToWkt() expWkt = "MultiPoint ((1 2))" self.assertTrue( compareWkt(expWkt, wkt), "saving geometry with multi conversion failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt), )
def on_btnLoad_clicked(self): fileName, _ = QFileDialog.getOpenFileName(None, self.tr('Import Colors and elevations from XML'), QDir.homePath(), self.tr('XML files (*.xml *.XML)')) if fileName == '': return doc = QDomDocument() with codecs.open(fileName, 'r', encoding='utf-8') as f: content = f.read() if not doc.setContent(content): QMessageBox.critical(None, self.tr('Error parsing XML'), self.tr('The XML file could not be loaded')) return self.reliefClassTree.clear() reliefColorList = doc.elementsByTagName('ReliefColor') for i in range(reliefColorList.length()): elem = reliefColorList.at(i).toElement() item = QTreeWidgetItem() item.setText(0, elem.attribute('MinElevation')) item.setText(1, elem.attribute('MaxElevation')) item.setBackground(2, QBrush(QColor(int(elem.attribute('red')), int(elem.attribute('green')), int(elem.attribute('blue'))))) self.reliefClassTree.addTopLevelItem(item)
def testInteger64WriteTabfile(self): """Check writing Integer64 fields to an MapInfo tabfile (which does not support that type).""" ml = QgsVectorLayer(("Point?crs=epsg:4326&field=int8:int8"), "test", "memory") self.assertIsNotNone(ml, "Provider not initialized") self.assertTrue(ml.isValid(), "Source layer not valid") provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setAttributes([2123456789]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), "integer64.tab") crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result = QgsVectorFileWriter.writeAsVectorFormat(ml, dest_file_name, "utf-8", crs, "MapInfo File") self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer("{}|layerid=0".format(dest_file_name), "test", "ogr") fields = created_layer.dataProvider().fields() self.assertEqual(fields.at(fields.indexFromName("int8")).type(), QVariant.Double) f = next(created_layer.getFeatures(QgsFeatureRequest())) int8_idx = created_layer.fields().lookupField("int8") self.assertEqual(f.attributes()[int8_idx], 2123456789)
def main(): datestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") if QT5: ini_out_dir = QStandardPaths.writableLocation(QStandardPaths.DesktopLocation) else: ini_out_dir = QDesktopServices.storageLocation(QDesktopServices.DesktopLocation) ini_name = 'org.qgis.{0}-settings_{1}.ini'.format(QGIS_APP_NAME, datestamp) ini_out = QDir(ini_out_dir).absoluteFilePath(ini_name) if not os.path.exists(ini_out_dir): print('INI output directory does not exist: {0}'.format(ini_out_dir)) return if not os.access(ini_out_dir, os.W_OK | os.X_OK): print('INI output directory is not writeable: {0}'.format(ini_out_dir)) return # QGIS settings if HAS_QGSSETTINGS: qgis_settings = QgsSettings() else: qgis_settings = QSettings() # Output INI settings ini_settings = QSettings(ini_out, QSettings.IniFormat) qgis_keys = qgis_settings.allKeys() for k in qgis_keys: ini_settings.setValue(k, qgis_settings.value(k)) ini_settings.sync() print("Settings output to: {0}".format(QDir.toNativeSeparators(ini_out)))
def on_btnSave_clicked(self): fileName, _ = QFileDialog.getSaveFileName( None, self.tr("Export Colors and elevations as XML"), QDir.homePath(), self.tr("XML files (*.xml *.XML)") ) if fileName == "": return if not fileName.lower().endswith(".xml"): fileName += ".xml" doc = QDomDocument() colorsElem = doc.createElement("ReliefColors") doc.appendChild(colorsElem) colors = self.reliefColors() for c in colors: elem = doc.createElement("ReliefColor") elem.setAttribute("MinElevation", str(c.minElevation)) elem.setAttribute("MaxElevation", str(c.maxElevation)) elem.setAttribute("red", str(c.color.red())) elem.setAttribute("green", str(c.color.green())) elem.setAttribute("blue", str(c.color.blue())) colorsElem.appendChild(elem) with codecs.open(fileName, "w", encoding="utf-8") as f: f.write(doc.toString(2))
def testQgsSvgMarkerSymbolLayer(self): """ Create a new style from a .sld file and match test """ mTestName = 'QgsSvgMarkerSymbolLayer' mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.sld' % (unitTestDataPath(), mTestName)) mDoc = QDomDocument(mTestName) mFile = QFile(mFilePath) mFile.open(QIODevice.ReadOnly) mDoc.setContent(mFile, True) mFile.close() mSymbolLayer = QgsSvgMarkerSymbolLayer.createFromSld(mDoc.elementsByTagName('PointSymbolizer').item(0).toElement()) mExpectedValue = type(QgsSvgMarkerSymbolLayer("")) mValue = type(mSymbolLayer) mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = 'skull.svg' mValue = os.path.basename(mSymbolLayer.path()) print(("VALUE", mSymbolLayer.path())) mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = 12 mValue = mSymbolLayer.size() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = 45 mValue = mSymbolLayer.angle() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage
def selFile(self): sf = QFileInfo(QFileDialog.getOpenFileName(self, 'Open logo file', QDir.homePath(), 'Image files (*.png)')) f = sf.fileName() if f!='': self.logopath = sf.absoluteFilePath() self.label.setPixmap(QPixmap(self.logopath)) return f
def testQgsSVGFillSymbolLayer(self): """ Create a new style from a .sld file and match test """ mTestName = 'QgsSVGFillSymbolLayer' mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.sld' % (unitTestDataPath(), mTestName)) mDoc = QDomDocument(mTestName) mFile = QFile(mFilePath) mFile.open(QIODevice.ReadOnly) mDoc.setContent(mFile, True) mFile.close() mSymbolLayer = QgsSVGFillSymbolLayer.createFromSld( mDoc.elementsByTagName('PolygonSymbolizer').item(0).toElement()) mExpectedValue = type(QgsSVGFillSymbolLayer("")) mValue = type(mSymbolLayer) mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = 'accommodation_camping.svg' mValue = os.path.basename(mSymbolLayer.svgFilePath()) mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = 6 mValue = mSymbolLayer.patternWidth() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage
def testWriteWithBinaryField(self): """ Test writing with a binary field :return: """ basetestpath = tempfile.mkdtemp() tmpfile = os.path.join(basetestpath, 'binaryfield.sqlite') ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid']) lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('binfield', ogr.OFTBinary)) lyr.CreateField(ogr.FieldDefn('binfield2', ogr.OFTBinary)) f = None ds = None vl = QgsVectorLayer(tmpfile) self.assertTrue(vl.isValid()) # check that 1 of its fields is a bool fields = vl.fields() self.assertEqual(fields.at(fields.indexFromName('binfield')).type(), QVariant.ByteArray) dp = vl.dataProvider() f = QgsFeature(fields) bin_1 = b'xxx' bin_2 = b'yyy' bin_val1 = QByteArray(bin_1) bin_val2 = QByteArray(bin_2) f.setAttributes([1, 'str', 100, bin_val1, bin_val2]) self.assertTrue(dp.addFeature(f)) # write a gpkg package with a binary field filename = os.path.join(str(QDir.tempPath()), 'with_bin_field') rc, errmsg = QgsVectorFileWriter.writeAsVectorFormat(vl, filename, 'utf-8', vl.crs(), 'GPKG') self.assertEqual(rc, QgsVectorFileWriter.NoError) # open the resulting geopackage vl = QgsVectorLayer(filename + '.gpkg', '', 'ogr') self.assertTrue(vl.isValid()) fields = vl.fields() # test type of converted field idx = fields.indexFromName('binfield') self.assertEqual(fields.at(idx).type(), QVariant.ByteArray) idx2 = fields.indexFromName('binfield2') self.assertEqual(fields.at(idx2).type(), QVariant.ByteArray) # test values self.assertEqual(vl.getFeature(1).attributes()[idx], bin_val1) self.assertEqual(vl.getFeature(1).attributes()[idx2], bin_val2) del vl os.unlink(filename + '.gpkg')
def testAddZ(self): """Check adding z values to non z input.""" input = QgsVectorLayer( 'Point?crs=epsg:4326&field=name:string(20)', 'test', 'memory') self.assertTrue(input.isValid(), 'Provider not initialized') ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10))) myResult, myFeatures = input.dataProvider().addFeatures([ft]) self.assertTrue(myResult) self.assertTrue(myFeatures) dest_file_name = os.path.join(str(QDir.tempPath()), 'add_z.geojson') options = QgsVectorFileWriter.SaveVectorOptions() options.overrideGeometryType = QgsWkbTypes.PointZ options.driverName = 'GeoJSON' write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( input, dest_file_name, options) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer(dest_file_name, 'test', 'ogr') self.assertTrue(created_layer.isValid()) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f.geometry().asWkt(), 'PointZ (10 10 0)')
def __init__(self, obsids=[''], settingsdict = {}): reportfolder = os.path.join(QDir.tempPath(), 'midvatten_reports') if not os.path.exists(reportfolder): os.makedirs(reportfolder) reportpath = os.path.join(reportfolder, "drill_report.html") logopath = os.path.join(os.sep,os.path.dirname(__file__),"..","templates","midvatten_logga.png") imgpath = os.path.join(os.sep,os.path.dirname(__file__),"..","templates") if len(obsids) == 0: utils.pop_up_info(ru(QCoreApplication.translate('Drillreport', "Must select one or more obsids!"))) return None elif len(obsids) == 1: merged_question = False else: #Due to problems regarding speed when opening many tabs, only the merge mode is used. #merged_question = utils.Askuser(question='YesNo', msg="Do you want to open all drill reports merged on the same tab?\n" # "Else they will be opened separately.\n\n(If answering no, creating drill reports for many obsids take 0.2 seconds per obsid.\nIt might fail if the computer is to slow.\nIf it fails, try to select only one obsid at the time)").result merged_question = True if merged_question: f, rpt = self.open_file(', '.join(obsids), reportpath) for obsid in obsids: self.write_obsid(obsid, rpt, imgpath, logopath, f) self.close_file(f, reportpath) else: #opened = False for obsid in obsids: f, rpt = self.open_file(obsid, reportpath) self.write_obsid(obsid, rpt, imgpath, logopath, f) url_status = self.close_file(f, reportpath)
def saveAsScriptFile(self, index=None): tabWidget = self.tabEditorWidget.currentWidget() if not index: index = self.tabEditorWidget.currentIndex() if not tabWidget.path: fileName = self.tabEditorWidget.tabText(index) + '.py' folder = self.settings.value("pythonConsole/lastDirPath", QDir.homePath()) pathFileName = os.path.join(folder, fileName) fileNone = True else: pathFileName = tabWidget.path fileNone = False saveAsFileTr = QCoreApplication.translate("PythonConsole", "Save File As") filename, filter = QFileDialog.getSaveFileName(self, saveAsFileTr, pathFileName, "Script file (*.py)") if filename: try: tabWidget.save(filename) except (IOError, OSError) as error: msgText = QCoreApplication.translate('PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) if fileNone: tabWidget.path = None else: tabWidget.path = pathFileName return if not fileNone: self.updateTabListScript(pathFileName, action='remove')
def installFromZipFile(self, filePath): if not os.path.isfile(filePath): return settings = QgsSettings() settings.setValue(settingsGroup + '/lastZipDirectory', QFileInfo(filePath).absoluteDir().absolutePath()) error = False infoString = None with zipfile.ZipFile(filePath, 'r') as zf: pluginName = os.path.split(zf.namelist()[0])[0] pluginFileName = os.path.splitext(os.path.basename(filePath))[0] pluginsDirectory = qgis.utils.home_plugin_path if not QDir(pluginsDirectory).exists(): QDir().mkpath(pluginsDirectory) # If the target directory already exists as a link, # remove the link without resolving QFile(os.path.join(pluginsDirectory, pluginFileName)).remove() try: # Test extraction. If fails, then exception will be raised # and no removing occurs unzip(str(filePath), str(pluginsDirectory)) # Removing old plugin files if exist removeDir(QDir.cleanPath(os.path.join(pluginsDirectory, pluginFileName))) # Extract new files unzip(str(filePath), str(pluginsDirectory)) except: error = True infoString = (self.tr("Plugin installation failed"), self.tr("Failed to unzip the plugin package\n{}.\nProbably it is broken".format(filePath))) if infoString is None: updateAvailablePlugins() loadPlugin(pluginName) plugins.getAllInstalled(testLoad=True) plugins.rebuild() if settings.contains('/PythonPlugins/' + pluginName): if settings.value('/PythonPlugins/' + pluginName, False, bool): startPlugin(pluginName) reloadPlugin(pluginName) else: unloadPlugin(pluginName) loadPlugin(pluginName) else: if startPlugin(pluginName): settings.setValue('/PythonPlugins/' + pluginName, True) infoString = (self.tr("Plugin installed successfully"), "") if infoString[0]: level = error and QgsMessageBar.CRITICAL or QgsMessageBar.INFO msg = "<b>%s:</b>%s" % (infoString[0], infoString[1]) iface.pluginManagerInterface().pushMessage(msg, level)
def openProject(projectFile): folder = os.path.dirname(projectFile) projectName = os.path.basename(projectFile) tempDir = os.path.join(QDir.tempPath(), "lessons", "lesson{}".format(str(time.time()))) dest = os.path.abspath(tempDir) shutil.copytree(folder, dest) tempProjectFile = os.path.join(dest, projectName) iface.addProject(tempProjectFile)
def filer(self): if self.comboBox.currentText()=='ESRI shape file': a = 'Save as ESRI shape file' sf = QFileDialog.getExistingDirectory(self, a, QDir.homePath()) # b = 'ESRI shape files (*.shp)' elif self.comboBox.currentText()=='Comma separated value (CSV)': a = 'Save as comma separated value (CSV)' sf = QFileDialog.getExistingDirectory(self, a, QDir.homePath()) # b = 'CSV files (*.csv)' elif self.comboBox.currentText()=='SQLite database': a = 'SQLite database' sf = QFileDialog.getOpenFileName(self, a, QDir.homePath()) elif self.comboBox.currentText()=='Copy complete database': a = 'Copy complete database' sf = QFileDialog.getSaveFileName(self, a, QDir.homePath()) self.lineEdit.setText(sf)
def createDestDir(alg, toFile): """ Generates an mkdir command for GRASS7 script """ # Creates the destination directory command = "{} \"{}\"".format( "MD" if isWindows() else "mkdir -p", QDir.toNativeSeparators(os.path.dirname(toFile)) ) alg.commands.append(command)
def testSingleSymbolNoScaleDependencies(self): layer = QgsVectorLayer("Point", "addfeat", "memory") mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "singleSymbol")) layer.loadNamedStyle(mFilePath) dom, root = self.layerToSld(layer) # print("No dep on single symbol:" + dom.toString()) self.assertScaleDenominator(root, None, None)
def lessonsBaseFolder(): """Returns the folder where to store lessons. It is created inside the lessonPluginBaseFolder(). """ folder = os.path.join(lessonPluginBaseFolder(), "lessons") if not QDir(folder).exists(): QDir().mkpath(folder) return QDir.toNativeSeparators(folder)
def __init__(self, parent, plugin): QDialog.__init__(self, parent) self.setupUi(self) self.plugin = plugin self.mResult = "" self.progressBar.setRange(0, 0) self.progressBar.setFormat("%p%") self.labelName.setText(plugin["name"]) self.buttonBox.clicked.connect(self.abort) self.url = QUrl(plugin["download_url"]) self.redirectionCounter = 0 fileName = plugin["filename"] tmpDir = QDir.tempPath() tmpPath = QDir.cleanPath(tmpDir + "/" + fileName) self.file = QFile(tmpPath) self.requestDownloading()
def tempFolder(): tempDir = os.path.join(QDir.tempPath(), 'qgis2web') if not QDir(tempDir).exists(): QDir().mkpath(tempDir) return os.path.abspath(tempDir)
def testWriteWithBinaryField(self): """ Test writing with a binary field :return: """ basetestpath = tempfile.mkdtemp() tmpfile = os.path.join(basetestpath, 'binaryfield.sqlite') ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid']) lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('binfield', ogr.OFTBinary)) lyr.CreateField(ogr.FieldDefn('binfield2', ogr.OFTBinary)) f = None ds = None vl = QgsVectorLayer(tmpfile) self.assertTrue(vl.isValid()) # check that 1 of its fields is a bool fields = vl.fields() self.assertEqual( fields.at(fields.indexFromName('binfield')).type(), QVariant.ByteArray) dp = vl.dataProvider() f = QgsFeature(fields) bin_1 = b'xxx' bin_2 = b'yyy' bin_val1 = QByteArray(bin_1) bin_val2 = QByteArray(bin_2) f.setAttributes([1, 'str', 100, bin_val1, bin_val2]) self.assertTrue(dp.addFeature(f)) # write a gpkg package with a binary field filename = os.path.join(str(QDir.tempPath()), 'with_bin_field') rc, errmsg = QgsVectorFileWriter.writeAsVectorFormat( vl, filename, 'utf-8', vl.crs(), 'GPKG') self.assertEqual(rc, QgsVectorFileWriter.NoError) # open the resulting geopackage vl = QgsVectorLayer(filename + '.gpkg', '', 'ogr') self.assertTrue(vl.isValid()) fields = vl.fields() # test type of converted field idx = fields.indexFromName('binfield') self.assertEqual(fields.at(idx).type(), QVariant.ByteArray) idx2 = fields.indexFromName('binfield2') self.assertEqual(fields.at(idx2).type(), QVariant.ByteArray) # test values self.assertEqual(vl.getFeature(1).attributes()[idx], bin_val1) self.assertEqual(vl.getFeature(1).attributes()[idx2], bin_val2) del vl os.unlink(filename + '.gpkg')
def exportStyles(layers, folder, clustered, feedback): stylesFolder = os.path.join(folder, "styles") QDir().mkpath(stylesFolder) legendFolder = os.path.join(stylesFolder, "legend") QDir().mkpath(legendFolder) vtStyles = {} mapUnitLayers = [] for count, (layer, cluster) in enumerate(zip(layers, clustered)): sln = safeName(layer.name()) + "_" + str(count) if layer.type() != layer.VectorLayer: continue pattern = "" setPattern = "" vts = layer.customProperty("VectorTilesReader/vector_tile_url") labelText = getLabels(layer, folder, sln) defs = "var size = 0;\nvar placement = 'point';" renderer = layer.renderer() layer_alpha = layer.opacity() try: if isinstance(renderer, QgsSingleSymbolRenderer): (style, pattern, setPattern, value, useMapUnits) = singleSymbol(renderer, stylesFolder, layer_alpha, sln, legendFolder, layer, feedback) elif isinstance(renderer, QgsCategorizedSymbolRenderer): (style, pattern, setPattern, value, defs, useMapUnits) = categorized(defs, sln, layer, renderer, legendFolder, stylesFolder, layer_alpha, feedback) elif isinstance(renderer, QgsGraduatedSymbolRenderer): (style, pattern, setPattern, value, useMapUnits) = graduated(layer, renderer, legendFolder, sln, stylesFolder, layer_alpha, feedback) elif isinstance(renderer, QgsRuleBasedRenderer): (style, pattern, setPattern, value, useMapUnits) = ruleBased(renderer, folder, stylesFolder, layer_alpha, sln, layer, feedback) else: value = "''" style = """ var style = [ new ol.style.Style({ text: createTextStyle(feature, resolution, labelText, labelFont, labelFill, placement, bufferColor, bufferWidth) })];""" useMapUnits = False if useMapUnits: if vts is None: mapUnitLayers.append(sln) else: mapUnitLayers.append(safeName(vts)) (labelRes, size, face, color, bufferColor, bufferWidth) = getLabelFormat(layer) if style != "": geom = TYPE_MAP[layer.wkbType()].replace("Multi", "") style = getStyle(style, cluster, labelRes, labelText, sln, size, face, color, bufferColor, bufferWidth, value, geom) else: style = "''" except Exception: style = "''" feedback.showFeedback("""Exception in layer {} with renderer {}: <span style=\"color: red\">{}</span>""".format( layer.id(), renderer.dump(), traceback.format_exc())) if vts is None: path = os.path.join(stylesFolder, sln + "_style.js") with codecs.open(path, "w", "utf-8") as f: f.write( '''%(defs)s %(pattern)s var style_%(name)s = %(style)s; %(setPattern)s''' % { "defs": defs, "pattern": pattern, "name": sln, "style": style, "setPattern": setPattern }) elif style != "" and style != "''": new_vtStyle = defs new_vtStyle += "if (feature.get('layer') == " new_vtStyle += """'%s' && feature.getGeometry().getType() == '%s'){ return %s(feature, resolution); }""" % (layer.name(), TYPE_MAP[layer.wkbType()].replace("Multi", ""), style) try: old_vtStyles = vtStyles[vts] new_vtStyles = """%s %s""" % (old_vtStyles, new_vtStyle) except Exception: new_vtStyles = new_vtStyle vtStyles[vts] = new_vtStyles for k, v in vtStyles.items(): styleName = safeName(k) styleString = v path = os.path.join(stylesFolder, styleName + "_style.js") with codecs.open(path, "w", "utf-8") as f: f.write( ''' var style_%(name)s = function(feature, resolution) { %(style)s; }''' % { "defs": defs, "pattern": pattern, "name": styleName, "style": styleString, "setPattern": setPattern }) return mapUnitLayers
def create_temp_filename(base_file): return os.path.join(str(QDir.tempPath()), base_file)
def userFolder(): userDir = os.path.join(QgsApplication.qgisSettingsDirPath(), 'processing') if not QDir(userDir).exists(): QDir().mkpath(userDir) return str(QDir.toNativeSeparators(userDir))
def installPlugin(self, key, quiet=False): """ Install given plugin """ error = False infoString = ('', '') plugin = plugins.all()[key] previousStatus = plugin["status"] if not plugin: return if plugin["status"] == "newer" and not plugin[ "error"]: # ask for confirmation if user downgrades an usable plugin if QMessageBox.warning( iface.mainWindow(), self.tr("QGIS Python Plugin Installer"), self. tr("Are you sure you want to downgrade the plugin to the latest available version? The installed one is newer!" ), QMessageBox.Yes, QMessageBox.No) == QMessageBox.No: return dlg = QgsPluginInstallerInstallingDialog(iface.mainWindow(), plugin) dlg.exec_() if dlg.result(): error = True infoString = (self.tr("Plugin installation failed"), dlg.result()) elif not QDir(qgis.utils.home_plugin_path + "/" + key).exists(): error = True infoString = ( self.tr("Plugin has disappeared"), self. tr("The plugin seems to have been installed but I don't know where. Probably the plugin package contained a wrong named directory.\nPlease search the list of installed plugins. I'm nearly sure you'll find the plugin there, but I just can't determine which of them it is. It also means that I won't be able to determine if this plugin is installed and inform you about available updates. However the plugin may work. Please contact the plugin author and submit this issue." )) QApplication.setOverrideCursor(Qt.WaitCursor) plugins.getAllInstalled() plugins.rebuild() self.exportPluginsToManager() QApplication.restoreOverrideCursor() else: QApplication.setOverrideCursor(Qt.WaitCursor) # update the list of plugins in plugin handling routines updateAvailablePlugins() # try to load the plugin loadPlugin(plugin["id"]) plugins.getAllInstalled() plugins.rebuild() plugin = plugins.all()[key] if not plugin["error"]: if previousStatus in ["not installed", "new"]: infoString = (self.tr("Plugin installed successfully"), "") if startPlugin(plugin["id"]): settings = QgsSettings() settings.setValue("/PythonPlugins/" + plugin["id"], True) else: settings = QgsSettings() if settings.value( "/PythonPlugins/" + key, False, type=bool ): # plugin will be reloaded on the fly only if currently loaded reloadPlugin( key) # unloadPlugin + loadPlugin + startPlugin infoString = ( self.tr("Plugin reinstalled successfully"), "") else: unloadPlugin( key ) # Just for a case. Will exit quietly if really not loaded loadPlugin(key) infoString = ( self.tr("Plugin reinstalled successfully"), self. tr("Python plugin reinstalled.\nYou need to restart QGIS in order to reload it." )) if quiet: infoString = (None, None) QApplication.restoreOverrideCursor() else: QApplication.restoreOverrideCursor() if plugin["error"] == "incompatible": message = self.tr( "The plugin is not compatible with this version of QGIS. It's designed for QGIS versions:" ) message += " <b>" + plugin["error_details"] + "</b>" elif plugin["error"] == "dependent": message = self.tr( "The plugin depends on some components missing on your system. You need to install the following Python module in order to enable it:" ) message += "<b> " + plugin["error_details"] + "</b>" else: message = self.tr("The plugin is broken. Python said:") message += "<br><b>" + plugin["error_details"] + "</b>" dlg = QgsPluginInstallerPluginErrorDialog( iface.mainWindow(), message) dlg.exec_() if dlg.result(): # revert installation pluginDir = qgis.utils.home_plugin_path + "/" + plugin["id"] result = removeDir(pluginDir) if QDir(pluginDir).exists(): error = True infoString = (self.tr("Plugin uninstall failed"), result) try: exec("sys.path_importer_cache.clear()") exec("import %s" % plugin["id"]) exec("reload (%s)" % plugin["id"]) except: pass else: try: exec("del sys.modules[%s]" % plugin["id"]) except: pass plugins.getAllInstalled() plugins.rebuild() self.exportPluginsToManager() if infoString[0]: level = error and Qgis.Critical or Qgis.Info msg = "<b>%s</b>" % infoString[0] if infoString[1]: msg += "<b>:</b> %s" % infoString[1] iface.pluginManagerInterface().pushMessage(msg, level)
def tempFolder(): tempDir = os.path.join(str(QDir.tempPath()), 'processing' + _tempFolderSuffix) if not QDir(tempDir).exists(): QDir().mkpath(tempDir) return str(os.path.abspath(tempDir))
def testWriteShapefileWithZ(self): """Check writing geometries with Z dimension to an ESRI shapefile.""" # start by saving a memory layer and forcing z ml = QgsVectorLayer(('Point?crs=epsg:4326&field=id:int'), 'test', 'memory') self.assertIsNotNone(ml, 'Provider not initialized') self.assertTrue(ml.isValid(), 'Source layer not valid') provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt('PointZ (1 2 3)')) ft.setAttributes([1]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) # check with both a standard PointZ and 25d style Point25D type for t in [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D]: dest_file_name = os.path.join( str(QDir.tempPath()), 'point_{}.shp'.format(QgsWkbTypes.displayString(t))) crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', overrideGeometryType=t) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer( '{}|layerid=0'.format(dest_file_name), 'test', 'ogr') f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.asWkt() expWkt = 'PointZ (1 2 3)' self.assertTrue( compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)) # also try saving out the shapefile version again, as an extra test # this tests that saving a layer with z WITHOUT explicitly telling the writer to keep z values, # will stay retain the z values dest_file_name = os.path.join( str(QDir.tempPath()), 'point_{}_copy.shp'.format(QgsWkbTypes.displayString(t))) crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( created_layer, dest_file_name, 'utf-8', crs, 'ESRI Shapefile') self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer_from_shp = QgsVectorLayer( '{}|layerid=0'.format(dest_file_name), 'test', 'ogr') f = next(created_layer_from_shp.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.asWkt() self.assertTrue( compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))
def exportAsPython(self): filename, filter = QFileDialog.getSaveFileName(self, self.tr('Save Model As Python Script'), '', self.tr('Processing scripts (*.py *.PY)')) if not filename: return if not filename.lower().endswith('.py'): filename += '.py' text = self.model.asPythonCode() with codecs.open(filename, 'w', encoding='utf-8') as fout: fout.write(text) self.bar.pushMessage("", self.tr("Successfully exported model as python script to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
def __init__(self, parent, name, path): super(ProcessingModelItem, self).__init__(QgsDataItem.Custom, parent, name, path) self.setState(QgsDataItem.Populated) # no children self.setIconName(":/images/themes/default/processingModel.svg") self.setToolTip(QDir.toNativeSeparators(path))
def testWriteShapefileWithAttributeSubsets(self): """Tests writing subsets of attributes to files.""" ml = QgsVectorLayer(( 'Point?crs=epsg:4326&field=id:int&field=field1:int&field=field2:int&field=field3:int' ), 'test', 'memory') self.assertIsNotNone(ml, 'Provider not initialized') self.assertTrue(ml.isValid(), 'Source layer not valid') provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt('Point (1 2)')) ft.setAttributes([1, 11, 12, 13]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) # first write out with all attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'all_attributes.shp') crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[]) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') self.assertEqual(created_layer.fields().count(), 4) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f['id'], 1) self.assertEqual(f['field1'], 11) self.assertEqual(f['field2'], 12) self.assertEqual(f['field3'], 13) # now test writing out only a subset of attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'subset_attributes.shp') write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[1, 3]) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') self.assertEqual(created_layer.fields().count(), 2) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f['field1'], 11) self.assertEqual(f['field3'], 13) # finally test writing no attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'no_attributes.shp') write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', skipAttributeCreation=True) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') # expect only a default 'FID' field for shapefiles self.assertEqual(created_layer.fields().count(), 1) self.assertEqual(created_layer.fields()[0].name(), 'FID') # in this case we also check that the geometry exists, to make sure feature has been correctly written # even without attributes f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.asWkt() expWkt = 'Point (1 2)' self.assertTrue( compareWkt(expWkt, wkt), "geometry not saved correctly when saving without attributes : mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)) self.assertEqual(f['FID'], 0)
def save(self): toSave = [] context = dataobjects.createContext() for row in range(self.batchRowCount()): algParams = {} algOutputs = {} col = 0 alg = self.alg for param in alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if param.isDestination(): continue wrapper = self.wrappers[row][col] # For compatibility with 3.x API, we need to check whether the wrapper is # the deprecated WidgetWrapper class. If not, it's the newer # QgsAbstractProcessingParameterWidgetWrapper class # TODO QGIS 4.0 - remove if issubclass(wrapper.__class__, WidgetWrapper): widget = wrapper.widget else: widget = wrapper.wrappedWidget() value = wrapper.parameterValue() if not param.checkValueIsAcceptable(value, context): self.parent.messageBar().pushMessage( "", self.tr( 'Wrong or missing parameter value: {0} (row {1})'). format(param.description(), row + 1), level=Qgis.Warning, duration=5) return algParams[param.name()] = param.valueAsPythonString( value, context) col += 1 for out in alg.destinationParameterDefinitions(): if out.flags() & QgsProcessingParameterDefinition.FlagHidden: continue widget = self.tblParameters.cellWidget(row + 1, col) text = widget.getValue() if text.strip() != '': algOutputs[out.name()] = text.strip() col += 1 else: self.parent.messageBar().pushMessage( "", self.tr('Wrong or missing output value: {0} (row {1})' ).format(out.description(), row + 1), level=Qgis.Warning, duration=5) return toSave.append({ self.PARAMETERS: algParams, self.OUTPUTS: algOutputs }) settings = QgsSettings() last_path = settings.value("/Processing/LastBatchPath", QDir.homePath()) filename, __ = QFileDialog.getSaveFileName( self, self.tr('Save Batch'), last_path, self.tr('JSON files (*.json)')) if filename: if not filename.endswith('.json'): filename += '.json' last_path = QFileInfo(filename).path() settings.setValue('/Processing/LastBatchPath', last_path) with open(filename, 'w') as f: json.dump(toSave, f)
def updateDescription(self, current, previous): if isinstance(current, TreeResultItem): html = '<b>Algorithm</b>: {}<br><b>File path</b>: <a href="{}">{}</a>'.format(current.algorithm, QUrl.fromLocalFile(current.filename).toString(), QDir.toNativeSeparators(current.filename)) self.txtDescription.setHtml(html)
def tempHelpFolder(): tmp = os.path.join(str(QDir.tempPath()), 'processing_help') if not QDir(tmp).exists(): QDir().mkpath(tmp) return str(os.path.abspath(tmp))
def installFromZipFile(self, filePath): if not os.path.isfile(filePath): return settings = QgsSettings() settings.setValue(settingsGroup + '/lastZipDirectory', QFileInfo(filePath).absoluteDir().absolutePath()) with zipfile.ZipFile(filePath, 'r') as zf: pluginName = os.path.split(zf.namelist()[0])[0] pluginFileName = os.path.splitext(os.path.basename(filePath))[0] pluginsDirectory = qgis.utils.home_plugin_path if not QDir(pluginsDirectory).exists(): QDir().mkpath(pluginsDirectory) pluginDirectory = QDir.cleanPath( os.path.join(pluginsDirectory, pluginName)) # If the target directory already exists as a link, # remove the link without resolving QFile(pluginDirectory).remove() password = None infoString = None success = False keepTrying = True while keepTrying: try: # Test extraction. If fails, then exception will be raised and no removing occurs unzip(filePath, pluginsDirectory, password) # Removing old plugin files if exist removeDir(pluginDirectory) # Extract new files unzip(filePath, pluginsDirectory, password) keepTrying = False success = True except Exception as e: success = False if 'password' in str(e): infoString = self.tr('Aborted by user') if 'Bad password' in str(e): msg = self.tr( 'Wrong password. Please enter a correct password to the zip file.' ) else: msg = self.tr( 'The zip file is encrypted. Please enter password.' ) # Display a password dialog with QgsPasswordLineEdit dlg = QDialog() dlg.setWindowTitle(self.tr('Enter password')) buttonBox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal) buttonBox.rejected.connect(dlg.reject) buttonBox.accepted.connect(dlg.accept) lePass = QgsPasswordLineEdit() layout = QVBoxLayout() layout.addWidget(QLabel(msg)) layout.addWidget(lePass) layout.addWidget(buttonBox) dlg.setLayout(layout) keepTrying = dlg.exec_() password = lePass.text() else: infoString = self.tr( "Failed to unzip the plugin package\n{}.\nProbably it is broken" .format(filePath)) keepTrying = False if success: updateAvailablePlugins() loadPlugin(pluginName) plugins.getAllInstalled() plugins.rebuild() if settings.contains('/PythonPlugins/' + pluginName): if settings.value('/PythonPlugins/' + pluginName, False, bool): startPlugin(pluginName) reloadPlugin(pluginName) else: unloadPlugin(pluginName) loadPlugin(pluginName) else: if startPlugin(pluginName): settings.setValue('/PythonPlugins/' + pluginName, True) self.exportPluginsToManager() msg = "<b>%s</b>" % self.tr("Plugin installed successfully") else: msg = "<b>%s:</b> %s" % (self.tr("Plugin installation failed"), infoString) level = Qgis.Info if success else Qgis.Critical iface.pluginManagerInterface().pushMessage(msg, level)
def exportAsSvg(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As SVG'), '', self.tr('SVG files (*.svg *.SVG)')) if not filename: return if not filename.lower().endswith('.svg'): filename += '.svg' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) svgRect = QRectF(0, 0, totalRect.width(), totalRect.height()) svg = QSvgGenerator() svg.setFileName(filename) svg.setSize(QSize(totalRect.width(), totalRect.height())) svg.setViewBox(svgRect) svg.setTitle(self.model.displayName()) painter = QPainter(svg) self.scene.render(painter, svgRect, totalRect) painter.end() self.bar.pushMessage("", self.tr("Successfully exported model as SVG to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def exportAsImage(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As Image'), '', self.tr('PNG files (*.png *.PNG)')) if not filename: return if not filename.lower().endswith('.png'): filename += '.png' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) imgRect = QRectF(0, 0, totalRect.width(), totalRect.height()) img = QImage(totalRect.width(), totalRect.height(), QImage.Format_ARGB32_Premultiplied) img.fill(Qt.white) painter = QPainter() painter.setRenderHint(QPainter.Antialiasing) painter.begin(img) self.scene.render(painter, imgRect, totalRect) painter.end() img.save(filename) self.bar.pushMessage("", self.tr("Successfully exported model as image to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def load(self, layer, visible=True, collapsed_legend=False, collapsed_group=True): settings = QSettings("CatAIS", "VeriSO") module_name = settings.value("project/appmodule") provider = settings.value("project/provider") db_host = settings.value("project/dbhost") db_port = settings.value("project/dbport") db_name = settings.value("project/dbname") db_schema = settings.value("project/dbschema") db_user = settings.value("project/dbuser") db_pwd = settings.value("project/dbpwd") db_admin = settings.value("project/dbadmin") db_admin_pwd = settings.value("project/dbadminpwd") epsg = settings.value("project/epsg") if not db_schema: self.message_bar.pushMessage( "Error", tr("Missing database schema parameter."), QgsMessageBar.CRITICAL, duration=0) return if not db_host: self.message_bar.pushMessage( "Error", tr("Missing database host parameter."), QgsMessageBar.CRITICAL, duration=0) return if not db_name: self.message_bar.pushMessage( "Error", tr("Missing database name parameter."), QgsMessageBar.CRITICAL, duration=0) return if not db_port: self.message_bar.pushMessage( "Error", tr("Missing database port parameter."), QgsMessageBar.CRITICAL, duration=0) return if not db_user: self.message_bar.pushMessage( "Error", tr("Missing database user parameter."), QgsMessageBar.CRITICAL, duration=0) return if not db_pwd: self.message_bar.pushMessage( "Error", tr("Missing database user password parameter."), QgsMessageBar.CRITICAL, duration=0) return if not db_admin: self.message_bar.pushMessage( "Error", tr("Missing database administrator parameter."), QgsMessageBar.CRITICAL, duration=0) return if not db_admin_pwd: self.message_bar.pushMessage( "Error", tr("Missing database administrator password parameter."), QgsMessageBar.CRITICAL, duration=0) return if not provider: self.message_bar.pushMessage( "Error", tr("Missing provider parameter. Cannot load layer."), QgsMessageBar.CRITICAL, duration=0) return if not module_name: self.message_bar.pushMessage( "Error", tr("Missing module name parameter. Cannot load layer."), QgsMessageBar.CRITICAL, duration=0) return try: # Postgres if layer["type"] == "postgres": featuretype = str(layer["featuretype"]) title = layer["title"] key = str(layer["key"]) try: readonly = (layer["readonly"]) except: readonly = True try: geom = str(layer["geom"]) if geom == "": geom = None except: geom = None try: style = str(layer["style"]) except: style = "" try: group = str(layer["group"]) except: group = None try: sql = str(layer["sql"]) except: sql = "" # Overwrite the active project settings/parameters to add # *any* postgres layers. try: params = layer["params"] provider = layer["type"] db_host = params["dbhost"] db_port = str(params["dbport"]) db_name = params["dbname"] db_schema = params["dbschema"] db_user = params["dbuser"] db_pwd = params["dbpwd"] db_admin = params["dbadmin"] db_admin_pwd = params["dbadminpwd"] except: pass uri = QgsDataSourceURI() if readonly: uri.setConnection(db_host, db_port, db_name, db_user, db_pwd) else: uri.setConnection(db_host, db_port, db_name, db_admin, db_admin_pwd) uri.setDataSource(db_schema, featuretype, geom, sql, key) my_layer = QgsVectorLayer(uri.uri(), title, provider) # WMS / WMTS: # WMTS is a bit ugly since we need to know the tileMatrixSet: # Load layer manually in QGIS once an look for the tileMatrixSet # in the layer properties. elif layer["type"] in ["wms", "wmts"]: url = layer["url"] title = layer["title"] layers = layer["layers"] format = layer["format"] try: tilematrixset = layer["tilematrixset"] except: tilematrixset = None try: crs = layer["crs"] except: crs = "EPSG:" + str(epsg) try: styles = layer["styles"] except: styles = "" try: group = layer["group"] except: group = None try: style = layer["style"] except: style = "" my_layers = layers.split(",") my_styles = styles.split(",") layer_string = "" style_string = "" for my_layer in my_layers: layer_string += "&layers=" + my_layer # So werden einfach leere Styles requested. # Korrekterweise wäre style=qml und wmsstyle = Style der # vom WMS requested wird. style_string += "&styles=" if layer["type"] == "wms": uri = "IgnoreGetMapUrl=1&crs=" + crs + layer_string + \ style_string + "&format=" + format + "&url=" + url else: uri = "crs=" + crs + layer_string + style_string + \ "&format=" + format + "&tileMatrixSet=" + \ tilematrixset + "&url=" + url my_layer = QgsRasterLayer(uri, title, "wms", False) # local ogr and gdal formats elif layer["type"] in ["gdal", "ogr"]: title = layer["title"] url = layer["url"] try: style = str(layer["style"]) except: style = "" try: group = str(layer["group"]) except: group = None if layer["type"] == 'ogr': my_layer = QgsVectorLayer(url, title, layer["type"]) else: my_layer = QgsRasterLayer(url, title) else: self.message_bar.pushMessage( "Error", tr("Data provider not yet supported: ") + str(layer["type"]), QgsMessageBar.CRITICAL, duration=0) return if style != "": if style.startswith('global_qml'): qml_dir = "/python/plugins/veriso/" else: qml_dir = "/python/plugins/veriso/modules/%s/qml/" % \ module_name """qml_path = QDir.convertSeparators(QDir.cleanPath( QgsApplication.qgisSettingsDirPath() + qml_dir + style))""" qml_path = QDir.convertSeparators( QDir.cleanPath( (os.path.realpath(__file__)).split("python")[0] + qml_dir + style)) qml = QDir.convertSeparators(QDir.cleanPath(qml_path)) my_layer.loadNamedStyle(qml) if not my_layer.isValid(): # str(title) throws some ascii out of range error... self.message_bar.pushMessage("Error", title + tr(" is not valid layer."), QgsMessageBar.CRITICAL, duration=0) return else: # QgsMapLayerRegistry.instance().addMapLayer(my_layer) if group: # Layer soll in eine bestimmte Gruppe hinzugefügt # werden. QgsMapLayerRegistry.instance().addMapLayer(my_layer, False) my_group_node = self.root.findGroup(group) if not my_group_node: # Gruppe noch nicht vorhanden. my_group_node = self.root.addGroup(group) # Achtung: Das ist eher ein Workaround. Meines # Erachtens hats noch einen Bug. # Mit QgsMapLayerRegistry.instance().addMapLayer( # my_layer, False) wird # ein Layer noch nicht in die Legende gehängt. # Anschliessend kann man ihn # mit my_layer_node = self.root.addLayer(my_layer) # der Legende hinzufügen. # Das führt aber dazu, dass was mit dem MapCanvas # nicht mehr stimmt, dh. # .setExtent() funktioniert nicht mehr richtig. Wird # der Layer jedoch direkt # in die Legende gehängt, funktioniert .setExtent() # tadellos. Jetzt wird halt # momentan der Layer direkt eingehängt und # anschliessend in die gewünschte # Gruppe verschoben. # Kleiner (positiver) Nebeneffekt: Der Layer ist # defaultmässig ausgeschaltet. # # NEIN: Anscheinend ist es ein Problem wenn man dann # layer_node.setVisible(Qt.Checked) # macht. Dann funktionierts nicht mehr. -> Wieder # zurückändern auf einfachere Methode. # "Umweg": Hat Probleme gemacht, falls ein Gruppe # "active" war. Dann wurden der neue # Layer ebenfalls (zusätzlich) ihr hinzugefügt. # print my_layer.id() # my_layer_node = self.root.findLayer( # my_layer.id()) # print my_layer_node # cloned_layer = my_layer_node.clone() # print cloned_layer # my_group_node.insertChildNode(0, # cloned_layer) # self.root.removeChildNode( # my_layer_node) # my_layer_node = self.root.findLayer( # my_layer.id()) # Layer bekommt neuen layer_node. # "Direkt(er)" my_layer_node = my_group_node.insertLayer(0, my_layer) else: QgsMapLayerRegistry.instance().addMapLayer(my_layer, False) my_layer_node = self.root.addLayer(my_layer) my_layer_node.setVisible(Qt.Unchecked) if visible: my_layer_node.setVisible(Qt.Checked) if collapsed_legend: my_layer_node.setExpanded(False) else: my_layer_node.setExpanded(True) if 'my_group_node' in locals(): if collapsed_group: my_group_node.setExpanded(False) else: my_group_node.setExpanded(True) return my_layer except Exception as e: self.message_bar.pushMessage("Error", str(e), QgsMessageBar.CRITICAL, duration=0) QgsMessageLog.logMessage(str(e), "VeriSO", QgsMessageLog.CRITICAL) return
def reloadData(self): self.beginResetModel() self._document_list = [] if self._relation.isValid() is False or self._feature.isValid( ) is False: self.endResetModel() return feature_list = [] layer = self._relation.referencingLayer() request = self._relation.getRelatedFeaturesRequest(self._feature) for feature in layer.getFeatures(request): feature_list.append(feature) if self._nmRelation.isValid(): filters = [] for joinTableFeature in feature_list: referencedFeatureRequest = self._nmRelation.getReferencedFeatureRequest( joinTableFeature) filterExpression = referencedFeatureRequest.filterExpression() filters.append("(" + filterExpression.expression() + ")") nmRequest = QgsFeatureRequest() nmRequest.setFilterExpression(" OR ".join(filters)) feature_list = [] layer = self._nmRelation.referencedLayer() for documentFeature in layer.getFeatures(nmRequest): feature_list.append(documentFeature) for documentFeature in feature_list: documents_path = str() if self._documents_path: exp = QgsExpression(self._documents_path) context = QgsExpressionContext() context.appendScopes( QgsExpressionContextUtils.globalProjectLayerScopes(layer)) context.setFeature(documentFeature) documents_path = exp.evaluate(context) document_filename = str() if self._document_filename: exp = QgsExpression(self._document_filename) context = QgsExpressionContext() context.appendScopes( QgsExpressionContextUtils.globalProjectLayerScopes(layer)) context.setFeature(documentFeature) document_filename = exp.evaluate(context) file_info = QFileInfo(QDir(str(documents_path)), str(document_filename)) # ToolTip toolTipList = [] toolTipList.append("<ul>") for field in documentFeature.fields(): index = documentFeature.fields().indexFromName(field.name()) toolTipList.append("<li><strong>{0}</strong>: {1}</li>".format( field.displayName(), documentFeature[index])) toolTipList.append("</ul>") self._document_list.append({ self.DocumentIdRole: documentFeature.id(), self.DocumentPathRole: file_info.filePath(), self.DocumentNameRole: file_info.fileName(), self.DocumentExistsRole: file_info.exists(), self.DocumentToolTipRole: "".join(toolTipList), self.DocumentIsImageRole: PreviewImageProvider.isMimeTypeSupported(file_info.filePath()) }) self.endResetModel()
def getRasterFiles(path, recursive=False): rasters = [] if not QFileInfo(path).exists(): return rasters # TODO remove *.aux.xml _filter = getRasterExtensions() workDir = QDir(path) workDir.setFilter(QDir.Files | QDir.NoSymLinks | QDir.NoDotAndDotDot) workDir.setNameFilters(_filter) files = workDir.entryList() for f in files: rasters.append(path + "/" + f) if recursive: for myRoot, myDirs, myFiles in os.walk(str(path)): for dir in myDirs: workDir = QDir(myRoot + "/" + dir) workDir.setFilter(QDir.Files | QDir.NoSymLinks | QDir.NoDotAndDotDot) workDir.setNameFilters(_filter) workFiles = workDir.entryList() for f in workFiles: rasters.append(myRoot + "/" + dir + "/" + f) return rasters
def exportAsPdf(self): self.repaintModel(controls=False) filename, fileFilter = QFileDialog.getSaveFileName(self, self.tr('Save Model As PDF'), '', self.tr('PDF files (*.pdf *.PDF)')) if not filename: return if not filename.lower().endswith('.pdf'): filename += '.pdf' totalRect = self.scene.itemsBoundingRect() totalRect.adjust(-10, -10, 10, 10) printerRect = QRectF(0, 0, totalRect.width(), totalRect.height()) printer = QPrinter() printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filename) printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel) printer.setFullPage(True) painter = QPainter(printer) self.scene.render(painter, printerRect, totalRect) painter.end() self.bar.pushMessage("", self.tr("Successfully exported model as PDF to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5) self.repaintModel(controls=True)
def installFromZipFile(self, filePath): if not os.path.isfile(filePath): return settings = QgsSettings() settings.setValue(settingsGroup + '/lastZipDirectory', QFileInfo(filePath).absoluteDir().absolutePath()) pluginName = None with zipfile.ZipFile(filePath, 'r') as zf: # search for metadata.txt. In case of multiple files, we can assume that # the shortest path relates <pluginname>/metadata.txt metadatafiles = sorted(f for f in zf.namelist() if f.endswith('metadata.txt')) if len(metadatafiles) > 0: pluginName = os.path.split(metadatafiles[0])[0] pluginFileName = os.path.splitext(os.path.basename(filePath))[0] if not pluginName: msg_box = QMessageBox() msg_box.setIcon(QMessageBox.Warning) msg_box.setWindowTitle( self.tr("QGIS Python Install from ZIP Plugin Installer")) msg_box.setText( self. tr("The Zip file is not a valid QGIS python plugin. No root folder was found inside." )) msg_box.setStandardButtons(QMessageBox.Ok) more_info_btn = msg_box.addButton(self.tr("More Information"), QMessageBox.HelpRole) msg_box.exec() if msg_box.clickedButton() == more_info_btn: QgsHelp.openHelp( "plugins/plugins.html#the-install-from-zip-tab") return pluginsDirectory = qgis.utils.home_plugin_path if not QDir(pluginsDirectory).exists(): QDir().mkpath(pluginsDirectory) pluginDirectory = QDir.cleanPath( os.path.join(pluginsDirectory, pluginName)) # If the target directory already exists as a link, # remove the link without resolving QFile(pluginDirectory).remove() password = None infoString = None success = False keepTrying = True while keepTrying: try: # Test extraction. If fails, then exception will be raised and no removing occurs unzip(filePath, pluginsDirectory, password) # Removing old plugin files if exist removeDir(pluginDirectory) # Extract new files unzip(filePath, pluginsDirectory, password) keepTrying = False success = True except Exception as e: success = False if 'password' in str(e): infoString = self.tr('Aborted by user') if 'Bad password' in str(e): msg = self.tr( 'Wrong password. Please enter a correct password to the zip file.' ) else: msg = self.tr( 'The zip file is encrypted. Please enter password.' ) # Display a password dialog with QgsPasswordLineEdit dlg = QDialog() dlg.setWindowTitle(self.tr('Enter password')) buttonBox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal) buttonBox.rejected.connect(dlg.reject) buttonBox.accepted.connect(dlg.accept) lePass = QgsPasswordLineEdit() layout = QVBoxLayout() layout.addWidget(QLabel(msg)) layout.addWidget(lePass) layout.addWidget(buttonBox) dlg.setLayout(layout) keepTrying = dlg.exec_() password = lePass.text() else: infoString = self.tr( "Failed to unzip the plugin package\n{}.\nProbably it is broken" .format(filePath)) keepTrying = False if success: updateAvailablePlugins() self.processDependencies(pluginName) loadPlugin(pluginName) plugins.getAllInstalled() plugins.rebuild() if settings.contains('/PythonPlugins/' + pluginName): # Plugin was available? if settings.value('/PythonPlugins/' + pluginName, False, bool): # Plugin was also active? reloadPlugin( pluginName) # unloadPlugin + loadPlugin + startPlugin else: unloadPlugin(pluginName) loadPlugin(pluginName) else: if startPlugin(pluginName): settings.setValue('/PythonPlugins/' + pluginName, True) self.exportPluginsToManager() msg = "<b>%s</b>" % self.tr("Plugin installed successfully") else: msg = "<b>%s:</b> %s" % (self.tr("Plugin installation failed"), infoString) level = Qgis.Info if success else Qgis.Critical iface.pluginManagerInterface().pushMessage(msg, level)
def testStyle(self): self.execSQLCommand('DROP TABLE IF EXISTS layer_styles CASCADE') vl = self.getEditableLayer() self.assertTrue(vl.isValid()) self.assertTrue(vl.dataProvider().isSaveAndLoadStyleToDatabaseSupported()) self.assertTrue(vl.dataProvider().isDeleteStyleFromDatabaseSupported()) # table layer_styles does not exit related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase() self.assertEqual(related_count, -1) self.assertEqual(idlist, []) self.assertEqual(namelist, []) self.assertEqual(desclist, []) self.assertNotEqual(errmsg, "") qml, errmsg = vl.getStyleFromDatabase("1") self.assertEqual(qml, "") self.assertNotEqual(errmsg, "") mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "singleSymbol")) status = vl.loadNamedStyle(mFilePath) self.assertTrue(status) errorMsg = vl.saveStyleToDatabase("by day", "faded greens and elegant patterns", False, "") self.assertEqual(errorMsg, "") # the style id should be "1", not "by day" qml, errmsg = vl.getStyleFromDatabase("by day") self.assertEqual(qml, "") self.assertNotEqual(errmsg, "") related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase() self.assertEqual(related_count, 1) self.assertEqual(errmsg, "") self.assertEqual(idlist, ["1"]) self.assertEqual(namelist, ["by day"]) self.assertEqual(desclist, ["faded greens and elegant patterns"]) qml, errmsg = vl.getStyleFromDatabase("100") self.assertEqual(qml, "") self.assertNotEqual(errmsg, "") qml, errmsg = vl.getStyleFromDatabase("1") self.assertTrue(qml.startswith('<!DOCTYPE qgis'), qml) self.assertEqual(errmsg, "") res, errmsg = vl.deleteStyleFromDatabase("100") self.assertTrue(res) self.assertEqual(errmsg, "") res, errmsg = vl.deleteStyleFromDatabase("1") self.assertTrue(res) self.assertEqual(errmsg, "") # table layer_styles does exit, but is now empty related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase() self.assertEqual(related_count, 0) self.assertEqual(idlist, []) self.assertEqual(namelist, []) self.assertEqual(desclist, []) self.assertEqual(errmsg, "")
def testDateTimeWriteShapefile(self): """Check writing date and time fields to an ESRI shapefile.""" ml = QgsVectorLayer( ('Point?crs=epsg:4326&field=id:int&' 'field=date_f:date&field=time_f:time&field=dt_f:datetime'), 'test', 'memory') self.assertTrue(ml.isValid()) provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10))) ft.setAttributes([ 1, QDate(2014, 3, 5), QTime(13, 45, 22), QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)) ]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), 'datetime.shp') crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile') self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') fields = created_layer.dataProvider().fields() self.assertEqual( fields.at(fields.indexFromName('date_f')).type(), QVariant.Date) # shapefiles do not support time types, result should be string self.assertEqual( fields.at(fields.indexFromName('time_f')).type(), QVariant.String) # shapefiles do not support datetime types, result should be string self.assertEqual( fields.at(fields.indexFromName('dt_f')).type(), QVariant.String) f = next(created_layer.getFeatures(QgsFeatureRequest())) date_idx = created_layer.fields().lookupField('date_f') self.assertIsInstance(f.attributes()[date_idx], QDate) self.assertEqual(f.attributes()[date_idx], QDate(2014, 3, 5)) time_idx = created_layer.fields().lookupField('time_f') # shapefiles do not support time types self.assertIsInstance(f.attributes()[time_idx], str) self.assertEqual(f.attributes()[time_idx], '13:45:22') # shapefiles do not support datetime types datetime_idx = created_layer.fields().lookupField('dt_f') self.assertIsInstance(f.attributes()[datetime_idx], str) self.assertEqual( f.attributes()[datetime_idx], QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)).toString("yyyy/MM/dd hh:mm:ss.zzz"))
def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report)
def defaultOutputFolder(): folder = os.path.join(userFolder(), 'outputs') if not QDir(folder).exists(): QDir().mkpath(folder) return str(QDir.toNativeSeparators(folder))
def getInstalledPlugin(self, key, path, readOnly, testLoad=True): """ get the metadata of an installed plugin """ def metadataParser(fct): """ plugin metadata parser reimplemented from qgis.utils for better control on wchich module is examined in case there is an installed plugin masking a core one """ global errorDetails cp = configparser.ConfigParser() try: with codecs.open(metadataFile, "r", "utf8") as f: cp.read_file(f) return cp.get('general', fct) except Exception as e: if not errorDetails: errorDetails = e.args[0] # set to the first problem return "" def pluginMetadata(fct): """ calls metadataParser for current l10n. If failed, fallbacks to the standard metadata """ locale = QLocale.system().name() if locale and fct in translatableAttributes: value = metadataParser("%s[%s]" % (fct, locale)) if value: return value value = metadataParser("%s[%s]" % (fct, locale.split("_")[0])) if value: return value return metadataParser(fct) if not QDir(path).exists(): return global errorDetails # to communicate with the metadataParser fn plugin = dict() error = "" errorDetails = "" version = None metadataFile = os.path.join(path, 'metadata.txt') if os.path.exists(metadataFile): version = normalizeVersion(pluginMetadata("version")) if version: qgisMinimumVersion = pluginMetadata("qgisMinimumVersion").strip() if not qgisMinimumVersion: qgisMinimumVersion = "0" qgisMaximumVersion = pluginMetadata("qgisMaximumVersion").strip() if not qgisMaximumVersion: qgisMaximumVersion = qgisMinimumVersion[0] + ".99" # if compatible, add the plugin to the list if not isCompatible(Qgis.QGIS_VERSION, qgisMinimumVersion, qgisMaximumVersion): error = "incompatible" errorDetails = "%s - %s" % (qgisMinimumVersion, qgisMaximumVersion) elif testLoad: # only testLoad if compatible version try: pkg = __import__(key) reload(pkg) pkg.classFactory(iface) except Exception as e: error = "broken" errorDetails = str(e.args[0]) except SystemExit as e: error = "broken" errorDetails = QCoreApplication.translate("QgsPluginInstaller", "The plugin exited with error status: {0}").format(e.args[0]) except: error = "broken" errorDetails = QCoreApplication.translate("QgsPluginInstaller", "Unknown error") elif not os.path.exists(metadataFile): error = "broken" errorDetails = QCoreApplication.translate("QgsPluginInstaller", "Missing metadata file") else: error = "broken" e = errorDetails errorDetails = QCoreApplication.translate("QgsPluginInstaller", u"Error reading metadata") if e: errorDetails += ": " + e if not version: version = "?" if error[:16] == "No module named ": mona = error.replace("No module named ", "") if mona != key: error = "dependent" errorDetails = mona icon = pluginMetadata("icon") if QFileInfo(icon).isRelative(): icon = path + "/" + icon plugin = { "id": key, "plugin_id": None, "name": pluginMetadata("name") or key, "description": pluginMetadata("description"), "about": pluginMetadata("about"), "icon": icon, "category": pluginMetadata("category"), "tags": pluginMetadata("tags"), "changelog": pluginMetadata("changelog"), "author_name": pluginMetadata("author_name") or pluginMetadata("author"), "author_email": pluginMetadata("email"), "homepage": pluginMetadata("homepage"), "tracker": pluginMetadata("tracker"), "code_repository": pluginMetadata("repository"), "version_installed": version, "library": path, "pythonic": True, "experimental": pluginMetadata("experimental").strip().upper() in ["TRUE", "YES"], "deprecated": pluginMetadata("deprecated").strip().upper() in ["TRUE", "YES"], "trusted": False, "version_available": "", "zip_repository": "", "download_url": path, # warning: local path as url! "filename": "", "downloads": "", "average_vote": "", "rating_votes": "", "available": False, # Will be overwritten, if any available version found. "installed": True, "status": "orphan", # Will be overwritten, if any available version found. "error": error, "error_details": errorDetails, "readonly": readOnly} return plugin
def saveModel(self, saveAs): if not self.can_save(): return self.model.setName(str(self.textName.text())) self.model.setGroup(str(self.textGroup.text())) if self.model.sourceFilePath() and not saveAs: filename = self.model.sourceFilePath() else: filename, filter = QFileDialog.getSaveFileName(self, self.tr('Save Model'), ModelerUtils.modelsFolders()[0], self.tr('Processing models (*.model3 *.MODEL3)')) if filename: if not filename.endswith('.model3'): filename += '.model3' self.model.setSourceFilePath(filename) if filename: if not self.model.toFile(filename): if saveAs: QMessageBox.warning(self, self.tr('I/O error'), self.tr('Unable to save edits. Reason:\n {0}').format(str(sys.exc_info()[1]))) else: QMessageBox.warning(self, self.tr("Can't save model"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', ( "This model can't be saved in its original location (probably you do not " "have permission to do it). Please, use the 'Save as…' option.")) ) return self.update_model.emit() if saveAs: self.bar.pushMessage("", self.tr("Model was correctly saved to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5) else: self.bar.pushMessage("", self.tr("Model was correctly saved"), level=Qgis.Success, duration=5) self.hasChanged = False
def testStatistics(self): """Test zonal stats""" TEST_DATA_DIR = unitTestDataPath() + "/zonalstatistics/" myTempPath = QDir.tempPath() + "/" testDir = QDir(TEST_DATA_DIR) for f in testDir.entryList(QDir.Files): QFile.remove(myTempPath + f) QFile.copy(TEST_DATA_DIR + f, myTempPath + f) myVector = QgsVectorLayer(myTempPath + "polys.shp", "poly", "ogr") myRaster = QgsRasterLayer(myTempPath + "edge_problem.asc", "raster", "gdal") zs = QgsZonalStatistics(myVector, myRaster, "", 1, QgsZonalStatistics.All) zs.calculateStatistics(None) feat = QgsFeature() # validate statistics for each feature request = QgsFeatureRequest().setFilterFid(0) feat = next(myVector.getFeatures(request)) myMessage = ('Expected: %f\nGot: %f\n' % (12.0, feat[1])) assert feat[1] == 12.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (8.0, feat[2])) assert feat[2] == 8.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.666666666666667, feat[3])) assert abs(feat[3] - 0.666666666666667) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4])) assert feat[4] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.47140452079103201, feat[5])) assert abs(feat[5] - 0.47140452079103201) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6])) assert feat[6] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7])) assert feat[7] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8])) assert feat[8] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9])) assert feat[9] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10])) assert feat[10] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11])) assert feat[11] == 2.0, myMessage request.setFilterFid(1) feat = next(myVector.getFeatures(request)) myMessage = ('Expected: %f\nGot: %f\n' % (9.0, feat[1])) assert feat[1] == 9.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (5.0, feat[2])) assert feat[2] == 5.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.555555555555556, feat[3])) assert abs(feat[3] - 0.555555555555556) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4])) assert feat[4] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.49690399499995302, feat[5])) assert abs(feat[5] - 0.49690399499995302) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6])) assert feat[6] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7])) assert feat[7] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8])) assert feat[8] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9])) assert feat[9] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10])) assert feat[10] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11])) assert feat[11] == 2.0, myMessage request.setFilterFid(2) feat = next(myVector.getFeatures(request)) myMessage = ('Expected: %f\nGot: %f\n' % (6.0, feat[1])) assert feat[1] == 6.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (5.0, feat[2])) assert feat[2] == 5.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.833333333333333, feat[3])) assert abs(feat[3] - 0.833333333333333) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4])) assert feat[4] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.372677996249965, feat[5])) assert abs(feat[5] - 0.372677996249965) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6])) assert feat[6] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7])) assert feat[7] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8])) assert feat[8] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9])) assert feat[9] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10])) assert feat[10] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11])) assert feat[11] == 2.0, myMessage
def tearDownClass(cls): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(cls.report)