mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
986 lines
32 KiB
Python
986 lines
32 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
***************************************************************************
|
|
GdalTools_utils.py
|
|
---------------------
|
|
Date : June 2010
|
|
Copyright : (C) 2010 by Giuseppe Sucameli
|
|
Email : brush dot tyler at gmail dot com
|
|
***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************
|
|
"""
|
|
from builtins import filter
|
|
from builtins import map
|
|
from builtins import str
|
|
from builtins import range
|
|
from builtins import object
|
|
|
|
__author__ = 'Giuseppe Sucameli'
|
|
__date__ = 'June 2010'
|
|
__copyright__ = '(C) 2010, Giuseppe Sucameli'
|
|
# This will get replaced with a git SHA1 when you do a git archive
|
|
__revision__ = '$Format:%H$'
|
|
|
|
# Utility functions
|
|
# -------------------------------------------------
|
|
# getLastUsedDir()
|
|
# setLastUsedDir( QString *file_or_dir path )
|
|
# -------------------------------------------------
|
|
|
|
from qgis.PyQt.QtCore import QObject, QSettings, QFileInfo, QDir, QCoreApplication, pyqtSignal
|
|
from qgis.PyQt.QtWidgets import QFileDialog
|
|
|
|
from qgis.core import QgsApplication, QgsRectangle, QgsProviderRegistry, QgsLogger, QgsProject
|
|
from qgis.gui import QgsEncodingFileDialog
|
|
|
|
from osgeo import gdal, ogr, osr
|
|
|
|
import os
|
|
# to know the os
|
|
import platform
|
|
import sys
|
|
import string
|
|
import re
|
|
|
|
# Escapes arguments and return them joined in a string
|
|
|
|
|
|
def escapeAndJoin(strList):
|
|
joined = ''
|
|
for s in strList:
|
|
if s.find(" ") is not -1:
|
|
escaped = '"' + s.replace('\\', '\\\\').replace('"', '\\"') + '"'
|
|
else:
|
|
escaped = s
|
|
joined += escaped + " "
|
|
return joined.strip()
|
|
|
|
# Retrieves last used dir from persistent settings
|
|
|
|
|
|
def getLastUsedDir():
|
|
settings = QSettings()
|
|
lastProjectDir = settings.value("/UI/lastProjectDir", u".", type=str)
|
|
return settings.value("/GdalTools/lastUsedDir", lastProjectDir, type=str)
|
|
|
|
# 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", dirPath)
|
|
|
|
# Retrieves GDAL binaries location
|
|
|
|
|
|
def getGdalBinPath():
|
|
settings = QSettings()
|
|
return settings.value("/GdalTools/gdalPath", u"", type=str)
|
|
|
|
# Stores GDAL binaries location
|
|
|
|
|
|
def setGdalBinPath(path):
|
|
settings = QSettings()
|
|
settings.setValue("/GdalTools/gdalPath", path)
|
|
|
|
# Retrieves GDAL python modules location
|
|
|
|
|
|
def getGdalPymodPath():
|
|
settings = QSettings()
|
|
return settings.value("/GdalTools/gdalPymodPath", u"", type=str)
|
|
|
|
# Stores GDAL python modules location
|
|
|
|
|
|
def setGdalPymodPath(path):
|
|
settings = QSettings()
|
|
settings.setValue("/GdalTools/gdalPymodPath", path)
|
|
|
|
# Retrieves GDAL help files location
|
|
|
|
|
|
def getHelpPath():
|
|
settings = QSettings()
|
|
return settings.value("/GdalTools/helpPath", u"", type=str)
|
|
|
|
# Stores GDAL help files location
|
|
|
|
|
|
def setHelpPath(path):
|
|
settings = QSettings()
|
|
settings.setValue("/GdalTools/helpPath", path)
|
|
|
|
# Retrieves last used encoding from persistent settings
|
|
|
|
|
|
def getLastUsedEncoding():
|
|
settings = QSettings()
|
|
return settings.value("/UI/encoding", u"System", type=str)
|
|
|
|
# Stores last used encoding in persistent settings
|
|
|
|
|
|
def setLastUsedEncoding(encoding):
|
|
settings = QSettings()
|
|
settings.setValue("/UI/encoding", encoding)
|
|
|
|
|
|
def getRasterExtensions():
|
|
formats = FileFilter.allRastersFilter().split(";;")
|
|
extensions = []
|
|
for f in formats:
|
|
if string.find(f, "*.bt") is not -1 or string.find(f, "*.mpr") is not -1: # Binary Terrain or ILWIS
|
|
continue
|
|
extensions.extend(FileFilter.getFilterExtensions(f))
|
|
return extensions
|
|
|
|
|
|
def getVectorExtensions():
|
|
formats = FileFilter.allVectorsFilter().split(";;")
|
|
extensions = []
|
|
for f in formats:
|
|
extensions.extend(FileFilter.getFilterExtensions(f))
|
|
return extensions
|
|
|
|
|
|
class LayerRegistry(QObject):
|
|
layersChanged = pyqtSignal()
|
|
|
|
_instance = None
|
|
_iface = None
|
|
|
|
@staticmethod
|
|
def instance():
|
|
if LayerRegistry._instance is None:
|
|
LayerRegistry._instance = LayerRegistry()
|
|
return LayerRegistry._instance
|
|
|
|
@staticmethod
|
|
def setIface(iface):
|
|
LayerRegistry._iface = iface
|
|
|
|
layers = []
|
|
|
|
def __init__(self):
|
|
QObject.__init__(self)
|
|
if LayerRegistry._instance is not None:
|
|
return
|
|
|
|
LayerRegistry.layers = self.getAllLayers()
|
|
LayerRegistry._instance = self
|
|
QgsProject.instance().removeAll.connect(self.removeAllLayers)
|
|
QgsProject.instance().layerWasAdded.connect(self.layerAdded)
|
|
QgsProject.instance().layerWillBeRemoved.connect(self.removeLayer)
|
|
|
|
def getAllLayers(self):
|
|
return list(node.layer() for node in QgsProject.instance().layerTreeRoot().findLayers())
|
|
|
|
def layerAdded(self, layer):
|
|
LayerRegistry.layers.append(layer)
|
|
self.layersChanged.emit()
|
|
|
|
def removeLayer(self, layerId):
|
|
LayerRegistry.layers = [x for x in LayerRegistry.layers if x.id() != layerId]
|
|
self.layersChanged.emit()
|
|
|
|
def removeAllLayers(self):
|
|
LayerRegistry.layers = []
|
|
self.layersChanged.emit()
|
|
|
|
@classmethod
|
|
def isRaster(self, layer):
|
|
# only gdal raster layers
|
|
if layer.type() != layer.RasterLayer:
|
|
return False
|
|
if layer.providerType() != 'gdal':
|
|
return False
|
|
return True
|
|
|
|
def getRasterLayers(self):
|
|
return list(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 list(filter(self.isVector, LayerRegistry.layers))
|
|
|
|
|
|
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 fillRasterOutputFormat(aFilter=None, filename=None):
|
|
shortName = ''
|
|
|
|
if aFilter is not None:
|
|
supportedRasters = GdalConfig.getSupportedRasters()
|
|
filterName = re.sub('^.*\] ', '', FileFilter.getFilterName(aFilter))
|
|
if filterName is supportedRasters:
|
|
return supportedRasters[filterName]["SHORTNAME"]
|
|
|
|
shortName = GdalConfig.SupportedRasters.long2ShortName(filterName)
|
|
|
|
if shortName == '' and filename is not None:
|
|
shortName = GdalConfig.SupportedRasters.filename2ShortName(filename)
|
|
|
|
if shortName == '':
|
|
shortName = "GTiff"
|
|
|
|
return shortName
|
|
|
|
|
|
def fillVectorOutputFormat(aFilter=None, filename=None):
|
|
shortName = ''
|
|
|
|
if aFilter is not None:
|
|
supportedVectors = GdalConfig.getSupportedVectors()
|
|
filterName = re.sub('^.*\] ', '', FileFilter.getFilterName(aFilter))
|
|
if filterName in supportedVectors:
|
|
return supportedVectors[filterName]["SHORTNAME"]
|
|
|
|
pass # shortName = GdalConfig.SupportedVectors.long2ShortName(filterName)
|
|
|
|
if shortName == '' and filename is not None:
|
|
pass # shortName = GdalConfig.SupportedVectors.filename2ShortName(filename)
|
|
|
|
if shortName == '':
|
|
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(str(vectorFile).encode('utf8'))
|
|
if hds is 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):
|
|
ds = gdal.Open(fileName)
|
|
if ds is None:
|
|
return ''
|
|
|
|
proj = ds.GetProjectionRef()
|
|
if proj is None:
|
|
return ''
|
|
|
|
sr = osr.SpatialReference()
|
|
if sr.ImportFromWkt(proj) != gdal.CE_None:
|
|
return ''
|
|
|
|
name = sr.GetAuthorityName(None)
|
|
code = sr.GetAuthorityCode(None)
|
|
if name is not None and code is not None:
|
|
return '%s:%s' % (name, code)
|
|
|
|
return ''
|
|
|
|
# get raster extent using python API - replaces old method which parsed gdalinfo output
|
|
|
|
|
|
def getRasterExtent(parent, fileName):
|
|
ds = gdal.Open(fileName)
|
|
if ds is None:
|
|
return
|
|
|
|
x = ds.RasterXSize
|
|
y = ds.RasterYSize
|
|
|
|
gt = ds.GetGeoTransform()
|
|
if gt is None:
|
|
xUL = 0
|
|
yUL = 0
|
|
xLR = x
|
|
yLR = y
|
|
else:
|
|
xUL = gt[0]
|
|
yUL = gt[3]
|
|
xLR = gt[0] + gt[1] * x + gt[2] * y
|
|
yLR = gt[3] + gt[4] * x + gt[5] * y
|
|
|
|
return QgsRectangle(xUL, yLR, xLR, yUL)
|
|
|
|
|
|
# get raster resolution
|
|
|
|
def getRasterResolution(fileName):
|
|
ds = gdal.Open(fileName)
|
|
if ds is None:
|
|
return
|
|
|
|
gt = ds.GetGeoTransform()
|
|
|
|
if gt is None:
|
|
return
|
|
else:
|
|
xRes = abs(gt[1])
|
|
yRes = abs(gt[5])
|
|
return (xRes, yRes)
|
|
|
|
# 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(object):
|
|
|
|
@classmethod
|
|
def getDialog(self, parent=None, caption='', acceptMode=QFileDialog.AcceptOpen, fileMode=QFileDialog.ExistingFile, filter='', 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 is not None:
|
|
dialog.selectNameFilter(selectedFilter[0])
|
|
|
|
if not dialog.exec_():
|
|
if useEncoding:
|
|
return ('', None)
|
|
return ''
|
|
|
|
# change the selected filter value
|
|
if selectedFilter is not None:
|
|
selectedFilter[0] = dialog.selectedNameFilter()
|
|
|
|
# save the last used dir and return the selected files
|
|
files = dialog.selectedFiles()
|
|
if files != '':
|
|
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 is None:
|
|
firstExt = ext
|
|
|
|
if firstExt is not None:
|
|
if firstExt.startswith('*'):
|
|
files += 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='', filter='', selectedFilter=None, useEncoding=False):
|
|
if useEncoding:
|
|
return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.ExistingFiles, filter, selectedFilter, useEncoding)
|
|
res, selected_filter = QFileDialog.getOpenFileNames(parent, caption, getLastUsedDir(), filter)
|
|
if len(res) > 0:
|
|
setLastUsedDir(res[-1])
|
|
return res
|
|
|
|
@classmethod
|
|
def getOpenFileName(self, parent=None, caption='', filter='', selectedFilter=None, useEncoding=False):
|
|
if useEncoding:
|
|
return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.ExistingFile, filter, selectedFilter, useEncoding)
|
|
res, selected_filter = QFileDialog.getOpenFileName(parent, caption, getLastUsedDir(), filter)
|
|
if res:
|
|
setLastUsedDir(res)
|
|
return res
|
|
|
|
@classmethod
|
|
def getSaveFileName(self, parent=None, caption='', filter='', selectedFilter=None, useEncoding=False):
|
|
if useEncoding:
|
|
return self.getDialog(parent, caption, QFileDialog.AcceptSave, QFileDialog.AnyFile, filter, selectedFilter, useEncoding)
|
|
res, filter = QFileDialog.getSaveFileName(parent, caption, getLastUsedDir(), filter)
|
|
if res:
|
|
setLastUsedDir(res)
|
|
return res
|
|
|
|
@classmethod
|
|
def getExistingDirectory(self, parent=None, caption='', useEncoding=False):
|
|
if useEncoding:
|
|
return self.getDialog(parent, caption, QFileDialog.AcceptOpen, QFileDialog.DirectoryOnly, '', None, useEncoding)
|
|
res = QFileDialog.getExistingDirectory(parent, caption, getLastUsedDir(), QFileDialog.ShowDirsOnly)
|
|
if res:
|
|
setLastUsedDir(res)
|
|
return res
|
|
|
|
|
|
class FileFilter(object):
|
|
|
|
@classmethod
|
|
def getFilter(self, typeName):
|
|
settings = QSettings()
|
|
return settings.value("/GdalTools/" + typeName + "FileFilter", u"", type=str)
|
|
|
|
@classmethod
|
|
def setFilter(self, typeName, aFilter):
|
|
settings = QSettings()
|
|
settings.setValue("/GdalTools/" + typeName + "FileFilter", aFilter)
|
|
|
|
# stores the supported raster file filter
|
|
rastersFilter = ''
|
|
|
|
# Retrieves the filter for supported raster files
|
|
@classmethod
|
|
def allRastersFilter(self):
|
|
if self.rastersFilter == '':
|
|
self.rastersFilter = QgsProviderRegistry.instance().fileRasterFilters()
|
|
|
|
# workaround for Qgis < 1.5 (see #2376)
|
|
# removed as this is a core plugin Qgis >= 1.9
|
|
|
|
return self.rastersFilter
|
|
|
|
# Retrieves the filter for supported raster files to save
|
|
# Skip *, *.zip and *.vrt and move tif to top
|
|
# TODO: only the formats with GDAL_DCAP_CREATE
|
|
@classmethod
|
|
def saveRastersFilter(self):
|
|
# move tif to top if available
|
|
available = self.allRastersFilter().split(";;")
|
|
|
|
filters = []
|
|
|
|
for f in available:
|
|
if "*.tif" in f:
|
|
filters.append(f)
|
|
break
|
|
|
|
for f in available:
|
|
if "*.tif" in f or "*.zip" in f or "(*)" in f:
|
|
continue
|
|
|
|
filters.append(f)
|
|
|
|
return ";;".join(filters)
|
|
|
|
# Retrieves the last used filter for raster files
|
|
# Note: filter string is in a list
|
|
@classmethod
|
|
def lastUsedRasterFilter(self):
|
|
return [self.getFilter("lastRaster")]
|
|
|
|
@classmethod
|
|
def setLastUsedRasterFilter(self, aFilter):
|
|
self.setFilter("lastRaster", aFilter[0])
|
|
|
|
# stores the supported vectors file filter
|
|
vectorsFilter = ''
|
|
|
|
# Retrieves the filter for supported vector files
|
|
@classmethod
|
|
def allVectorsFilter(self):
|
|
if self.vectorsFilter == '':
|
|
self.vectorsFilter = QgsProviderRegistry.instance().fileVectorFilters()
|
|
return self.vectorsFilter
|
|
|
|
# Retrieves the last used filter for vector files
|
|
# Note: filter string is in a list
|
|
@classmethod
|
|
def lastUsedVectorFilter(self):
|
|
return [self.getFilter("lastVector")]
|
|
|
|
@classmethod
|
|
def setLastUsedVectorFilter(self, aFilter):
|
|
self.setFilter("lastVector", aFilter[0])
|
|
|
|
# Retrieves the extensions list from a filter string
|
|
@classmethod
|
|
def getFilterExtensions(self, aFilter):
|
|
extList = []
|
|
# foreach format in filter string
|
|
for f in aFilter.split(";;"):
|
|
# gets the list of extensions from the filter
|
|
exts = re.sub('\).*$', '', re.sub('^.*\(', '', f))
|
|
# if there is no extensions or the filter matches all, then return an empty list
|
|
# otherwise return the list of estensions
|
|
if exts != '' and exts != "*" and exts != "*.*":
|
|
extList.extend(exts.split(" "))
|
|
return extList
|
|
|
|
@classmethod
|
|
def getFilterName(self, aFilter):
|
|
if isinstance(aFilter, list):
|
|
if len(aFilter):
|
|
aFilter = aFilter[0]
|
|
else:
|
|
aFilter = ""
|
|
return string.strip(re.sub('\ \(.*$', '', aFilter))
|
|
|
|
@classmethod
|
|
def filenameMatchesFilterExt(self, fileName, ext):
|
|
return re.match('.' + str(ext), fileName) is not None
|
|
|
|
# Retrieves gdal information
|
|
|
|
|
|
class GdalConfig(object):
|
|
# retrieves and return the installed gdal version
|
|
|
|
@classmethod
|
|
def version(self):
|
|
return Version(gdal.VersionInfo("RELEASE_NAME"))
|
|
|
|
@classmethod
|
|
def versionNum(self):
|
|
return int(gdal.VersionInfo("VERSION_NUM"))
|
|
|
|
# store the supported rasters info
|
|
supportedRasters = None
|
|
|
|
# retrieve the supported rasters info
|
|
@classmethod
|
|
def getSupportedRasters(self):
|
|
if self.supportedRasters is not 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 is None:
|
|
QgsLogger.warning("unable to get driver " + str(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 = string.strip(re.sub('\(.*$', '', driver.LongName))
|
|
shortName = string.strip(re.sub('\(.*$', '', driver.ShortName))
|
|
extensions = ''
|
|
|
|
description = driver.GetDescription()
|
|
glob = []
|
|
|
|
metadata = driver.GetMetadata()
|
|
if gdal.DMD_EXTENSION in metadata:
|
|
extensions = str(metadata[gdal.DMD_EXTENSION])
|
|
|
|
if longName != '':
|
|
if extensions != '':
|
|
# XXX add check for SDTS; in that case we want (*CATD.DDF)
|
|
|
|
#TODO fix and test
|
|
#glob.append( QString("*." + extensions.replace("/", " *.")).split(" "))
|
|
glob.append(string.split("*." + string.replace(extensions, "/", " *."), sep=(" ")))
|
|
|
|
# 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 is not None:
|
|
continue # skip if already found a JP2 driver
|
|
jp2Driver = driver # first JP2 driver found
|
|
glob.append("*.j2k") # add alternate extension
|
|
elif description == "GTiff":
|
|
glob.append("*.tiff")
|
|
elif description == "JPEG":
|
|
glob.append("*.jpeg")
|
|
else:
|
|
# USGS DEMs use "*.dem"
|
|
if description.startswith("USGSDEM"):
|
|
glob.append("*.dem")
|
|
elif description.startswith("DTED"):
|
|
# DTED use "*.dt0"
|
|
glob.append("*.dt0")
|
|
elif description.startswith("MrSID"):
|
|
# MrSID use "*.sid"
|
|
glob.append("*.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 is not 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 is None:
|
|
QgsLogger.warning("unable to get driver " + str(i))
|
|
continue
|
|
|
|
driverName = driver.GetName()
|
|
longName = ''
|
|
glob = []
|
|
|
|
if driverName.startswith("AVCBin"):
|
|
pass # myDirectoryDrivers += "Arc/Info Binary Coverage,AVCBin"
|
|
elif driverName.startswith("AVCE00"):
|
|
longName = "Arc/Info ASCII Coverage"
|
|
glob.append("*.e00")
|
|
elif driverName.startswith("BNA"):
|
|
longName = "Atlas BNA"
|
|
glob.append("*.bna")
|
|
elif driverName.startswith("CSV"):
|
|
longName = "Comma Separated Value"
|
|
glob.append("*.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.append("*.mdb")
|
|
elif driverName.startswith("SDE"):
|
|
pass # myDatabaseDrivers += "ESRI ArcSDE,SDE"
|
|
elif driverName.startswith("ESRI"):
|
|
longName = "ESRI Shapefiles"
|
|
glob.append("*.shp")
|
|
elif driverName.startswith("FMEObjects Gateway"):
|
|
longName = "FMEObjects Gateway"
|
|
glob.append("*.fdd")
|
|
elif driverName.startswith("GeoJSON"):
|
|
pass # myProtocolDrivers += "GeoJSON,GeoJSON"
|
|
longName = "GeoJSON"
|
|
glob.append("*.geojson")
|
|
elif driverName.startswith("GeoRSS"):
|
|
longName = "GeoRSS"
|
|
glob.append("*.xml")
|
|
elif driverName.startswith("GML"):
|
|
longName = "Geography Markup Language"
|
|
glob.append("*.gml")
|
|
elif driverName.startswith("GMT"):
|
|
longName = "GMT"
|
|
glob.append("*.gmt")
|
|
elif driverName.startswith("GPX"):
|
|
longName = "GPX"
|
|
glob.append("*.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.append("*.itf")
|
|
glob.append("*.xml")
|
|
glob.append("*.ili")
|
|
elif driverName.startswith("Interlis 2"):
|
|
longName = "INTERLIS 2"
|
|
glob.append("*.itf")
|
|
glob.append("*.xml")
|
|
glob.append("*.ili")
|
|
elif driverName.startswith("INGRES"):
|
|
pass # myDatabaseDrivers += "INGRES,INGRES"
|
|
elif driverName.startswith("KML"):
|
|
longName = "KML"
|
|
glob.append("*.kml")
|
|
elif driverName.startswith("MapInfo File"):
|
|
longName = "Mapinfo File"
|
|
glob.append("*.mif")
|
|
glob.append("*.tab")
|
|
elif driverName.startswith("DGN"):
|
|
longName = "Microstation DGN"
|
|
glob.append("*.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.append("*.000")
|
|
elif driverName.startswith("SDTS"):
|
|
longName = "Spatial Data Transfer Standard"
|
|
glob.append("*catd.ddf")
|
|
elif driverName.startswith("SQLite"):
|
|
longName = "SQLite"
|
|
glob.append("*.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.append("*.vrt")
|
|
elif driverName.startswith("XPlane"):
|
|
longName = "X-Plane/Flighgear"
|
|
glob.append("apt.dat")
|
|
glob.append("nav.dat")
|
|
glob.append("fix.dat")
|
|
glob.append("awy.dat")
|
|
|
|
longName = string.strip(longName)
|
|
|
|
if longName == '':
|
|
continue
|
|
|
|
self.supportedVectors[longName] = {'EXTENSIONS': glob, 'LONGNAME': longName, 'SHORTNAME': driverName}
|
|
|
|
return self.supportedVectors
|
|
|
|
class SupportedRasters(object):
|
|
dict_long2shortName = dict()
|
|
|
|
# retrieve the raster format short name by long format name
|
|
@classmethod
|
|
def long2ShortName(self, longName):
|
|
if longName == '':
|
|
return ''
|
|
|
|
if longName in self.dict_long2shortName:
|
|
return self.dict_long2shortName[longName]
|
|
|
|
# first get the GDAL driver manager
|
|
if gdal.GetDriverCount() == 0:
|
|
gdal.AllRegister()
|
|
|
|
shortName = ''
|
|
|
|
# for each loaded GDAL driver
|
|
for i in range(gdal.GetDriverCount()):
|
|
driver = gdal.GetDriver(i)
|
|
if driver is 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 == '':
|
|
return ''
|
|
|
|
shortName = ''
|
|
|
|
# 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 == '':
|
|
break
|
|
|
|
return shortName
|
|
|
|
# class which allows creating version objects and compare them
|
|
|
|
|
|
class Version(object):
|
|
|
|
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 = list(map(str, ver))
|
|
elif isinstance(ver, str):
|
|
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(),
|
|
"GDAL_FILENAME_IS_UTF8": "NO"
|
|
}
|
|
|
|
sep = os.pathsep
|
|
|
|
for name, val in envvar_list.items():
|
|
if val is None or val == "":
|
|
continue
|
|
|
|
envval = os.getenv(name)
|
|
if envval is None or envval == "":
|
|
envval = str(val)
|
|
elif (platform.system() == "Windows" and val.lower() not in envval.lower().split(sep)) or \
|
|
(platform.system() != "Windows" and val not in envval.split(sep)):
|
|
envval += "%s%s" % (sep, str(val))
|
|
else:
|
|
envval = None
|
|
|
|
if envval is not None:
|
|
os.putenv(name, envval)
|
|
|
|
|
|
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_versionsplit = str(GdalConfig.version()).split('.')
|
|
gdal_base_path = u"/Library/Frameworks/GDAL.framework/Versions/%s.%s" % (gdal_versionsplit[0], gdal_versionsplit[1])
|
|
|
|
if os.path.exists(qgis_standalone_gdal_path): # qgis standalone
|
|
# GDAL executables are in the Qgis bin folder
|
|
if getGdalBinPath() == '':
|
|
setGdalBinPath(qgis_bin)
|
|
# GDAL pymods are in the Qgis python folder
|
|
if getGdalPymodPath() == '':
|
|
setGdalPymodPath(qgis_python)
|
|
# GDAL help is in the framework folder
|
|
if getHelpPath() == '':
|
|
setHelpPath(u"%s/Resources/doc" % qgis_standalone_gdal_path)
|
|
|
|
elif os.path.exists(gdal_base_path):
|
|
# all GDAL parts are in the GDAL framework folder
|
|
if getGdalBinPath() == '':
|
|
setGdalBinPath(u"%s/Programs" % gdal_base_path)
|
|
if getGdalPymodPath() == '':
|
|
setGdalPymodPath(u"%s/Python/%s.%s/site-packages" % (gdal_base_path, sys.version_info[0], sys.version_info[1]))
|
|
if getHelpPath() == '':
|
|
setHelpPath(u"%s/Resources/doc" % gdal_base_path)
|
|
|
|
|
|
# setup the MacOSX path to both GDAL executables and python modules
|
|
if platform.system() == "Darwin":
|
|
setMacOSXDefaultEnvironment()
|