[postgis-users] EMPTY geometries
David Blasby
dblasby at refractions.net
Thu Apr 10 14:37:39 PDT 2003
Paul and I have been looking at PostGIS conformance, and I've been
looking at empty geometries.
1. The OGC SF SQL spec doesnt seem to deal with empty geometries - it
calls them "the empty set". It appears that it would be fine with a
single "NULL" geometry.
2. WKT is really loosy-goosey about EMPTY geometries. All the base
types can be empty (POINT, LINESTRING, MULTIPOLYON, etc...), but also
components of the types can be EMPTY. For example:
MULTILINESTRING( EMPTY, (EMPTY, EMPTY, EMPTY) )
represents two linestrings - an empty one, and one made up of 3 empty
points.
3. WKB isnt as loosy-goosey as WKT, but fairly free formed. You cannot
represent an EMPTY point in WKB. You can have empty objects like
linestrings with 0 points, or multilinestrings with 0 linestrings, or
multilinestrings with empty linestrings inside.
Currently PostGIS does not allow empty geometries at all. It uses the
SQL-NULL to represent them.
----
I dont really see any advantage to supporting the nasty empty
geometries. They dont really add anything, and the specification say
that you cannot make empty geometries:
"The instantiable subclasses of Geometry defined in this specification
are restricted to 0, 1 and twodimensional
geometric objects that exist in two-dimensional coordinate space."
Empty geometries do not have a dimension.
Also, the diagram (Figure 2.1) says that objects like LINESTRING have 2+
points (not 0, or 2+). And MULTILINESTRING has 1+ linestrings in it.
But, in keeping with the spirit of the spec, I see two ways of dealing
with this:
A. Simple one-empty geometry
Have a single empty geometry type. Its WKT representation would be
"GEOMETRYCOLLECTION( EMPTY )" and its WKB representation would also
be an empty geometrycollection. Any WKT with an empty in it would be
converted to this type:
LINESTRING( EMPTY) -> GEOMETRYCOLLECTION( EMPTY )
LINESTRING(0 0, EMPTY, 1 1) -> GEOMETRYCOLLECTION( EMPTY )
MULTILINESTRING( (0 0, 1 1), EMPTY) -> GEOMETRYCOLLECTION( EMPTY )
* NB: a valid geometry was thrown away in the last case. We might
want this to return a MULTILINESTRING( (0 0, 1 1)), but that
would take a bit of time to fix with the parser.
Any GEOS function that returns an empty set would have its results
represented with this.
difference(g,g) -> GEOMETRYCOLLECTION( EMPTY )
intersection( disjoin geoms) -> GEOMETRYCOLLECTION( EMPTY )
The main problem with this is the loss of type information
LINESTRING( EMPTY) -> GEOMETRYCOLLECTION( EMPTY )
The type of the geometry has changed from LINESTRING to a GC.
This could cause problems with tables that have constraints
on them to ensure they have a homogeneous type.
This fixable by having the contraint on the table be:
isnull(geom) || geometryType(geom) = 'LINESTRING' ||
isEmpty(geom)
GeometryType( <empty geometry>) -> GEOMETRYCOLLECTION
A second problem is that the location of sub-geometries in MULTI*
geometries will change:
GeometryN(MULTILINESTRING( (0 0, 1 1), EMPTY, (2 2, 3 3)), 2)
should be LINESTRING EMPTY, but in our implementation
it would either be an error, or LINESTRING (2 2, 3 3).
B. Typed empty geometries
This involves adding 7 new types (cf. postgis.h)
EMPTY_POINT
EMPTY_MULTIPOINT
EMPTY_LINESTRING
EMPTY_MULTILINESTRING
EMPTY_POLYGON
EMPTY_MULTIPOLYGON
EMPTY_GEOMETRYCOLLECTION
NB: EMPTY_POINT is not representable in WKB, so it would have
to be converted to an EMPTY_MULTIPOINT.
Internal GEOS functions would only create EMPTY_GEOMETRYCOLLECTION.
The only real advantage of this is that users can create empty
geometries of a known type (ie. POINT EMPTY is different from LINESTRING
EMPTY).
This isnt too much more work than the single-type version.
C. Typed empty geometries with actual empty sub-types
This is very much like the WKB system.
Make geometries like LINESTRING valid with 0 points (representing
"LINESTRING EMPTY"). Make MULTI* valid with 0 sub-objects.
Make an EMPTYPOINT type.
This means we're fully able to represent all the geometries except
screwy things like "LINESTRING( EMPTY, 1 2, EMPTY, 3 3)".
In terms of work, "A" is faily simple, "B" is about 3* as much work, and
"C" could take quite a while to ensure everything is 0-point and
0-object aware.
In terms of conformance, "A" seems like its all we need. The spec looks
like it only requires some type of "empty set" geometry. The other two
methods are just there to be nice for the WKT and WKB specification.
I'm loath to mess up to code to allow for empty objects that people will
probably never use.
What do you think? Anyone have any different impressions of the
specification? Anyone have any use for the funnier empty geometries?
dave
More information about the postgis-users
mailing list