What's in Your Feature Class: Nothing, Null, or Empty?

4645
0
05-29-2015 04:34 PM
Labels (1)
JoshuaBixby
MVP Esteemed Contributor
3 0 4,645

I think this blog post follows up nicely to Dan Patterson's recent blog post, ...That empty feeling...  The conversation about null and empty geometries in ArcGIS isn't new, but it does take some getting your head around.

When it comes to creating new feature classes, I am sure most people are quite familiar with the following screen from the New Feature Class wizard:

arccatalog_103_new_feature_class_shape_null.PNG

When creating a new feature class using ArcGIS Desktop, either through the GUI or ArcPy, the default settings allow for NULL values in the SHAPE field (see yellow highlight above).  Regardless of whether NULLs in the SHAPE field are a good or bad idea, they are supported and allowed by default, so it is good to understand what does/can happen when geometries aren't populated with the rest of a record in feature classes.

After troubleshooting several cases where NULL wasn't NULL, I decided to take a deeper look at what really happens when geometries aren't populated in feature classes.  It turns out, the answer depends both on the tool and type of geodatabase being used to insert, store, and retrieve records.  Presented here are the results for some of the more common tools and types of geodatabases.

Table 1 shows what actually gets populated in the SHAPE field when nothing, None, an empty geometry, and a non-empty geometry are inserted into a polygon feature class using three different methods.

TABLE 1:  SHAPE Field Values in Feature Class

Storage

Type

Insert

Method

NOTHINGNONEEMPTYPOLYGON

PGDB

ArcMap Editor

NullN/AN/APolygon
PGDBarcpy.InsertCursorNullErrorEmptyPolygon
PGDBarcpy.da.InsertCursorNullNullNullPolygon
FGDBArcMap EditorEmptyN/AN/APolygon
FGDBarcpy.InsertCursorNullErrorEmptyPolygon
FGDBarcpy.da.InsertCursorNullNullNullPolygon
SDE(SQL)ArcMap EditorEmptyN/AN/APolygon
SDE(SQL)arcpy.InsertCursorNullErrorEmptyPolygon
SDE(SQL)arcpy.da.InsertCursorNullNullNullPolygon
SDE(ORA)ArcMap EditorEmptyN/AN/APolygon
SDE(ORA)arcpy.InsertCursorNullErrorEmptyPolygon
SDE(ORA)arcpy.da.InsertCursorNullNullNullPolygon

NOTE:

  1. Storage Type:
    1. PGDB := personal geodatabase
    2. FGDB := file geodatabase
    3. SDE(SQL) := SQL Server enterprise geodatabase
    4. SDE(ORA) := Oracle enterprise geodatabase
  2. Insert Method:
    1. ArcMap Editor := edit session in ArcMap
    2. arcpy.InsertCursor := original/older ArcPy insert cursor
    3. arcpy.da.InsertCursor := ArcPy Data Access insert cursor
  3. Insert Geometry:
    1. NOTHING := no geometry is specified.
      1. In ArcMap edit session, table is populated with no geometry
      2. In ArcPy insert cursors, SHAPE field is not specified with cursor
    2. NONE := Python None object is passed to SHAPE field
    3. EMPTY := empty polygon is passed to SHAPE field
    4. POLYGON := non-empty polygon is created or passed to SHAPE field
  4. SHAPE Value:
    1. N/A := not applicable, i.e., not possible to insert or attempt to insert type of geometry or object
    2. Error := error is generated attempting to insert type of geometry or object
    3. Null := NULL value/marker in SHAPE field
    4. Empty := empty polygon or empty collection in SHAPE field
    5. Polygon := non-empty polygon in SHAPE field

Table 2 shows what gets returned by search cursors once the records from Table 1 have been inserted into a feature class.

Table 2:  Retrieved Geometry/Object From SHAPE Field

Storage

Type

Retrieve

Method

NULLEMPTYPOLYGON
PGDBarcpy.SearchCursorNoneEmptyPolygon
PGDBarcpy.da.SearchCursorNoneNonePolygon
FGDBarcpy.SearchCursorNoneEmptyPolygon
FGDBarcpy.da.SearchCursorNoneNonePolygon
SDE(SQL)arcpy.SearchCursorNoneEmptyPolygon
SDE(SQL)arcpy.da.SearchCursorNoneNonePolygon
SDE(ORA)arcpy.SearchCursorNoneEmptyPolygon
SDE(ORA)arcpy.da.SearchCursorNoneNonePolygon

NOTE:

  1. Storage Type:
    1. PGDB := personal geodatabase
    2. FGDB := file geodatabase
    3. SDE(SQL) := SQL Server enterprise geodatabase
    4. SDE(ORA) := Oracle enterprise geodatabase
  2. Retrieve Method:
    1. arcpy.SearchCursor := original/older ArcPy search cursor
    2. arcpy.da.SearchCursor := ArcPy Data Access search cursor
  3. SHAPE Value:
    1. NULL := NULL value/marker in SHAPE field
    2. EMPTY := empty polygon or empty collection in SHAPE field
    3. POLYGON := non-empty polygon in SHAPE field
  4. Retrieve Geometry:
    1. None := Python None object
    2. Empty := empty polygon or empty collection
    3. Polygon := non-empty polygon

It is clear there are some differences, inconsistencies one might say, with how different tools insert nothing or empty geometries into a feature class that allows NULL values.  Even with the same tool, there are situations where nothing or empty geometries are handled differently between different types of geodatabases.  There are also differences with how different search cursors, and likely update cursors, retrieve empty geometries from feature classes.

I can't say what it all means, but there are a few items that stuck out for me.

  • Non-empty geometries are handled consistently across tools and types of geodatabases.
  • "Allow NULL Values" for the SHAPE field doesn't mean missing geometries will be NULL, it means missing geometries may be NULL, they could also be empty.
  • The ArcPy Data Access search cursor returns None whether a SHAPE field is NULL or contains an empty geometry, so None doesn't necessarily mean NULL for geometries.
About the Author
I am currently a Geospatial Systems Engineer within the Geospatial Branch of the Forest Service's Chief Information Office (CIO). The Geospatial Branch of the CIO is responsible for managing the geospatial platform (ArcGIS Desktop, ArcGIS Enterprise, ArcGIS Online) for thousands of users across the Forest Service. My position is hosted on the Superior National Forest. The Superior NF comprises 3 million acres in northeastern MN and includes the million-acre Boundary Waters Canoe Area Wilderness (BWCAW).