Skip to main content
1 of 4
Michael Stimson
  • 25.7k
  • 2
  • 35
  • 75

Assuming you've created the polygons by closing the ends (closing lines are given elevation of -9999 so they're removed and not factored into the min and max) and using Feature to Polygon then added your field (nilai as text):

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) 

Using Generate Near Table with a 0 tolerance to find the link between polygons and their bounding lines. To the near table add a field to store the elevations of the lines they describe, then it's just a matter of getting the statistics for min and max elevations in the near table for each unique input FID (polygon) then joining to the polygons and populating the field.

The tool Generate Near Table will take a very long time to run, so try to do it overnight; I have tested this code with 350 polygons and 345 lines which took about 10 minutes to complete.

Isolations (only one elevation for min and max) will have just their value populated, intermediate polygons will be populated with min - max in that field.

Michael Stimson
  • 25.7k
  • 2
  • 35
  • 75