diff --git a/python/plugins/processing/algs/gdal/GdalOgrAlgorithmProvider.py b/python/plugins/processing/algs/gdal/GdalOgrAlgorithmProvider.py index 202dacf0ccf..d35271f7ae1 100644 --- a/python/plugins/processing/algs/gdal/GdalOgrAlgorithmProvider.py +++ b/python/plugins/processing/algs/gdal/GdalOgrAlgorithmProvider.py @@ -67,6 +67,8 @@ from GridDataMetrics import GridDataMetrics from gdaltindex import gdaltindex from gdalcalc import gdalcalc from rasterize_over import rasterize_over +from retile import retile +from gdal2tiles import gdal2tiles from ogr2ogr import Ogr2Ogr from ogr2ogrclip import Ogr2OgrClip @@ -137,6 +139,7 @@ class GdalOgrAlgorithmProvider(AlgorithmProvider): hillshade(), slope(), aspect(), tri(), tpi(), roughness(), ColorRelief(), GridInvDist(), GridAverage(), GridNearest(), GridDataMetrics(), gdaltindex(), gdalcalc(), rasterize_over(), + retile(), gdal2tiles(), # ----- OGR tools ----- OgrInfo(), Ogr2Ogr(), Ogr2OgrClip(), Ogr2OgrClipExtent(), Ogr2OgrToPostGis(), Ogr2OgrToPostGisList(), Ogr2OgrPointsOnLines(), diff --git a/python/plugins/processing/algs/gdal/gdal2tiles.py b/python/plugins/processing/algs/gdal/gdal2tiles.py new file mode 100644 index 00000000000..47c4174dce5 --- /dev/null +++ b/python/plugins/processing/algs/gdal/gdal2tiles.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- + +""" +*************************************************************************** + gdal2tiles.py + --------------------- + Date : January 2016 + Copyright : (C) 2016 by Médéric Ribreux + Email : mederic dot ribreux at medspx dot fr +*************************************************************************** +* * +* 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. * +* * +*************************************************************************** +""" + +__author__ = 'Médéric Ribreux' +__date__ = 'January 2016' +__copyright__ = '(C) 2016, Médéric Ribreux' + +# This will get replaced with a git SHA1 when you do a git archive + +__revision__ = '$Format:%H$' + +from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm +from processing.core.parameters import ParameterRaster +from processing.core.parameters import ParameterString +from processing.core.parameters import ParameterSelection +from processing.core.parameters import ParameterCrs +from processing.core.parameters import ParameterBoolean +from processing.core.outputs import OutputDirectory +from processing.tools.system import isWindows +from processing.algs.gdal.GdalUtils import GdalUtils + + +class gdal2tiles(GdalAlgorithm): + + INPUT = 'INPUT' + PROFILE = 'PROFILE' + RESAMPLING = 'RESAMPLING' + ZOOM = 'ZOOM' + S_SRS = 'S_SRS' + OUTPUTDIR = 'OUTPUTDIR' + RESUME = 'RESUME' + NODATA = 'NODATA' + FORCEKML = 'FORCEKML' + NOKML = 'NOKML' + URL = 'URL' + WEBVIEWER = 'WEBVIEWER' + TITLE = 'TITLE' + COPYRIGHT = 'COPYRIGHT' + GOOGLEKEY = 'GOOGLEKEY' + BINGKEY = 'BINGKEY' + + PROFILES = ['mercator', 'geodetic', 'raster'] + RESAMPLINGS = ['average', 'near', 'bilinear', 'cubic', 'cubicspline', 'lanczos', 'antialias'] + WEBVIEWERS = ['all', 'google', 'openlayers', 'leaflet', 'none'] + + def commandLineName(self): + return "gdalogr:gdal2tiles" + + def defineCharacteristics(self): + self.name, self.i18n_name = self.trAlgorithm('gdal2tiles') + self.group, self.i18n_group = self.trAlgorithm('[GDAL] Miscellaneous') + + # Required parameters + self.addParameter(ParameterRaster(self.INPUT, self.tr('Input layer'))) + + # Advanced parameters + params = [] + params.append(ParameterSelection(self.PROFILE, + self.tr('Tile cutting profile'), + self.PROFILES, 0, False, True)) + params.append(ParameterSelection(self.RESAMPLING, + self.tr('Resampling method'), + self.RESAMPLINGS, 0, False, True)) + params.append(ParameterCrs(self.S_SRS, + self.tr('The spatial reference system used for the source input data'), + None, True)) + params.append(ParameterString(self.ZOOM, + self.tr('Zoom levels to render'), + None, False, True)) + params.append(ParameterBoolean(self.RESUME, + self.tr('Resume mode, generate only missing files'), + False, True)) + params.append(ParameterString(self.NODATA, + self.tr('NODATA transparency value to assign to the input data'), + None, False, True)) + params.append(ParameterBoolean(self.FORCEKML, + self.tr('Generate KML for Google Earth - default for "geodetic" profile and "raster" in EPSG:4326'), + False, True)) + params.append(ParameterBoolean(self.NOKML, + self.tr('Avoid automatic generation of KML files for EPSG:4326'), + False, True)) + params.append(ParameterString(self.URL, + self.tr('URL address where the generated tiles are going to be published'), + None, False, True)) + params.append(ParameterSelection(self.WEBVIEWER, + self.tr('Web viewer to generate'), + self.WEBVIEWERS, 0, False, True)) + params.append(ParameterString(self.TITLE, + self.tr('Title of the map'), + None, False, True)) + params.append(ParameterString(self.COPYRIGHT, + self.tr('Copyright for the map'), + None, False, True)) + params.append(ParameterString(self.GOOGLEKEY, + self.tr('Google Maps API key from http://code.google.com/apis/maps/signup.html'), + None, False, True)) + params.append(ParameterString(self.BINGKEY, + self.tr('Bing Maps API key from https://www.bingmapsportal.com/'), + None, False, True)) + + for param in params: + param.isAdvanced = True + self.addParameter(param) + + self.addOutput(OutputDirectory(self.OUTPUTDIR, + self.tr('The directory where the tile result is created'))) + + def getConsoleCommands(self): + + arguments = [] + + if self.getParameterValue(self.PROFILE): + arguments.append('-p') + arguments.append(self.PROFILES[self.getParameterValue(self.PROFILE)]) + + if self.getParameterValue(self.RESAMPLING): + arguments.append('-r') + arguments.append(self.RESAMPLINGS[self.getParameterValue(self.RESAMPLING)]) + + ssrs = unicode(self.getParameterValue(self.S_SRS)) + if len(ssrs) > 0: + arguments.append('-s') + arguments.append(ssrs) + + if self.getParameterValue(self.ZOOM): + arguments.append('-z') + arguments.append(unicode(self.getParameterValue(self.ZOOM))) + + if self.getParameterValue(self.RESUME): + arguments.append('-e') + + if self.getParameterValue(self.NODATA): + arguments.append('-a') + arguments.append(unicode(self.getParameterValue(self.NODATA))) + + # KML arguments + if self.getParameterValue(self.FORCEKML): + arguments.append('-k') + + if self.getParameterValue(self.NOKML): + arguments.append('-n') + + if self.getParameterValue(self.URL): + arguments.append('-u') + arguments.append(unicode(self.getParameterValue(self.URL))) + + # Web viewer arguments + if self.getParameterValue(self.WEBVIEWER): + arguments.append('-w') + arguments.append(self.WEBVIEWERS[self.getParameterValue(self.WEBVIEWER)]) + + parameters = {self.TITLE: '-t', self.COPYRIGHT: '-c', + self.GOOGLEKEY: '-g', self.BINGKEY: '-b'} + for arg, parameter in parameters.iteritems(): + if self.getParameterValue(arg): + arguments.append(parameter) + arguments.append(self.getParameterValue(arg)) + + arguments.append(self.getParameterValue(self.INPUT)) + arguments.append(self.getOutputValue(self.OUTPUTDIR)) + + commands = [] + if isWindows(): + commands = ['cmd.exe', '/C ', 'gdal2tiles.bat', + GdalUtils.escapeAndJoin(arguments)] + else: + commands = ['gdal2tiles.py', + GdalUtils.escapeAndJoin(arguments)] + + return commands diff --git a/python/plugins/processing/algs/gdal/retile.py b/python/plugins/processing/algs/gdal/retile.py new file mode 100644 index 00000000000..53bec04819c --- /dev/null +++ b/python/plugins/processing/algs/gdal/retile.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- + +""" +*************************************************************************** + retile.py + --------------------- + Date : January 2016 + Copyright : (C) 2016 by Médéric Ribreux + Email : mederic dot ribreux at medspx dot fr +*************************************************************************** +* * +* 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. * +* * +*************************************************************************** +""" + +__author__ = 'Médéric Ribreux' +__date__ = 'January 2016' +__copyright__ = '(C) 2016, Médéric Ribreux' + +# This will get replaced with a git SHA1 when you do a git archive + +__revision__ = '$Format:%H$' + +from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm +from processing.core.parameters import ParameterString +from processing.core.parameters import ParameterSelection +from processing.core.parameters import ParameterNumber +from processing.core.parameters import ParameterMultipleInput +from processing.core.parameters import ParameterCrs +from processing.core.parameters import ParameterBoolean +from processing.core.outputs import OutputDirectory +from processing.tools.system import isWindows +from processing.algs.gdal.GdalUtils import GdalUtils +import re + + +class retile(GdalAlgorithm): + + INPUT = 'INPUT' + RTYPE = 'RTYPE' + ONLYPYRAMIDS = 'ONLYPYRAMIDS' + PYRAMIDLEVELS = 'PYRAMIDLEVELS' + PIXELSIZE = 'PIXELSIZE' + ALGORITHM = 'ALGORITHM' + USEDIRFOREACHROW = 'USEDIRFOREACHROW' + S_SRS = 'S_SRS' + TARGETDIR = 'TARGETDIR' + CSVFILE = 'CSVFILE' + CSVDELIM = 'CSVDELIM' + TILEINDEX = 'TILEINDEX' + TILEINDEXFIELD = 'TILEINDEXFIELD' + FORMAT = 'FORMAT' + + TYPE = ['Byte', 'Int16', 'UInt16', 'UInt32', 'Int32', 'Float32', 'Float64'] + ALGO = ['near', 'bilinear', 'cubic', 'cubicspline', 'lanczos'] + + def commandLineName(self): + return "gdalogr:retile" + + def commandName(self): + return "gdal_retile" + + def defineCharacteristics(self): + self.name, self.i18n_name = self.trAlgorithm('Retile') + self.group, self.i18n_group = self.trAlgorithm('[GDAL] Miscellaneous') + + # Required parameters + self.addParameter(ParameterMultipleInput(self.INPUT, + self.tr('Input layers'), + ParameterMultipleInput.TYPE_RASTER)) + # Advanced parameters + params = [] + params.append(ParameterString(self.PIXELSIZE, + self.tr('Pixel size to be used for the output file (XSIZE YSIZE like 512 512)'), + None, False, True)) + params.append(ParameterSelection(self.ALGORITHM, + self.tr('Resampling algorithm'), self.ALGO, 0, False, True)) + params.append(ParameterCrs(self.S_SRS, + self.tr('Override source CRS'), None, True)) + params.append(ParameterNumber(self.PYRAMIDLEVELS, + self.tr('Number of pyramids levels to build'), + None, None, None, True)) + params.append(ParameterBoolean(self.ONLYPYRAMIDS, + self.tr('Build only the pyramids'), + False, True)) + params.append(ParameterSelection(self.RTYPE, + self.tr('Output raster type'), + self.TYPE, 5, False, True)) + params.append(ParameterSelection(self.FORMAT, + self.tr('Output raster format'), + GdalUtils.getSupportedRasters().keys(), 0, False, True)) + params.append(ParameterBoolean(self.USEDIRFOREACHROW, + self.tr('Use a directory for each row'), + False, True)) + params.append(ParameterString(self.CSVFILE, + self.tr('Name of the csv file containing the tile(s) georeferencing information'), + None, False, True)) + params.append(ParameterString(self.CSVDELIM, + self.tr('Column delimiter used in the CSV file'), + None, False, True)) + params.append(ParameterString(self.TILEINDEX, + self.tr('name of shape file containing the result tile(s) index'), + None, False, True)) + params.append(ParameterString(self.TILEINDEXFIELD, + self.tr('name of the attribute containing the tile name in the result shape file'), + None, False, True)) + + for param in params: + param.isAdvanced = True + self.addParameter(param) + + self.addOutput(OutputDirectory(self.TARGETDIR, + self.tr('The directory where the tile result is created'))) + + def getConsoleCommands(self): + + arguments = [] + + if self.getParameterValue(self.RTYPE): + arguments.append('-ot') + arguments.append(self.TYPE[self.getParameterValue(self.RTYPE)]) + + arguments.append('-of') + arguments.append(GdalUtils.getSupportedRasters().keys()[self.getParameterValue(self.FORMAT)]) + + if self.getParameterValue(self.PIXELSIZE): + pixelSize = self.getParameterValue(self.PIXELSIZE) + if re.match(r'\d+ \d+', pixelSize): + xsize, ysize = pixelSize.split(' ') + arguments.append('-ps') + arguments.append(xsize) + arguments.append(ysize) + + if self.getParameterValue(self.ONLYPYRAMIDS): + arguments.append('-pyramidOnly') + + if self.getParameterValue(self.USEDIRFOREACHROW): + arguments.append('-useDirForEachRow') + + ssrs = unicode(self.getParameterValue(self.S_SRS)) + if len(ssrs) > 0: + arguments.append('-s_srs') + arguments.append(ssrs) + + if self.getParameterValue(self.PYRAMIDLEVELS): + arguments.append('-levels') + arguments.append(unicode(self.getParameterValue(self.PYRAMIDLEVELS))) + + arguments.append('-r') + arguments.append(self.ALGO[self.getParameterValue(self.ALGORITHM)]) + + # Handle CSV + if self.getParameterValue(self.CSVFILE): + arguments.append('-csv') + arguments.append(self.getParameterValue(self.CSVFILE)) + + if self.getParameterValue(self.CSVFILE) and self.getParameterValue(self.CSVDELIM): + arguments.append('-csvDelim') + arguments.append(self.getParameterValue(self.CSVDELIM)) + + # Handle Shp + if self.getParameterValue(self.TILEINDEX): + arguments.append('-tileIndex') + arguments.append(self.getParameterValue(self.TILEINDEX)) + + if self.getParameterValue(self.TILEINDEX) and self.getParameterValue(self.TILEINDEXFIELD): + arguments.append('-tileIndexField') + arguments.append(self.getParameterValue(self.TILEINDEXFIELD)) + + arguments.append('-targetDir') + arguments.append(self.getOutputValue(self.TARGETDIR)) + + arguments.extend(self.getParameterValue(self.INPUT).split(';')) + + commands = [] + if isWindows(): + commands = ['cmd.exe', '/C ', 'gdal_retile.bat', + GdalUtils.escapeAndJoin(arguments)] + else: + commands = ['gdal_retile.py', + GdalUtils.escapeAndJoin(arguments)] + + return commands