aanderson@amherst.edu

Unexpected Cumulative Extent of Polygon Feature Class

Discussion created by aanderson@amherst.edu on Mar 18, 2011
Latest reply on Mar 21, 2011 by aanderson@amherst.edu
I've noticed what seems to be a bug in one aspect of the geoprocessor, namely that when a polygon feature is updated the extent of its feature class is not properly updated to match. This can be observed in the case of a single feature in the feature class that is replaced by a smaller subset feature or by an overlapping feature; in the former case the feature class extent does not change, and in the latter it is expanded but not shifted. This suggests that the geoprocessor is simply calculating the union of the old feature class and updated feature, rather than recalculating the union of all features. The script below illustrates this:

**************************

import arcgisscripting, os
gp = arcgisscripting.create(9.3)

gp.Workspace = "in_memory"
bPolygon = "boundaryPolygon"
gp.CreateFeatureClass_management( gp.Workspace, bPolygon, "Polygon" )
bPolygon = os.path.join( gp.Workspace, bPolygon )
insertCursor = gp.InsertCursor( bPolygon )
polygonRow = insertCursor.NewRow()
insertCursor.InsertRow( polygonRow )
updateCursor = gp.UpdateCursor( bPolygon )
polygonRow = updateCursor.Next( )
corner = gp.CreateObject("Point")
left = 0.; right = 1.; bottom = 0.; top = 1.
width = right - left
height = top - bottom

for z in range( 0, 2 ) : 
  gp.AddMessage( "\n\tNext extent = " + str( ( left, right, bottom, top ) ) )
  boundary = gp.CreateObject("Array")
  corner.ID = 0; corner.X = left; corner.Y = top; boundary.Add(corner)
  corner.ID = 1; corner.X = left; corner.Y = bottom; boundary.Add(corner)
  corner.ID = 2; corner.X = right; corner.Y = bottom; boundary.Add(corner)
  corner.ID = 3; corner.X = right; corner.Y = top; boundary.Add(corner)
  # Create a polygon from the corners within the previously created shapefile bPolygon
  polygonRow.Shape = boundary  # Should always point to the same one row.
  updateCursor.UpdateRow( polygonRow )
  searchCursor = gp.SearchCursor( bPolygon )    # Use this instead of just polygonRow to verify that UpdateRow works
  gp.AddMessage( "\tBoundary polygon feature extent = " + str( searchCursor.Next( ).Shape.Extent ) )
  gp.AddMessage( "\tBoundary polygon feature class extent = " + str( gp.Describe( bPolygon ).Extent ) )
  # Subset polygon:
  left += width/4; right -= width/4; width /= 2
  bottom += height/4; top -= height/4; height /= 2

**************************

In this case, the output (edited for clarity) is:

Next extent = (0.0, 1.0, 0.0, 1.0)
Boundary polygon feature extent = 0 0 1.0 1.0
Boundary polygon feature class extent = 0 0 1.0 1.0

Next extent = (0.25, 0.75, 0.25, 0.75)
Boundary polygon feature extent = 0.25 0.25 0.75 0.75
Boundary polygon feature class extent = 0 0 1.0 1.0

That is, the feature class extent is unchanged. If the last three lines are replaced with:

  # Overlapping polygon:
  left += width; right += width
  bottom += height; top += height

the output is:

Next extent = (0.0, 1.0, 0.0, 1.0)
Boundary polygon feature extent = 0 0 1.0 1.0
Boundary polygon feature class extent = 0 0 1.0 1.0

Next extent = (1.0, 2.0, 1.0, 2.0)
Boundary polygon feature extent = 1.0 1.0 2.0 2.0
Boundary polygon feature class extent = 0 0 2.0 2.0

So the geoprocessor is willing to expand the extent, but not shrink it.

Am I unjustified in expecting the single-feature extent to always be the same as the feature class extent?

I'll note that the values returned by the Describe function are correct, because subsequent operations with this feature class reflect the cumulative extent.

Deleting a row and re-inserting it has the same deficiency, so my work-around is to delete the entire feature class and recreate it. Not too big a deal, I guess, except for my wasted time!

-- Andy

Outcomes