2014-04-19 15:53:43 +02:00
# -*- coding: utf-8 -*-
"""
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Grass7Algorithm . py
- - - - - - - - - - - - - - - - - - - - -
2015-02-07 21:53:30 +01:00
Date : February 2015
Copyright : ( C ) 2014 - 2015 by Victor Olaya
2014-04-19 15:53:43 +02:00
Email : volayaf 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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
"""
__author__ = ' Victor Olaya '
2015-02-07 21:53:30 +01:00
__date__ = ' February 2015 '
__copyright__ = ' (C) 2012-2015, Victor Olaya '
2014-04-19 15:53:43 +02:00
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = ' $Format: % H$ '
2017-09-03 17:42:13 +02:00
import sys
2014-04-19 15:53:43 +02:00
import os
2017-12-14 11:21:01 +02:00
import re
2014-04-19 15:53:43 +02:00
import uuid
import importlib
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
2016-04-22 10:38:48 +02:00
from qgis . PyQt . QtCore import QCoreApplication , QUrl
2015-07-26 03:48:27 +02:00
2018-02-05 22:11:34 -04:00
from qgis . core import ( Qgis ,
QgsRasterLayer ,
2017-04-24 14:35:50 +10:00
QgsApplication ,
2017-09-07 18:47:37 +02:00
QgsMapLayer ,
2017-04-24 14:35:50 +10:00
QgsProcessingUtils ,
2017-10-22 10:25:09 +02:00
QgsProcessing ,
2017-05-16 15:21:41 +10:00
QgsMessageLog ,
2017-09-06 14:15:24 +02:00
QgsVectorFileWriter ,
2017-05-16 16:36:00 +10:00
QgsProcessingAlgorithm ,
2017-09-01 17:53:33 +02:00
QgsProcessingParameterDefinition ,
QgsProcessingException ,
QgsProcessingParameterExtent ,
2017-09-04 16:31:31 +02:00
QgsProcessingParameterEnum ,
2017-09-03 17:42:13 +02:00
QgsProcessingParameterNumber ,
QgsProcessingParameterString ,
2017-10-22 10:25:09 +02:00
QgsProcessingParameterField ,
2017-09-03 17:42:13 +02:00
QgsProcessingParameterPoint ,
QgsProcessingParameterBoolean ,
QgsProcessingParameterVectorLayer ,
QgsProcessingParameterRasterLayer ,
QgsProcessingParameterMultipleLayers ,
2017-09-04 16:31:31 +02:00
QgsProcessingParameterVectorDestination ,
QgsProcessingParameterRasterDestination ,
2017-09-06 14:15:24 +02:00
QgsProcessingParameterFileDestination ,
2017-12-27 20:13:05 +01:00
QgsProcessingParameterFile ,
2017-10-25 21:29:28 +02:00
QgsProcessingParameterFolderDestination ,
QgsProcessingOutputFolder ,
2017-09-03 17:42:13 +02:00
QgsProcessingOutputVectorLayer ,
QgsProcessingOutputRasterLayer ,
2017-09-11 18:19:56 +02:00
QgsProcessingOutputHtml ,
QgsProcessingUtils )
2014-05-20 16:30:59 +02:00
from qgis . utils import iface
2014-04-19 15:53:43 +02:00
from processing . core . ProcessingConfig import ProcessingConfig
2017-09-03 17:42:13 +02:00
from processing . core . parameters import ( getParameterFromString )
2014-04-19 15:53:43 +02:00
2016-03-21 04:58:12 +01:00
from . Grass7Utils import Grass7Utils
2014-04-19 15:53:43 +02:00
2017-09-11 18:19:56 +02:00
#from processing.tools import dataobjects, system
from processing . tools . system import isWindows , getTempFilename
2014-04-19 15:53:43 +02:00
2015-05-18 19:51:26 +03:00
pluginPath = os . path . normpath ( os . path . join (
os . path . split ( os . path . dirname ( __file__ ) ) [ 0 ] , os . pardir ) )
2014-04-19 15:53:43 +02:00
2017-09-01 17:53:33 +02:00
class Grass7Algorithm ( QgsProcessingAlgorithm ) :
2014-04-19 15:53:43 +02:00
GRASS_OUTPUT_TYPE_PARAMETER = ' GRASS_OUTPUT_TYPE_PARAMETER '
GRASS_MIN_AREA_PARAMETER = ' GRASS_MIN_AREA_PARAMETER '
GRASS_SNAP_TOLERANCE_PARAMETER = ' GRASS_SNAP_TOLERANCE_PARAMETER '
GRASS_REGION_EXTENT_PARAMETER = ' GRASS_REGION_PARAMETER '
GRASS_REGION_CELLSIZE_PARAMETER = ' GRASS_REGION_CELLSIZE_PARAMETER '
2017-10-22 10:25:09 +02:00
GRASS_REGION_ALIGN_TO_RESOLUTION = ' GRASS_REGION_ALIGN_TO_RESOLUTION '
2017-11-05 13:18:24 +01:00
GRASS_RASTER_FORMAT_OPT = ' GRASS_RASTER_FORMAT_OPT '
GRASS_RASTER_FORMAT_META = ' GRASS_RASTER_FORMAT_META '
2014-04-19 15:53:43 +02:00
OUTPUT_TYPES = [ ' auto ' , ' point ' , ' line ' , ' area ' ]
2017-10-22 10:25:09 +02:00
QGIS_OUTPUT_TYPES = { QgsProcessing . TypeVectorAnyGeometry : ' auto ' ,
QgsProcessing . TypeVectorPoint : ' point ' ,
QgsProcessing . TypeVectorLine : ' line ' ,
QgsProcessing . TypeVectorPolygon : ' area ' }
2014-04-19 15:53:43 +02:00
def __init__ ( self , descriptionfile ) :
2017-09-01 17:53:33 +02:00
super ( ) . __init__ ( )
2017-03-29 12:51:59 +10:00
self . _name = ' '
self . _display_name = ' '
2017-03-29 12:04:09 +10:00
self . _group = ' '
2017-12-14 11:21:01 +02:00
self . _groupId = ' '
self . groupIdRegex = re . compile ( ' ^[^ \ s \ (]+ ' )
2017-09-01 17:53:33 +02:00
self . grass7Name = ' '
2017-09-03 17:42:13 +02:00
self . params = [ ]
2015-10-22 09:44:19 +02:00
self . hardcodedStrings = [ ]
2017-10-22 10:25:09 +02:00
self . inputLayers = [ ]
2014-04-19 15:53:43 +02:00
self . descriptionFile = descriptionfile
2017-09-06 14:15:24 +02:00
# Default GRASS parameters
self . region = None
self . cellSize = None
self . snaptTolerance = None
self . outputType = None
self . minArea = None
self . alignToResolution = None
2017-10-22 10:25:09 +02:00
2017-09-04 16:31:31 +02:00
# Load parameters from a description file
2014-04-19 15:53:43 +02:00
self . defineCharacteristicsFromFile ( )
self . numExportedLayers = 0
2017-09-04 16:31:31 +02:00
# Do we need this anymore?
2017-03-04 16:23:36 +01:00
self . uniqueSuffix = str ( uuid . uuid4 ( ) ) . replace ( ' - ' , ' ' )
2015-12-16 17:39:16 +01:00
# Use the ext mechanism
2017-04-03 20:35:03 +10:00
name = self . name ( ) . replace ( ' . ' , ' _ ' )
2015-12-16 17:39:16 +01:00
try :
2017-10-22 10:25:09 +02:00
self . module = importlib . import_module (
' processing.algs.grass7.ext. {} ' . format ( name ) )
2015-12-16 17:39:16 +01:00
except ImportError :
self . module = None
2014-04-19 15:53:43 +02:00
2017-09-04 16:31:31 +02:00
def createInstance ( self ) :
return self . __class__ ( self . descriptionFile )
2017-10-22 10:25:09 +02:00
2017-03-29 12:51:59 +10:00
def name ( self ) :
return self . _name
def displayName ( self ) :
return self . _display_name
2017-03-29 12:04:09 +10:00
def group ( self ) :
return self . _group
2017-12-14 11:21:01 +02:00
def groupId ( self ) :
return self . _groupId
2017-03-29 10:42:42 +10:00
def icon ( self ) :
return QgsApplication . getThemeIcon ( " /providerGrass.svg " )
def svgIconPath ( self ) :
return QgsApplication . iconPath ( " providerGrass.svg " )
2016-09-14 06:42:04 +10:00
2018-01-29 12:21:41 +10:00
def flags ( self ) :
# TODO - maybe it's safe to background thread this?
return super ( ) . flags ( ) | QgsProcessingAlgorithm . FlagNoThreading
2017-09-01 17:53:33 +02:00
def tr ( self , string , context = ' ' ) :
if context == ' ' :
context = self . __class__ . __name__
return QCoreApplication . translate ( context , string )
2017-10-22 10:25:09 +02:00
2017-05-15 13:09:41 +10:00
def helpUrl ( self ) :
2017-01-09 15:32:42 +02:00
helpPath = Grass7Utils . grassHelpPath ( )
if helpPath == ' ' :
2017-05-15 13:09:41 +10:00
return None
2017-01-09 15:32:42 +02:00
if os . path . exists ( helpPath ) :
2017-05-15 13:09:41 +10:00
return QUrl . fromLocalFile ( os . path . join ( helpPath , ' {} .html ' . format ( self . grass7Name ) ) ) . toString ( )
2016-03-06 11:48:41 +01:00
else :
2017-05-15 13:09:41 +10:00
return helpPath + ' {} .html ' . format ( self . grass7Name )
2014-04-19 15:53:43 +02:00
2017-09-03 17:42:13 +02:00
def initAlgorithm ( self , config = None ) :
2017-09-06 14:15:24 +02:00
"""
Algorithm initialization
"""
2017-09-03 17:42:13 +02:00
for p in self . params :
2017-09-06 14:15:24 +02:00
# We use createOutput argument for automatic output creation
2017-09-11 18:19:56 +02:00
res = self . addParameter ( p , True )
# File destinations are not automatically added as outputs
2017-10-22 10:25:09 +02:00
if ( isinstance ( p , QgsProcessingParameterFileDestination )
and p . defaultFileExtension ( ) . lower ( ) == ' html ' ) :
2017-09-11 18:19:56 +02:00
self . addOutput ( QgsProcessingOutputHtml ( p . name ( ) , p . description ( ) ) )
2014-04-19 15:53:43 +02:00
def defineCharacteristicsFromFile ( self ) :
2017-09-01 17:53:33 +02:00
"""
Create algorithm parameters and outputs from a text file .
"""
2016-11-07 10:35:15 +10:00
with open ( self . descriptionFile ) as lines :
2017-09-01 17:53:33 +02:00
# First line of the file is the Grass algorithm name
2016-11-07 10:35:15 +10:00
line = lines . readline ( ) . strip ( ' \n ' ) . strip ( )
self . grass7Name = line
2017-09-01 17:53:33 +02:00
# Second line if the algorithm name in Processing
2016-11-07 10:35:15 +10:00
line = lines . readline ( ) . strip ( ' \n ' ) . strip ( )
2017-03-29 12:51:59 +10:00
self . _name = line
self . _display_name = QCoreApplication . translate ( " GrassAlgorithm " , line )
if " - " not in self . _name :
self . _name = self . grass7Name + " - " + self . _name
self . _display_name = self . grass7Name + " - " + self . _display_name
2017-03-29 17:09:39 +10:00
self . _name = self . _name [ : self . _name . find ( ' ' ) ] . lower ( )
2017-09-01 17:53:33 +02:00
# Read the grass group
2016-11-07 10:35:15 +10:00
line = lines . readline ( ) . strip ( ' \n ' ) . strip ( )
2017-03-29 12:04:09 +10:00
self . _group = QCoreApplication . translate ( " GrassAlgorithm " , line )
2017-12-14 11:21:01 +02:00
self . _groupId = self . groupIdRegex . search ( line ) . group ( 0 ) . lower ( )
2016-11-07 10:35:15 +10:00
hasRasterOutput = False
2017-11-05 13:52:26 +01:00
hasRasterInput = False
2016-11-07 10:35:15 +10:00
hasVectorInput = False
2017-09-04 16:31:31 +02:00
vectorOutputs = False
2017-09-01 17:53:33 +02:00
# Then you have parameters/output definition
2016-11-07 10:35:15 +10:00
line = lines . readline ( ) . strip ( ' \n ' ) . strip ( )
while line != ' ' :
try :
line = line . strip ( ' \n ' ) . strip ( )
if line . startswith ( ' Hardcoded ' ) :
self . hardcodedStrings . append ( line [ len ( ' Hardcoded| ' ) : ] )
parameter = getParameterFromString ( line )
if parameter is not None :
2017-09-03 17:42:13 +02:00
self . params . append ( parameter )
if isinstance ( parameter , QgsProcessingParameterVectorLayer ) :
2016-11-07 10:35:15 +10:00
hasVectorInput = True
2017-11-05 13:52:26 +01:00
elif isinstance ( parameter , QgsProcessingParameterRasterLayer ) :
hasRasterInput = True
elif isinstance ( parameter , QgsProcessingParameterMultipleLayers ) :
if parameter . layerType ( ) < 3 or parameter . layerType ( ) == 5 :
hasVectorInput = True
elif parameter . layerType ( ) == 3 :
hasRasterInput = True
2017-09-04 16:31:31 +02:00
elif isinstance ( parameter , QgsProcessingParameterVectorDestination ) :
vectorOutputs = True
elif isinstance ( parameter , QgsProcessingParameterRasterDestination ) :
hasRasterOutput = True
2016-11-07 10:35:15 +10:00
line = lines . readline ( ) . strip ( ' \n ' ) . strip ( )
except Exception as e :
2018-02-05 22:11:34 -04:00
QgsMessageLog . logMessage ( self . tr ( ' Could not open GRASS GIS 7 algorithm: {0} \n {1} ' ) . format ( self . descriptionFile , line ) , self . tr ( ' Processing ' ) , Qgis . Critical )
2016-11-07 10:35:15 +10:00
raise e
2014-04-19 15:53:43 +02:00
2017-09-04 16:31:31 +02:00
param = QgsProcessingParameterExtent (
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
self . GRASS_REGION_EXTENT_PARAMETER ,
2017-09-04 16:31:31 +02:00
self . tr ( ' GRASS GIS 7 region extent ' ) ,
optional = True
fix python pep8 warnings and fix some revealed errors
pep8 --ignore=E111,E128,E201,E202,E203,E211,E221,E222,E225,E226,E227,E231,E241,E261,E265,E272,E302,E303,E501,E701 \
--exclude="ui_*.py,debian/*,python/ext-libs/*" \
.
2015-02-01 14:15:42 +01:00
)
2017-09-04 16:31:31 +02:00
param . setFlags ( param . flags ( ) | QgsProcessingParameterDefinition . FlagAdvanced )
self . params . append ( param )
2017-10-22 10:25:09 +02:00
2017-11-05 13:52:26 +01:00
if hasRasterOutput or hasRasterInput :
2017-11-05 13:18:24 +01:00
# Add a cellsize parameter
2017-09-04 16:31:31 +02:00
param = QgsProcessingParameterNumber (
2014-04-19 15:53:43 +02:00
self . GRASS_REGION_CELLSIZE_PARAMETER ,
2015-01-16 15:56:05 +02:00
self . tr ( ' GRASS GIS 7 region cellsize (leave 0 for default) ' ) ,
2017-09-01 17:53:33 +02:00
type = QgsProcessingParameterNumber . Double ,
2017-09-04 16:31:31 +02:00
minValue = 0.0 , maxValue = sys . float_info . max + 1 , defaultValue = 0.0
2017-09-01 17:53:33 +02:00
)
2017-09-04 16:31:31 +02:00
param . setFlags ( param . flags ( ) | QgsProcessingParameterDefinition . FlagAdvanced )
self . params . append ( param )
2017-10-22 10:25:09 +02:00
2017-11-05 13:52:26 +01:00
if hasRasterOutput :
2017-11-05 13:18:24 +01:00
# Add a createopt parameter for format export
param = QgsProcessingParameterString (
self . GRASS_RASTER_FORMAT_OPT ,
self . tr ( ' Output Rasters format options (createopt) ' ) ,
multiLine = True , optional = True
)
param . setFlags ( param . flags ( ) | QgsProcessingParameterDefinition . FlagAdvanced )
self . params . append ( param )
# Add a metadata parameter for format export
param = QgsProcessingParameterString (
self . GRASS_RASTER_FORMAT_META ,
self . tr ( ' Output Rasters format metadata options (metaopt) ' ) ,
multiLine = True , optional = True
)
param . setFlags ( param . flags ( ) | QgsProcessingParameterDefinition . FlagAdvanced )
self . params . append ( param )
2014-04-19 15:53:43 +02:00
if hasVectorInput :
2017-09-01 17:53:33 +02:00
param = QgsProcessingParameterNumber ( self . GRASS_SNAP_TOLERANCE_PARAMETER ,
self . tr ( ' v.in.ogr snap tolerance (-1 = no snap) ' ) ,
type = QgsProcessingParameterNumber . Double ,
2017-09-03 17:42:13 +02:00
minValue = - 1.0 , maxValue = sys . float_info . max + 1 ,
defaultValue = - 1.0 )
2017-05-16 16:36:00 +10:00
param . setFlags ( param . flags ( ) | QgsProcessingParameterDefinition . FlagAdvanced )
2017-09-04 16:31:31 +02:00
self . params . append ( param )
2017-09-01 17:53:33 +02:00
param = QgsProcessingParameterNumber ( self . GRASS_MIN_AREA_PARAMETER ,
self . tr ( ' v.in.ogr min area ' ) ,
2017-09-03 17:42:13 +02:00
type = QgsProcessingParameterNumber . Double ,
minValue = 0.0 , maxValue = sys . float_info . max + 1 ,
defaultValue = 0.0001 )
2017-05-16 16:36:00 +10:00
param . setFlags ( param . flags ( ) | QgsProcessingParameterDefinition . FlagAdvanced )
2017-09-04 16:31:31 +02:00
self . params . append ( param )
2017-10-22 10:25:09 +02:00
2017-09-04 16:31:31 +02:00
if vectorOutputs :
2017-09-01 17:53:33 +02:00
param = QgsProcessingParameterEnum ( self . GRASS_OUTPUT_TYPE_PARAMETER ,
self . tr ( ' v.out.ogr output type ' ) ,
self . OUTPUT_TYPES )
2017-05-16 16:36:00 +10:00
param . setFlags ( param . flags ( ) | QgsProcessingParameterDefinition . FlagAdvanced )
2017-09-04 16:31:31 +02:00
self . params . append ( param )
2014-04-19 15:53:43 +02:00
2017-10-22 10:25:09 +02:00
def getDefaultCellSize ( self ) :
2017-09-08 17:47:24 +02:00
"""
Determine a default cell size from all the raster layers .
"""
2017-09-11 18:19:56 +02:00
cellsize = 0.0
2017-10-22 10:25:09 +02:00
layers = [ l for l in self . inputLayers if isinstance ( l , QgsRasterLayer ) ]
for layer in layers :
2017-10-26 16:09:46 +02:00
cellsize = max ( layer . rasterUnitsPerPixelX ( ) , cellsize )
2017-10-22 10:25:09 +02:00
2017-09-11 18:19:56 +02:00
if cellsize == 0.0 :
cellsize = 100.0
2017-10-22 10:25:09 +02:00
2017-09-11 18:19:56 +02:00
return cellsize
2014-04-19 15:53:43 +02:00
2017-09-06 14:15:24 +02:00
def grabDefaultGrassParameters ( self , parameters , context ) :
"""
Imports default GRASS parameters ( EXTENT , etc ) into
object attributes for faster retrieving .
"""
# GRASS region extent
2017-10-22 10:25:09 +02:00
self . region = self . parameterAsExtent ( parameters ,
self . GRASS_REGION_EXTENT_PARAMETER ,
context )
2017-09-06 14:15:24 +02:00
# GRASS cell size
2017-09-11 18:19:56 +02:00
if self . parameterDefinition ( self . GRASS_REGION_CELLSIZE_PARAMETER ) :
self . cellSize = self . parameterAsDouble ( parameters ,
self . GRASS_REGION_CELLSIZE_PARAMETER ,
context )
2017-09-06 14:15:24 +02:00
# GRASS snap tolerance
self . snapTolerance = self . parameterAsDouble ( parameters ,
2017-10-22 10:25:09 +02:00
self . GRASS_SNAP_TOLERANCE_PARAMETER ,
context )
2017-09-06 14:15:24 +02:00
# GRASS min area
self . minArea = self . parameterAsDouble ( parameters ,
self . GRASS_MIN_AREA_PARAMETER ,
context )
# GRASS output type
self . outputType = self . parameterAsString ( parameters ,
self . GRASS_OUTPUT_TYPE_PARAMETER ,
context )
# GRASS align to resolution
self . alignToResolution = self . parameterAsBool ( parameters ,
self . GRASS_REGION_ALIGN_TO_RESOLUTION ,
context )
2017-10-22 10:25:09 +02:00
2017-05-15 16:19:46 +10:00
def processAlgorithm ( self , parameters , context , feedback ) :
2017-09-11 18:19:56 +02:00
if isWindows ( ) :
2014-04-19 15:53:43 +02:00
path = Grass7Utils . grassPath ( )
if path == ' ' :
2017-09-01 17:53:33 +02:00
raise QgsProcessingException (
2015-01-16 15:56:05 +02:00
self . tr ( ' GRASS GIS 7 folder is not configured. Please '
' configure it before running GRASS GIS 7 algorithms. ' ) )
2016-01-02 16:14:41 +01:00
2015-12-16 17:39:16 +01:00
# Create brand new commands lists
self . commands = [ ]
self . outputCommands = [ ]
2014-04-19 15:53:43 +02:00
self . exportedLayers = { }
# If GRASS session has been created outside of this algorithm then
# get the list of layers loaded in GRASS otherwise start a new
# session
existingSession = Grass7Utils . sessionRunning
if existingSession :
self . exportedLayers = Grass7Utils . getSessionLayers ( )
else :
2017-10-26 16:09:46 +02:00
Grass7Utils . startGrassSession ( )
2014-04-19 15:53:43 +02:00
2017-09-06 14:15:24 +02:00
# Handle default GRASS parameters
self . grabDefaultGrassParameters ( parameters , context )
2017-10-22 10:25:09 +02:00
2015-12-16 17:39:16 +01:00
# Handle ext functions for inputs/command/outputs
2017-09-12 21:58:12 +02:00
for fName in [ ' Inputs ' , ' Command ' , ' Outputs ' ] :
fullName = ' process {} ' . format ( fName )
if self . module and hasattr ( self . module , fullName ) :
getattr ( self . module , fullName ) ( self , parameters , context )
2015-12-16 17:39:16 +01:00
else :
2017-09-12 21:58:12 +02:00
getattr ( self , fullName ) ( parameters , context )
2015-12-16 17:39:16 +01:00
# Run GRASS
loglines = [ ]
2016-01-14 12:19:31 +01:00
loglines . append ( self . tr ( ' GRASS GIS 7 execution commands ' ) )
2015-12-16 17:39:16 +01:00
for line in self . commands :
2017-01-06 20:04:00 +10:00
feedback . pushCommandInfo ( line )
2015-12-16 17:39:16 +01:00
loglines . append ( line )
if ProcessingConfig . getSetting ( Grass7Utils . GRASS_LOG_COMMANDS ) :
2018-02-05 22:11:34 -04:00
QgsMessageLog . logMessage ( " \n " . join ( loglines ) , self . tr ( ' Processing ' ) , Qgis . Info )
2015-12-16 17:39:16 +01:00
2017-10-26 16:09:46 +02:00
Grass7Utils . executeGrass ( self . commands , feedback , self . outputCommands )
2015-12-16 17:39:16 +01:00
# If the session has been created outside of this algorithm, add
# the new GRASS GIS 7 layers to it otherwise finish the session
if existingSession :
Grass7Utils . addSessionLayers ( self . exportedLayers )
else :
2017-10-26 16:09:46 +02:00
Grass7Utils . endGrassSession ( )
2014-04-19 15:53:43 +02:00
2017-09-06 14:15:24 +02:00
# Return outputs map
outputs = { }
2017-10-22 10:25:09 +02:00
for out in self . outputDefinitions ( ) :
outName = out . name ( )
2017-09-06 14:15:24 +02:00
if outName in parameters :
outputs [ outName ] = parameters [ outName ]
2017-10-22 10:25:09 +02:00
if isinstance ( out , QgsProcessingOutputHtml ) :
self . convertToHtml ( parameters [ outName ] )
2017-09-06 14:15:24 +02:00
return outputs
2017-05-17 08:12:43 +10:00
def processInputs ( self , parameters , context ) :
2015-12-16 17:39:16 +01:00
""" Prepare the GRASS import commands """
2017-09-06 14:15:24 +02:00
inputs = [ p for p in self . parameterDefinitions ( )
if isinstance ( p , ( QgsProcessingParameterVectorLayer ,
QgsProcessingParameterRasterLayer ,
QgsProcessingParameterMultipleLayers ) ) ]
for param in inputs :
2017-09-04 16:31:31 +02:00
paramName = param . name ( )
2017-10-22 10:25:09 +02:00
if not paramName in parameters :
continue
2017-12-26 18:53:30 +01:00
# Handle Null parameter
if parameters [ paramName ] is None :
2017-10-22 10:25:09 +02:00
continue
2017-12-26 18:53:30 +01:00
elif isinstance ( parameters [ paramName ] , str ) and len ( parameters [ paramName ] ) == 0 :
continue
2017-12-30 17:16:16 +01:00
2017-09-06 14:15:24 +02:00
# Raster inputs needs to be imported into temp GRASS DB
2017-09-04 16:31:31 +02:00
if isinstance ( param , QgsProcessingParameterRasterLayer ) :
2017-10-22 10:25:09 +02:00
if paramName not in self . exportedLayers :
self . loadRasterLayerFromParameter (
paramName , parameters , context )
2017-09-06 14:15:24 +02:00
# Vector inputs needs to be imported into temp GRASS DB
2017-09-07 18:47:37 +02:00
elif isinstance ( param , QgsProcessingParameterVectorLayer ) :
2017-10-22 10:25:09 +02:00
if paramName not in self . exportedLayers :
2017-12-30 17:16:16 +01:00
# Attribute tables are also vector inputs
if QgsProcessing . TypeFile in param . dataTypes ( ) :
self . loadAttributeTableFromParameter (
paramName , parameters , context )
else :
self . loadVectorLayerFromParameter (
2018-01-07 11:01:44 +01:00
paramName , parameters , context , None )
2017-10-22 10:25:09 +02:00
# For multiple inputs, process each layer
2017-09-07 18:47:37 +02:00
elif isinstance ( param , QgsProcessingParameterMultipleLayers ) :
layers = self . parameterAsLayerList ( parameters , paramName , context )
for idx , layer in enumerate ( layers ) :
layerName = ' {} _ {} ' . format ( paramName , idx )
2017-10-22 10:25:09 +02:00
# Add a raster layer
if layer . type ( ) == QgsMapLayer . RasterLayer :
2017-11-04 18:34:25 +01:00
self . loadRasterLayer ( layerName , layer )
2017-10-22 10:25:09 +02:00
# Add a vector layer
elif layer . type ( ) == QgsMapLayer . VectorLayer :
2018-01-07 11:01:44 +01:00
self . loadVectorLayer ( layerName , layer , None )
2017-10-22 10:25:09 +02:00
2017-09-12 21:58:12 +02:00
self . postInputs ( )
2017-10-22 10:25:09 +02:00
2017-09-12 21:58:12 +02:00
def postInputs ( self ) :
"""
After layer imports , we need to update some internal parameters
"""
2017-09-04 16:31:31 +02:00
# If projection has not already be set, use the project
self . setSessionProjectionFromProject ( )
2014-04-19 15:53:43 +02:00
2017-09-04 16:31:31 +02:00
# Build GRASS region
2017-09-07 11:25:02 +02:00
if self . region . isEmpty ( ) :
2017-10-22 10:25:09 +02:00
self . region = QgsProcessingUtils . combineLayerExtents ( self . inputLayers )
2017-09-04 16:31:31 +02:00
command = ' g.region n= {} s= {} e= {} w= {} ' . format (
2017-09-06 14:15:24 +02:00
self . region . yMaximum ( ) , self . region . yMinimum ( ) ,
2017-09-07 11:25:02 +02:00
self . region . xMaximum ( ) , self . region . xMinimum ( )
2017-09-04 16:31:31 +02:00
)
2017-09-08 17:47:24 +02:00
# Handle cell size
2017-09-11 18:19:56 +02:00
if self . parameterDefinition ( self . GRASS_REGION_CELLSIZE_PARAMETER ) :
if self . cellSize :
cellSize = self . cellSize
else :
2017-10-22 10:25:09 +02:00
cellSize = self . getDefaultCellSize ( )
2017-09-11 18:19:56 +02:00
command + = ' res= {} ' . format ( cellSize )
2017-10-22 10:25:09 +02:00
2017-09-08 17:47:24 +02:00
# Handle align to resolution
2017-09-06 14:15:24 +02:00
if self . alignToResolution :
2014-04-19 15:53:43 +02:00
command + = ' -a '
2017-09-06 14:15:24 +02:00
# Add the default parameters commands
2015-12-16 17:39:16 +01:00
self . commands . append ( command )
2017-10-22 10:25:09 +02:00
2018-02-18 15:49:19 +01:00
QgsMessageLog . logMessage ( self . tr ( ' processInputs end. Commands: {} ' ) . format ( self . commands ) , ' Grass7 ' , Qgis . Info )
2014-04-19 15:53:43 +02:00
2017-10-22 10:25:09 +02:00
def processCommand ( self , parameters , context , delOutputs = False ) :
2017-09-11 18:19:56 +02:00
"""
Prepare the GRASS algorithm command
2017-05-15 16:19:46 +10:00
: param parameters :
2017-10-22 10:25:09 +02:00
: param context :
: param delOutputs : do not add outputs to commands .
2017-05-15 16:19:46 +10:00
"""
2017-09-06 14:15:24 +02:00
noOutputs = [ o for o in self . parameterDefinitions ( ) if o not in self . destinationParameterDefinitions ( ) ]
command = ' {} ' . format ( self . grass7Name )
command + = ' {} ' . join ( self . hardcodedStrings )
2015-10-22 09:44:19 +02:00
2015-12-16 17:39:16 +01:00
# Add algorithm command
2017-09-06 14:15:24 +02:00
for param in noOutputs :
paramName = param . name ( )
value = None
2017-10-22 10:25:09 +02:00
2017-09-06 14:15:24 +02:00
# Exclude default GRASS parameters
if paramName in [ self . GRASS_REGION_CELLSIZE_PARAMETER ,
self . GRASS_REGION_EXTENT_PARAMETER ,
self . GRASS_MIN_AREA_PARAMETER ,
self . GRASS_SNAP_TOLERANCE_PARAMETER ,
self . GRASS_OUTPUT_TYPE_PARAMETER ,
2017-11-05 13:18:24 +01:00
self . GRASS_REGION_ALIGN_TO_RESOLUTION ,
self . GRASS_RASTER_FORMAT_OPT ,
self . GRASS_RASTER_FORMAT_META ] :
2014-04-19 15:53:43 +02:00
continue
2017-10-22 10:25:09 +02:00
2017-09-06 14:15:24 +02:00
# Raster and vector layers
if isinstance ( param , ( QgsProcessingParameterRasterLayer ,
QgsProcessingParameterVectorLayer ) ) :
if paramName in self . exportedLayers :
value = self . exportedLayers [ paramName ]
2014-04-19 15:53:43 +02:00
else :
2017-09-06 14:15:24 +02:00
value = self . parameterAsCompatibleSourceLayerPath (
parameters , paramName , context ,
QgsVectorFileWriter . supportedFormatExtensions ( )
)
2017-09-07 18:47:37 +02:00
# MultipleLayers
elif isinstance ( param , QgsProcessingParameterMultipleLayers ) :
layers = self . parameterAsLayerList ( parameters , paramName , context )
values = [ ]
for idx in range ( len ( layers ) ) :
layerName = ' {} _ {} ' . format ( paramName , idx )
values . append ( self . exportedLayers [ layerName ] )
value = ' , ' . join ( values )
2017-09-06 14:15:24 +02:00
# For booleans, we just add the parameter name
elif isinstance ( param , QgsProcessingParameterBoolean ) :
if self . parameterAsBool ( parameters , paramName , context ) :
2017-09-07 18:47:37 +02:00
command + = ' {} ' . format ( paramName )
2017-12-28 18:28:18 +01:00
# For Extents, remove if the value is null
elif isinstance ( param , QgsProcessingParameterExtent ) :
if self . parameterAsExtent ( parameters , paramName , context ) :
value = self . parameterAsString ( parameters , paramName , context )
2017-09-06 14:15:24 +02:00
# For enumeration, we need to grab the string value
2017-09-01 17:53:33 +02:00
elif isinstance ( param , QgsProcessingParameterEnum ) :
2017-12-27 11:16:14 +01:00
# Handle multiple values
if param . allowMultiple ( ) :
indexes = self . parameterAsEnums ( parameters , paramName , context )
else :
indexes = [ self . parameterAsEnum ( parameters , paramName , context ) ]
2017-12-28 18:28:18 +01:00
if indexes :
value = ' " {} " ' . format ( ' , ' . join ( [ param . options ( ) [ i ] for i in indexes ] ) )
2017-09-06 14:15:24 +02:00
# For strings, we just translate as string
elif isinstance ( param , QgsProcessingParameterString ) :
2017-10-22 10:25:09 +02:00
data = self . parameterAsString ( parameters , paramName , context )
# if string is empty, we don't add it
if len ( data ) > 0 :
value = ' " {} " ' . format (
self . parameterAsString ( parameters , paramName , context )
)
# For fields, we just translate as string
elif isinstance ( param , QgsProcessingParameterField ) :
2017-12-27 11:52:01 +01:00
value = ' , ' . join (
self . parameterAsFields ( parameters , paramName , context )
2017-09-06 14:15:24 +02:00
)
2017-12-27 20:13:05 +01:00
elif isinstance ( param , QgsProcessingParameterFile ) :
2017-12-28 18:28:18 +01:00
if self . parameterAsString ( parameters , paramName , context ) :
value = ' " {} " ' . format (
self . parameterAsString ( parameters , paramName , context )
)
2017-09-06 14:15:24 +02:00
# For numbers and points, we translate as a string
elif isinstance ( param , ( QgsProcessingParameterNumber ,
QgsProcessingParameterPoint ) ) :
value = self . parameterAsString ( parameters , paramName , context )
# For everything else, we assume that it is a string
else :
value = ' " {} " ' . format (
self . parameterAsString ( parameters , paramName , context )
)
if value :
command + = ' {} = {} ' . format ( paramName , value )
# Handle outputs
2017-10-22 10:25:09 +02:00
if not delOutputs :
for out in self . destinationParameterDefinitions ( ) :
2017-12-27 12:08:21 +01:00
# We exclude hidden parameters
if out . flags ( ) & QgsProcessingParameterDefinition . FlagHidden :
continue
2017-10-22 10:25:09 +02:00
outName = out . name ( )
# For File destination
if isinstance ( out , QgsProcessingParameterFileDestination ) :
# for HTML reports, we need to redirect stdout
if out . defaultFileExtension ( ) . lower ( ) == ' html ' :
command + = ' > " {} " ' . format (
self . parameterAsFileOutput (
parameters , outName , context )
)
else :
command + = ' {} = " {} " ' . format (
outName ,
self . parameterAsFileOutput (
parameters , outName , context ) )
2017-10-25 21:29:28 +02:00
# For folders destination
2017-11-04 18:34:25 +01:00
elif isinstance ( out , QgsProcessingParameterFolderDestination ) :
2017-10-25 21:29:28 +02:00
# We need to add a unique temporary basename
uniqueBasename = outName + self . uniqueSuffix
command + = ' {} = {} ' . format ( outName , uniqueBasename )
2017-10-22 10:25:09 +02:00
else :
# We add an output name to make sure it is unique if the session
# uses this algorithm several times.
#value = self.parameterAsOutputLayer(parameters, outName, context)
uniqueOutputName = outName + self . uniqueSuffix
command + = ' {} = {} ' . format ( outName , uniqueOutputName )
2014-04-19 15:53:43 +02:00
2017-10-22 10:25:09 +02:00
# Add output file to exported layers, to indicate that
# they are present in GRASS
self . exportedLayers [ outName ] = uniqueOutputName
2014-04-19 15:53:43 +02:00
command + = ' --overwrite '
2015-12-16 17:39:16 +01:00
self . commands . append ( command )
2018-02-18 15:49:19 +01:00
QgsMessageLog . logMessage ( self . tr ( ' processCommands end. Commands: {} ' ) . format ( self . commands ) , ' Grass7 ' , Qgis . Info )
2017-10-22 10:25:09 +02:00
def vectorOutputType ( self , parameters , context ) :
""" Determine vector output types for outputs """
self . outType = ' auto '
if self . parameterDefinition ( self . GRASS_OUTPUT_TYPE_PARAMETER ) :
typeidx = self . parameterAsEnum ( parameters ,
self . GRASS_OUTPUT_TYPE_PARAMETER ,
context )
self . outType = ( ' auto ' if typeidx
is None else self . OUTPUT_TYPES [ typeidx ] )
2017-09-06 14:15:24 +02:00
def processOutputs ( self , parameters , context ) :
2015-12-16 17:39:16 +01:00
""" Prepare the GRASS v.out.ogr commands """
2017-09-06 14:15:24 +02:00
# TODO: support multiple raster formats.
# TODO: support multiple vector formats.
2017-10-22 10:25:09 +02:00
# Determine general vector output type
self . vectorOutputType ( parameters , context )
2017-09-06 14:15:24 +02:00
for out in self . destinationParameterDefinitions ( ) :
outName = out . name ( )
if isinstance ( out , QgsProcessingParameterRasterDestination ) :
2017-10-22 10:25:09 +02:00
self . exportRasterLayerFromParameter ( outName , parameters , context )
elif isinstance ( out , QgsProcessingParameterVectorDestination ) :
self . exportVectorLayerFromParameter ( outName , parameters , context )
2017-10-25 21:29:28 +02:00
elif isinstance ( out , QgsProcessingParameterFolderDestination ) :
self . exportRasterLayersIntoDirectory ( outName , parameters , context )
2017-10-22 10:25:09 +02:00
def loadRasterLayerFromParameter ( self , name , parameters , context , external = True , band = 1 ) :
"""
2017-10-26 16:09:46 +02:00
Creates a dedicated command to load a raster into
the temporary GRASS DB .
: param name : name of the parameter .
: param parameters : algorithm parameters dict .
: param context : algorithm context .
: param external : True if using r . external .
: param band : imports only specified band . None for all bands .
2017-10-22 10:25:09 +02:00
"""
layer = self . parameterAsRasterLayer ( parameters , name , context )
self . loadRasterLayer ( name , layer , external , band )
2017-12-29 17:13:30 +01:00
def loadRasterLayer ( self , name , layer , external = True , band = 1 , destName = None ) :
2017-09-11 18:19:56 +02:00
"""
Creates a dedicated command to load a raster into
2017-10-26 16:09:46 +02:00
the temporary GRASS DB .
: param name : name of the parameter .
: param layer : QgsMapLayer for the raster layer .
: param external : True if using r . external .
: param band : imports only specified band . None for all bands .
2017-12-29 17:13:30 +01:00
: param destName : force the destination name of the raster .
2017-09-11 18:19:56 +02:00
"""
2017-10-22 10:25:09 +02:00
self . inputLayers . append ( layer )
self . setSessionProjectionFromLayer ( layer )
2017-12-29 17:13:30 +01:00
if not destName :
destName = ' rast_ {} ' . format ( os . path . basename ( getTempFilename ( ) ) )
self . exportedLayers [ name ] = destName
2017-10-22 10:25:09 +02:00
command = ' {0} input= " {1} " {2} output= " {3} " --overwrite -o ' . format (
2017-09-12 21:58:12 +02:00
' r.external ' if external else ' r.in.gdal ' ,
2017-10-26 16:09:46 +02:00
os . path . normpath ( layer . source ( ) ) ,
2017-10-22 10:25:09 +02:00
' band= {} ' . format ( band ) if band else ' ' ,
2017-12-29 17:13:30 +01:00
destName )
2017-10-22 10:25:09 +02:00
self . commands . append ( command )
2017-12-30 17:16:16 +01:00
2017-10-22 10:25:09 +02:00
def exportRasterLayerFromParameter ( self , name , parameters , context , colorTable = True ) :
"""
Creates a dedicated command to export a raster from
temporary GRASS DB into a file via gdal .
2017-10-25 21:29:28 +02:00
: param name : name of the parameter .
2017-10-26 16:09:46 +02:00
: param parameters : Algorithm parameters dict .
2017-10-25 21:29:28 +02:00
: param context : Algorithm context .
2017-10-22 10:25:09 +02:00
: param colorTable : preserve color Table .
"""
2017-10-26 16:09:46 +02:00
fileName = os . path . normpath (
self . parameterAsOutputLayer ( parameters , name , context ) )
2017-10-22 10:25:09 +02:00
grassName = ' {} {} ' . format ( name , self . uniqueSuffix )
2017-11-05 13:18:24 +01:00
outFormat = Grass7Utils . getRasterFormatFromFilename ( fileName )
createOpt = self . parameterAsString ( parameters , self . GRASS_RASTER_FORMAT_OPT , context )
metaOpt = self . parameterAsString ( parameters , self . GRASS_RASTER_FORMAT_META , context )
self . exportRasterLayer ( grassName , fileName , colorTable , outFormat , createOpt , metaOpt )
def exportRasterLayer ( self , grassName , fileName ,
colorTable = True , outFormat = ' GTiff ' ,
createOpt = None ,
metaOpt = None ) :
2017-10-22 10:25:09 +02:00
"""
Creates a dedicated command to export a raster from
temporary GRASS DB into a file via gdal .
2017-11-05 13:18:24 +01:00
: param grassName : name of the raster to export .
: param fileName : file path of raster layer .
2017-10-22 10:25:09 +02:00
: param colorTable : preserve color Table .
2017-11-05 13:18:24 +01:00
: param outFormat : file format for export .
: param createOpt : creation options for format .
: param metatOpt : metadata options for export .
2017-10-22 10:25:09 +02:00
"""
2017-11-05 13:18:24 +01:00
if not createOpt :
if outFormat in Grass7Utils . GRASS_RASTER_FORMATS_CREATEOPTS :
createOpt = Grass7Utils . GRASS_RASTER_FORMATS_CREATEOPTS [ outFormat ]
2017-10-22 10:25:09 +02:00
for cmd in [ self . commands , self . outputCommands ] :
# Adjust region to layer before exporting
cmd . append ( ' g.region raster= {} ' . format ( grassName ) )
cmd . append (
2017-12-27 20:13:05 +01:00
' r.out.gdal -t -m {0} input= " {1} " output= " {2} " format= " {3} " {4} {5} --overwrite ' . format (
' ' if colorTable else ' -c ' ,
2017-10-22 10:25:09 +02:00
grassName , fileName ,
2017-11-05 13:18:24 +01:00
outFormat ,
' createopt= " {} " ' . format ( createOpt ) if createOpt else ' ' ,
' metaopt= " {} " ' . format ( metaOpt ) if metaOpt else ' '
2017-10-22 10:25:09 +02:00
)
)
2017-12-29 17:13:30 +01:00
def exportRasterLayersIntoDirectory ( self , name , parameters , context , colorTable = True , wholeDB = False ) :
2017-10-25 21:29:28 +02:00
"""
Creates a dedicated loop command to export rasters from
2017-10-26 16:09:46 +02:00
temporary GRASS DB into a directory via gdal .
: param name : name of the output directory parameter .
: param parameters : Algorithm parameters dict .
: param context : Algorithm context .
2017-10-25 21:29:28 +02:00
: param colorTable : preserve color Table .
2017-12-29 17:13:30 +01:00
: param wholeDB : export every raster layer from the GRASSDB
2017-10-25 21:29:28 +02:00
"""
# Grab directory name and temporary basename
2017-10-26 16:09:46 +02:00
outDir = os . path . normpath (
self . parameterAsString ( parameters , name , context ) )
2017-12-29 17:13:30 +01:00
basename = ' '
if not wholeDB :
basename = name + self . uniqueSuffix
2017-10-25 21:29:28 +02:00
# Add a loop export from the basename
for cmd in [ self . commands , self . outputCommands ] :
2017-12-27 20:13:05 +01:00
# TODO Windows support
# TODO Format/options support
2017-10-25 21:29:28 +02:00
cmd . append ( " for r in $(g.list type=rast pattern= ' {} * ' ); do " . format ( basename ) )
2017-10-26 16:09:46 +02:00
cmd . append ( " r.out.gdal -m {0} input=$ {{ r}} output= {1} /$ {{ r}}.tif {2} " . format (
2017-10-25 21:29:28 +02:00
' -t ' if colorTable else ' ' , outDir ,
' --overwrite -c createopt= " TFW=YES,COMPRESS=LZW " '
)
)
cmd . append ( " done " )
2017-12-27 10:19:51 +01:00
def loadVectorLayerFromParameter ( self , name , parameters , context , external = False ) :
2017-10-22 10:25:09 +02:00
"""
2017-10-26 16:09:46 +02:00
Creates a dedicated command to load a vector into
the temporary GRASS DB .
: param name : name of the parameter
: param parameters : Parameters of the algorithm .
: param context : Processing context
: param external : use v . external ( v . in . ogr if False ) .
2017-10-22 10:25:09 +02:00
"""
layer = self . parameterAsVectorLayer ( parameters , name , context )
self . loadVectorLayer ( name , layer , external )
2017-12-27 10:19:51 +01:00
def loadVectorLayer ( self , name , layer , external = False ) :
2017-10-22 10:25:09 +02:00
"""
Creates a dedicated command to load a vector into
temporary GRASS DB .
: param name : name of the parameter
2017-10-26 16:09:46 +02:00
: param layer : QgsMapLayer for the vector layer .
2017-10-22 10:25:09 +02:00
: param external : use v . external ( v . in . ogr if False ) .
"""
# TODO: support selections
# TODO: support multiple input formats
if external is None :
external = ProcessingConfig . getSetting (
Grass7Utils . GRASS_USE_VEXTERNAL )
self . inputLayers . append ( layer )
self . setSessionProjectionFromLayer ( layer )
2017-12-30 17:16:16 +01:00
destFilename = ' vector_ {} ' . format ( os . path . basename ( getTempFilename ( ) ) )
2017-10-22 10:25:09 +02:00
self . exportedLayers [ name ] = destFilename
command = ' {0} {1} {2} input= " {3} " output= " {4} " --overwrite -o ' . format (
' v.external ' if external else ' v.in.ogr ' ,
' min_area= {} ' . format ( self . minArea ) if not external else ' ' ,
' snap= {} ' . format ( self . snapTolerance ) if not external else ' ' ,
2017-10-26 16:09:46 +02:00
os . path . normpath ( layer . source ( ) ) ,
2017-10-22 10:25:09 +02:00
destFilename )
self . commands . append ( command )
def exportVectorLayerFromParameter ( self , name , parameters , context ) :
"""
Creates a dedicated command to export a raster from
temporary GRASS DB into a file via gdal .
: param grassName : name of the parameter
: param fileName : file path of raster layer
: param colorTable : preserve color Table .
"""
2017-10-26 16:09:46 +02:00
fileName = os . path . normpath (
self . parameterAsOutputLayer ( parameters , name , context ) )
2017-10-22 10:25:09 +02:00
# Find if there is a dataType
dataType = self . outType
if self . outType == ' auto ' :
parameter = self . parameterDefinition ( name )
if parameter :
layerType = parameter . dataType ( )
if layerType in self . QGIS_OUTPUT_TYPES :
dataType = self . QGIS_OUTPUT_TYPES [ layerType ]
grassName = ' {} {} ' . format ( name , self . uniqueSuffix )
self . exportVectorLayer ( grassName , fileName , dataType )
def exportVectorLayer ( self , grassName , fileName , dataType = ' auto ' , layer = None , nocats = False ) :
"""
Creates a dedicated command to export a vector from
temporary GRASS DB into a file via ogr .
2017-12-28 18:28:18 +01:00
: param grassName : name of the parameter .
: param fileName : file path of raster layer .
: param dataType : GRASS data type for exporting data .
: param layer : In GRASS a vector can have multiple layers .
: param nocats : Also export features without category if True .
2017-10-22 10:25:09 +02:00
"""
for cmd in [ self . commands , self . outputCommands ] :
cmd . append (
2017-10-22 19:03:39 +02:00
' v.out.ogr {0} type= {1} {2} input= " {3} " output= " {4} " {5} ' . format (
2017-12-28 18:28:18 +01:00
' -c ' if nocats else ' ' ,
2017-10-22 10:25:09 +02:00
dataType ,
2017-10-22 19:03:39 +02:00
' layer= {} ' . format ( layer ) if layer else ' ' ,
2017-10-22 10:25:09 +02:00
grassName ,
fileName ,
' format=ESRI_Shapefile --overwrite '
)
)
2014-04-19 15:53:43 +02:00
2017-12-30 17:16:16 +01:00
def loadAttributeTableFromParameter ( self , name , parameters , context ) :
"""
Creates a dedicated command to load an attribute table
into the temporary GRASS DB .
: param name : name of the parameter
: param parameters : Parameters of the algorithm .
: param context : Processing context
"""
table = self . parameterAsVectorLayer ( parameters , name , context )
self . loadAttributeTable ( name , table )
def loadAttributeTable ( self , name , layer , destName = None ) :
"""
Creates a dedicated command to load an attribute table
into the temporary GRASS DB .
: param name : name of the input parameter .
: param layer : a layer object to import from .
: param destName : force the name for the table into GRASS DB .
"""
self . inputLayers . append ( layer )
if not destName :
destName = ' table_ {} ' . format ( os . path . basename ( getTempFilename ( ) ) )
self . exportedLayers [ name ] = destName
command = ' db.in.ogr --overwrite input= " {0} " output= " {1} " ' . format (
os . path . normpath ( layer . source ( ) ) , destName )
self . commands . append ( command )
def exportAttributeTable ( self , grassName , fileName , outFormat = ' CSV ' , layer = 1 ) :
"""
Creates a dedicated command to export an attribute
table from the temporary GRASS DB into a file via ogr .
: param grassName : name of the parameter .
: param fileName : file path of raster layer .
: param outFormat : file format for export .
: param layer : In GRASS a vector can have multiple layers .
"""
for cmd in [ self . commands , self . outputCommands ] :
cmd . append (
' db.out.ogr input= " {0} " output= " {1} " layer= {2} format= {3} --overwrite ' . format (
grassName , fileName , layer , outFormat
)
)
2017-09-04 16:31:31 +02:00
def setSessionProjectionFromProject ( self ) :
"""
Set the projection from the project .
We creates a PROJ4 definition which is transmitted to Grass
"""
2016-05-06 12:02:59 +02:00
if not Grass7Utils . projectionSet and iface :
2016-01-20 16:39:13 +02:00
proj4 = iface . mapCanvas ( ) . mapSettings ( ) . destinationCrs ( ) . toProj4 ( )
2017-09-04 16:31:31 +02:00
command = ' g.proj -c proj4= " {} " ' . format ( proj4 )
2015-12-16 17:39:16 +01:00
self . commands . append ( command )
2014-04-19 15:53:43 +02:00
Grass7Utils . projectionSet = True
2017-09-04 16:31:31 +02:00
def setSessionProjectionFromLayer ( self , layer ) :
"""
Set the projection from a QgsVectorLayer .
We creates a PROJ4 definition which is transmitted to Grass
"""
2014-04-19 15:53:43 +02:00
if not Grass7Utils . projectionSet :
2017-09-04 16:31:31 +02:00
proj4 = str ( layer . crs ( ) . toProj4 ( ) )
command = ' g.proj -c proj4= " {} " ' . format ( proj4 )
self . commands . append ( command )
Grass7Utils . projectionSet = True
2014-04-19 15:53:43 +02:00
2017-10-22 10:25:09 +02:00
def convertToHtml ( self , fileName ) :
# Read HTML contents
lines = [ ]
html = False
with open ( fileName , ' r ' , encoding = ' utf-8 ' ) as f :
lines = f . readlines ( )
if len ( lines ) > 1 and ' <html> ' not in lines [ 0 ] :
# Then write into the HTML file
with open ( fileName , ' w ' , encoding = ' utf-8 ' ) as f :
f . write ( ' <html><head> ' )
f . write ( ' <meta http-equiv= " Content-Type " content= " text/html; charset=utf-8 " /></head> ' )
f . write ( ' <body><p> ' )
for line in lines :
f . write ( ' {} </br> ' . format ( line ) )
f . write ( ' </p></body></html> ' )
2017-05-15 12:08:26 +10:00
def canExecute ( self ) :
2017-10-26 16:09:46 +02:00
message = Grass7Utils . checkGrassIsInstalled ( )
2017-05-15 12:08:26 +10:00
return not message , message
2014-04-19 15:53:43 +02:00
2017-05-16 15:21:41 +10:00
def checkParameterValues ( self , parameters , context ) :
2015-12-16 17:39:16 +01:00
if self . module :
if hasattr ( self . module , ' checkParameterValuesBeforeExecuting ' ) :
func = getattr ( self . module , ' checkParameterValuesBeforeExecuting ' )
2017-10-22 10:25:09 +02:00
#return func(self, parameters, context), None
return None , func ( self , parameters , context )
2017-05-16 15:21:41 +10:00
return super ( Grass7Algorithm , self ) . checkParameterValues ( parameters , context )