GIS Logo GSP 118 (318): GIS Programming

An ArcGIS Interface Module

In Review

This section will have you use and extend an existing "class". We'll learn more about classes in the near future.

1. Introduction

The purpose of this module is to provide an adapter between our scripts and ArcGIS. When ArcGIS changes, we can just change the adapter functions and we don't have to change all of our scripts.

2. The Module

The module below contains one class. Copy the class below into Wing and save it as a file named "SAInterface". This matches the name of the file to the name of the class it contains and is a good programming practice so you can find where your classes are located.

###################################################################################
# ArcGIS Interface Module
# This module includes classes to interface with ArcGIS.
# The class provides insulation from ArcGIS changes and provides friendlier error
# messages.
# Author: Jim Graham
# Date: 4th of November, 2011
###################################################################################
import arcpy # import ArcGIS Python bindings

###################################################################################
# Class to interface with spatial analyst
###################################################################################
class SAInterface: # class to interface with spatial analyst

	###################################################################################
	# Constructor for the spatial analyst interface class
	###################################################################################
	def __init__(self): # called when the class is created
		arcpy.CheckOutExtension("Spatial") # make sure the spatial analyst is checked out
		arcpy.env.overwriteOutput=True # allow overwrites
		
	###################################################################################
	# Performs an aspect transform on a DEM and returns the aspect raster
	# Inputs: 
	#  InputDEM: Just about any single band raster
	#  Output: Returns a raster with the aspect of the Input raster
	###################################################################################
	def Aspect(self,InputDEM): # perform aspect on a DEM and return it
		try:
			TheRaster=arcpy.sa.Aspect(InputDEM) # Call ArcGIS to perform the aspect transform
			return(TheRaster)
		
		except Exception, err: # an error occurred (probably in arcGIS)
			raise RuntimeError("** Error: Aspect Failed ("+str(err)+")")

Notice that the module imports "arcpy" so we don't have to import it in our other code. The module contains one class "SAInterface" as an interface class to the Spatial Analyst in ArcGIS. This class as a "constructor" called "__init__" which checks out spatial analyst so we don't have to do this either. Next is a class to call to create an aspect raster from a DEM. Notice that all the function does is call ArcGIS and handle exceptions. I've added a message to the error so we know the error occurred in the aspect function.

3. Using The Class

The code below will call the aspect function in our ArcGIS class above. Copy it into Wing and execute it.

import os

try:
     # import our ArcGIS spatial analyst interface class
     import SAInterface 
     
     TheInterface=SAInterface.SAInterface() # create the instance to call ArcGIS

     # Setup our folder paths
     TheOriginalFolder="C:/ProjectsPython/Original/"
     TheProcessedFolder="C:/ProjectsPython/Processed/"

     # get the list of files (and directories) in the original folder
     TheList=os.listdir(TheOriginalFolder)
    
     # go through the entire folder contents
     for TheFile in TheList:
          TheFileName, TheFileExtension = os.path.splitext(TheFile)
        
          # process only IMAGINE files (also avoids folders and other file types)
          if (TheFileExtension==".img"):
               
               print("Creating an aspect raster for "+TheFileName)
               
               # Perform an aspect transform
               OriginalPath=TheOriginalFolder+TheFileName+TheFileExtension
               TheAspectRaster=TheInterface.Aspect(OriginalPath)
               
               # save the aspect raster to the processed folder
               TheAspectRaster.save(TheProcessedFolder+"TheAspectRaster.img")     
               
               # let the user know which files we've completed
               print("Done with Aspect for "+TheFileName) # Let everyone know we are done with the slope
	
except Exception, err: # an error occurred
     print(str(err))
	
print("Completed Script") # Let everyone know we are done with all processing

Notice that all we have to do is import our class and then create a new instance of the class. Then we can call the functions in the interface without having to worry about the details of the ArcGIS interface. We also have to do a little more work to get the error string back from our class but this is the standard method to get a message from an exception in Python.

You can add additional functions to the class such as:

OutRaster=arcpy.sa.Slope(OriginalPath,"DEGREE","1")
OutRaster=arcpy.sa.HillShade(OriginalPath, 180, 75, "SHADOWS", 1)

You could also add additional classes to work with other portions of ArcGIS.

The script above is one model for a complete script to process GIS data using ArcGIS. You can vary from this script as you desire but it's important to think about the design goals as you do.