In this section, the memory layout of each simple geometry type is described. The format is based on the OGC specification, which is built on the memory layout of a C++ struct. All arrays have a computable size and are inline; they do not point to a different location in memory. This format allows streaming of geometry data.
First, the different data types, their size, and memory layout are discussed.
// double == 8byte IEEE double number in little endian encoding.
// int == 4 byte integer in little endian encoding
// the type of the geometry
enum GeometryType : int
{
None = 0,
Point = 1,
LineString = 2,
Polygon = 3,
MultiPoint = 4,
MultiLineString = 5,
MultiPolygon = 6,
MultiGeometry = 7,
CurveString = 10,
CurvePolygon = 11,
MultiCurveString = 12,
MultiCurvePolygon = 13
}
This is a bit field, for example, xym == coordinateDimensionality.XY | CoordinateDimensionality.M. The following sequence defines the type of coordinates used for this object:
enum CoordinateDimensionality : FdoInt32
{
XY = 0,
Z = 1,
M = 2
}
The following sequence establishes the basic pure geometry:
struct Geometry
{
int geomType;
CoordinateDimensionality type;
}
The following sequence defines a notation used to specify geometries within a byte stream.
// Define a notation within this specification
// int PositionSize(geometry)
// {
// if (geometry.type == CoordinateDimensionality.XY |
// CoordinateDimensionality.M ||
// geometry.type == CoordinateDimensionality.XY |
// CoordinateDimensionality.Z)
// return 3;
// if (geometry.type == CoordinateDimensionality.XY |
// CoordinateDimensionality.M | CoordinateDimensionality.Z)
// return 4
// return 2;
// }
struct Point // : Geometry
{
int geomType; // == GeometryType.Point;
CoordinateDimensionality type; // all types allowed
double[] coords; // size = PositionSize(this)
}
struct LineString
{
int geomType;
CoordinateDimensionality type;
int numPts; // >0
double[] coords; // size = numPts* PositionSize(this)
}
struct MultiPoint
{
int geomType;
int numPoints; // > 0
Point[] points; // size = numPoints
}
struct MultiLineString
{
int geomType;
int numLineStrings; // >= 0
LineString[] lineStrings; // size = numLineStrings
}
// building block for polygons, not geometry by itself
struct LinearRing
{
int numPts; // >0
double[] coords; // size = numPts* PositionSize(polygon)
}
struct Polygon
{
int geomType;
CoordinateDimensionality type;
int numRings; // >= 1 as there has to be at least one ring
LinearRing[] lineStrings; // size = numRings
}
struct MultiPolygon
{
int geomType;
int numPolygons; // >= 0
Polygon[] polygons; // size = numPolygons
}
struct MultiGeometry
{
int geomType;
int numGeom; // >= 0
Geometry[] geometry; // size = numGeom
}
enum CurveElementType : int
{
LineString = 1,
CircularArc = 2
}
struct CurveStringElement
{
int CurveElementType;
}
struct LinearCurveStringElement
{
int CurveElementType;
int length;
double[] coords; // size = this.length * PositionSize (this)
}
struct CircularArcCurveStringElement
{
int CurveElementType; // == CurveElmentType.Arc
double[] coords; // size = 2 * PositionSize(this)
}
struct CurveString
{
int geomType;
CoordinateDimensionality type; // all types allowed
double[] startPoint; // size = PositionSize(this)
int numElements; // >=0
CurveStringElement[] elements; // size = numElements
}
struct Ring
{
double[] startPoint; // size = PositionSize(this)
int numElements; // >=0
CurveStringElement[] elements; // size = numElements
}
struct MultiCurveString
{
int geomType;
int numCurveStrings; // >= 0
CurveString[] curveStrings; // size = numCurveStrings
}
struct CurvePolygon
{
int geomType; ;
CoordinateDimensionality type;
int numRings; // >=1 as there has to be at least one ring
Ring[] rings; // size = numRings
}
struct MultiCurvePolygon
{
int geomType;
int numPolygons; // >=0
CurvePolygon[] polygons; // size = numElements
}
In the following example a polygon is formatted within a byte array representing the stream according to the FGF specification.
T = 3 stands for GeometryType == GeometryType.Polygon
CT = 0 stands for CoordinateDimensionality == CoordinateDimensionality.XY