ArcGIS Pro RasterCalc Tool Map Algebra Expression Proper Syntax through code

2862
5
02-02-2017 08:47 AM
ThomasCox
Occasional Contributor

I would appreciate some syntax assistance regarding how to build in code the map algebra syntax used by RasterCalc tool in ArcGIS Pro.  I have successfully implemented other Geoprocessing tools and was able to create the necessary args for required value array without much heartburn.

However, doing this for the RasterCalc Geoprocessing through code has proven elusive.  I have looked at the native tool in ArcGIS Pro. The tool appears to call for building a map algebra expression using an input raster and whatever calculation you wish to perform.  When I interactively use the tool, the desired syntax it produces is:

"sd_20170201" * 10000

raster calc tool ArcGIS Pro

I am able to run the tool interactively in ArcGIS Pro successfully. I thought this would be simple enough to build in code. Unfortunately, it has proven more involved.  I have build numerous versions ( fully qualifying the path to the input raster, various quoting strategies etc ) with no luck. 


Interestingly, when I returned to running the tool interactively through ArcGIS Pro to revisit this, when I first build the string through the tool interface,  I noticed the icon appeared adjacent to the Map Algebra expression label displays a red circle with a white X,  when I hover over the icon, it displays a same syntax error message I am encountering through code:  "ERROR 000989  Python Syntax Error: Parsing error SyntaxError: invalid syntax ( <string>, line 1)"

However, when  I click out of the expression textbox, the error icon disappears and the tool now likes the expression. 

After observing this, I thought that perhaps clicking out of the expression textbox might append a carriage return
to the string.  I tried the same approach in code, but it still threw the 989 error.  If anyone could provide the code version of building this seemingly simple string that the RasterCalc tool would like in code, I would be quite grateful.

Thanks for your time.

Cheers.

0 Kudos
5 Replies
MaxMax2
Occasional Contributor II

Hi Thomas,

You want to use Raster Calculator tool in your .NET code, is it correct? If yes I see no problems to do this:

var expression = "\"tmp.png\\Band_1\" * 10";
var outputRaster = @"D:\tmp\out_from_rc";
var parameters = Geoprocessing.MakeValueArray(expression,
                                              outputRaster);

var workspace = @"D:\tmp";
var environments = Geoprocessing.MakeEnvironmentArray(workspace: workspace);

var gpResult = await Geoprocessing.ExecuteToolAsync("RasterCalculator",
                                                    parameters,
                                                    environments,
                                                    CancelableProgressor.None);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I succesfully created out_from_rc raster dataset with this code. It seems that you've missed to set workspace environment variable. It should be set to location where your rasters are placed.

P.S. Very often validation in text boxes occurs only on text box lost keyboard focus. It is standard practice and there is really nothing unusual in this behavior. So if you type some invalid expression, click outside of the text box (now red circle with X will appear), then return to text box and correct your expression, red circle with X will not disappear until the text box lost keyboard focus. It is normal.

0 Kudos
ThomasCox
Occasional Contributor

Hi Max,

 

Thanks for your help.  I appreciate you taking to the time to respond.

Yes, I am trying to use the RasterCalc tool from dot net code.

 

I have tried using your syntax as well as using the workspace environment, and am still encountering the same problem.  I noticed your example referenced a png file.  I don’t know if using esri GRIDS requires a different approach.  However, I interactively ran the raster calculator tool in ArcGIS Pro and the syntax it built on the screen appeared to be the same for GRIDs as well as pngs.  I noticed your example referenced Band_1 in the expression piece.  The GRIDs I am using only contain one band.  However, as an experiment, I did try expressions referencing Band_1 with the same results.

 

If you don’t mind taking a look, perhaps you can see the error of my ways.  The ‘source’  esri GRID directory is located on one of our network drives. For example the source grid would be:

 

@”\\dom.example\data\snow\sd_20170201    This path points to a GRID directory. 

 

With these parameters I have tried the following:

 

      var expression = @”\\dom.example\data\snow\sd_20170201” + “ * “ + “10000”;

      var outputRaster = @”C:\Temp\out_from_rc”;

      var parameters = Geoprocessing.MakeValueArray(expression, outputRaster);

      var workspace = @”C:\Temp”;

      var environments = Geoprocessing.MakeEnvironmentArray(workspace: workspace);

      var gpResults = await Geoprocessing.ExecuteToolAsycn(“RasterCalculator”,                               parameters,environments,CancelableProgressor.None);

 

I have tried some variations of syntax for the expression, with no luck.   I don’t know if using the GRID format introduces different requirements or having the source data and the results data living in different workspaces creates issues.  The interactive tool does not seem to mind any of this.

 

Once again, thanks for responding.

0 Kudos
MaxMax2
Occasional Contributor II

Hi Thomas,

Of course I am seeing errors:

  1. Your input raster is placed in \\dom.example\data\snow. So why do you try to use C:\Temp as a value for the workspace environment variable? This variable must be set to location where your rasters are placed as I wrote in my previous comment.
  2. Expression must not contain full paths of input rasters. You specify path to them in workspace environment variable. Expression should contain only names of input rasters (optionally with band name).

So the right version of your code is:

var expression = "\"sd_20170201\" * 10000";
var outputRaster = @"C:\Temp\out_from_rc";
var parameters = Geoprocessing.MakeValueArray(expression,
                                              outputRaster);

var workspace = @"\\dom.example\data\snow";
var environments = Geoprocessing.MakeEnvironmentArray(workspace: workspace);
var gpResult = await Geoprocessing.ExecuteToolAsycn("RasterCalculator",
                                                    parameters,
                                                    environments,
                                                    CancelableProgressor.None);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I've tested this code with input ESRI GRID raster stored in remote directory and succesfully created output raster with it.

0 Kudos
ThomasCox
Occasional Contributor

Thanks Max.  I did not understand the role of the workspace in the process.  I thought fully pathing to the source was necessary in the 'expression'. Now that you pointed out the error of my ways, it seems straight forward.

Additionally, while I was working on this, with a tip from ESRI, I looked at the "Times" tool and was able to use it to achieve the desired result as well.

I appreciate your time and thanks for the assistance.

0 Kudos
LesleyBross1
New Contributor III

I struggled to get a simple raster calculator expression working with v2.8.2. I started with this example from the ArcGIS blog. The problem is that the example shows the layer file names encased by single quotes and it apparently needs to be double quotes. With double quotes, my expression with fully qualified file names works fine. Unfortunately comments are closed for the blog entry.

Some sample C#:
string annualRaster =  @”C:\Docs\animas_AOI_prms\prism.gdb\annual”;
string quarterlyRaster =  @”C:\Docs\animas_AOI_prms\prism.gdb\sq1”;
string maExpression = String.Format("\"{1}\" / \"{0}\" * 100", annualRaster, quarterlyRaster);
var valueArray = Geoprocessing.MakeValueArray(maExpression, outRaster);
var gpResult = await Geoprocessing.ExecuteToolAsync("RasterCalculator_sa", valueArray, environments);

0 Kudos