In a separate post (ST_Geometry — Don't allow empty geometry), @VinceAngelo mentioned:
A NIL (zero vertex) geometry is a valid shape type. It is required for some operations (e.g., the result of the intersection of two disjoint features). The shapefile specification permits Nil paired with any other one geometry type as the supported types in shapefiles.
Are there any other ways to create NIL (zero vertex) geometry -- other than "intersecting two disjoint features"?
For example, create NIL (zero vertex) geometry using editing tools in ArcGIS Pro. Use case: SQL query testing (Oracle 18c; 10.7.1 EGDB; SDE.ST_GEOMETRY).
Thanks.
Edit - Related: WKT: What is the reasoning behind the concept of a POINT EMPTY?
pline = arcpy.Polyline(arcpy.Array(None)) # -- create a polyline with an empty array
# -- some properties
pline.length # -- no length
0.0
pline.pointCount # -- no points
0
pline.JSON # -- no path to make
'{"paths":[],"spatialReference":{"wkid":null}}'
print(pline.centroid) # -- it has no centroid
None
For reference, the empty array trick works for Polygon, Polyline, and Multipoint classes, but PointGeometry won't accept a None point parameter.
- V
I'm struggling with Python since I don't write Python scripts very often. Is there any chance you could provide a full script for inserting a nil geometry row into an existing polygon feature class?
You can use the Well-Known Text keyword "EMPTY" to generate a NIL geometry:
import arcpy
sr = arcpy.SpatialReference(4326)
np = arcpy.FromWKT("POLYGON EMPTY",sr)
print("np - pointCount: {:d} JSON: {:s}".format(np.pointCount,np.JSON))
nl = arcpy.FromWKT("LINESTRING EMPTY",sr)
print("nl - pointCount: {:d} JSON: {:s}".format(nl.pointCount,nl.JSON))
nm = arcpy.FromWKT("MULTIPOINT EMPTY",sr)
print("nm - pointCount: {:d} JSON: {:s}".format(nm.pointCount,nm.JSON))
nx = arcpy.FromWKT("POINT EMPTY",sr)
print("nx - pointCount: {:d} JSON: {:s}".format(nx.pointCount,nx.JSON))
print("nx - firstPoint: {:s}".format(str(nx.firstPoint)))
which results in:
np - pointCount: 0 JSON: {"rings":[],"spatialReference":{"wkid":4326,"latestWkid":4326}}
nl - pointCount: 0 JSON: {"paths":[],"spatialReference":{"wkid":4326,"latestWkid":4326}}
nm - pointCount: 0 JSON: {"points":[],"spatialReference":{"wkid":4326,"latestWkid":4326}}
nx - pointCount: 1 JSON: {"x":"NaN","y":"NaN","spatialReference":{"wkid":4326,"latestWkid":4326}}
nx - firstPoint: None
Curiously, the PointGeometry type always returns a pointCount of one, but the firstPoint is None.
WKT can also be used at the SQL prompt in Oracle:
SQL> SELECT 'POLYGON' as type,SDE.ST_ASTEXT(SDE.ST_PolyFromText('POLYGON EMPTY',4326)) as geom FROM DUAL;
TYPE
-------
GEOM
--------------------------------------------------------------------------------
POLYGON
POLYGON EMPTY
SQL> SELECT 'LINE ' as type,SDE.ST_ASTEXT(SDE.ST_LineFromText('LINESTRING EMPTY',4326)) as geom FROM DUAL;
TYPE
-------
GEOM
--------------------------------------------------------------------------------
LINE
LINESTRING EMPTY
SQL> SELECT 'MPOINT ' as type,SDE.ST_ASTEXT(SDE.ST_MPointFromText('MULTIPOINT EMPTY',4326)) as geom FROM DUAL;
TYPE
--------
GEOM
--------------------------------------------------------------------------------
MPOINT
MULTIPOINT EMPTY
SQL> SELECT 'POINT ' as type,SDE.ST_ASTEXT(SDE.ST_PointFromText('POINT EMPTY',4326)) as geom FROM DUAL;
TYPE
-------
GEOM
--------------------------------------------------------------------------------
POINT
POINT EMPTY
SQL>
- V
For my notes, regarding, "WKT can also be used at the SQL prompt in Oracle:"
In Oracle, functions like SDE.ST_PolyFromText() return the subtype [SDE.ST_POLYFROMTEXT] , not the supertype [SDE.ST_GEOMETRY] .
See: Is it ok to store ST_POLYFROMTEXT in ST_GEOMETRY shape column?
I suspect that might be a problem: Esri Canada Case #03491474 - Is it ok to store ST_POLYFROMTEXT in ST_GEOMETRY shape column?
This bug report suggests to "...convert any geometry values which were created with a subtype to st_geometry, by using the st_geometry constructor."
Bug: Unable to define a query layer in ArcGIS where the data source uses an st_geometry subtype in Oracle
That seems to work:
For what it's worth, I think "by using the st_geometry constructor." is a recent addition to that bug report. That part wasn't included in the bug report previously; Esri must have added it to clarify how to convert from the subtype to the supertype.
GIS Stack Exchange: Get ArcGIS to recognize ST_POINT
Ideas:
Which brings us back to the old question about arcpy.Point having a value for x and y which is a valid number.
You can assign math.nan or numpy.nan to the x and y values but you have to test whether they are nan (not a number)
I can only wish points could just be defined from arrays
np.full(shape=(4,), fill_value=np.nan, order='C')
array([nan, nan, nan, nan])
# -- or
np.empty((0,))
array([], dtype=float64)
import math
import arcpy
p0 = arcpy.Point() # -- sadly given default values
p0
<Point (0.0, 0.0, #, #)>
# -- define invalid x, y values
p1 = arcpy.Point(math.nan, math.nan)
p1
<Point (nan, nan, #, #)>
#
# -- then check in code
math.isnan(p1.X)
pg0 = arcpy.PointGeometry(p0, None, None, None)
pg0[0] # must contain a point
<Point (nan, nan, #, #)>