Improving cursor performance with geometry tokens

Geometry tokens were introduced in ArcGIS 10.1 as a performance improvement for cursors. Rather than returning the entire geometry of a feature inside the cursor, only a portion of the geometry is returned. Returning the entire geometry of a feature can result in decreased cursor performance due to the amount of data that has to be returned. It's significantly faster to return only the specific portion of the geometry that is needed.

Getting ready

A token is provided as one of the fields in the field list passed into the constructor for a cursor and is in the SHAPE@<Part of Feature to be Returned> format. The only exception to this format is the OID@ token, which returns the object ID of the feature. The following code example retrieves only the X and Y coordinates of a feature:

with arcpy.da.SearchCursor(fc, ("SHAPE@XY","Facility","Name")) as cursor:

The following table lists the available geometry tokens. Not all cursors support the full list of tokens. Check the ArcGIS help files for information about the tokens supported by each cursor type. The SHAPE@ token returns the entire geometry of the feature. Use this carefully though, because it is an expensive operation to return the entire geometry of a feature and can dramatically affect performance. If you don't need the entire geometry, then do not include this token!

Getting ready

In this recipe, you will use a geometry token to increase the performance of a cursor. You'll retrieve the X and Y coordinates of each land parcel from the parcels feature class along with some attribute information about the parcel.

How to do it…

Follow these steps to add a geometry token to a cursor, which should improve the performance of this object:

  1. Open IDLE and create a new script window.
  2. Save the script as C:ArcpyBookCh8GeometryToken.py.
  3. Import the arcpy.da module and the time module:
    import arcpy.da
    import time
  4. Set the workspace:
    arcpy.env.workspace = "c:/ArcpyBook/Ch8"
  5. We're going to measure how long it takes to execute the code using a geometry token. Add the start time for the script:
    start = time.clock()
  6. Use a Python with statement to create a cursor that includes the centroid of each feature as well as the ownership information stored in the PY_FULL_OW field:
    with arcpy.da.SearchCursor("coa_parcels.shp",("PY_FULL_OW","SHAPE@XY")) as cursor:
  7. Loop through each row in SearchCursor and print the name of the parcel and location. Make sure you indent the for loop inside the with block:
    for row in cursor:
      print("Parcel owner: {0} has a location of: {1}".format(row[0], row[1]))
  8. Measure the elapsed time:
    elapsed = (time.clock() - start)
  9. Print the execution time:
    print("Execution time: " + str(elapsed))
  10. The entire script should appear as follows:
    import arcpy.da
    import time
    arcpy.env.workspace = "c:/ArcpyBook/Ch9"
    start = time.clock()
    with arcpy.da.SearchCursor("coa_parcels.shp",("PY_FULL_OW", "SHAPE@XY")) as cursor:
        for row in cursor:
            print("Parcel owner: {0} has a location of: {1}".format(row[0], row[1]))
    elapsed = (time.clock() - start)
    print("Execution time: " + str(elapsed))
  11. You can check your work by examining the C:ArcpyBookcodeCh8GeometryToken.py solution file.
  12. Save the script.
  13. Run the script. You should see something similar to the following output. Note the execution time; your time will vary:
    Parcel owner: CITY OF AUSTIN ATTN REAL ESTATE DIVISION has a location of: (3110480.5197341456, 10070911.174956793)
    Parcel owner: CITY OF AUSTIN ATTN REAL ESTATE DIVISION has a location of: (3110670.413783513, 10070800.960865)
    Parcel owner: CITY OF AUSTIN has a location of: (3143925.0013213265, 10029388.97419636)
    Parcel owner: CITY OF AUSTIN % DOROTHY NELL ANDERSON ATTN BARRY LEE ANDERSON has a location of: (3134432.983822767, 10072192.047894118)
    Execution time: 9.08046185109
    

Now, we're going to measure the execution time if the entire geometry is returned instead of just the portion of the geometry that we need:

  1. Save a new copy of the script as C:ArcpyBookCh8GeometryTokenEntireGeometry.py.
  2. Change the SearchCursor() function to return the entire geometry using SHAPE@ instead of SHAPE@XY:
    with arcpy.da.SearchCursor("coa_parcels.shp",("PY_FULL_OW", "SHAPE@")) as cursor:
  3. You can check your work by examining the C:ArcpyBookcodeCh8GeometryTokenEntireGeometry.py solution file.
  4. Save and run the script. You should see the following output. Your time will vary from mine, but notice that the execution time is slower. In this case, it's only a little over a second slower, but we're only returning 2600 features. If the feature class were significantly larger, as many are, this would be amplified:
    Parcel owner: CITY OF AUSTIN ATTN REAL ESTATE DIVISION has a location of: <geoprocessing describe geometry object object at 0x06B9BE00>
    Parcel owner: CITY OF AUSTIN ATTN REAL ESTATE DIVISION has a location of: <geoprocessing describe geometry object object at 0x2400A700>
    Parcel owner: CITY OF AUSTIN has a location of: <geoprocessing describe geometry object object at 0x06B9BE00>
    Parcel owner: CITY OF AUSTIN % DOROTHY NELL ANDERSON ATTN BARRY LEE ANDERSON has a location of: <geoprocessing describe geometry object object at 0x2400A700>
    Execution time: 10.1211390896
    

How it works…

A geometry token can be supplied as one of the field names supplied in the constructor for the cursor. These tokens are used to increase the performance of a cursor by returning only a portion of the geometry instead of the entire geometry. This can dramatically increase the performance of a cursor, particularly when you are working with large polyline or polygon datasets. If you only need specific properties of the geometry in your cursor, you should use these tokens.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset