Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
marioba committed Aug 8, 2017
1 parent bbfdcf3 commit baede35
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 35 deletions.
123 changes: 88 additions & 35 deletions python/plugins/processing/algs/qgis/Rasterize.py
Expand Up @@ -35,7 +35,7 @@
QgsProcessingParameterString,
QgsProcessingParameterNumber,
QgsProcessingParameterRasterLayer,
QgsProcessingOutputRasterLayer,
QgsProcessingParameterMapLayer,
QgsProcessingParameterRasterDestination
)

Expand Down Expand Up @@ -70,7 +70,7 @@ class RasterizeAlgorithm(QgisAlgorithm):
# used when calling the algorithm from another algorithm, or when
# calling from the QGIS console.

OUTPUT_LAYER = 'OUTPUT_LAYER'
OUTPUT = 'OUTPUT'
MAP_THEME = 'MAP_THEME'
LAYER = 'LAYER'
EXTENT = 'EXTENT'
Expand All @@ -84,38 +84,54 @@ def initAlgorithm(self, config=None):
"""Here we define the inputs and output of the algorithm, along
with some other properties.
"""

# The parameters
self.addParameter(
QgsProcessingParameterString(self.MAP_THEME,
description=self.tr(
'Map theme to render.'),
defaultValue=None, optional=True))
map_theme_param = QgsProcessingParameterString(
self.MAP_THEME,
description=self.tr(
'Map theme to render.'),
defaultValue=None, optional=True)

map_theme_param.setMetadata(
{'widget_wrapper': {
'class':
'processing.gui.wrappers_map_theme.MapThemeWrapper'}})
self.addParameter(map_theme_param)

self.addParameter(
QgsProcessingParameterRasterLayer(self.LAYER, description=self.tr(
'Layer to render. Will only be used if the map theme is not '
'set. '
'If both, map theme and layer are not '
'set, the current map content will be rendered.'),
# TODO Why is this restricted to raster layers only? I think
# QgsProcessingParameterMapLayer makes more sense here so that
# users can choose to render single vector layers if desired.
QgsProcessingParameterRasterLayer(
self.LAYER,
description=self.tr(
'Layer to render. Will only be used if the map theme '
'is not set. '
'If both, map theme and layer are not '
'set, the current map content will be rendered.'),
optional=True))
self.addParameter(
QgsProcessingParameterExtent(self.EXTENT, description=self.tr(
'The minimum extent to render. Will internally be extended to '
'be '
'a multiple of the tile sizes.')))
'be a multiple of the tile sizes.')))
self.addParameter(
QgsProcessingParameterNumber(self.TILE_SIZE, self.tr('Tile size'),
defaultValue=1024))
self.addParameter(QgsProcessingParameterNumber(self.MAP_UNITS_PER_PIXEL,
self.tr(
'Map units per '
'pixel'),
defaultValue=100))
QgsProcessingParameterNumber(
self.TILE_SIZE,
self.tr('Tile size'),
defaultValue=1024))

self.addParameter(QgsProcessingParameterNumber(
self.MAP_UNITS_PER_PIXEL,
self.tr(
'Map units per '
'pixel'),
defaultValue=100,
minValue=0,
type=QgsProcessingParameterNumber.Double
))

# We add a raster layer as output
self.addParameter(QgsProcessingParameterRasterDestination(
self.OUTPUT_LAYER,
self.OUTPUT,
self.tr(
'Output layer')))

Expand All @@ -130,30 +146,64 @@ def displayName(self):
def group(self):
return self.tr('Raster tools')

def tags(self):
return self.tr('layer,raster,convert,file,map themes,tiles').split(',')

# def processAlgorithm(self, progress):
def processAlgorithm(self, parameters, context, feedback):
"""Here is where the processing itself takes place."""

# The first thing to do is retrieve the values of the parameters
# entered by the user
map_theme = self.parameterAsString(parameters, self.MAP_THEME, context)
layer = self.parameterAsString(parameters, self.LAYER, context)
extent = self.parameterAsExtent(parameters, self.EXTENT,
context)
tile_size = self.parameterAsInt(parameters, self.TILE_SIZE, context)
mupp = self.parameterAsInt(parameters, self.MAP_UNITS_PER_PIXEL, context)

output_layer = self.parameterAsOutputLayer(parameters, self.OUTPUT_LAYER,
context)
map_theme = self.parameterAsString(
parameters,
self.MAP_THEME,
context)

layer = self.parameterAsLayer(
parameters,
self.LAYER,
context)

extent = self.parameterAsExtent(
parameters,
self.EXTENT,
context)

tile_size = self.parameterAsInt(
parameters,
self.TILE_SIZE,
context)

mupp = self.parameterAsDouble(
parameters,
self.MAP_UNITS_PER_PIXEL,
context)

output_layer = self.parameterAsOutputLayer(
parameters,
self.OUTPUT,
context)

print('map_theme {}'.format(map_theme))
print('layer {}'.format(layer))
print('extent {}'.format(extent))
print('tile_size {}'.format(tile_size))
print('mupp {}'.format(mupp))
print('output_layer {}'.format(output_layer))

# This probably affects the whole system but it's a lot nicer
osgeo.gdal.UseExceptions()

tile_set = TileSet(map_theme, layer, extent, tile_size, mupp, output_layer,
tile_set = TileSet(map_theme, layer, extent, tile_size, mupp,
output_layer,
qgis.utils.iface.mapCanvas().mapSettings())
# TODO Can you add feedback as a parameter to render and add
# appropriate hooks within render to check for feedback.isCanceled()
# and abort the render early?
tile_set.render()

return {self.OUTPUT_LAYER: output_layer}
return {self.OUTPUT: output_layer}


class TileSet():
Expand Down Expand Up @@ -268,14 +318,17 @@ def renderTile(self, x, y):

def getDriverForFile(self, filename):
"""
Get the GDAL driver for a filename, based on its extension. (.gpkg, .mbtiles...)
Get the GDAL driver for a filename, based on its extension. (.gpkg,
.mbtiles...)
"""
_, extension = os.path.splitext(filename)

# If no extension is set, use .tif as default
if extension == '':
extension = '.tif'

# TODO It should be removed and
# QgsRasterFileWriter::driverForExtension used instead.
for i in range(osgeo.gdal.GetDriverCount()):
driver = osgeo.gdal.GetDriver(i)
if driver.GetMetadataItem('DMD_EXTENSION') == extension[1:]:
Expand Down
7 changes: 7 additions & 0 deletions python/plugins/processing/gui/wrappers.py
Expand Up @@ -754,6 +754,11 @@ def value(self):
return self.widget.currentData()


class LayerWidgetWrapper(WidgetWrapper):
def __init__(self):
raise NotImplementedError('Layer widget is not implemented yet')


class VectorWidgetWrapper(WidgetWrapper):

NOT_SELECTED = '[Not selected]'
Expand Down Expand Up @@ -1388,6 +1393,8 @@ def create_wrapper_from_class(param, dialog, row=0, col=0):
wrapper = VectorWidgetWrapper
elif param.type() == 'band':
wrapper = BandWidgetWrapper
elif param.type() == 'layer':
wrapper = LayerWidgetWrapper
else:
assert False, param.type()
return wrapper(param, dialog, row, col)
72 changes: 72 additions & 0 deletions python/plugins/processing/gui/wrappers_map_theme.py
@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
wrappers_map_theme.py - Map theme widget wrappers
---------------------
Date : August 2017
Copyright : (C) 2017 by OPENGIS.ch
Email : mario@opengis.ch
***************************************************************************
* *
* 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 qgis.core import (QgsSettings,
QgsProcessingParameterNumber,
QgsProcessingParameterFile,
QgsProcessingParameterField,
QgsProcessingParameterExpression,
QgsProcessingOutputString,
QgsProcessingParameterString,
QgsMapThemeCollection,
QgsProject
)

from qgis.PyQt.QtWidgets import QComboBox
from qgis.PyQt.QtCore import pyqtSignal

from processing.gui.wrappers import (
BasicWidgetWrapper
)
from processing.tools.postgis import GeoDB


class MapThemeWrapper(BasicWidgetWrapper):
"""
WidgetWrapper for ParameterString that create and manage a combobox widget
with existing postgis connections.
"""

def createWidget(self):
self._combo = QComboBox()
for item in self.items():
self._combo.addItem(item, item)
self._combo.currentIndexChanged.connect(lambda:
self.widgetValueHasChanged.emit(self))
return self._combo

def items(self):
items = QgsProject.instance().mapThemeCollection().mapThemes()
#if self.dialogType == DIALOG_MODELER:
# strings = self.dialog.getAvailableValuesOfType(
# [QgsProcessingParameterString, QgsProcessingParameterNumber,
# QgsProcessingParameterFile,
# QgsProcessingParameterField,
# QgsProcessingParameterExpression], QgsProcessingOutputString)
# items = items + [(self.dialog.resolveValueDescription(s),
# s) for s in strings]
#
return items

def setValue(self, value):
self.setComboValue(value, self._combo)

def value(self):
return self.comboValue(combobox=self._combo)

0 comments on commit baede35

Please sign in to comment.