I understand that the standard validation/repair tools are not for use with ArcSDE and that ESRI needs to fix this, but are there work-arounds for at least checking where there might be empty geometry in a feature using ArcObjects or a script? Anything really. I'm attempting to export features from layers in an ArcSDE instance but some of those layers in the database give the "Attempted an operation on empty geometry" error when attempting to extract. I'm running ArcMap 10.3
[GIS] Repair/Check for empty geometry in ArcSDE
arcgis-10.3arcmaparcpyenterprise-geodatabase
Related Solutions
Below are a couple of extension methods for IFeature/IRow that show the actual setting of a value. You'll want to check out cursors and row/feature buffers if you need better performance: http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/d/0001000002rs000000.htm
the extension methods would need to be called when you are already in an edit operation (editor.StartOperation()/editor.StopOperation()): http://resources.esri.com/help/9.3/ArcGISDesktop/dotnet/abbd6e92-04f8-4957-a205-a53773fbf023.htm
/// <summary>
/// Sets the value on IFeature
/// </summary>
/// <param name="feature">The feature with the field to be set</param>
/// <param name="fieldName">Name of the field.</param>
/// <param name="value">The new field value</param>
/// <param name="ignoreMissingFields">if set to <c>true</c> [ignore missing fields].</param>
public static void SetValue(this IFeature feature, string fieldName, object value, bool ignoreMissingFields)
{
(feature as IRow).SetValue(fieldName, value, ignoreMissingFields);
}
/// <summary>
/// Sets the value on IRow
/// </summary>
/// <param name="row">The row with the field to update</param>
/// <param name="fieldName">Name of the field.</param>
/// <param name="value">The new field value</param>
/// <param name="ignoreMissingFields">if set to <c>true</c> [ignore missing fields].</param>
public static void SetValue(this IRow row, string fieldName, object value, bool ignoreMissingFields)
{
int index = row.Fields.FindField(fieldName);
if (index != -1)
{
if (row.Fields.get_Field(index).Editable)
{
row.set_Value(index, value);
}
}
else
{
if (!ignoreMissingFields)
{
throw new System.ArgumentException("Field '{0}' Not Found.".FormatString(fieldName));
}
}
}
The default geometry creation type for ArcGIS in PostgreSQL databases depends on the version of software and how it's installed.
On Amazon RDS instances, where it's not possible to add the sde.st_geometry type, the geodatabase enablement code is able to detect RDS is in use, and the default DBTUNE entry is automatically altered to:
keyword: "DEFAULTS"
parameter_name: "GEOMETRY_STORAGE"
config_string: "PG_GEOMETRY"
On other PostgreSQL enterprise geodatabase-enabled databases, the default on initial install is:
keyword: "DEFAULTS"
parameter_name: "GEOMETRY_STORAGE"
config_string: "ST_GEOMETRY"
ArcGIS 10.4 and higher can write to PostgreSQL 9.3 and higher without enabling an enterprise geodatabase, and therefore use PostGIS geometry
as a default.
The sdedbtune
command-line utility was used to edit DBTUNE keywords at ArcGIS 10.2 and earlier, but that tool was deprecated, and a pair of ArcPy toolbox tools were added at 10.3:
- arcpy.ExportGeodatabaseConfigurationKeywords_management()
- arcpy.ImportGeodatabaseConfigurationKeywords_management()
I've generally just used SQL to make a simple change to one keyword parameter (but you need to make sure the transaction has committed before you try using it).
Note that the environment you have listed -- ArcGIS 10.2.x with PG 9.4.x and PostGIS 2.1.x -- is not a supported configuration. PostgreSQL 9.4 support was added at ArcGIS 10.4 (though it would probably work at ArcGIS 10.3.x). Always search on "system requirements" from desktop.arcgis.com to research RDBMS compatibility before enabling a geodatabase.
Best Answer
ArcGIS does not include tools to detect corrupt geometries because it is not possible to create them (short of hacking the SDE metadata tables). Native SQL types can create corrupt geometries, if ArcGIS is not used in the pipeline, but then there are native tools to detect and repair or delete those same corrupt geometries, so no Esri tools are needed.
A definition or selection query of
SHAPE IS NULL
orSHAPE IS NOT NULL
is the simple solution for identifying NULL or not-NULL features (this will work for all storage types). This is not an error condition, just a natural database state, for which repair tools are not necessary.Detecting NIL shapes (not-NULL shapes with zero vertices) is a different problem, easily detected with SQL queries by storage type (e.g.,
WHERE sde.ST_NumPoints(shape) = 0
). NIL shapes are also not invalid, since they can only be populated if the database layer permits them (the "n" in "npc", "npc+", "nslc+", and "nac+" entity flags layer properties). Any supported mechanism to remove NILs from a layer would also first delete the NILs in the layer.The most common way to generate invalid geometries is by using inappropriate on-the-fly projection parameters, which result in horizon clipping or vertex sequences beyond the coordinate reference precision. These objects are not technically in the data table, and therefore do not need detection/removal tools either.
It is far more likely that there is an error in your procedure that is producing corrupt output than that filesystem corruption has occurred only to the degree to cause subtle errors in a few disparate byte sequences which will still pass internal validation checks (and if this has occurred, you should immediately buy a lottery ticket, since normal rules of causality do not apply).