I am trying to create a script that will iterate through a list of elevations in a text file and calculate surface and volume using the 3D analyst surface volume tool. I have success for the first line of a file only. It seems to stop after it's calculated the first value and I can't for the life of me figure out why it will not continue. Looking at the second elif statement with the height_file.

#Purpose: To calculate area and volume on a surface.

# Create the Geoprocessor object
import arcpy
from arcpy import env
import exceptions, traceback, os, sys

#Check out the 3D Analyst extension

    # Set the workspace (to avoid having to type in the full path to the data every time)
    # Select the 3D Analyst Toolbox
    env.toolbox = "3D"
    tin = sys.argv[1]
    output = sys.argv[2]
    reference_plane = sys.argv[3]
    z_factor = sys.argv[4]
    zmin = int(sys.argv[5])
    zmax = int(sys.argv[6])
    base_z = sys.argv[7]             # For specified height value, conflicts with height text file and height interval, inactive value=-9999
    interval = float(sys.argv[8])    # For specifying an interval, conflicts with specified height value and height text file input, inactive when zmin&zmax=0
    height_file = sys.argv[9]       # For height text file input, conflicts with specified height value and height interval inactive when no input
    print "Base Z = " + str(base_z)

    if base_z != '-9999':
        # Process: Calculating areas and volumes on a TIN above a reference plane
        print "Calculating single base value: " + str(base_z)
        arcpy.SurfaceVolume_3d(tin, output, reference_plane, base_z, z_factor)
    elif zmin != 0 and zmax != 0 and interval != 0 and zmax > zmin:
        print "Processing intervals"
        elev = float(zmin)
        while elev < zmax + interval:
            print "Height: " + str(elev)
            arcpy.SurfaceVolume_3d(tin, output, reference_plane, elev, z_factor)
            elev = elev + interval
    elif height_file != "":
        print "Processing elevation file"
        fo = open(height_file, 'r')
        while True:
            elevInString = fo.readline()
            if not elevInString:
            a = elevInString.strip()
            if a == "":
            elev = float(a)
            print "Height: " + str(elev)
            arcpy.SurfaceVolume_3d(tin, output, reference_plane, elev, z_factor)

except arcpy.ExecuteError:
    print arcpy.GetMessages()
    # Get the traceback object
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]
    # Concatenate error information into message string
    pymsg = 'PYTHON ERRORS:\nTraceback info:\n{0}\nError Info:\n{1}'\
          .format(tbinfo, str(sys.exc_info()[1]))
    msgs = 'ArcPy ERRORS:\n {0}\n'.format(arcpy.GetMessages(2))
    # Return python error messages for script tool or Python Window
  • I think that you should remove your try/except statements while testing and for presenting code here because they can mask otherwise useful error messages. – PolyGeo Apr 4 at 19:45

The main issue I see is that the output of the Surface Volume process in the 3D Toolbox is a text file, so for each iteration of the process (that is, for each elevation line read from your input document), it's overwriting the same file and not generating new ones.

You could try something like this:

with open(height_file, 'r') as f:
    data = f.read()
elevations = map(float, data.split('\n'))
count = 1
for elev in elevations:
    this_output = output[:-4] + str(count) + '.txt'
    arcpy.SurfaceVolume_3d(tin, this_output, reference_plane, elev, z_factor)
    count += 1
  • That is the issue it seems. This still didn't resolve the issue, however. This code is now just renaming the output file name with a 1 tacked on the end. – David Gates Apr 8 at 15:05
  • Sorry! Forgot to add to the increment after each run - try the updated version. – AlecZ Apr 8 at 16:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.