Skip to main content
replaced http://gis.stackexchange.com/ with https://gis.stackexchange.com/
Source Link

If you have a spatial analyst license and the raster the contours came from you can follow the workflow in Colouring areas between (vector) contours?Colouring areas between (vector) contours? as translated for Esri and performed interactively in ArcMap:

If you have a spatial analyst license and the raster the contours came from you can follow the workflow in Colouring areas between (vector) contours? as translated for Esri and performed interactively in ArcMap:

If you have a spatial analyst license and the raster the contours came from you can follow the workflow in Colouring areas between (vector) contours? as translated for Esri and performed interactively in ArcMap:

added 1719 characters in body
Source Link
Michael Stimson
  • 25.7k
  • 2
  • 35
  • 75

Alternate (Spatial Analyst) method, much faster

If you have a spatial analyst license and the raster the contours came from you can follow the workflow in Colouring areas between (vector) contours? as translated for Esri and performed interactively in ArcMap:

Use the Zonal Statistics as Table tool to create a table using the polygons as input zones and FID (OBJECTID) as the zone field, I used statistics type "ALL" to avoid confusion later. This gives you a table with the raster statistics (min & max) for each polygon - and it's really fast!

Add fields to the polygons for the minimum and maximum elevation and then join the zonal statistics table (join in ArcMap polygon FID to ZonalTable ObjectID_1 or FID_1 depending on table type, either way it should be the second field in the zonal stats table) to your polygon and use the calculation like this:

MinElev = round( !ZonalStatsObjectID.MIN!,0 )
MaxElev = round( !ZonalStatsObjectID.MAX!,0 )

The name of the zonal statistics table in this example is ZonalStatsObjectID, change to match your table name. Do NOT use int( !ZonalStatsObjectID.MIN!), that's a truncation and will give you the wrong value.

After rounding and copying the values for min and max use field calculator on the table to calculate the nilai field:

def CalcNilai(Min,Max):
    if Min == Max:
        return "%d" % Min
    else:
        return "%d - %d" % (Min,Max)

Which should look like this (I've removed the join for simplicity): enter image description here

Alternate (Spatial Analyst) method, much faster

If you have a spatial analyst license and the raster the contours came from you can follow the workflow in Colouring areas between (vector) contours? as translated for Esri and performed interactively in ArcMap:

Use the Zonal Statistics as Table tool to create a table using the polygons as input zones and FID (OBJECTID) as the zone field, I used statistics type "ALL" to avoid confusion later. This gives you a table with the raster statistics (min & max) for each polygon - and it's really fast!

Add fields to the polygons for the minimum and maximum elevation and then join the zonal statistics table (join in ArcMap polygon FID to ZonalTable ObjectID_1 or FID_1 depending on table type, either way it should be the second field in the zonal stats table) to your polygon and use the calculation like this:

MinElev = round( !ZonalStatsObjectID.MIN!,0 )
MaxElev = round( !ZonalStatsObjectID.MAX!,0 )

The name of the zonal statistics table in this example is ZonalStatsObjectID, change to match your table name. Do NOT use int( !ZonalStatsObjectID.MIN!), that's a truncation and will give you the wrong value.

After rounding and copying the values for min and max use field calculator on the table to calculate the nilai field:

def CalcNilai(Min,Max):
    if Min == Max:
        return "%d" % Min
    else:
        return "%d - %d" % (Min,Max)

Which should look like this (I've removed the join for simplicity): enter image description here

Added language tag
Source Link
Hornbydd
  • 44.6k
  • 5
  • 42
  • 84
import sys, os, arcpy

InPolygons = sys.argv[1]
NearContour = sys.argv[2]
OutPolygons = sys.argv[3]

ElevationFieldName = "Elevation" # change this to match your field name

InFolder = os.path.dirname(InPolygons) # the folder the input is in
Working = InFolder + "\\Working.gdb"
WorkingContour = Working+"\\Contour"
WorkingPoly = Working+"\\Poly"

arcpy.CreateFileGDB_management(InFolder,"Working.gdb") # create a working space
arcpy.AddMessage("Copy 1")
arcpy.CopyFeatures_management(NearContour,WorkingContour) # need to do this to take charge of names
arcpy.AddMessage("Copy 2")
arcpy.CopyFeatures_management(InPolygons,WorkingPoly) 

# remove 'bad' edges, tagged with elevation = -9999 to show they are a boundary
arcpy.MakeFeatureLayer_management(WorkingContour,"Remove",ElevationFieldName + " = -9999")
arcpy.DeleteFeatures_management("Remove")
arcpy.Delete_management("Remove") # relax, it's just removing the layer, just to keep it clean

# Create a near table
arcpy.AddMessage("Near table")
arcpy.GenerateNearTable_analysis(WorkingPoly,WorkingContour,Working+"\\NearTable","0",closest="ALL")
arcpy.AddField_management(Working+"\\NearTable","Elev","DOUBLE")

try:
    arcpy.AddIndex_management(Working+"\\NearTable","NEAR_FID","NEAR_FID")
except:
    arcpy.AddWarning("Unable to index")

# join and copy elevations
arcpy.AddMessage("Join & calc")
arcpy.MakeTableView_management(Working+"\\NearTable","View")
arcpy.AddJoin_management("View","NEAR_FID",WorkingContour,"OBJECTID")
arcpy.CalculateField_management("View","NearTable.Elev","!Contour."+ElevationFieldName+"!","PYTHON")
arcpy.Delete_management("View") # relax, it's just removing the table view, just to keep it clean

# remove join and summary statistics
arcpy.AddMessage("Make stats")
#arcpy.RemoveJoin_management("View")
arcpy.Statistics_analysis(Working+"\\NearTable",Working+"\\NearStats",[["Elev","MIN"],["Elev","Max"]],"IN_FID")

# copy the min and max to the working contours
arcpy.AddMessage("Copy min/max")
arcpy.AddField_management(WorkingPoly,"MinElev","DOUBLE")
arcpy.AddField_management(WorkingPoly,"MaxElev","DOUBLE")
arcpy.MakeFeatureLayer_management(WorkingPoly,"Layer")
arcpy.AddJoin_management("Layer","OBJECTID",Working+"\\NearStats","IN_FID")
arcpy.CalculateField_management("Layer","Poly.MinElev","!NearStats.Min_Elev!","PYTHON")
arcpy.CalculateField_management("Layer","Poly.MaxElev","!NearStats.Max_Elev!","PYTHON")
arcpy.RemoveJoin_management("Layer")
arcpy.Delete_management("Layer") # relax, it's just removing the layer, just to keep it clean

# check for field
arcpy.AddMessage("Checking for field")
Fields = arcpy.ListFields(WorkingPoly,"nilai")
if not Fields:
    arcpy.AddMessage("-Adding field")
    arcpy.AddField_management(WorkingPoly,"nilai","TEXT",field_length="10")

# format the field with the min and max,
# this could be done with a field calculation
# but in this case I want a special case for isolations
arcpy.AddMessage("Cursoring")
with arcpy.da.UpdateCursor(WorkingPoly,("nilai","MinElev","MaxElev")) as UpCur:
    for Feat in UpCur:
        if (Feat[1]==Feat[2]):
            # values are the same = an isolation
            Feat[0] = str(int(Feat[1]))
        else:
            Feat[0] = "%d - %d" % (Feat[1],Feat[2])
        UpCur.updateRow(Feat)

arcpy.AddMessage("Copy out")
arcpy.CopyFeatures_management(WorkingPoly,OutPolygons) 
import sys, os, arcpy

InPolygons = sys.argv[1]
NearContour = sys.argv[2]
OutPolygons = sys.argv[3]

ElevationFieldName = "Elevation" # change this to match your field name

InFolder = os.path.dirname(InPolygons) # the folder the input is in
Working = InFolder + "\\Working.gdb"
WorkingContour = Working+"\\Contour"
WorkingPoly = Working+"\\Poly"

arcpy.CreateFileGDB_management(InFolder,"Working.gdb") # create a working space
arcpy.AddMessage("Copy 1")
arcpy.CopyFeatures_management(NearContour,WorkingContour) # need to do this to take charge of names
arcpy.AddMessage("Copy 2")
arcpy.CopyFeatures_management(InPolygons,WorkingPoly) 

# remove 'bad' edges, tagged with elevation = -9999 to show they are a boundary
arcpy.MakeFeatureLayer_management(WorkingContour,"Remove",ElevationFieldName + " = -9999")
arcpy.DeleteFeatures_management("Remove")
arcpy.Delete_management("Remove") # relax, it's just removing the layer, just to keep it clean

# Create a near table
arcpy.AddMessage("Near table")
arcpy.GenerateNearTable_analysis(WorkingPoly,WorkingContour,Working+"\\NearTable","0",closest="ALL")
arcpy.AddField_management(Working+"\\NearTable","Elev","DOUBLE")

try:
    arcpy.AddIndex_management(Working+"\\NearTable","NEAR_FID","NEAR_FID")
except:
    arcpy.AddWarning("Unable to index")

# join and copy elevations
arcpy.AddMessage("Join & calc")
arcpy.MakeTableView_management(Working+"\\NearTable","View")
arcpy.AddJoin_management("View","NEAR_FID",WorkingContour,"OBJECTID")
arcpy.CalculateField_management("View","NearTable.Elev","!Contour."+ElevationFieldName+"!","PYTHON")
arcpy.Delete_management("View") # relax, it's just removing the table view, just to keep it clean

# remove join and summary statistics
arcpy.AddMessage("Make stats")
#arcpy.RemoveJoin_management("View")
arcpy.Statistics_analysis(Working+"\\NearTable",Working+"\\NearStats",[["Elev","MIN"],["Elev","Max"]],"IN_FID")

# copy the min and max to the working contours
arcpy.AddMessage("Copy min/max")
arcpy.AddField_management(WorkingPoly,"MinElev","DOUBLE")
arcpy.AddField_management(WorkingPoly,"MaxElev","DOUBLE")
arcpy.MakeFeatureLayer_management(WorkingPoly,"Layer")
arcpy.AddJoin_management("Layer","OBJECTID",Working+"\\NearStats","IN_FID")
arcpy.CalculateField_management("Layer","Poly.MinElev","!NearStats.Min_Elev!","PYTHON")
arcpy.CalculateField_management("Layer","Poly.MaxElev","!NearStats.Max_Elev!","PYTHON")
arcpy.RemoveJoin_management("Layer")
arcpy.Delete_management("Layer") # relax, it's just removing the layer, just to keep it clean

# check for field
arcpy.AddMessage("Checking for field")
Fields = arcpy.ListFields(WorkingPoly,"nilai")
if not Fields:
    arcpy.AddMessage("-Adding field")
    arcpy.AddField_management(WorkingPoly,"nilai","TEXT",field_length="10")

# format the field with the min and max,
# this could be done with a field calculation
# but in this case I want a special case for isolations
arcpy.AddMessage("Cursoring")
with arcpy.da.UpdateCursor(WorkingPoly,("nilai","MinElev","MaxElev")) as UpCur:
    for Feat in UpCur:
        if (Feat[1]==Feat[2]):
            # values are the same = an isolation
            Feat[0] = str(int(Feat[1]))
        else:
            Feat[0] = "%d - %d" % (Feat[1],Feat[2])
        UpCur.updateRow(Feat)

arcpy.AddMessage("Copy out")
arcpy.CopyFeatures_management(WorkingPoly,OutPolygons) 
import sys, os, arcpy

InPolygons = sys.argv[1]
NearContour = sys.argv[2]
OutPolygons = sys.argv[3]

ElevationFieldName = "Elevation" # change this to match your field name

InFolder = os.path.dirname(InPolygons) # the folder the input is in
Working = InFolder + "\\Working.gdb"
WorkingContour = Working+"\\Contour"
WorkingPoly = Working+"\\Poly"

arcpy.CreateFileGDB_management(InFolder,"Working.gdb") # create a working space
arcpy.AddMessage("Copy 1")
arcpy.CopyFeatures_management(NearContour,WorkingContour) # need to do this to take charge of names
arcpy.AddMessage("Copy 2")
arcpy.CopyFeatures_management(InPolygons,WorkingPoly) 

# remove 'bad' edges, tagged with elevation = -9999 to show they are a boundary
arcpy.MakeFeatureLayer_management(WorkingContour,"Remove",ElevationFieldName + " = -9999")
arcpy.DeleteFeatures_management("Remove")
arcpy.Delete_management("Remove") # relax, it's just removing the layer, just to keep it clean

# Create a near table
arcpy.AddMessage("Near table")
arcpy.GenerateNearTable_analysis(WorkingPoly,WorkingContour,Working+"\\NearTable","0",closest="ALL")
arcpy.AddField_management(Working+"\\NearTable","Elev","DOUBLE")

try:
    arcpy.AddIndex_management(Working+"\\NearTable","NEAR_FID","NEAR_FID")
except:
    arcpy.AddWarning("Unable to index")

# join and copy elevations
arcpy.AddMessage("Join & calc")
arcpy.MakeTableView_management(Working+"\\NearTable","View")
arcpy.AddJoin_management("View","NEAR_FID",WorkingContour,"OBJECTID")
arcpy.CalculateField_management("View","NearTable.Elev","!Contour."+ElevationFieldName+"!","PYTHON")
arcpy.Delete_management("View") # relax, it's just removing the table view, just to keep it clean

# remove join and summary statistics
arcpy.AddMessage("Make stats")
#arcpy.RemoveJoin_management("View")
arcpy.Statistics_analysis(Working+"\\NearTable",Working+"\\NearStats",[["Elev","MIN"],["Elev","Max"]],"IN_FID")

# copy the min and max to the working contours
arcpy.AddMessage("Copy min/max")
arcpy.AddField_management(WorkingPoly,"MinElev","DOUBLE")
arcpy.AddField_management(WorkingPoly,"MaxElev","DOUBLE")
arcpy.MakeFeatureLayer_management(WorkingPoly,"Layer")
arcpy.AddJoin_management("Layer","OBJECTID",Working+"\\NearStats","IN_FID")
arcpy.CalculateField_management("Layer","Poly.MinElev","!NearStats.Min_Elev!","PYTHON")
arcpy.CalculateField_management("Layer","Poly.MaxElev","!NearStats.Max_Elev!","PYTHON")
arcpy.RemoveJoin_management("Layer")
arcpy.Delete_management("Layer") # relax, it's just removing the layer, just to keep it clean

# check for field
arcpy.AddMessage("Checking for field")
Fields = arcpy.ListFields(WorkingPoly,"nilai")
if not Fields:
    arcpy.AddMessage("-Adding field")
    arcpy.AddField_management(WorkingPoly,"nilai","TEXT",field_length="10")

# format the field with the min and max,
# this could be done with a field calculation
# but in this case I want a special case for isolations
arcpy.AddMessage("Cursoring")
with arcpy.da.UpdateCursor(WorkingPoly,("nilai","MinElev","MaxElev")) as UpCur:
    for Feat in UpCur:
        if (Feat[1]==Feat[2]):
            # values are the same = an isolation
            Feat[0] = str(int(Feat[1]))
        else:
            Feat[0] = "%d - %d" % (Feat[1],Feat[2])
        UpCur.updateRow(Feat)

arcpy.AddMessage("Copy out")
arcpy.CopyFeatures_management(WorkingPoly,OutPolygons) 
import sys, os, arcpy

InPolygons = sys.argv[1]
NearContour = sys.argv[2]
OutPolygons = sys.argv[3]

ElevationFieldName = "Elevation" # change this to match your field name

InFolder = os.path.dirname(InPolygons) # the folder the input is in
Working = InFolder + "\\Working.gdb"
WorkingContour = Working+"\\Contour"
WorkingPoly = Working+"\\Poly"

arcpy.CreateFileGDB_management(InFolder,"Working.gdb") # create a working space
arcpy.AddMessage("Copy 1")
arcpy.CopyFeatures_management(NearContour,WorkingContour) # need to do this to take charge of names
arcpy.AddMessage("Copy 2")
arcpy.CopyFeatures_management(InPolygons,WorkingPoly) 

# remove 'bad' edges, tagged with elevation = -9999 to show they are a boundary
arcpy.MakeFeatureLayer_management(WorkingContour,"Remove",ElevationFieldName + " = -9999")
arcpy.DeleteFeatures_management("Remove")
arcpy.Delete_management("Remove") # relax, it's just removing the layer, just to keep it clean

# Create a near table
arcpy.AddMessage("Near table")
arcpy.GenerateNearTable_analysis(WorkingPoly,WorkingContour,Working+"\\NearTable","0",closest="ALL")
arcpy.AddField_management(Working+"\\NearTable","Elev","DOUBLE")

try:
    arcpy.AddIndex_management(Working+"\\NearTable","NEAR_FID","NEAR_FID")
except:
    arcpy.AddWarning("Unable to index")

# join and copy elevations
arcpy.AddMessage("Join & calc")
arcpy.MakeTableView_management(Working+"\\NearTable","View")
arcpy.AddJoin_management("View","NEAR_FID",WorkingContour,"OBJECTID")
arcpy.CalculateField_management("View","NearTable.Elev","!Contour."+ElevationFieldName+"!","PYTHON")
arcpy.Delete_management("View") # relax, it's just removing the table view, just to keep it clean

# remove join and summary statistics
arcpy.AddMessage("Make stats")
#arcpy.RemoveJoin_management("View")
arcpy.Statistics_analysis(Working+"\\NearTable",Working+"\\NearStats",[["Elev","MIN"],["Elev","Max"]],"IN_FID")

# copy the min and max to the working contours
arcpy.AddMessage("Copy min/max")
arcpy.AddField_management(WorkingPoly,"MinElev","DOUBLE")
arcpy.AddField_management(WorkingPoly,"MaxElev","DOUBLE")
arcpy.MakeFeatureLayer_management(WorkingPoly,"Layer")
arcpy.AddJoin_management("Layer","OBJECTID",Working+"\\NearStats","IN_FID")
arcpy.CalculateField_management("Layer","Poly.MinElev","!NearStats.Min_Elev!","PYTHON")
arcpy.CalculateField_management("Layer","Poly.MaxElev","!NearStats.Max_Elev!","PYTHON")
arcpy.RemoveJoin_management("Layer")
arcpy.Delete_management("Layer") # relax, it's just removing the layer, just to keep it clean

# check for field
arcpy.AddMessage("Checking for field")
Fields = arcpy.ListFields(WorkingPoly,"nilai")
if not Fields:
    arcpy.AddMessage("-Adding field")
    arcpy.AddField_management(WorkingPoly,"nilai","TEXT",field_length="10")

# format the field with the min and max,
# this could be done with a field calculation
# but in this case I want a special case for isolations
arcpy.AddMessage("Cursoring")
with arcpy.da.UpdateCursor(WorkingPoly,("nilai","MinElev","MaxElev")) as UpCur:
    for Feat in UpCur:
        if (Feat[1]==Feat[2]):
            # values are the same = an isolation
            Feat[0] = str(int(Feat[1]))
        else:
            Feat[0] = "%d - %d" % (Feat[1],Feat[2])
        UpCur.updateRow(Feat)

arcpy.AddMessage("Copy out")
arcpy.CopyFeatures_management(WorkingPoly,OutPolygons) 
Source Link
Michael Stimson
  • 25.7k
  • 2
  • 35
  • 75
Loading