In the first part of this series I covered access to the geoprocessor and how one can navigate the first part of the diagram of the model. If you are not familiar with the geoprocessor, please have a quick look at that post to understand the geoprocessing model ESRI provides.

In this post I will finish covering the bottom left part of the model that deals with direct access to features and their geometry. In order to do that, we will discuss cursors, features and geometries.

Spatial Data Primer

Before we begin discussing deep access to data, we need to define what spatial data are. In essence, there are two types of spatial data, vector and raster data. An easy way to understand the difference is to imagine raster data as images, while vector data are defined by points, lines and polygons. What is special about spatial data is their dimension of space, or location. Raster data offer extensive coverage of an area, in which our spatial data offer a regular grid of cells that provide data. Space in this case is depended on the location of the cell in the raster file (and therefore implicit location). Vector files on the other hand contain explicit information about the location of things (providing coordinates). Data are then associated with the locations of features. We will be dealing with vector data mostly, so a further investigation is warranted.

In order to represent the world in spatial data, we choose a type of vector data we want to use (for example, choosing points to represent trees, lines to represent road networks, etc). Each of the features in the world get assigned two types of data: spatial characteristics (for a point, an x,y pairs, for a line, a series of points, etc.) and non-spatial characteristics (think of them as attributes). A file that contains all the trees in a neighborhood then includes a list of all the trees, with each tree having a location attribute, and a set of attributes that describe the tree (like type of tree, or age of tree, etc). Therefore, spatial data are defined as follows:

  • A file dealing with a specific type of feature in the world.
    • The file has a list of features that all satisfy the requirement of belonging in that type of feature.
      • Each feature contains a spatial footprint for where it is located.
      • Along with location, each feature contains zero or more characteristics that are aspatial but refer to the feature itself.

Similarly, when one tries to access the geometry or the characteristics of a specific feature in our data, one has to first access the file we need, within the file, identify the right feature we need, and then eventually, within the feature find the geometry and/or the characteristics associated with it.

Accessing Data Using the Geoprocessor

From the Geoprocessor to Geometry

From the Geoprocessor to Geometry

The image above shows the path one needs to travel within the Geoprocessor to access a Geometry. The cyan box on the left represents the commands available to the geoprocessor object, as discusses in the previous post. The commands that include the word Cursor have an arrow to their right, that show they can access rows, which is actually a representation of the spatial data file in Python. From there on, one can access a single row (the third box from the left), which can eventually lead to the Geometry object on the left. So in the geoprocessing world, in order to access a geometry (or spatial characterics of a feature), we need to do the following:

  1. Create the geoprocessor object.
  2. Call the appropriate cursor command to receive a rows object, which is a Python representation of the file we need to access.
  3. Within the rows object, we call the Next() or NewRow() command to receive an individual feature, represented as a single row.
  4. The row object allows us to directly access characteristics of the file, including the Geometry object. Please note that the characteristics are actually variables now, and not methods.

A question people often ask is how one knows which path to follow when they need to access a specific object (or box in the diagram). If you are not intimately familiar with the model, there is one method to follow: Identify the object you want, and then follow the arrows in reverse to find the methods that can get you there. Once you have those steps reverse them and you have a workflow. Remember, you will always need to end up in the cyan, geoprocessor object, as this is your only starting point.

From the Geoprocessor to Spatial File Access

There are three methods to access your spatial file, as shown in the diagram, explained below:

  • InsertCursor: The insert cursor allows you to access a spatial file with the sole purpose of adding new features (or rows). Use this cursor to add more features to a file.
  • SearchCursor: The search cursor allows you to access a spatial file with the sole purpose of reading features (rows). Use this cursor to read the characteristics of each feature.
  • UpdateCursor: The update cursor allows you to access a spatial file in order to update values in each feature (row), or completely remove it. Use this cursor to update characteristics (including geometry) of a feature, or to remove the feature itself.

The required parameter for each of these cursor is the file you want to access, called InputValue in the diagram. Here is an example of how to use each cursor:

import arcgisscripting
# Import the module provided by ESRI

gp = arcgisscripting.create(9.3)
# Create the geoprocessor object

fcWrite = gp.InsertCursor(r"c:\data\testWrite.shp")
# Create an insert cursor that points to the testWrite.shp file.
# The returned value fcWrite is actually a rows object.
# You are now able to add new features to the file.

fcRead = gp.SearchCursor(r"c:\data\testRead.shp")
# Create a search cursor that points to the testRead.shp file.
# The returned value fcRead is actually a rows object.
# You are now able to read the information about features from the file.

fcUpdate = gp.UpdateCursor(r"c:\data\testUpdate.shp")
# Create an update cursor that points to the testUpadate.shp file.
# The returned value fcUpdate is actually a rows object.
# You are now able to update values in features, of completely remove them from the file.

If you follow the above examples, you manage to escape from the geoprocessor object (the cyan box) and move to the rows object, the first yellow box on the left. Note that the rows object has different methods available depending on how you access it.

From the Rows Object to a Single Row

From the file to a single row

From the file to a single row

Now that you have access to the rows object, you can continue accessing the file by individual feature (or row). Depending on the Cursor method you used, you will have the following options available to you:

  • SearchCursor Rows Object: This provides you with read-only access to the elements/features of your file. As such, there are two methods available: Next() and Reset(). As you may infer from their name, Next() will provide to you the next feature as a row object, while the Reset() method simply returns the pointed to the specific row in the beginning of the file.
  • InsertCursor Rows Object: As the InsertCursor() method provides the ability to add new features in the file, the methods available are NewRow(), InsertRow() and Reset(). This creates some confusion, but it is easy to distinguish what happens when you understand the internals. NewRow() creates a new and empty row object in memory, which allows you to create your new feature. This row object remains in memory until one calls the InsertRow() function, which will save the row object to your file. The Reset() method functions as with the SearchCursor Rows object explained above.
  • UpdateCursor Rows Object: As the UpdateCursor() provides you the most functionality, it comes with more methods: Next(), Reset(), UpdateRow() and DeleteRow(). The Next() and Reset() methods function the same way as with the SearchCursor Rows object. UpdateRow() is similar to the InsertRow() method of the InsertCursor Rows object. Given a row object, it will update the feature the cursor is set on. Similarly, the DeleteRow() method will delete the current row object the cursor points to.

Examples on how to use the commands follow:

Example 1: Writing a new feature

# Example 1: Create a new Row
import arcgisscripting
# Import the module provided by ESRI

gp = arcgisscripting.create(9.3)
# Create the geoprocessor object

fcWrite = gp.InsertCursor(r"c:\data\testWrite.shp")
# Create an insert cursor that points to the testWrite.shp file.
# The returned value fcWrite is actually a rows object.

fcWrite.Reset()
# Reset the cursor to the rows object

fcRow = fcWrite.NewRow()
# Create a new row object in memory, saved in the fcRow variable

# Manipulate the row here.

fcWrite.InsertRow(fcRow)
# Save the row object back to our file

Example 2: Reading a feature

 # Example 2: Read the n feature of a file
 import arcgisscripting
 # Import the module provided by ESRI

 gp = arcgisscripting.create(9.3)
 # Create the geoprocessor object

 fcRead = gp.InsertCursor(r"c:\data\testRead.shp")
 # Create an insert cursor that points to the testRead.shp file.
 # The returned value fcRead is actually a rows object.

 fcRead.Reset()
 # Reset the cursor to the rows object

 fcRow = fcRead.Next()
 # Read the first row of the file and save it to the fcRow variable

 # Read the information for the feature here

# If you need to find a specific feature, you need to continue your search
# Use a while loop to achieve this
while fcRow:
    # Test whether this feature is the one you want
    # When you found the feature, you can use break to end the loop
    # If the feature is not the right one, keep trying
    fcRow = fcRead.Next()
 

Example 3: Updating and Deleting Rows

# Example 3: Updating and Deleting Rows
import arcgisscripting
# Import the module provided by ESRI

gp = arcgisscripting.create(9.3)
# Create the geoprocessor object

fcUpdate = gp.UpdateCursor(r"c:\data\testUpdate.shp")
# Create an update cursor that points to the testUpadate.shp file.
# The returned value fcUpdate is actually a rows object.

fcUpdate.Reset()
# Reset the cursor to the rows object

fcRow = fcUpdate.Next()
# Receive the first row

# Loop through the rows until you find one to delete and one to update
while fcRow:
    # If this is the row that needs deleting, then
        fcUpdate.DeleteRow(fcRow)
        # Call the DeleteRow() method with the current row as a parameter
    # If this is the row that needs updating, then
        # Perform the update to the row
        fcUpdate.UpdateRow(fcRow)
        # Call the UpdateRow() method with the current row as a parameter

Manipulating Individual Features and Geometries

If you followed the above examples, then you are aware on how one can access an individual feature from a file. The question then remains on how one manipulates that row. Below are some explanations on how one can perform this.

Individual Features (row) and their Geometry

Individual Features (row) and their Geometry

As with the Rows object, there are different versions of the Row object depending on who calls it. The two possibilities are:

  • Row object derived from a SearchCursor: This object provides the GetValue() method that allows one to read values associated with a field. Along with the method, there is a collection of read-only variables that represent the fields/attributes the row represents.
  • Row object derived from an InsertCursor or UpdateCursor: This object provides what the read-only version provides, with the variables representing fields/attributes being write-enabled as well. The SetValue() method is also provided to allow one to set new values to fields.
The Field Object

The Field Object

Before we continue on with the idea of geometries, we need to show how one can access the field names. Often we know the names of fields/attributes because we are familiar with the dataset or have access to the metadata. Another way to get familiar with the names of the fields though exists, and is through the ListFields() method available to the geoprocessor object. This command will return a Python list that includes all the attributes available to you, as Field objects. What this object provides to you is a set of variables that are read-only and make available to you information like the name, alias, domain, editable ability and more information about the field. Please have a look at the diagram on the right for a full listing of information included in a Field object.

# Example of finding out the fields available in a file
import arcgisscripting
# Import the module provided by ESRI

gp = arcgisscripting.create(9.3)
# Create the geoprocessor object

fieldsList = gp.ListFields(r"c:\data\test.shp")
# Call the ListFields() method on the test.shp file
# The returned list is saved in fieldsList

for field in fieldsList:
# Loop through all the field
    print field.Name
# Print the name of the field

This is one way to also identify the field that includes the geometry. Unfortunately, depending on the type of file you have (or database for that matter), the name may change. There is a trick to find the actual name of the field that stores geometry, but it will be covered in another part. For now, here is how one can do it:

# Example of finding out the fields available in a file
import arcgisscripting
# Import the module provided by ESRI

gp = arcgisscripting.create(9.3)
# Create the geoprocessor object

fcDsc = gp.Describe(r"c:\data\test.shp")
# Get the descriptor of the file
geometryField = fcDsc.ShapeFieldName
# Get the geometry(shape) field name from the description

As you now know what the name of the geometry field is, you can access is as mentioned before with the GetValue() method. Similarly, you can save a geometry using the SetValue() method. It is important to remember that geometries in the ESRI world are Geometry objects of multiple parts which are held in Array objects holding one or more Point objects. This means when you use the GetValue() method, you first receive a Geometry object. Within that object, you will call the GetPart() method to receive an Array object, which in turn holds a number of Point objects, which are called through the Next() method. An example follows to help you understand this.

# Example of accessing a Geometry of a feature / print geometry type
import arcgisscripting
# Import the module provided by ESRI

gp = arcgisscripting.create(9.3)
# Create the geoprocessor object

fcDsc = gp.Describe(r"c:\data\test.shp")
# Get the descriptor of the file
geometryField = fcDsc.ShapeFieldName
# Get the geometry(shape) field name from the description

srcCursor = gp.SearchCursor(r"c:\data\test.shp")
# Create a search cursor to the file

row = srcCursor.Next()
# Grab the first row

while row:
# Loop through the features/rows
rowGeom = row.Getvalue(geometryField)
# Grab the geometry of the row

print rowGeom.Type
# Print the type of the geometry

row = srcCursor.Next()
# Grab the next row

With this installment, you should have the knowledge to navigate the Geoprocessor Programming Model on the bottom, where accessor methods for files reside. Also, you should be able to access a Geometry object for every vector dataset you have available. In the next installment we will further navigate the programming model.

Note: Thanks to Eric for catching a Python error.

1 Star2 Stars3 Stars4 Stars5 Stars (5 votes, average: 5.00 out of 5)
Loading ... Loading ...

Related posts:

  1. Accessing Geometries using the Geoprocessor (Updated)
  2. Understanding the Geoprocessor Programming Model part 1
  3. Understanding the Geoprocessor Programming Model part 3
  4. Python Geoprocessing in ArcGIS 9.2 vs. 9.3
  5. Loading the Geoprocessor Safely

2 Responses to “Understanding the Geoprocessor Programming Model part 2”

  1. Your Geoprocessing postings are excellent. Very easy to follow and make a lot more sense than ESRI’s documentation. Please do a lot more of them,

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2010 Michalis Avraam Suffusion theme by Sayontan Sinha