def _add_raster_layer(self, raster_layer, layer_name): """Add a raster layer to the folder. :param raster_layer: The layer to add. :type raster_layer: QgsRasterLayer :param layer_name: The name of the layer in the datastore. :type layer_name: str :returns: A two-tuple. The first element will be True if we could add the layer to the datastore. The second element will be the layer name which has been used or the error message. :rtype: (bool, str) .. versionadded:: 4.0 """ if not self.is_writable(): return False, 'The destination is not writable.' output = QFileInfo(self.uri.filePath(layer_name + '.tif')) source = QFileInfo(raster_layer.source()) if source.exists() and source.suffix() in ['tiff', 'tif']: # If it's tiff file based. QFile.copy(source.absoluteFilePath(), output.absoluteFilePath()) else: # If it's not file based. renderer = raster_layer.renderer() provider = raster_layer.dataProvider() crs = raster_layer.crs() pipe = QgsRasterPipe() pipe.set(provider.clone()) pipe.set(renderer.clone()) file_writer = QgsRasterFileWriter(output.absoluteFilePath()) file_writer.Mode(1) file_writer.writeRaster( pipe, provider.xSize(), provider.ySize(), provider.extent(), crs) del file_writer assert output.exists() return True, output.baseName()
def _add_vector_layer(self, vector_layer, layer_name): """Add a vector layer to the folder. :param vector_layer: The layer to add. :type vector_layer: QgsVectorLayer :param layer_name: The name of the layer in the datastore. :type layer_name: str :returns: A two-tuple. The first element will be True if we could add the layer to the datastore. The second element will be the layer name which has been used or the error message. :rtype: (bool, str) .. versionadded:: 4.0 """ if not self.is_writable(): return False, 'The destination is not writable.' output = QFileInfo( self.uri.filePath(layer_name + '.' + self._default_vector_format)) driver_mapping = { 'shp': 'ESRI Shapefile', 'kml': 'KML', 'geojson': 'GeoJSON', } QgsVectorFileWriter.writeAsVectorFormat( vector_layer, output.absoluteFilePath(), 'utf-8', vector_layer.crs(), driver_mapping[self._default_vector_format]) assert output.exists() return True, output.baseName()
def _add_tabular_layer(self, tabular_layer, layer_name): """Add a tabular layer to the folder. :param tabular_layer: The layer to add. :type tabular_layer: QgsVectorLayer :param layer_name: The name of the layer in the datastore. :type layer_name: str :returns: A two-tuple. The first element will be True if we could add the layer to the datastore. The second element will be the layer name which has been used or the error message. :rtype: (bool, str) .. versionadded:: 4.0 """ output = QFileInfo( self.uri.filePath(layer_name + '.csv')) QgsVectorFileWriter.writeAsVectorFormat( tabular_layer, output.absoluteFilePath(), 'utf-8', None, 'CSV') assert output.exists() return True, output.baseName()
def _add_tabular_layer(self, tabular_layer, layer_name): """Add a tabular layer to the folder. :param tabular_layer: The layer to add. :type tabular_layer: QgsVectorLayer :param layer_name: The name of the layer in the datastore. :type layer_name: str :returns: A two-tuple. The first element will be True if we could add the layer to the datastore. The second element will be the layer name which has been used or the error message. :rtype: (bool, str) .. versionadded:: 4.0 """ output = QFileInfo( self.uri.filePath(layer_name + '.csv')) QgsVectorFileWriter.writeAsVectorFormat( tabular_layer, output.absoluteFilePath(), 'utf-8', None, 'CSV') return True, output.baseName()
def browsePath(self): """用户点击了浏览路径的按钮。如果成功设置了路径,就返回True,如果用户取消了操作或者出错,就返回False 返回的用途参见showEvent()""" filename = QFileDialog.getOpenFileName(self, self.windowTitle()) if filename == "": return False fi = QFileInfo(filename) if fi.isSymLink(): filename = fi.symLinkTarget() if not os.path.exists(filename): QMessageBox.information(self, self.windowTitle(), self.trUtf8("快捷方式所指向的程序不正确。")) return False fi = QFileInfo(filename) self.txtName.setText(fi.baseName()) self.txtPath.setText(fi.absoluteFilePath()) self.setFileIcon(fi.absoluteFilePath()) self.txtDir.setText(fi.dir().absolutePath()) return True
def __workingDirectory(path_): """ Private function to determine working directory for the file dialog. @param path_ path of the intended working directory (string or QString) @return calculated working directory (QString) """ path = QString(path_) if not path.isEmpty(): info = QFileInfo(path) if info.exists() and info.isDir(): return info.absoluteFilePath() return info.absolutePath() return QDir.currentPath()
def browseOpenwith(self): filename = QFileDialog.getOpenFileName(self, self.windowTitle()) if filename == "": return fi = QFileInfo(filename) if fi.isSymLink(): filename = fi.symLinkTarget() if not os.path.exists(filename): QMessageBox.information(self, self.windowTitle(), self.trUtf8("快捷方式所指向的程序不正确。")) return fi = QFileInfo(filename) if not fi.isExecutable(): QMessageBox.information(self, self.windowTitle(), self.trUtf8("编辑程序必须是一个可执行文件。请重新选择。该选项是选填项,并不一定要填写。")) self.txtOpenwith.setText(fi.absoluteFilePath())
def layer_uri(self, layer_name): """Get layer URI. :param layer_name: The name of the layer to fetch. :type layer_name: str :return: The URI to the layer. :rtype: str .. versionadded:: 4.0 """ layers = self.layers() for layer, extension in product(layers, EXTENSIONS): one_file = QFileInfo(self.uri.filePath(layer + '.' + extension)) if one_file.exists(): if one_file.baseName() == layer_name: return one_file.absoluteFilePath() else: return None
def layer_uri(self, layer_name): """Get layer URI. :param layer_name: The name of the layer to fetch. :type layer_name: str :return: The URI to the layer. :rtype: str .. versionadded:: 4.0 """ layers = self.layers() for layer, extension in product(layers, EXTENSIONS): one_file = QFileInfo( self.uri.filePath(layer + '.' + extension)) if one_file.exists(): if one_file.baseName() == layer_name: return one_file.absoluteFilePath() else: return None
class Georeferencer(QObject): # Step enum Start = 0 Crop = 1 Translate = 2 Warp = 3 Overview = 4 Stop = 5 Step = [0, 1, 2, 3, 4, 5] Label = ['Start', 'Crop', 'Translate', 'Warp', 'Overview', 'Stop'] # Georeferencer.Step, ProcessStatus status = pyqtSignal(int, int) # Georeferencer.Step, Message error = pyqtSignal(int, str) def __init__(self, parent=None): super(Georeferencer, self).__init__(parent) # Internal variables self._debug = True self._gdalDir = QDir() self._step = 0 self._status = 0 self._translate = QFileInfo() self._warp = QFileInfo() self._overview = QFileInfo() self._command = '' self._args = '' self._process = QProcess() self._gc = Transform() self._rawFile = QFileInfo() self._pointFile = QFileInfo() self._cropFile = QFileInfo() self._translateFile = QFileInfo() self._geoFile = QFileInfo() tempDir = QDir.temp() self._cropFile.setFile( tempDir.absoluteFilePath('.ark_georef_crop.png')) self._translateFile = QFileInfo( tempDir.absoluteFilePath('.ark_georef_translate.tiff')) self._gdalDir = QDir(self.gdalPath()) if self._debug: debug('GDAL Path: ' + self._gdalDir.absolutePath()) self._translate.setFile(self._gdalDir, 'gdal_translate') self._warp.setFile(self._gdalDir, 'gdalwarp') self._overview.setFile(self._gdalDir, 'gdaladdo') if (not self._translate.exists() or not self._warp.exists() or not self._overview.exists()): self._signalError( 'GDAL commands not found, please ensure GDAL Tools plugin is installed and has correct path set!' ) return self._process.started.connect(self._processStarted) self._process.finished.connect(self._processFinished) self._process.error.connect(self._processError) self._process.readyReadStandardError.connect(self._processError) def step(self): return self._step def processStatus(self): return self._status def run(self, gc, rawFile, pointFile, geoFile): self._step = Georeferencer.Start if (not gc.isValid()): self._signalError('Invalid ground control points.') return self._gc = gc if (not rawFile.exists()): self._signalError('Raw file not found.') return self._rawFile = rawFile self._pointFile = pointFile self._geoFile = geoFile if not self._geoFile.absoluteDir().exists(): self._geoFile.absoluteDir().mkpath('.') if (self._debug): debug('Raw File: \'' + self._rawFile.absoluteFilePath() + '\'') debug('GCP File: \'' + self._pointFile.absoluteFilePath() + '\'') debug('Crop File: \'' + self._cropFile.absoluteFilePath() + '\'') debug('Translate File: \'' + self._translateFile.absoluteFilePath() + '\'') debug('Geo File: \'' + self._geoFile.absoluteFilePath() + '\'') QCoreApplication.processEvents() self._runCropStep() def _runCropStep(self): if self._debug: debug('Crop') self._step = Georeferencer.Crop self._args = [] self._command = '' pixmap = QPixmap(self._rawFile.absoluteFilePath()) if pixmap.isNull(): self._signalError('Loading of raw image failed.') return pixmap = pixmap.copy(0, 0, pixmap.width(), int(pixmap.height() * 0.84)) image = pixmap.toImage() if image.isNull(): self._signalError('Cropping of raw image failed.') return if not image.save(self._cropFile.absoluteFilePath(), 'PNG', 100): self._signalError('Saving of cropped image failed.') return self._signalStatus() self._runTranslateStep() def _formatGcp(self, point): point = self._gc.point(point) return "{0:f} {1:f} {2:f} {3:f}".format(point.raw().x(), point.raw().y(), point.map().x(), point.map().y()) def _runTranslateStep(self): self._step = Georeferencer.Translate self._args = [] self._args.extend(['-of', 'GTiff']) self._args.extend(['-a_srs', self._gc.crs]) # self._args.extend(['-gcp', self._formatGcp(1)]) # self._args.extend(['-gcp', self._formatGcp(2)]) # self._args.extend(['-gcp', self._formatGcp(3)]) # self._args.extend(['-gcp', self._formatGcp(4)]) self._args.extend([ '-gcp', str(self._gc.point(1).raw().x()), str(self._gc.point(1).raw().y()), str(self._gc.point(1).map().x()), str(self._gc.point(1).map().y()) ]) self._args.extend([ '-gcp', str(self._gc.point(2).raw().x()), str(self._gc.point(2).raw().y()), str(self._gc.point(2).map().x()), str(self._gc.point(2).map().y()) ]) self._args.extend([ '-gcp', str(self._gc.point(3).raw().x()), str(self._gc.point(3).raw().y()), str(self._gc.point(3).map().x()), str(self._gc.point(3).map().y()) ]) self._args.extend([ '-gcp', str(self._gc.point(4).raw().x()), str(self._gc.point(4).raw().y()), str(self._gc.point(4).map().x()), str(self._gc.point(4).map().y()) ]) self._args.append(self._cropFile.absoluteFilePath()) self._args.append(self._translateFile.absoluteFilePath()) self._command = self._translate.absoluteFilePath() + ' ' + ' '.join( self._args) self._process.start(self._translate.absoluteFilePath(), self._args) def _runWarpStep(self): self._step = Georeferencer.Warp self._args = [] self._args.extend(['-order', '1']) self._args.extend(['-r', 'cubic']) self._args.extend(['-t_srs', self._gc.crs]) self._args.extend(['-of', 'GTiff']) self._args.extend(['-co', 'COMPRESS=JPEG']) self._args.extend(['-co', 'JPEG_QUALITY=50']) self._args.extend(['-co', 'TILED=YES']) self._args.append('-dstalpha') self._args.append('-overwrite') self._args.append('\"' + self._translateFile.absoluteFilePath() + '\"') self._args.append('\"' + self._geoFile.absoluteFilePath() + '\"') self._command = self._warp.absoluteFilePath() + ' ' + ' '.join( self._args) self._process.start(self._command) def _runOverviewStep(self): self._step = Georeferencer.Overview self._args = [] self._args.extend(['--config', 'COMPRESS_OVERVIEW JPEG']) self._args.extend(['--config', 'INTERLEAVE_OVERVIEW PIXEL']) self._args.extend(['-r', 'cubic']) self._args.append('\"' + self._geoFile.absoluteFilePath() + '\"') self._args.append('2 4 8 16') self._command = self._overview.absoluteFilePath() + ' ' + ' '.join( self._args) self._process.start(self._command) def _processStarted(self): self._status = ProcessStatus.Running self._signalStatus() if self._debug: debug(self.Label[self._step]) debug(self._command) def _processFinished(self): self._status = ProcessStatus.Success self._signalStatus() if (self._step == Georeferencer.Translate): self._runWarpStep() elif (self._step == Georeferencer.Warp): self._runOverviewStep() elif (self._step == Georeferencer.Overview): self.writeGcpFile(self._gc, self._pointFile.absoluteFilePath()) self._step = Georeferencer.Stop self._signalStatus() def _processError(self): self._status = ProcessStatus.Failure msg = str(self._process.readAllStandardError()) debug(msg) self._signalError(msg) def _signalStatus(self): self.status.emit(self._step, self._status) def _signalError(self, msg): self.error.emit(self._step, msg) @staticmethod def gdalPath(): return QSettings().value('/GdalTools/gdalPath', '/usr/bin') @staticmethod def loadGcpFile(path): inFile = QFile(path) if (not inFile.open(QIODevice.ReadOnly | QIODevice.Text)): return 'ERROR: Unable to open GCP file for reading' inStream = QTextStream(inFile) line = inStream.readLine() # Skip the header line if found if (line == 'mapX,mapY,pixelX,pixelY,enable'): line = inStream.readLine() lines = 0 gc = Transform() while (line): lines += 1 vals = line.split(',') if (len(vals) != 5): return None map = QgsPoint(float(vals[0]), float(vals[1])) raw = QPointF(float(vals[2]), float(vals[3])) enabled = bool(vals[4]) point = GroundControlPoint(raw, map, enabled) gc.setPoint(lines, point) line = inStream.readLine() inFile.close() return gc @staticmethod def writeGcpFile(gc, path): outFile = QFile(path) if (not outFile.open(QIODevice.WriteOnly | QIODevice.Text)): return 'Unable to open GCP file for writing' outStream = QTextStream(outFile) outStream << gc.asCsv() outFile.close()
class FileSystemItem(QObject): """ An element in the FileSystemModel. """ iconProvider = QFileIconProvider() fileExtensions = ['*.qlr'] xmlSearchableTags = ['title', 'abstract','layername', 'attribution'] def __init__(self, file, recurse = True, recursion_counter = None, namingregex = None): super(FileSystemItem, self).__init__() # Raise exception if root path has too many child elements if recursion_counter: recursion_counter.increment() if isinstance(file, QFileInfo): self.fileinfo = file else: self.fileinfo = QFileInfo(file) self.fullpath = self.fileinfo.absoluteFilePath() self.basename = self.fileinfo.completeBaseName() self.displayname = self.fileinfo.fileName() if self.fileinfo.isDir() else self.fileinfo.completeBaseName() if namingregex: self.displayname = namingregex.match(self.displayname).group(1) self.icon = FileSystemItem.iconProvider.icon(self.fileinfo) self.isdir = self.fileinfo.isDir() self.children = [] if self.isdir else None if self.isdir and recurse: qdir = QDir(self.fullpath) for finfo in qdir.entryInfoList( FileSystemItem.fileExtensions , QDir.Files | QDir.AllDirs | QDir.NoDotAndDotDot,QDir.Name): self.children.append(FileSystemItem(finfo, recurse, recursion_counter, namingregex)) else: # file # Populate this if and when needed self.searchablecontent = None def filtered(self, filter): """ Filters the root path. :filter is a string. Is it contained in the basename or displayname then this item will be rendered. :return: the directory item. If nothing is found returns None. """ if not filter: return self filterlower = filter.lower() namematch = self.name_matches(filter) if self.isdir: if namematch: # Stop searching. Return this dir and all sub items return FileSystemItem(self.fullpath, True) else: # Only return dir if at least one sub item is a filter match diritem = FileSystemItem(self.fullpath, False) for child in self.children: childmatch = child.filtered(filter) if childmatch is not None: diritem.children.append((childmatch)) if len(diritem.children) > 0: return diritem else: if self.searchablecontent is None: self.searchablecontent = self.get_searchable_content().lower() if namematch or self.content_matches(filter): return FileSystemItem(self.fullpath, False) return None def matches(self, searchterm): """Returns true if this item mathces the searchterm""" return self.name_matches(searchterm) or self.content_matches(searchterm) def name_matches(self, searchterm): """Returns true if the searchterm matches the name of this item""" lowered = searchterm.lower() return lowered in self.basename.lower() or lowered in self.displayname.lower() def content_matches(self, searchterm): """Returns True if the searchterm matches content of this item""" if self.isdir: return False lowered = searchterm.lower() if self.searchablecontent is None: self.searchablecontent = self.get_searchable_content().lower() return lowered in self.searchablecontent def get_searchable_content(self): """ Pulls out tags from the object and returns them in order to be used by the filtered() method. """ f = QFile(self.fileinfo.absoluteFilePath()) f.open(QIODevice.ReadOnly) #stream = QTextStream(f) #stream.setCodec("UTF-8") try: doc = QDomDocument() doc.setContent( f.readAll() ) docelt = doc.documentElement() texts = [] for tagName in FileSystemItem.xmlSearchableTags: nodes = docelt.elementsByTagName(tagName) for i in range(nodes.count()): node = nodes.at(i) value = node.firstChild().toText().data() #print value texts.append( value ) # Add keywords nodes = docelt.elementsByTagName("keywordList") for i in range(nodes.count()): kwnode = nodes.at(i) valnodes = kwnode.toElement().elementsByTagName("value") for j in range(valnodes.count()): value = valnodes.at(j).firstChild().toText().data() texts.append(value) return u' '.join(texts) finally: f.close()
def _create_perimeter(self): """Calls methods for creating and loading perimeter layer.""" try: succes, layer = self.dW.check_layer(self) if not succes: return if layer.featureCount() == 0: self.set_text_statusbar.emit( u'Aktivní vrstva neobsahuje žádný prvek.', 10, True) return editing = self.dW.check_editing() title = u'Uložit vrstvu obvodu jako...' filters = u'.shp (*.shp)' perimeterLayerFilePath = self.dW.open_file_dialog( title, filters, False) if perimeterLayerFilePath: self.set_text_statusbar.emit(u'Vytvářím vrstvu obvodu...', 0, False) fileInfo = QFileInfo(perimeterLayerFilePath) if not fileInfo.suffix() == u'shp': perimeterLayerFilePath = \ fileInfo.absoluteFilePath() + u'.shp' fileInfo = QFileInfo(perimeterLayerFilePath) selectedFeaturesIds = layer.selectedFeaturesIds() perimeterLayerName = fileInfo.completeBaseName() loadedLayer = self.dW.check_loaded_layers( perimeterLayerFilePath) perimeterLayer = self._create_perimeter_layer( layer, perimeterLayerFilePath, self.categoryName, perimeterLayerName, loadedLayer) QgsApplication.processEvents() loadedLayer = self.dW.check_loaded_layers( perimeterLayerFilePath) if loadedLayer: self.iface.actionDraw().trigger() self.set_perimeter_layer(loadedLayer, False) self.sync_perimeter_map_layer_combo_box() else: QgsMapLayerRegistry.instance().addMapLayer(perimeterLayer) layer.selectByIds(selectedFeaturesIds) self.iface.setActiveLayer(layer) if editing: self.toggleEditingAction.trigger() self.set_text_statusbar.emit(u'Obvod byl úspešně vytvořen.', 15, False) except: self.dW.display_error_messages(self, u'Error creating perimeter.', u'Chyba při vytváření obvodu.')
def test_create_geopackage(self): """Test if we can store geopackage.""" # Create a geopackage from an empty file. path = QFileInfo(mktemp() + '.gpkg') self.assertFalse(path.exists()) data_store = GeoPackage(path) path.refresh() self.assertTrue(path.exists()) # Let's add a vector layer. layer_name = 'flood_test' layer = standard_data_path('hazard', 'flood_multipart_polygons.shp') vector_layer = QgsVectorLayer(layer, 'Flood', 'ogr') result = data_store.add_layer(vector_layer, layer_name) self.assertTrue(result[0]) # We should have one layer. layers = data_store.layers() self.assertEqual(len(layers), 1) self.assertIn(layer_name, layers) # Add the same layer with another name. layer_name = 'another_vector_flood' result = data_store.add_layer(vector_layer, layer_name) self.assertTrue(result[0]) # We should have two layers. layers = data_store.layers() self.assertEqual(len(layers), 2) self.assertIn(layer_name, layers) # Test the URI of the new layer. expected = path.absoluteFilePath() + '|layername=' + layer_name self.assertEqual(data_store.layer_uri(layer_name), expected) # Test a fake layer. self.assertIsNone(data_store.layer_uri('fake_layer')) # Test to add a raster layer_name = 'raster_flood' layer = standard_data_path('hazard', 'classified_hazard.tif') raster_layer = QgsRasterLayer(layer, layer_name) result = data_store.add_layer(raster_layer, layer_name) self.assertTrue(result[0]) # We should have 3 layers inside. layers = data_store.layers() self.assertEqual(len(layers), 3) # Check the URI for the raster layer. expected = 'GPKG:' + path.absoluteFilePath() + ':' + layer_name self.assertEqual(data_store.layer_uri(layer_name), expected) # Add a second raster. layer_name = 'big raster flood' self.assertTrue(data_store.add_layer(raster_layer, layer_name)) self.assertEqual(len(data_store.layers()), 4) # Test layer without geometry layer = load_test_vector_layer( 'gisv4', 'impacts', 'exposure_summary_table.csv') tabular_layer_name = 'breakdown' result = data_store.add_layer(layer, tabular_layer_name) self.assertTrue(result[0])