Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port gdalcalc with formula excaping fix #6984

Merged
merged 21 commits into from
May 14, 2018

Conversation

luipir
Copy link
Contributor

@luipir luipir commented May 14, 2018

Description

Ported missing gdal processing alg gdalcalc (wrapper to wdal_calc) to 3.X. Console tests included.

fix promoted inside GeoMove [1] project for Cartolab [2] (A Coruña university)

[1] http://cartolab.udc.es/geomove/
[2] http://cartolab.udc.es

Checklist

Reviewing is a process done by project maintainers, mostly on a volunteer basis. We try to keep the overhead as small as possible and appreciate if you help us to do so by completing the following items. Feel free to ask in a comment if you have troubles with any of them.

  • Commit messages are descriptive and explain the rationale for changes
  • Commits which fix bugs include fixes #11111 in the commit message next to the description
  • Commits which add new features are tagged with [FEATURE] in the commit message
  • Commits which change the UI or existing user workflows are tagged with [needs-docs] in the commit message and contain sufficient information in the commit message to be documented
  • I have read the QGIS Coding Standards and this PR complies with them
  • This PR passes all existing unit tests (test results will be reported by travis-ci after opening this PR)
  • New unit tests have been added for core changes
  • I have run the scripts/prepare-commit.sh script before each commit

@luipir luipir requested a review from nyalldawson May 14, 2018 10:06
Copy link
Collaborator

@nyalldawson nyalldawson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!! So nice to see this resurrected.

@@ -176,7 +176,7 @@ def loadAlgorithms(self):
warp(),
# rasterize(),
# ExtractProjection(),
# gdalcalc(),
gdalcalc(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#pedantic , but we've started sorting these imports and algorithms

self.tr('Calculation in gdalnumeric syntax using +-/* or any numpy array functions (i.e. logical_and())'),
'A*2',
optional=False))
self.addParameter(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.addParameter(ParameterString(self.EXTRA,
self.tr('Additional creation parameters'), '', optional=True))
self.addOutput(OutputRaster(self.OUTPUT, self.tr('Calculated')))
self.addParameter(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set the metadata for this param to get the nice widget - e.g. copy https://github.com/qgis/QGIS/blob/master/python/plugins/processing/algs/gdal/merge.py#L93

@@ -105,24 +172,32 @@ def group(self):
def groupId(self):
return 'rastermiscellaneous'

def commandName(self):
if isWindows():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commandName doesn't include the .py extension - this should always return 'gdal_calc'

noData = self.getParameterValue(self.NO_DATA)
if noData is not None:
noData = str(noData)
if not parameters:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise would fail test https://github.com/qgis/QGIS/blob/master/python/plugins/processing/tests/GdalAlgorithmsTest.py#L112
or the test should be adapted to consider other type of processing exceptions

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you implement the other changes I've listed here then that test should pass ok

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I see, tnx

# extra = str(extra)
#debug = self.getParameterValue(parameters, self.DEBUG)
formula = self.parameterAsString(parameters, self.FORMULA, context)
noData = self.parameterAsDouble(parameters, self.NO_DATA, context)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


arguments = []
arguments.append('--calc')
arguments.append('"' + formula + '"')
arguments.append('--calc "{}"'.format(formula) )
arguments.append('--format')
arguments.append(GdalUtils.getFormatShortNameFromFilename(out))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here use QgsRasterFileWriter.driverForExtension(os.path.splitext(out)[1])

if self.getParameterValue(self.BAND_A):
arguments.append('--A_band ' + self.getParameterValue(self.BAND_A))
if self.getParameterValue(self.INPUT_B):
arguments.append(self.parameterAsLayer(parameters, self.INPUT_A, context).source())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a bit more safety:

layer_a = self.parameterAsRasterLayer(parameters, self.INPUT_A, context)
if layer_a is None:
        raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT_A))
arguments.append(layer_a.source())

arguments.append(self.parameterAsLayer(parameters, self.INPUT_A, context).source())
if self.parameterAsString(parameters, self.BAND_A, context):
arguments.append('--A_band ' + self.parameterAsString(parameters, self.BAND_A, context))
if self.parameterAsLayer(parameters, self.INPUT_B, context):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the optional layers you would go:

if self.INPUT_B in parameters and parameters[self.INPUT_B] is not None:
    layer_b = self.parameterAsRasterLayer(parameters, self.INPUT_B, context)
    if layer_b is None:
         raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT_B))
    arguments.append(layer_b.source())

'A*2',
optional=False))
self.addParameter(
QgsProcessingParameterString(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a numeric parameter, not string

return ['gdal_calc', GdalUtils.escapeAndJoin(arguments)]
else:
return ['gdal_calc.py', GdalUtils.escapeAndJoin(arguments)]
return ['gdal_calc.py', GdalUtils.escapeAndJoin(arguments)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need to use gdal_calc (no .py) outside of windows? Other gdal algs still use the non .py command names on Linux.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no idea if it's a problem with my compied installation... but I receive a "gdal_calc" not found if I use self.commandName(), that's running test locally. No idea if it change on travis, it should be strange. btw I try to set again self.commandName and see what append to travis.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry I was referring running the alg. Tests just check commandConsole return

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GDAL command:
gdal_calc --calc "A*2" --format GTiff --type Float32 -A /home/ginetto/PROGRAMMING/GIS/GISDATA/qgis_sample_data/raster/landcover.img --A_band 1 --outfile /tmp/processing_b75de98ae82149cea15c40d81f2d6b96/c8207372386d409d87ef0351a3718727/OUTPUT.tif
GDAL command output:
/bin/sh: 1: gdal_calc: not found

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, confirmed on Fedora - gdal_calc.py works, gdal_calc doesn't

@nyalldawson
Copy link
Collaborator

Perfect - much appreciated!!

@nyalldawson nyalldawson merged commit 9b28e3d into qgis:master May 14, 2018
@luipir
Copy link
Contributor Author

luipir commented May 14, 2018

thx @nyalldawson for the review

@luipir
Copy link
Contributor Author

luipir commented May 15, 2018

@nyalldawson should I have to produce a fix for the commandName() result depending on win or not? (adding .py)? or it's a packaging problem? No idea why travis is able to run the command and a compiled version do not!

@nyalldawson
Copy link
Collaborator

I'd wait and see. It looks ok to me as is, so let's just see if anyone reports issues.

@luipir
Copy link
Contributor Author

luipir commented May 15, 2018

I'll ask to @gioman if he can verify any issue on his different platforms

@luipir luipir deleted the port_gdalcalc_with_formula_exaping_fix branch May 15, 2018 08:43
@gioman
Copy link
Contributor

gioman commented May 15, 2018

I'll ask to @gioman if he can verify any issue on his different platforms

@luipir on Linux the command works only with the .py extension, on Windows is the opposite.

@luipir
Copy link
Contributor Author

luipir commented May 15, 2018

so I can't explain because it pass tests on docker! any idea @3nids ?

@nyalldawson
Copy link
Collaborator

on Linux the command works only with the .py extension, on Windows is the opposite.

I don't see that - for me I have to use gdal_calc.py:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants