Problem with raster Reclassify in python script

7513
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
14 Replies
RebeccaStrauch__GISP
MVP Emeritus

I tried that, but that didn't help any. Still getting 127.  I've tried various versions of the reclassArg formatting and using the  remap =  and using the RemapRange(reclassArg) with various formatting...both with .0 and without.  All either they come out as 127 or it just doesn't reclass. 

Maybe Curtis will have some other ideas.  Otherwise, hopefully tech support will have some ideas.  I'm getting close to giving up for the night.

0 Kudos
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")

RebeccaStrauch__GISP
MVP Emeritus

So, that worked, but I need to get my reclassArg, which will be created on the fly, into that format.  I've been working on that.

EDIT: after quite a bit more manipulation in getting my reclassArg into a list, I also realized for some reason it wants the new value to not be the same as my reclassValue.  No sure what the reason is for that right now, but at least now I might be able to clean it up and get it to work in the morning.   

EDIT2: cleaned up script a little...this is a snippet of what ended up working.  Super quick now, so I can now continue on.  Thanks for you help Dan (and Curtis Price​ via the other thread).  It was my reclassArg not being formatted correctly all along.

flatElevBreak = ("1000; 2000; 3000")

elevFeet = (Raster(rasterIn) * toElevFeet)
elevMin = elevFeet.minimum
elevMax = elevFeet.maximum  
print("\n Elevation raster source: {0}".format(elevFeet))

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

# Process: Reclassify
outDEMtmp = Reclassify(elevFeet, "Value", remap, "NODATA")

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



Dan, no need to keep refining the code...it works, it's readable...time for me to move on. 

0 Kudos
DanPatterson_Retired
MVP Emeritus

sorry It is late, I was thinking about how you put it together as well

minelev = 649

elevs = [1000,2000,3000]

elevs.insert(0,minelev)

remap = [[elevs[i-1],elevs,elevs] for i in range(1,len(elevs))]

print("remap ... {}".format(remap))

#out_reclass = Reclassify(raster, "Value", remap, "NODATA")   # then do this thing

print yields remap ... [[649, 1000, 1000], [1000, 2000, 2000], [2000, 3000, 3000]]

ADDENDUM

an example from one of Curtis's remap examples for weighted overlay

Re: Assign Dynamic Influence % to Weighted Overlay Table for Weighted Overlay Analysis

0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

I'm at a loss.

Dan/Curtis, et al., please send any suggestions if you have them, but time to put in a tech support ticket.  Most likely it is my just interpreting the help somehow, but having it comes out as one big 127 value has really got me stumped.  I even tried running it against the original elevation raster (meters) and it came out the same, so it has to be something with my range argument.

0 Kudos