Null & Empty Geometries

5132
5
10-01-2012 11:53 AM
RobertCoup
New Contributor II
Hi folks,

I'm doing some debugging for a GDAL ticket ( http://trac.osgeo.org/gdal/ticket/4832 ), and I have come across some odd behaviour, and have some questions relating to null & empty geometries.

My test code is here: https://gist.github.com/3813984 and everything has been run under Linux/64bit against the v1.2 API.

Null geometries:

What is the correct way to define them?

Option 1:
row.SetNull(L"SHAPE");  // where SHAPE is the geometry field in the feature class
// then check for null via
row.IsNull(L"SHAPE");


This seems to work, and a table with only null geometries has a table extent of Nan,Nan,Nan,Nan. But what is geometryNull/shapeNull for then?

Option 2:
    Don't call row.setGeometry(). Rows get added to the FGDB with geometries as random types (sometimes geometryNull, sometimes geometryMultiPatch, sometimes the previous geometry type created), and with coordinates NaN/random/from the previous geometry created.

Option 3:
PointShapeBuffer geom;
row.SetGeometry(geom); // Errors with: Invalid pointer function parameter. (-2147467261)


Option 4:
PointShapeBuffer geom;
geom.Setup(FileGDBAPI::shapeNull); // Errors with: 522
row.SetGeometry(geom); // If you ignore the above, errors with: Invalid pointer function parameter. (-2147467261)


Option 5:
    Something else? 🙂

Empty Geometries:

(I'm using POINT EMPTY as an example, but the same logic presumably applies to GEOMETRYCOLLECTION EMPTY, POLYGON EMPTY, etc)
PointShapeBuffer geom;
geom.Setup(FileGDBAPI::shapePoint);
geom.SetEmpty();
row.SetGeometry(geom);


If you do this as the first features in an table, you get a random shapeType (eg. 64, 65), and geometryNull for the geometryType. geom.IsEmpty() returns false.

If you do this after you've added other points, you get the same shapeType, geometryType, and coordinates as the last non-empty point. geom.IsEmpty() returns false - ie. the geometry of the last non-empty feature is copied to the empty feature.

If a table has any rows with empty geometries, the bounds of the row extend to 0 - eg. add (100,100) and (POINT EMPTY) to a Table, and table.GetExtent() will return (xMin=0, xMax=100, yMin=0, yMax=100). If a table only has empty geometries, the extent will be (0, 0, 0, 0)

Is there a better way to set/read empty geometries?

Cheers,

Rob 🙂
0 Kudos
5 Replies
RobertCoup
New Contributor II
Empty geometries seem to crash ArcMap 10.0 - running "Check Geometry" hangs before the dialog even comes up, and I can't export the data to shapefile: "Error exporting data. The object has been deleted and is no longer valid. [tt] The parameter is (or has an element that is) the wrong kind of geometry."

Null geometries via row.SetNull(L"SHAPE") seem to work okay, and check/export to shapefile as expected.

Rob 🙂
0 Kudos
LanceShipman
Esri Regular Contributor
Option 1 is the correct method. Use row.SetNull
Should not be used. geometryNull/shapeNull

Option 2 is a result of not initializing the buffer.
Option 3 is the result of not initializing the buffer.
Option 4 is a result of initializing the buff incorrectly. The buffer should be initialize to reflect the geometry type being inserted (point in this case), Nulls should be inserted using SetNull.

Don't use empty geometries, use null geometries.

We have fixed a problem with feature class extents that your code brought to light. This is fixed in version 1.3 which we expect to release shortly (October).
0 Kudos
RobertCoup
New Contributor II
Hi Lance,

Option 1 is the correct method. Use row.SetNull


Thanks 🙂 I'll get GDAL updated with that behaviour.

Don't use empty geometries, use null geometries.


So the FileGDB API doesn't support creating empty geometries, or File Geodatabases in general don't support empty geometries? If the former, how should an empty geometry be tested for when reading a FGDB produced by ArcMap/etc?

We have fixed a problem with feature class extents that your code brought to light. This is fixed in version 1.3 which we expect to release shortly (October).


Happy to help!

Thanks again,

Rob 🙂
0 Kudos
DavidSousa
New Contributor III
Hi Lance,



Thanks 🙂 I'll get GDAL updated with that behaviour.



So the FileGDB API doesn't support creating empty geometries, or File Geodatabases in general don't support empty geometries? If the former, how should an empty geometry be tested for when reading a FGDB produced by ArcMap/etc?



Happy to help!

Thanks again,

Rob 🙂



It's not the the API does not support creating empty geometries (at least as far as I know).  Our recommendation has more to do with a semantic quibble about the utility of empty geometries, given the fact that NULL geometries work. 

A NULL geometry and an empty geometry are functionally equivalent in some ways, but they are not semantically identical.  It is similar to VARCHAR in a DBMS: a VARCHAR column that is NULL is not the same as one that is empty (i.e., a string with a length of 0).

I have a hard time coming up with a case for an empty geometry being useful from a data modeling standpoint.  You can't see them when you draw the feature class.  You cannot select them or identify them.  At least with a NULL geometry, you can select them in a where clause:

    WHERE shape IS NULL

The only way I can think of to determine whether a geometry is empty is to call an ArcObjects geometry function; in the API, there is an IsEmpty function that can be used.

In addition, a NULL geometry takes up exactly 1 bit of storage.  An empty geometry takes up much more space than that.
0 Kudos
RobertCoup
New Contributor II
Hi David,

It's not the the API does not support creating empty geometries (at least as far as I know).  Our recommendation has more to do with a semantic quibble about the utility of empty geometries, given the fact that NULL geometries work. 

A NULL geometry and an empty geometry are functionally equivalent in some ways, but they are not semantically identical.  It is similar to VARCHAR in a DBMS: a VARCHAR column that is NULL is not the same as one that is empty (i.e., a string with a length of 0).

I have a hard time coming up with a case for an empty geometry being useful from a data modeling standpoint.  You can't see them when you draw the feature class.  You cannot select them or identify them.  At least with a NULL geometry, you can select them in a where clause:


I completely understand your point and the semantic difference, but empty data vs no data does have use cases - the same for "" vs NULL in strings. A field modelling the output of Intersection(A, B) is empty (if they don't intersect), vs NULL where maybe the Intersection hasn't happened or been populated yet. (yes, a wee bit contrived, but beats adding an isDoneYet boolean column).

Anyway... if the FileGDB API does support empty geometries, and someone passes an empty geometry into GDAL/OGR, I want to continue that representation on - it's not my place to decide that empty geometries are useless if the input and output formats both support them. And if ArcMap can conceivably create empty geometries in an FGDB then I should be able to read them as such.

ShapeBuffer::SetEmpty() seems to do nothing... (or possibly it does something and ShapeBuffer::IsEmpty() doesn't work right) - any update on that?

Thanks,

Rob 🙂
0 Kudos