Well I want to apply multiple conditional statements within a Conditional tool. My aim is to loop through a list of rasters and on the basis of a specified range assign each range with a constant 1, 2, 3, 4 or 5 value so that all the final rasters have pixels having a DN of 1,2,3,4, or 5. I copied the template from the following Desktop Help website and adjusted to my requirements.
My code is as follows:
import arcpy
from arcpy import env
# Set the current workspace
env.workspace = r"C:\Experiments\Test_Jan03-11_A\Masked"
# Get a list of Rasters
rasters = arcpy.ListRasters("*", "ALL")
for raster in rasters:
output = arcpy.sa.Con(raster <= -10, 1, Con(raster <= 73, 2, Con(raster <= 196, 3, Con(raster <= 403, 4, Con(raster <= 600, 5, 0)))))
output.save("C:/zE/ResearchWork/UnderWorks/Experiments/Test_Jan03-11_A/Masked/Classify")
Print = "Done"
Runtime error <type 'exceptions.NameError'>: name 'Con' is not defined
The error indicates that I am making a mistake with the conditional statement that I can't identify.
The following code has worked. But with some issues stated below
import arcpy
from arcpy import env
arcpy.env.extent = "MAXOF"
# check out spatial analyst extension
if arcpy.CheckExtension('Spatial') == 'Available':
arcpy.CheckOutExtension('Spatial')
else:
arcpy.AddMessage("Error: Couldn't get Spatial Analyst extenstion, exiting")
sys.exit(1)
from arcpy.sa import *
# Set the current workspace
env.workspace = r"C:\zE\ResearchWork\UnderWorks\Experiments\Test_Jan03-11_A\Masked\CMasked"
# set cell size
arcpy.env.cellSize = r"C:\zE\ResearchWork\UnderWorks\Experiments\Test_Jan03-11_A\Masked\CMasked\GW1AM2_20130100_01M_EQMA_L3SGSMCLA1110100"
# Get a list of Rasters
rasters = arcpy.ListRasters("*", "ALL")
for raster in rasters:
inRas = Raster(raster)
for raster in rasters:
output = arcpy.sa.Con(inRas <= -10,1,Con(inRas <= 73,2,Con(inRas <= 196,3,Con(inRas <= 403,4,Con(inRas <= 600,5,0)))))
output.save("C:/zE/ResearchWork/UnderWorks/Experiments/Test_Jan03-11_A/Masked/CMasked/MaskedClassify")
Print = "Done"
The problem is that the result is only one raster. I was expecting each of the input rasters to be classified and saved separately. Also it is giving me the following error for saving data.
Runtime error <type 'exceptions.RuntimeError'>: ERROR 010240: Could not save raster dataset to C:/zE/ResearchWork/UnderWorks/Experiments/Test_Jan03-11_A/Masked/CMasked/MaskedClassify with output format GRID.
-
To clearify the range is <-10=1, -10<>73=2, 73<>196=3, 196<>403=4, 403<>600=5zEE– zEE2014年05月06日 04:04:42 +00:00Commented May 6, 2014 at 4:04
3 Answers 3
You'll laugh.
Reference http://resources.arcgis.com/en/help/main/10.1/index.html#//009z00000005000000
In order to use con directly in that statement one must from arcpy.sa import *
or arcpy.sa.Con(raster <= -10, 1, arcpy.sa.Con(raster <= 73, 2, arcpy.sa.Con(raster <= 196, 3, arcpy.sa.Con(raster <= 403, 4, arcpy.sa.Con(raster <= 600, 5, 0)))))
I've fiddled with your code and fixed a few little problems, please note the comments as there's still a few traps there...
for raster in rasters:
inRas = Raster(raster)
for raster in rasters:
output = arcpy.sa.Con(inRas <= -10,1,Con(inRas <= 73,2,Con(inRas <= 196,3,Con(inRas <= 403,4,Con(inRas <= 600,5,0)))))
Is incorrect logic so I have removed one of the loops: if you loop through creating your rasters and then loop again creating your outputs you are essentially creating the last raster as output, one for each input raster and they will all be the same! The value of inRas
coming into the second loop is the last raster and is not changed in the second loop.
This is the amended code:
import arcpy, os
from arcpy import env
arcpy.env.extent = "MAXOF"
# check out spatial analyst extension
if arcpy.CheckExtension('Spatial') == 'Available':
arcpy.CheckOutExtension('Spatial')
else:
arcpy.AddMessage("Error: Couldn't get Spatial Analyst extenstion, exiting")
sys.exit(1)
from arcpy.sa import *
# Set the current workspace
env.workspace = r"C:\zE\ResearchWork\UnderWorks\Experiments\Test_Jan03-11_A\Masked\CMasked"
# set cell size
arcpy.env.cellSize = r"C:\zE\ResearchWork\UnderWorks\Experiments\Test_Jan03-11_A\Masked\CMasked\GW1AM2_20130100_01M_EQMA_L3SGSMCLA1110100"
# Get a list of Rasters
rasters = arcpy.ListRasters("*", "ALL")
for raster in rasters:
# get the name and extention from the filename
# so abc.tif becomes RasName "abc" and RasExt ".tif"
RasName, RasExt = os.path.splitext(raster)
inRas = Raster(raster)
output = arcpy.sa.Con(inRas <= -10,1,Con(inRas <= 73,2,Con(inRas <= 196,3,Con(inRas <= 403,4,Con(inRas <= 600,5,0)))))
# note: you're putting your outputs in the same folder as your inputs
# so next time you run it the process will pick these up too
output.save(env.workspace + "/MaskedClassify" + RasName + ".tif")
Print = "Done"
# let it go until next time
arcpy.CheckInExtension("Spatial")
The function os.splitext has a great reference https://stackoverflow.com/questions/541390/extracting-extension-from-filename-in-python it separates the base name and extension of the file, this is not ArcPY just python. The base path of your output.save is the same as your env.workspace
so instead of putting it in full I changed it to concatenate (join) the strings using '+', there are other ways to do this but I felt that this way is the most basic.
-
Well this was stupid i was seeing this code everywhere i am amazed i had not added it but when I added "from arcpy.sa import *" then i got the following error "Runtime error <type 'exceptions.RuntimeError'>: No CellSize and Extent set" . Now working on what ibe told me to dozEE– zEE2014年05月06日 04:27:59 +00:00Commented May 6, 2014 at 4:27
-
They are environment settings help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… for cell size (MAXOF I reccomend) and help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/… for extent (MAXOF as well)Michael Stimson– Michael Stimson2014年05月06日 04:33:21 +00:00Commented May 6, 2014 at 4:33
-
Well i added these in the following order to the above mentioned code still the same error import arcpy from arcpy import env arcpy.env.cellSize = "MAXOF" arcpy.env.extent = "MAXOF"zEE– zEE2014年05月06日 04:36:29 +00:00Commented May 6, 2014 at 4:36
-
That's great, now please select the most helpful answer and accept it as answered.. this helps users in the future locating what worked for you.Michael Stimson– Michael Stimson2014年05月07日 02:10:34 +00:00Commented May 7, 2014 at 2:10
-
Well all of you have been helpful in different ways all have told me some part that was missing in the overall code so it wont be justice just to select on answer as the best answer :)zEE– zEE2014年05月07日 02:58:54 +00:00Commented May 7, 2014 at 2:58
Apart from the fact that you need to use
from arcpy.sa import *
in order to use Con without its full description (arcpy.sa.Con) as already mentioned by @Michael Miles-Stimson. You should also make sure to use a raster object in your statment.
Indeed, listRaster return a Python list of raster string names. In order to use them in a Con statment, the best method is to create a raster object.
for raster in rasters:
inRas = Raster(raster)
Con(inRas <=10, 1, Con( ... )
-
Do I have to create a raster object for each and every raster in the list??? Is it not possible to just give list as an input and the code runs through all the rasters in the list one at a time apply the conditional statement, save the result and move on to next raster in the list???? @Michael Miles-StimsonzEE– zEE2014年05月07日 04:23:31 +00:00Commented May 7, 2014 at 4:23
-
I don't think this part relates specifically, you've only got one raster so for raster in is not for you. The error you're getting is because GRID has a maximum length for name, either shorten the name or put ".tif" on the end (or ".img") like CMasked/MaskedClassify.img")Michael Stimson– Michael Stimson2014年05月07日 05:41:35 +00:00Commented May 7, 2014 at 5:41
I have edited your code. Please give it a shot.
import arcpy
from arcpy import env
arcpy.env.extent = "MAXOF"
# check out spatial analyst extension
if arcpy.CheckExtension('Spatial') == 'Available':
arcpy.CheckOutExtension('Spatial')
else:
arcpy.AddMessage("Error: Couldn't get Spatial Analyst extenstion, exiting")
sys.exit(1)
# Set the current workspace
env.workspace = r"C:\Experiments\Test_Jan03-11_A\Masked"
# set cell size
arcpy.env.cellSize = r"C:\temp_ras"
# Get a list of Rasters
rasters = arcpy.ListRasters("*", "ALL")
for idx,raster in enumerate(rasters):
inRas = Raster(raster)
output = arcpy.sa.Con(raster <= -10, 1, Con(raster <= 73, 2, Con(raster <= 196, 3, Con(raster <= 403, 4, Con(raster <= 600, 5, 0)))))
output.save("C:/zE/ResearchWork/UnderWorks/Experiments/Test_Jan03-11_A/Masked/Classify"+str(idx))
Print "Done"
-
I added your code still giving me error "Runtime error <type 'exceptions.RuntimeError'>: No CellSize and Extent set"zEE– zEE2014年05月06日 04:30:34 +00:00Commented May 6, 2014 at 4:30
-
See my updated answer.
r"C:\temp_ras"
could be any raster data from your workspace which has same cell size as you want in your final output.Ibe– Ibe2014年05月06日 04:49:25 +00:00Commented May 6, 2014 at 4:49 -
Please see my edit in for loop. Now you can save all rasters.Ibe– Ibe2014年05月07日 04:58:03 +00:00Commented May 7, 2014 at 4:58