Introduction
This document:
1) Defines 2.5D in abstract terms
2) Suggests how Simple Features could be extended for 2.5D
This document defines 2.5D in a way which is a simple extension of the existing 2D OpenGIS Simple Features specification.
It does NOT cover full 3D geometry (e.g. solids), or 3D coordinate systems. Handling these topics thoroughly is a more complicated job, and is outside the scope of this document.
Any 2.5D geometry can be converted into a 2D geometry by discarding all its Z values. The resulting 2D geometry is the "shadow" of the 2.5D geometry. By convention, shadows are assumed to lie on the (X,Y,0) plane. So any 2D geometry can be converted into a 2.5D geometry by adding Z=0 to all its vertices.
The term "simple geometry" is important, since Spatial Relationships and Spatial Operators are undefined on non-simple geometries.
A 2.5D geometry is simple if
1) Its 2D shadow is simple
2) There is at most one Z value at each 2D location: (So wherever two of the geometry's vertices match in (X,Y), they also match in Z. For example, this rule applies to the end-points of a LinearRing, and the tangential points of a multi-looped Polygon. Also, wherever the (X,Y) shadow of one of the geometry’s vertices lies in the interior of the (X,Y) shadow of another of the geometry’s line segments, then the vertex Z value matches the line segments interpolated Z value. This rule applies to the tangential point of a multi-looped polygon.)
With this definition, a sloping road centerline is simple, but a vertical flagpole is not. The fact that a flagpole is not simple is one of the limitations of 2.5D, whereas in a 3D system the flagpole could be considered simple.
Spatial Relationships
The DE9IM rules for spatial queries are applied to the 2D shadows of all 2.5D geometries. So a 2.5D point is inside a 2.5D polygon if its (X,Y) location is inside the polygon's 2D shadow. (For example, this allows testing whether a 3D GPS location is inside a land-parcel that is defined as a loop of 3D points.)
Spatial Operators
The operators Union, Intersect, SymmetricDifference and Difference are defined on 2.5D geometries by working on their 2D shadows. This will produce a 2D output. However, the 2D output can be converted back to 2.5D by assigning a Z value to each output vertex. This can be done in a well-defined way, since each output vertex will either match an input vertex, or it will lie on a curve of an input geometry, where the Z is defined using linear interpolation. If an output vertex lies on both of the input geometries, then the "this" geometry object is used for the Z value.
The output of the convex-hull operator on a 2.5D geometry takes its Z values from the original 2.5D geometry. Each vertex in the convex-hull output will correspond to a vertex in the input geometry, so its Z-value is well defined for simple geometries.
The buffer operator will work on the 2D shadow of 2.5D geometries, and every vertex of the output geometry will have a Z value of 0.
Compatibility with existing OpenGIS Simple Features
Compatibility of Abstract Model
The abstract section of this document carefully defines spatial relationships and spatial operators on 2.5D geometries, to ensure backwards-compatibility with Simple Features.
Backwards-compatibility at the abstract level can be shown with a mathematical argument along the following lines:
Define geometrical systems G, H and SF where
G = {Simple 2.5D geometries}
H = {Simple 2.5D geometries where all Z values are 0}
SF = {Simple 2D geometries, as defined by the OpenGIS Simple Features}
Then H is a subsystem of G, and H is isomorphic to SF, preserving the spatial relationship functions and the spatial operator functions.
Extensions to Well-Known-Binary format
The existing OpenGIS Simple Features specification has the following 2D geometry types:
enum wkbGeometryType {
wkbPoint = 1,
wkbLineString = 2,
wkbPolygon = 3,
wkbMultiPoint = 4,
wkbMultiLineString = 5,
wkbMultiPolygon = 6,
wkbGeometryCollection = 7
}
This type-code is put in the header of a WKB blob. To reflect that all of these 2D geometry types have a 2.5D analogue, we would add a flag to the type-code to indicate that all following points include a Z value. So the new enumeration would become:
enum wkbGeometryTypeZ {
wkbPoint = 1,
wkbLineString = 2,
wkbPolygon = 3,
wkbMultiPoint = 4,
wkbMultiLineString = 5,
wkbMultiPolygon = 6,
wkbGeometryCollection = 7,
wkbZ = 0x80000000
}
Alternatively, this could be less efficiently coded as:
enum wkbGeometryTypeZ {
wkbPoint = 1,
wkbLineString = 2,
wkbPolygon = 3,
wkbMultiPoint = 4,
wkbMultiLineString = 5,
wkbMultiPolygon = 6,
wkbGeometryCollection = 7,
wkbPoint25D = 0x80000001,
wkbLineString25D = 0x80000002,
wkbPolygon25D = 0x80000003,
wkbMultiPoint25D = 0x80000004,
wkbMultiLineString25D = 0x80000005,
wkbMultiPolygon25D = 0x80000006,
wkbGeometryCollection25D = 0x80000007,
}
For example, a 2.5D Point geometry at the location (10,20,30) would be:
WKBPoint {
byte byteOrder; // wkbXDR or wkbNDR
uint32 wkbType; // (wkbPoint+wkbZ) = 0x80000001
Point {
Double x; // 10.0
Double y; // 20.0
Double z; // 30.0
}
}
If all Z values in a 2.5D geometry object happen to be 0, then its WKB representation could be the same as for the existing Simple Features specification (i.e. does not use the wkbZ flag, and does not include Z values). We suggest that 2.5D server-implementations drop the wkbZ flag whenever all the Z values are zero. This would allow 2D clients to interoperate with the 2.5D server whenever the data happens to lie on the (X,Y,0) plane.
Extensions to Well-Known-Text format
A 2.5D line-string from (10,20,30) to (40,50,60) would be represented as "LINESTRING(10 20 30,40 50 60)".
Notice that in the line-string, each vertex is terminated by either a comma, or a bracket. This means that a vertex that happens to have a Z value of 0 could simply not print its Z value. So a line-string from (1,2,3) to (4,5,0) could be represented as "LINESTRING(1 2 3,4 5)". We suggest that 2.5D server-implementations skips printing the Z value whenever it is zero. This would allow 2D clients to interoperate with the 2.5D server whenever the data happens to lie on the (X,Y,0) plane.
Extensions to Microsoft COM Simple Features interfaces
Since we have not needed to introduce any new geometry classes, and we have not changed the abstract behavior of any existing 2D geometry objects, we should not need to change any existing COM Interface Definition Language (IDL) files.
All we need to do is add a new optional IDL file for 2.5D interoperability:
// File: ZIdl.idl
// Extension to Simple Features for 2.5D Z values.
import "ocidl.idl", "GeometryIdl.idl";
interface IPointZ;
[ object, uuid(D4579E2D-1D2B-11d3-80BE-00C04F680FFF) ]
interface IPointZ : IPoint
{
[propget] HRESULT Z([out, retval] double * z);
};
Since the new interface IPointZ inherits from IPoint, whenever a 2.5D aware component is asked for a point value (e.g. when getting a vertex from a line-string), the component can return an IPointZ interface pointer.
Any 2D client will work with a 2.5D server unchanged.
In Visual Basic, a 2.5D client which knows it is interoperating with a 2.5D server, could ask for the point locations with an IPointZ typed variable, and then pass this IPointZ variable back into other methods. For example:
Dim line As ILineString
Set line = CreateFromWKT("LINESTRING(10 11 12,20 21,30 31 32)", sref)
Dim sr As ISpatialRelation
Set sr = line
For i = 0 To 2
' Get line vertex as 3D point.
Dim ptz As IPointZ
Set ptz = line.Point(i)
' Re-use 3D point in other Simple Features methods.
Debug.Print i; ") "; ptz.x, ptz.y, ptz.Z
Debug.Print sr.Contains(ptz)
Next i
Document converted from word 8 by
MSWordView (mswordview 0.4.2)
MSWordView written by Caolan McNamara