mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
845 lines
28 KiB
Python
845 lines
28 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Utility functions
|
|
# -------------------------------------------------
|
|
# getLastUsedDir()
|
|
# setLastUsedDir( QString *file_or_dir path )
|
|
# -------------------------------------------------
|
|
|
|
from PyQt4.QtCore import *
|
|
from PyQt4.QtGui import *
|
|
|
|
from qgis.core import *
|
|
from qgis.gui import *
|
|
|
|
from osgeo import gdal
|
|
from osgeo.gdalconst import *
|
|
from osgeo import ogr
|
|
|
|
import os
|
|
# to know the os
|
|
import platform
|
|
|
|
# Escapes arguments and return them joined in a string
|
|
def escapeAndJoin(strList):
|
|
joined = QString()
|
|
for s in strList:
|
|
if s.contains(" "):
|
|
escaped = '"' + s.replace('\\', '\\\\').replace('"', '\\"') + '"'
|
|
else:
|
|
escaped = s
|
|
joined += escaped + " "
|
|
return joined.trimmed()
|
|
|
|
# Retrieves last used dir from persistent settings
|
|
def getLastUsedDir():
|
|
settings = QSettings()
|
|
lastProjectDir = settings.value( "/UI/lastProjectDir", QVariant(".") ).toString()
|
|
return settings.value( "/GdalTools/lastUsedDir", QVariant(lastProjectDir) ).toString()
|
|
|
|
# Stores last used dir in persistent settings
|
|
def setLastUsedDir(filePath):
|
|
settings = QSettings()
|
|
fileInfo = QFileInfo(filePath)
|
|
if fileInfo.isDir():
|
|
dirPath = fileInfo.filePath()
|
|
else:
|
|
dirPath = fileInfo.path()
|
|
settings.setValue( "/GdalTools/lastUsedDir", QVariant(dirPath) )
|
|
|
|
# Retrieves GDAL binaries location
|
|
def getGdalBinPath():
|
|
settings = QSettings()
|
|
return settings.value( "/GdalTools/gdalPath", QVariant( "" ) ).toString()
|
|
|
|
# Stores GDAL binaries location
|
|
def setGdalBinPath( path ):
|
|
settings = QSettings()
|
|
settings.setValue( "/GdalTools/gdalPath", QVariant( path ) )
|
|
|
|
# Retrieves GDAL python modules location
|
|
def getGdalPymodPath():
|
|
settings = QSettings()
|
|
return settings.value( "/GdalTools/gdalPymodPath", QVariant( "" ) ).toString()
|
|
|
|
# Stores GDAL python modules location
|
|
def setGdalPymodPath( path ):
|
|
settings = QSettings()
|
|
settings.setValue( "/GdalTools/gdalPymodPath", QVariant( path ) )
|
|
|
|
# Retrieves GDAL help files location
|
|
def getHelpPath():
|
|
settings = QSettings()
|
|
return settings.value( "/GdalTools/helpPath", QVariant( "" ) ).toString()
|
|
|
|
# Stores GDAL help files location
|
|
def setHelpPath( path ):
|
|
settings = QSettings()
|
|
settings.setValue( "/GdalTools/helpPath", QVariant( path ) )
|
|
|
|
# Retrieves last used encoding from persistent settings
|
|
def getLastUsedEncoding():
|
|
settings = QSettings()
|
|
return settings.value( "/UI/encoding", QVariant("System") ).toString()
|
|
|
|
# Stores last used encoding in persistent settings
|
|
def setLastUsedEncoding(encoding):
|
|
settings = QSettings()
|
|
settings.setValue( "/UI/encoding", QVariant(encoding) )
|
|
|
|
def getRasterExtensions():
|
|
formats = FileFilter.allRastersFilter().split( ";;" )
|
|
extensions = QStringList()
|
|
for f in formats:
|
|
if f.contains( "*.bt" ) or f.contains( "*.mpr" ): # Binary Terrain or ILWIS
|
|
continue
|
|
extensions << FileFilter.getFilterExtensions( f )
|
|
return extensions
|
|
|
|
def getVectorExtensions():
|
|
formats = FileFilter.allVectorsFilter().split( ";;" )
|
|
extensions = QStringList()
|
|
for f in formats:
|
|
extensions << FileFilter.getFilterExtensions( f )
|
|
return extensions
|
|
|
|
class LayerRegistry(QObject):
|
|
|
|
_instance = None
|
|
_iface = None
|
|
|
|
@staticmethod
|
|
def instance():
|
|
if LayerRegistry._instance == None:
|
|
LayerRegistry._instance = LayerRegistry()
|
|
return LayerRegistry._instance
|
|
|
|
@staticmethod
|
|
def setIface(iface):
|
|
LayerRegistry._iface = iface
|
|
|
|
layers = []
|
|
|
|
def __init__(self):
|
|
QObject.__init__(self)
|
|
if LayerRegistry._instance != None:
|
|
return
|
|
|
|
LayerRegistry.layers = self.getAllLayers()
|
|
LayerRegistry._instance = self
|
|
self.connect(QgsMapLayerRegistry.instance(), SIGNAL("removedAll()"), self.removeAllLayers)
|
|
self.connect(QgsMapLayerRegistry.instance(), SIGNAL("layerWasAdded(QgsMapLayer *)"), self.layerAdded)
|
|
self.connect(QgsMapLayerRegistry.instance(), SIGNAL("layerWillBeRemoved(QString)"), self.removeLayer)
|
|
|
|
def getAllLayers(self):
|
|
if LayerRegistry._iface and hasattr(LayerRegistry._iface, 'legendInterface'):
|
|
return LayerRegistry._iface.legendInterface().layers()
|
|
return QgsMapLayerRegistry.instance().mapLayers().values()
|
|
|
|
def layerAdded(self, layer):
|
|
LayerRegistry.layers.append( layer )
|
|
self.emit( SIGNAL( "layersChanged" ) )
|
|
|
|
def removeLayer(self, layerId):
|
|
LayerRegistry.layers = filter( lambda x: x.getLayerID() != layerId, LayerRegistry.layers)
|
|
self.emit( SIGNAL( "layersChanged" ) )
|
|
|
|
def removeAllLayers(self):
|
|
LayerRegistry.layers = []
|
|
self.emit( SIGNAL( "layersChanged" ) )
|
|
|
|
@classmethod
|
|
def isRaster(self, layer):
|
|
# only gdal raster layers
|
|
if layer.type() != layer.RasterLayer:
|
|
return False
|
|
if layer.usesProvider() and layer.providerKey() != 'gdal':
|
|
return False
|
|
return True
|
|
|
|
def getRasterLayers(self):
|
|
return filter( self.isRaster, LayerRegistry.layers )
|
|
|
|
@classmethod
|
|
def isVector(self, layer):
|
|
if layer.type() != layer.VectorLayer:
|
|
return False
|
|
if layer.providerType() != 'ogr':
|
|
return False
|
|
return True
|
|
|
|
def getVectorLayers(self):
|
|
return filter( self.isVector, LayerRegistry.layers )
|
|
|
|
def getRasterFiles(path, recursive=False):
|
|
rasters = QStringList()
|
|
if not QFileInfo(path).exists():
|
|
return rasters
|
|
|
|
filter = getRasterExtensions()
|
|
workDir = QDir( path )
|
|
workDir.setFilter( QDir.Files | QDir.NoSymLinks | QDir.NoDotAndDotDot )
|
|
workDir.setNameFilters( filter )
|
|
files = workDir.entryList()
|
|
for f in files:
|
|
rasters << path + "/" + f
|
|
|
|
if recursive:
|
|
for myRoot, myDirs, myFiles in os.walk( unicode(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 << myRoot + "/" + dir + "/" + f
|
|
|
|
return rasters
|
|
|
|
def fillRasterOutputFormat(aFilter = None, filename = None):
|
|
shortName = QString()
|
|
|
|
if aFilter != None:
|
|
supportedRasters = GdalConfig.getSupportedRasters()
|
|
filterName = FileFilter.getFilterName( aFilter ).remove( QRegExp('^.*\] ') )
|
|
if supportedRasters.has_key( filterName ):
|
|
return supportedRasters[ filterName ][ "SHORTNAME" ]
|
|
|
|
shortName = GdalConfig.SupportedRasters.long2ShortName(filterName)
|
|
|
|
if shortName.isEmpty() and filename != None:
|
|
shortName = GdalConfig.SupportedRasters.filename2ShortName(filename)
|
|
|
|
if shortName.isEmpty():
|
|
shortName = "GTiff"
|
|
|
|
return shortName
|
|
|
|
def fillVectorOutputFormat(aFilter = None, filename = None):
|
|
shortName = QString()
|
|
|
|
if aFilter != None:
|
|
supportedVectors = GdalConfig.getSupportedVectors()
|
|
filterName = FileFilter.getFilterName( aFilter ).remove( QRegExp('^.*\] ') )
|
|
if supportedVectors.has_key( filterName ):
|
|
return supportedVectors[ filterName ][ "SHORTNAME" ]
|
|
|
|
pass #shortName = GdalConfig.SupportedVectors.long2ShortName(filterName)
|
|
|
|
if shortName.isEmpty() and filename != None:
|
|
pass #shortName = GdalConfig.SupportedVectors.filename2ShortName(filename)
|
|
|
|
if shortName.isEmpty():
|
|
shortName = "ESRI Shapefile"
|
|
|
|
return shortName
|
|
|
|
class UnsupportedOGRFormat(Exception):
|
|
def __init__(self):
|
|
msg = QCoreApplication.translate( "GdalTools", "The selected file is not a supported OGR format" )
|
|
Exception.__init__(self, msg)
|
|
|
|
def getVectorFields(vectorFile):
|
|
hds = ogr.Open( unicode(vectorFile).encode('utf8') )
|
|
if hds == None:
|
|
raise UnsupportedOGRFormat()
|
|
|
|
fields = []
|
|
names = []
|
|
|
|
layer = hds.GetLayer(0)
|
|
defn = layer.GetLayerDefn()
|
|
|
|
for i in range(defn.GetFieldCount()):
|
|
fieldDefn = defn.GetFieldDefn(i)
|
|
fieldType = fieldDefn.GetType()
|
|
if fieldType == 0 or fieldType == 2:
|
|
fields.append(fieldDefn)
|
|
names.append(fieldDefn.GetName())
|
|
|
|
return (fields, names)
|
|
|
|
# get raster SRS if possible
|
|
def getRasterSRS( parent, fileName ):
|
|
processSRS = QProcess( parent )
|
|
processSRS.start( "gdalinfo", QStringList() << fileName, QIODevice.ReadOnly )
|
|
arr = QByteArray()
|
|
if processSRS.waitForFinished():
|
|
arr = processSRS.readAllStandardOutput()
|
|
processSRS.close()
|
|
|
|
if arr.isEmpty():
|
|
return QString()
|
|
|
|
info = QString( arr ).split( "\n" ).filter( "AUTHORITY" )
|
|
if info.count() == 0:
|
|
return QString()
|
|
|
|
srs = info[ info.count() - 1 ]
|
|
srs = srs.simplified().remove( "AUTHORITY[" )
|
|
srs = srs.remove( QRegExp( "\]{2,4},?" ) ).remove( "\"" )
|
|
info = srs.split( "," )
|
|
srs = info[ 0 ] + ":" + info[ 1 ]
|
|
return srs
|
|
|
|
def getRasterExtent(parent, fileName):
|
|
processSRS = QProcess( parent )
|
|
processSRS.start( "gdalinfo", QStringList() << fileName, QIODevice.ReadOnly )
|
|
arr = QByteArray()
|
|
if processSRS.waitForFinished():
|
|
arr = processSRS.readAllStandardOutput()
|
|
processSRS.close()
|
|
|
|
if arr.isEmpty():
|
|
return
|
|
|
|
info = QString( arr ).split( "\n" )
|
|
ulCoord = info[ info.indexOf( QRegExp( "^Upper\sLeft.*" ) ) ].simplified()
|
|
lrCoord = info[ info.indexOf( QRegExp( "^Lower\sRight.*" ) ) ].simplified()
|
|
ulCoord = ulCoord[ulCoord.indexOf( "(" ) + 1 : ulCoord.indexOf( ")" ) - 1].split( "," )
|
|
lrCoord = lrCoord[lrCoord.indexOf( "(" ) + 1 : lrCoord.indexOf( ")" ) - 1].split( "," )
|
|
xUL = ulCoord[0].toDouble()[0]
|
|
yUL = ulCoord[1].toDouble()[0]
|
|
xLR = lrCoord[0].toDouble()[0]
|
|
yLR = lrCoord[1].toDouble()[0]
|
|
|
|
return QgsRectangle( xUL, yLR, xLR, yUL )
|
|
|
|
|
|
# This class is used to replace the QFileDialog class.
|
|
# Its static methods are used in place of the respective QFileDialog ones to:
|
|
# 1. set the last used directory
|
|
# 2. append the selected extension to the file name
|
|
# 3. bypass the following bug:
|
|
# when you use the 'filter' argument, the dialog is enlarged up to the longest filter length,
|
|
# so sometimes the dialog excedes the screen width
|
|
class FileDialog:
|
|
@classmethod
|
|
def getDialog(self, parent = None, caption = QString(), acceptMode = QFileDialog.AcceptOpen, fileMode = QFileDialog.ExistingFile, filter = QString(), selectedFilter = None, useEncoding = False):
|
|
if useEncoding:
|
|
dialog = QgsEncodingFileDialog(parent, caption, getLastUsedDir(), filter, getLastUsedEncoding())
|
|
else:
|
|
dialog = QFileDialog(parent, caption, getLastUsedDir(), filter)
|
|
dialog.setFileMode(fileMode)
|
|
dialog.setAcceptMode(acceptMode)
|
|
|
|
if selectedFilter != None:
|
|
dialog.selectNameFilter(selectedFilter)
|
|
|
|
if not dialog.exec_():
|
|
if useEncoding:
|
|
return (QString(), None)
|
|
return QString()
|
|
|
|
# change the selected filter value
|
|
if selectedFilter != None:
|
|
selectedFilter.clear()
|
|
selectedFilter += dialog.selectedNameFilter()
|
|
|
|
# save the last used dir and return the selected files
|
|
files = dialog.selectedFiles()
|
|
if not files.isEmpty():
|
|
setLastUsedDir(files[0])
|
|
|
|
if fileMode != QFileDialog.ExistingFiles:
|
|
files = files[0]
|
|
# append the extension if not already present
|
|
if fileMode == QFileDialog.AnyFile:
|
|
firstExt = None
|
|
for ext in FileFilter.getFilterExtensions(dialog.selectedNameFilter()):
|
|
if FileFilter.filenameMatchesFilterExt(files, ext):
|
|
firstExt = None
|
|
break
|
|
|
|
if firstExt == None:
|
|
firstExt = ext
|
|
|
|
if firstExt != None:
|
|
if firstExt.startsWith('*'):
|
|
files.append( firstExt[1:] )
|
|
|
|
if useEncoding:
|
|
encoding = dialog.encoding()
|
|
# encoding setted yet by QgsEncodingFileDialog
|
|
#setLastUsedEncoding(encoding)
|
|
return (files, encoding)
|
|
|
|
return files
|
|
|
|
@classmethod
|
|
def getOpenFileNames(self, parent = None, caption = QString(), filter = QString(), selectedFilter = None, useEncoding = False):
|
|
return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.ExistingFiles, filter, selectedFilter, useEncoding)
|
|
|
|
@classmethod
|
|
def getOpenFileName(self, parent = None, caption = QString(), filter = QString(), selectedFilter = None, useEncoding = False):
|
|
return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.ExistingFile, filter, selectedFilter, useEncoding)
|
|
|
|
@classmethod
|
|
def getSaveFileName(self, parent = None, caption = QString(), filter = QString(), selectedFilter = None, useEncoding = False):
|
|
return self.getDialog(parent, caption, QFileDialog.AcceptSave, QFileDialog.AnyFile, filter, selectedFilter, useEncoding)
|
|
|
|
@classmethod
|
|
def getExistingDirectory(self, parent = None, caption = QString(), useEncoding = False):
|
|
return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.DirectoryOnly, QString(), None, useEncoding)
|
|
|
|
class FileFilter:
|
|
@classmethod
|
|
def getFilter(self, typeName):
|
|
settings = QSettings()
|
|
return settings.value( "/GdalTools/" + typeName + "FileFilter", QVariant( "" ) ).toString()
|
|
|
|
@classmethod
|
|
def setFilter(self, typeName, aFilter):
|
|
settings = QSettings()
|
|
settings.setValue( "/GdalTools/" + typeName + "FileFilter", QVariant( aFilter ) )
|
|
|
|
# stores the supported raster file filter
|
|
rastersFilter = QString()
|
|
|
|
# Retrieves the filter for supported raster files
|
|
@classmethod
|
|
def allRastersFilter(self):
|
|
if self.rastersFilter.isEmpty():
|
|
QgsRasterLayer.buildSupportedRasterFileFilter(self.rastersFilter)
|
|
|
|
# workaround for QGis < 1.5 (see #2376)
|
|
# separates multiple extensions that joined by a slash
|
|
if QGis.QGIS_VERSION[0:3] < "1.5":
|
|
formats = self.rastersFilter.split( ";;" )
|
|
self.rastersFilter = QString()
|
|
for f in formats:
|
|
oldExts = QString(f).remove( QRegExp('^.*\(') ).remove( QRegExp('\).*$') )
|
|
newExts = QString(oldExts).replace( '/', ' *.' )
|
|
if not self.rastersFilter.isEmpty():
|
|
self.rastersFilter += ';;'
|
|
self.rastersFilter += f.replace( oldExts, newExts )
|
|
|
|
return self.rastersFilter
|
|
|
|
@classmethod
|
|
def lastUsedRasterFilter(self):
|
|
return self.getFilter("lastRaster")
|
|
|
|
@classmethod
|
|
def setLastUsedRasterFilter(self, aFilter):
|
|
self.setFilter("lastRaster", aFilter)
|
|
|
|
# stores the supported vectors file filter
|
|
vectorsFilter = QString()
|
|
|
|
# Retrieves the filter for supported vector files
|
|
@classmethod
|
|
def allVectorsFilter(self):
|
|
if self.vectorsFilter.isEmpty():
|
|
self.vectorsFilter = QgsProviderRegistry.instance().fileVectorFilters()
|
|
return self.vectorsFilter
|
|
|
|
@classmethod
|
|
def lastUsedVectorFilter(self):
|
|
return self.getFilter("lastVector")
|
|
|
|
@classmethod
|
|
def setLastUsedVectorFilter(self, aFilter):
|
|
self.setFilter("lastVector", aFilter)
|
|
|
|
# Retrieves the extensions list from a filter string
|
|
@classmethod
|
|
def getFilterExtensions(self, aFilter):
|
|
extList = QStringList()
|
|
# foreach format in filter string
|
|
for f in aFilter.split( ";;" ):
|
|
# gets the list of extensions from the filter
|
|
exts = f.remove( QRegExp('^.*\(') ).remove( QRegExp('\).*$') )
|
|
# if there is no extensions or the filter matches all, then return an empty list
|
|
# otherwise return the list of estensions
|
|
if not exts.isEmpty() and exts != "*" and exts != "*.*":
|
|
extList << exts.split(" ")
|
|
return extList
|
|
|
|
@classmethod
|
|
def getFilterName(self, aFilter):
|
|
return QString(aFilter).remove( QRegExp('\ \(.*$') ).trimmed()
|
|
|
|
@classmethod
|
|
def filenameMatchesFilterExt(self, fileName, ext):
|
|
regex = QRegExp(ext)
|
|
# use the wildcard matching
|
|
regex.setPatternSyntax(QRegExp.Wildcard)
|
|
|
|
if regex.exactMatch(fileName):
|
|
return True
|
|
return False
|
|
|
|
# Retrieves gdal information
|
|
class GdalConfig:
|
|
# retrieves and return the installed gdal version
|
|
@classmethod
|
|
def version(self):
|
|
return Version(gdal.VersionInfo("RELEASE_NAME"))
|
|
|
|
# store the supported rasters info
|
|
supportedRasters = None
|
|
|
|
# retrieve the supported rasters info
|
|
@classmethod
|
|
def getSupportedRasters(self):
|
|
if self.supportedRasters != None:
|
|
return self.supportedRasters
|
|
|
|
# first get the GDAL driver manager
|
|
if gdal.GetDriverCount() == 0:
|
|
gdal.AllRegister()
|
|
|
|
self.supportedRasters = dict()
|
|
jp2Driver = None
|
|
|
|
# for each loaded GDAL driver
|
|
for i in range(gdal.GetDriverCount()):
|
|
driver = gdal.GetDriver(i)
|
|
|
|
if driver == None:
|
|
QgsLogger.warning("unable to get driver " + QString.number(i))
|
|
continue
|
|
|
|
# now we need to see if the driver is for something currently
|
|
# supported; if not, we give it a miss for the next driver
|
|
|
|
longName = QString(driver.LongName).remove( QRegExp( '\(.*$' ) ).trimmed()
|
|
shortName = QString(driver.ShortName).remove( QRegExp( '\(.*$' ) ).trimmed()
|
|
extensions = QString()
|
|
|
|
description = QString(driver.GetDescription())
|
|
glob = QStringList()
|
|
|
|
metadata = driver.GetMetadata()
|
|
if metadata.has_key(gdal.DMD_EXTENSION):
|
|
extensions = QString(metadata[gdal.DMD_EXTENSION])
|
|
|
|
if not longName.isEmpty():
|
|
if not extensions.isEmpty():
|
|
# XXX add check for SDTS; in that case we want (*CATD.DDF)
|
|
glob << QString("*." + extensions.replace("/", " *.")).split(" ")
|
|
|
|
# Add only the first JP2 driver found to the filter list (it's the one GDAL uses)
|
|
if description == "JPEG2000" or description.startsWith("JP2"): # JP2ECW, JP2KAK, JP2MrSID
|
|
if jp2Driver != None:
|
|
continue # skip if already found a JP2 driver
|
|
jp2Driver = driver # first JP2 driver found
|
|
glob << "*.j2k" # add alternate extension
|
|
elif description == "GTiff":
|
|
glob << "*.tiff"
|
|
elif description == "JPEG":
|
|
glob << "*.jpeg"
|
|
else:
|
|
# USGS DEMs use "*.dem"
|
|
if description.startsWith( "USGSDEM" ):
|
|
glob << "*.dem"
|
|
elif description.startsWith( "DTED" ):
|
|
# DTED use "*.dt0"
|
|
glob << "*.dt0"
|
|
elif description.startsWith( "MrSID" ):
|
|
# MrSID use "*.sid"
|
|
glob << "*.sid"
|
|
else:
|
|
continue
|
|
|
|
self.supportedRasters[longName] = {'EXTENSIONS': glob, 'LONGNAME': longName, 'SHORTNAME': shortName, 'DESCRIPTION': description}
|
|
|
|
return self.supportedRasters
|
|
|
|
# store the supported vectors info
|
|
supportedVectors = None
|
|
|
|
# retrieve the supported vectors info
|
|
@classmethod
|
|
def getSupportedVectors(self):
|
|
if self.supportedVectors != None:
|
|
return self.supportedVectors
|
|
|
|
# first get the OGR driver manager
|
|
QgsApplication.registerOgrDrivers()
|
|
|
|
self.supportedVectors = dict()
|
|
|
|
# for each loaded OGR driver
|
|
for i in range(ogr.GetDriverCount()):
|
|
driver = ogr.GetDriver(i)
|
|
|
|
if driver == None:
|
|
QgsLogger.warning("unable to get driver " + QString.number(i))
|
|
continue
|
|
|
|
driverName = QString(driver.GetName())
|
|
longName = QString()
|
|
glob = QStringList()
|
|
|
|
if driverName.startsWith( "AVCBin" ):
|
|
pass #myDirectoryDrivers += "Arc/Info Binary Coverage,AVCBin"
|
|
elif driverName.startsWith( "AVCE00" ):
|
|
longName = "Arc/Info ASCII Coverage"
|
|
glob << "*.e00"
|
|
elif driverName.startsWith( "BNA" ):
|
|
longName = "Atlas BNA"
|
|
glob << "*.bna"
|
|
elif driverName.startsWith( "CSV" ):
|
|
longName = "Comma Separated Value"
|
|
glob << "*.csv"
|
|
elif driverName.startsWith( "DODS" ):
|
|
pass #myProtocolDrivers += "DODS/OPeNDAP,DODS"
|
|
elif driverName.startsWith( "PGeo" ):
|
|
pass #myDatabaseDrivers += "ESRI Personal GeoDatabase,PGeo"
|
|
|
|
# on Windows add a pair to the dict for this driver
|
|
if platform.system() == "Windows":
|
|
longName = "ESRI Personal GeoDatabase"
|
|
glob << "*.mdb"
|
|
elif driverName.startsWith( "SDE" ):
|
|
pass #myDatabaseDrivers += "ESRI ArcSDE,SDE"
|
|
elif driverName.startsWith( "ESRI" ):
|
|
longName = "ESRI Shapefiles"
|
|
glob << "*.shp"
|
|
elif driverName.startsWith( "FMEObjects Gateway" ):
|
|
longName = "FMEObjects Gateway"
|
|
glob << "*.fdd"
|
|
elif driverName.startsWith( "GeoJSON" ):
|
|
pass #myProtocolDrivers += "GeoJSON,GeoJSON"
|
|
longName = "GeoJSON"
|
|
glob << "*.geojson"
|
|
elif driverName.startsWith( "GeoRSS" ):
|
|
longName = "GeoRSS"
|
|
glob << "*.xml"
|
|
elif driverName.startsWith( "GML" ):
|
|
longName = "Geography Markup Language"
|
|
glob << "*.gml"
|
|
elif driverName.startsWith( "GMT" ):
|
|
longName = "GMT"
|
|
glob << "*.gmt"
|
|
elif driverName.startsWith( "GPX" ):
|
|
longName = "GPX"
|
|
glob << "*.gpx"
|
|
elif driverName.startsWith( "GRASS" ):
|
|
pass #myDirectoryDrivers += "Grass Vector,GRASS"
|
|
elif driverName.startsWith( "IDB" ):
|
|
pass #myDatabaseDrivers += "Informix DataBlade,IDB"
|
|
elif driverName.startsWith( "Interlis 1" ):
|
|
longName = "INTERLIS 1"
|
|
glob << "*.itf" << "*.xml" << "*.ili"
|
|
elif driverName.startsWith( "Interlis 2" ):
|
|
longName = "INTERLIS 2"
|
|
glob << "*.itf" << "*.xml" << "*.ili"
|
|
elif driverName.startsWith( "INGRES" ):
|
|
pass #myDatabaseDrivers += "INGRES,INGRES"
|
|
elif driverName.startsWith( "KML" ):
|
|
longName = "KML"
|
|
glob << "*.kml"
|
|
elif driverName.startsWith( "MapInfo File" ):
|
|
longName = "Mapinfo File"
|
|
glob << "*.mif" << "*.tab"
|
|
elif driverName.startsWith( "DGN" ):
|
|
longName = "Microstation DGN"
|
|
glob << "*.dgn"
|
|
elif driverName.startsWith( "MySQL" ):
|
|
pass #myDatabaseDrivers += "MySQL,MySQL"
|
|
elif driverName.startsWith( "OCI" ):
|
|
pass #myDatabaseDrivers += "Oracle Spatial,OCI"
|
|
elif driverName.startsWith( "ODBC" ):
|
|
pass #myDatabaseDrivers += "ODBC,ODBC"
|
|
elif driverName.startsWith( "OGDI" ):
|
|
pass #myDatabaseDrivers += "OGDI Vectors,OGDI"
|
|
elif driverName.startsWith( "PostgreSQL" ):
|
|
pass #myDatabaseDrivers += "PostgreSQL,PostgreSQL"
|
|
elif driverName.startsWith( "S57" ):
|
|
longName = "S-57 Base file"
|
|
glob << "*.000"
|
|
elif driverName.startsWith( "SDTS" ):
|
|
longName = "Spatial Data Transfer Standard"
|
|
glob << "*catd.ddf"
|
|
elif driverName.startsWith( "SQLite" ):
|
|
longName = "SQLite"
|
|
glob << "*.sqlite"
|
|
elif driverName.startsWith( "UK .NTF" ):
|
|
pass #myDirectoryDrivers += "UK. NTF,UK. NTF"
|
|
elif driverName.startsWith( "TIGER" ):
|
|
pass #myDirectoryDrivers += "U.S. Census TIGER/Line,TIGER"
|
|
elif driverName.startsWith( "VRT" ):
|
|
longName = "VRT - Virtual Datasource "
|
|
glob << "*.vrt"
|
|
elif driverName.startsWith( "XPlane" ):
|
|
longName = "X-Plane/Flighgear"
|
|
glob << "apt.dat" << "nav.dat" << "fix.dat" << "awy.dat"
|
|
|
|
longName = QString(longName).trimmed()
|
|
|
|
if longName.isEmpty():
|
|
continue
|
|
|
|
self.supportedVectors[longName] = {'EXTENSIONS': glob, 'LONGNAME': longName, 'SHORTNAME': driverName}
|
|
|
|
return self.supportedVectors
|
|
|
|
class SupportedRasters:
|
|
dict_long2shortName = dict()
|
|
|
|
# retrieve the raster format short name by long format name
|
|
@classmethod
|
|
def long2ShortName(self, longName):
|
|
if longName.isEmpty():
|
|
return QString()
|
|
|
|
if self.dict_long2shortName.has_key(longName):
|
|
return self.dict_long2shortName[longName]
|
|
|
|
# first get the GDAL driver manager
|
|
if gdal.GetDriverCount() == 0:
|
|
gdal.AllRegister()
|
|
|
|
shortName = QString()
|
|
|
|
# for each loaded GDAL driver
|
|
for i in range(gdal.GetDriverCount()):
|
|
driver = gdal.GetDriver(i)
|
|
if driver == None:
|
|
continue
|
|
|
|
# if this is the driver we searched for then return its short name
|
|
if FileFilter.getFilterName(driver.LongName) == longName:
|
|
shortName = FileFilter.getFilterName(driver.ShortName)
|
|
self.dict_long2shortName[longName] = shortName
|
|
break
|
|
|
|
return shortName
|
|
|
|
# retrieve the raster format short name by using the file name extension
|
|
@classmethod
|
|
def filename2ShortName(self, fileName):
|
|
if fileName.isEmpty():
|
|
return QString()
|
|
|
|
shortName = QString()
|
|
|
|
# for each raster format search for the file extension
|
|
formats = FileFilter.allRastersFilter().split( ";;" )
|
|
for f in formats:
|
|
for ext in FileFilter.getFilterExtensions(f):
|
|
if FileFilter.filenameMatchesFilterExt(fileName, ext):
|
|
longName = FileFilter.getFilterName(f)
|
|
shortName = self.long2ShortName(longName)
|
|
break
|
|
|
|
if not shortName.isEmpty():
|
|
break
|
|
|
|
return shortName
|
|
|
|
# class which allows to create version objects and compare them
|
|
class Version:
|
|
def __init__(self, ver):
|
|
self.vers = ('0', '0', '0')
|
|
|
|
if isinstance(ver, Version):
|
|
self.vers = ver.vers
|
|
elif isinstance(ver, tuple) or isinstance(ver, list):
|
|
self.vers = map(str, ver)
|
|
elif isinstance(ver, str) or isinstance(ver, QString):
|
|
self.vers = self.string2vers(ver)
|
|
|
|
@staticmethod
|
|
def string2vers(string):
|
|
vers = ['0', '0', '0']
|
|
|
|
nums = str(string).split(".")
|
|
|
|
if len(nums) > 0:
|
|
vers[0] = nums[0]
|
|
if len(nums) > 1:
|
|
vers[1] = nums[1]
|
|
if len(nums) > 2:
|
|
vers[2] = nums[2]
|
|
|
|
return (vers[0], vers[1], vers[2])
|
|
|
|
def __cmp__(self, other):
|
|
if not isinstance(other, Version):
|
|
other = Version(other)
|
|
|
|
if self.vers > other.vers:
|
|
return 1
|
|
if self.vers < other.vers:
|
|
return -1
|
|
return 0
|
|
|
|
def __str__(self):
|
|
return ".".join(self.vers)
|
|
|
|
|
|
def setProcessEnvironment(process):
|
|
envvar_list = {
|
|
"PATH" : getGdalBinPath(),
|
|
"PYTHONPATH" : getGdalPymodPath()
|
|
}
|
|
|
|
sep = os.pathsep
|
|
|
|
for name, val in envvar_list.iteritems():
|
|
if val == None or val == "":
|
|
continue
|
|
|
|
envval = os.getenv(name)
|
|
if envval == None or envval == "":
|
|
envval = str(val)
|
|
elif not QString( envval ).split( sep ).contains( val, Qt.CaseInsensitive ):
|
|
envval += "%s%s" % (sep, str(val))
|
|
else:
|
|
envval = None
|
|
|
|
if envval != None:
|
|
os.putenv( name, envval )
|
|
|
|
if False: # not needed because os.putenv() has already updated the environment for new child processes
|
|
env = QProcess.systemEnvironment()
|
|
if env.contains( QRegExp( "^%s=(.*)" % name, Qt.CaseInsensitive ) ):
|
|
env.replaceInStrings( QRegExp( "^%s=(.*)" % name, Qt.CaseInsensitive ), "%s=\\1%s%s" % (name, sep, gdalPath) )
|
|
else:
|
|
env << "%s=%s" % (name, val)
|
|
process.setEnvironment( env )
|
|
|
|
|
|
def setMacOSXDefaultEnvironment():
|
|
# fix bug #3170: many GDAL Tools don't work in OS X standalone
|
|
|
|
if platform.system() != "Darwin":
|
|
return
|
|
|
|
# QgsApplication.prefixPath() contains the path to qgis executable (i.e. .../Qgis.app/MacOS)
|
|
# get the path to Qgis application folder
|
|
qgis_app = u"%s/.." % QgsApplication.prefixPath()
|
|
qgis_app = QDir( qgis_app ).absolutePath()
|
|
|
|
qgis_bin = u"%s/bin" % QgsApplication.prefixPath() # path to QGis bin folder
|
|
qgis_python = u"%s/Resources/python" % qgis_app # path to QGis python folder
|
|
|
|
# path to the GDAL framework within the Qgis application folder (QGis standalone only)
|
|
qgis_standalone_gdal_path = u"%s/Frameworks/GDAL.framework" % qgis_app
|
|
|
|
# path to the GDAL framework when installed as external framework
|
|
gdal_bin_path = u"/Library/Frameworks/GDAL.framework/Versions/%s/Programs" % str(GdalConfig.version())[:3]
|
|
|
|
if os.path.exists( qgis_standalone_gdal_path ): # qgis standalone
|
|
# GDAL executables are in the QGis bin folder
|
|
if getGdalBinPath().isEmpty():
|
|
setGdalBinPath( qgis_bin )
|
|
# GDAL pymods are in the QGis python folder
|
|
if getGdalPymodPath().isEmpty():
|
|
setGdalPymodPath( qgis_python )
|
|
|
|
elif os.path.exists( gdal_bin_path ):
|
|
# GDAL executables are in the GDAL framework Programs folder
|
|
if getGdalBinPath().isEmpty():
|
|
setGdalBinPath( gdal_bin_path )
|
|
|
|
|
|
# setup the MacOSX path to both GDAL executables and python modules
|
|
if platform.system() == "Darwin":
|
|
setMacOSXDefaultEnvironment()
|
|
|