Problem with raster Reclassify in python script

7508
14
Jump to solution
11-03-2015 04:39 PM
RebeccaStrauch__GISP
MVP Emeritus

Cross posting: Python

I'm writing a python tool that given a elevation raster (elevation value in meters), converts to a "raster object" with elevation value in feet. I then create a variable based on elevation Range provided be the user to be used with the Reclassify command as a RemapRange.  The result of this Reclassify (and maybe one other step eventually) will be input to RasterToPolygon

I've included a very simplified version of the code I have,

The out value of my reclassArg is

     [[327.850126532, 1000, 1000], [1000,  2000,  2000], [ 2000,  3000,  3000], [ 3000, 6500, 6500]]

But I have also tried  version     such as

     327.850126532 1000 1000; 1000  2000  2000;  2000  3000  3000;  3000 6500 6500

and all different variations of the two, based on the "results" snippet, and various help docs.

I've tried quite a few different commands and versions of the reclassArg, with the last being from the local ArcGIS 10.3 tool help

But my output raster keeps come out with a single value 127.   Full disclosure, before I tried

     outDEMtmp = Reclassify(elevFeet, "Value", RemapRange("{0}".format(reclassArg)), "NODATA")

or

     outDEMtmp = arcpy.sa.Reclassify(elevFeet, "Value", RemapRange("{0}".format(reclassArg)), "NODATA")

and even

     arcpy.gp.Reclassify_sa(elevFeet, "Value", reclassArg, outDEMtmp, "NODATA")

The first two (using the [[ ]] list as reclassArg)  finishes without an erro, but all values are are "127"

The third option is not reclassifying anything.

I admit my spatial analyst skills are very rusty, and the raster-object concept is new (all though similar to the old GRID), but I'm running out of ideas to try, other than running the tools manually.  Any help or a good resource on scripting the Reclassify tool would be helpful.

Using 10.3, ArcInfo/Advanced and Spatial Analyst (I have access to 3D if needed).

import os
import arcpy
from arcpy import env
from arcpy.sa import *

arcpy.CheckOutExtension("spatial")

theWorkspace = r"C:\_beartest\Prep.gdb"
arcpy.env.workspace = theWorkspace
arcpy.env.overwriteOutput = True
wsPath, wsGDB = os.path.split(theWorkspace)

rasterIn = r"C:\_beartest\Unit20Araster.gdb\elevClip"

toElevFeet = 3.280839895013123

elevFeet = (Raster(rasterIn) * toElevFeet)
elevMinimum = elevFeet.minimum

elevCutoffFt = "6500"
flatElevBreak = ("1000; 2000; 3000")

# processing the elevation and high-cuttoff variables to create reclass arguments
elevSplit = flatElevBreak.split(";")
lstCnt = 1
for reclassValue in elevSplit:
    print(reclassValue)
    print("Reclass value:{0} ft".format(reclassValue))
    if lstCnt == 1:
        reclassArg = ("[[{0}, {1}, {2}]".format(elevMinimum, reclassValue, ("{0}".format(reclassValue))))
    else:
        reclassArg = ("{0}, [{1}, {2}, {3}]".format(reclassArg, prevValue, reclassValue, ("{0}".format(reclassValue))))
    lstCnt += 1
    prevValue = reclassValue
reclassArg = ("{0}, [{1}, {2}, {3}]]".format(reclassArg, prevValue, elevCutoffFt, ("{0}".format(elevCutoffFt))))
print(reclassArg)

outDEMtmp = arcpy.sa.Reclassify(elevFeet, "Value", RemapRange("{0}".format(reclassArg)), "NODATA")
outDEMtmp.save(elevReclass)

print("hello2")
#arcpy.RasterToPolygon_conversion(outDEMtmp, "reclassPoly", "SIMPLIFY", "VALUE")

arcpy.CheckInExtension("spatial")

Suggestions would be greatly appreciated.  Thanks

EDIT: added line 18 which was missing.

Message was edited by: Rebecca Strauch, GISP EDIT: added line 18 which was missing.

0 Kudos
1 Solution

Accepted Solutions
DanPatterson_Retired
MVP Emeritus

I was thinking about his idea of doing it all at once, after building the remap table

eg.

remap = RemapRange([[1000, 2000, 1], [2000, 3000, 2],  [3000, 4000, 3]]

out_reclass = Reclassify(raster, "Value", remap, "NODATA")

View solution in original post

14 Replies
DanPatterson_Retired
MVP Emeritus

you are reclassing ranges to the higher of the range...correct? (it should be a list of lists)

can you show the results of your print statements? and perhaps whip in a few more at the various stages

0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

Hi Dan, running this in the ArcMap python window....

>>> import os
... import arcpy
... from arcpy import env
... from arcpy.sa import *
... 
... arcpy.CheckOutExtension("spatial")
... 
... theWorkspace = r"C:\_beartest\Prep.gdb"
... arcpy.env.workspace = theWorkspace
... arcpy.env.overwriteOutput = True
... wsPath, wsGDB = os.path.split(theWorkspace)
... 
... rasterIn = r"C:\_beartest\Unit20Araster.gdb\elevClip"
... 
... toElevFeet = 3.280839895013123
... 
... elevFeet = (Raster(rasterIn) * toElevFeet)
... elevMinimum = elevFeet.minimum
... 
... elevCutoffFt = "6500"
... flatElevBreak = ("1000; 2000; 3000")
... 
... # processing the elevation and high-cuttoff variables to create reclass arguments
... elevSplit = flatElevBreak.split(";")
... lstCnt = 1
... for reclassValue in elevSplit:
...     print(reclassValue)
...     print("Reclass value:{0} ft".format(reclassValue))
...     if lstCnt == 1:
...         reclassArg = ("[[{0}, {1}, {2}]".format(elevMinimum, reclassValue, ("{0}".format(reclassValue))))
...     else:
...         reclassArg = ("{0}, [{1}, {2}, {3}]".format(reclassArg, prevValue, reclassValue, ("{0}".format(reclassValue))))
...     lstCnt += 1
...     prevValue = reclassValue
... reclassArg = ("{0}, [{1}, {2}, {3}]]".format(reclassArg, prevValue, elevCutoffFt, ("{0}".format(elevCutoffFt))))
... print(reclassArg)
... 
... outDEMtmp = arcpy.sa.Reclassify(elevFeet, "Value", RemapRange("{0}".format(reclassArg)), "NODATA")
... #outDEMtmp.save(elevReclass)
... 
... print("hello2")
... #arcpy.RasterToPolygon_conversion(outDEMtmp, "reclassPoly", "SIMPLIFY", "VALUE")
... 
... arcpy.CheckInExtension("spatial")
... 
1000
Reclass value:1000 ft
 2000
Reclass value: 2000 ft
 3000
Reclass value: 3000 ft
[[327.850126532, 1000, 1000], [1000,  2000,  2000], [ 2000,  3000,  3000], [ 3000, 6500, 6500]]
hello2
>>> 
0 Kudos
DanPatterson_Retired
MVP Emeritus

I am trying to figure out where the 127 is coming from (I have my suspicions).  Can you change the reclass value ranges by putting a decimal point in the number range and convert to an integer output class ie( 1000.0, 2000.0, 2) just for fun.

Curtis Price​ if you are around, can you pin this down?

0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

Good thought Dan.  At least I'm getting an error now.  If I have the reclassArg as

     [[327.850126532, 1000.0, 1000], [1000.0,  2000.0,  2000], [ 2000.0,  3000.0,  3000], [ 3000.0, 6500.0, 6500]]

inputting it into the same command...

outDEMtmp = arcpy.sa.Reclassify(elevFeet, "Value", RemapRange("{0}".format(reclassArg)), "NODATA")

I am now getting error

I tried simplifying it more, as you suggested and getting same error.

     reclassArg = "(1000.0, 2000.0, 2)"

     print ("new reclassArg: {0}".format(reclassArg))

     outDEMtmp = arcpy.sa.Reclassify(elevFeet, "Value", RemapRange("{0}".format(reclassArg)), "NODATA")

I got the same error.  So, I'm trying a few more reclass command combinations to see if it will make any difference.

grrrrrrrrr......

0 Kudos
DanPatterson_Retired
MVP Emeritus

Do you have to send it as a string representation of a tuple, since you can send the tuple directly

>>> reclassArg = (1000.0,2000.0,2)

>>> print("new version: {}".format(reclassArg))

new version: (1000.0, 2000.0, 2)

and since you only have one parameter, you need not specify the parameter number unless you are providing things out of order. eg....

>>> ObiSpeak = ["Confused", "am", "I"]

>>> print("{2} {1} {0}".format(*ObiSpeak))

I am Confused

0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

Thanks Dan.

     reclassArg = (1000.0,2000.0,2)

     fff = arcpy.sa.Reclassify("elevClip", "Value", RemapRange("{0}".format(reclassArg)),"NODATA")

Still came out as 127.

BTW, I know the {#} isn't necessary, but I find its a good habit for me to be in so I don't screw up when I do reorder.  Doesn't hurt anything, IMO.

0 Kudos
DanPatterson_Retired
MVP Emeritus
RebeccaStrauch__GISP
MVP Emeritus

That is helpful, but still not fixing things.  But now I'm starting to think is is how I am building the reclassArg value.  if I set a new value to the value of reclassArg and follow hints in the other thread, it clearly shows that my variable is not seeing it as a list.  Looks like I need to work on the formatting, then test again

>>>reclassArg

'[[327.850126532, 1000.0, 1000], [1000.0,  2000.0,  2000], [ 2000.0,  3000.0,  3000], [ 3000.0, 6500.0, 6500]]'

>>> zzz = '[[327.850126532, 1000.0, 1000], [1000.0,  2000.0,  2000], [ 2000.0,  3000.0,  3000], [ 3000.0, 6500.0, 6500]]'

>>> remap = RemapRange(zzz)

>>> remap

RemapRange([['['], ['['], ['3'], ['2'], ['7'], ['.'], ['8'], ['5'], ['0'], ['1'], ['2'], ['6'], ['5'], ['3'], ['2'], [','], [' '], ['1'], ['0'], ['0'], ['0'], ['.'], ['0'], [','], [' '], ['1'], ['0'], ['0'], ['0'], [']'], [','], [' '], ['['], ['1'], ['0'], ['0'], ['0'], ['.'], ['0'], [','], [' '], [' '], ['2'], ['0'], ['0'], ['0'], ['.'], ['0'], [','], [' '], [' '], ['2'], ['0'], ['0'], ['0'], [']'], [','], [' '], ['['], [' '], ['2'], ['0'], ['0'], ['0'], ['.'], ['0'], [','], [' '], [' '], ['3'], ['0'], ['0'], ['0'], ['.'], ['0'], [','], [' '], [' '], ['3'], ['0'], ['0'], ['0'], [']'], [','], [' '], ['['], [' '], ['3'], ['0'], ['0'], ['0'], ['.'], ['0'], [','], [' '], ['6'], ['5'], ['0'], ['0'], ['.'], ['0'], [','], [' '], ['6'], ['5'], ['0'], ['0'], [']'], [']']])

So, at least that helps...maybe. 

0 Kudos
DanPatterson_Retired
MVP Emeritus

check my format string which doesn't cast the variable as a string which yours does, it casts it as a tuple. If you build the table as in curtis's example then you should have the format you need  Curtis should be online soon

0 Kudos