Advanced Con Statement in Raster Calculations

556
5
01-16-2012 03:45 AM
franzsuppan
New Contributor
Hi there,

i am trying to convert Python Code from 9.2 to 10.x
The problem i am facing: in ArcGIS 9.2 it was possible, to create a Map Algebra Expression with a variable number of input rasters by defining it as a string Variable.

In ArcGis 10 it is not anymore possible to use String Variables in a Raster Expression for building complex statements in a Con command.

So if i have an input list with 4 values, i want to create the expression like this,
(Raster(inRaster1) < var1[0]) & (Raster(inRaster2) > var1[1]) & (Raster(inRaster3) <> var1[2]) & (Raster(inRaster4) == var1[3]) ,

if i have only 2 input rasterfiles, only the first part of inRaster1 and inRaster2 should be used, if i have 16 or more files it should also work.

A conversion from String to Raster would be maybe the best solution, but the Con Command doesn't accept this.

Any suggestions, how to deal in ArcGis 10 with a variable number of input rasters?
With best regards
Tags (2)
0 Kudos
5 Replies
ChrisSnyder
Regular Contributor III
Some suggestions:

1. v10.0 map algebra syntax is pretty hokey I think, but it is doable. This post (my own v10.0 flailings) may help: http://forums.arcgis.com/threads/47540-Lookup-function-in-v10.0-Map-Algebra-implementing-dot-notatio...

2. Continue to use the pre-v10 raster algebra syntax in v10.0... it's still there just hidden: arcpy.gp.SingleOutputMapAlgebra_sa(blah, blah)
0 Kudos
Luke_Pinner
MVP Regular Contributor
Perhaps try the eval function (I haven't tested this):
expression = '(Raster(inRaster1) < var1[0]) & (Raster(inRaster2) > var1[1]) & (Raster(inRaster3) <> var1[2]) & (Raster(inRaster4) == var1[3])'
NewRaster=eval(expression)
0 Kudos
franzsuppan
New Contributor
Thanks a lot Chris and Luke for your quick and perfect response!!!

I tried the eval Function (to be honest - i never used it before - and it works!!!)
Below is a working sample code:

import arcpy
import sys, string, os, time, math
from arcpy.sa import *


arcpy.CheckOutExtension("Spatial")
arcpy.env.overwriteOutput = True

raster1 = "D:/ACC/version01_lc2.img"
outraster4 = "D:/ACC/version01_lc_res04.img"

# suppose
var1 = [311, 401]
var2 = 23
var3 = 27

exp04 = "Con((Raster(raster1) < var1[0]) | (Raster(raster1) > var1[1]), var2, var3)"
res04 = eval(exp04)

res04.save(outraster4)
0 Kudos
curtvprice
MVP Esteemed Contributor
IMHO, using substitution syntax makes for more readable code, whether you're using the old or new tools. Note the %s substitution converts numbers to strings for you if that is required.
expression = "(Raster(%s) < %s) & (Raster(%s) > %s) & "
    "(Raster(%s) <> %s) & (Raster(%s) == %s)"
expression = expression % \
    (inRaster1,var1[0],inRaster2,var1[1],inRaster3,var1[2],inraster4,var1[3])
NewRaster=eval(expression).
NewRaster.save("outRaster")
0 Kudos
PhilMorefield
Occasional Contributor III
It took some getting used to, but the new map algebra can make things pretty clean. My two cents (with Python style guide enforced!):

import arcpy as ap
from arcpy import sa

ap.CheckOutExtention('Spatial')
ap.env.overWriteOutput = True

raster1 = ap.Raster("D:\\ACC\\version01_lc2.img")
outraster4 = "D:\\ACC\\version01_lc_res04.img"

var1 = [311, 401]
var2 = 23
var3 = 27

tempRas = sa.Con(raster1 < var1[0] | raster1 > var1[1], var2, var3)
tempRas.save(outraster4)
0 Kudos