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.
Solved! Go to Solution.
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")
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
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 >>>
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?
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......
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
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.
hmmmm ringing a bell
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.
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