
GSERIALIZED FORM
=================

The new serialized form, used by GEOGRAPHY, attempts to learn from the lessons of the SERIALIZED_LWGEOM, making slightly different trade-offs between alignment and overall compactness.

* It is understood that GSERIALIZED is be used primarily (only) by PostGIS. Other users of the geometry library (for example, the loaders and dumpers) will serialize to WKB or EWKB or various text representations. Therefore, GSERIALIZED includes the uint32 "size" field at the top used by PostgreSQL for varlena types.
* Like SERIALIZED_LWGEOM, GSERIALIZED is built to be read and written recursively, so that nested collections of collections (of ...) are possible without restrictions on depth.
* GSERIALIZED preserves double alignment of ordinate arrays. This will allow coordinate access without memcpy.
* GSERIALIZED includes a mandatory SRID, in recognition of the fact that most production use of PostGIS does actually use an SRID. In SERIALIZED_LWGEOM the SRID is optional.
* GSERIALIZED places the dimensionality information, the SRID information and the bounding boxes at the front of the structure, and all sub-components inherit from those parent values.
* GSERIALIZED retains the idea of optional bounding boxes, so that small features do not carry the extra storage overhead of a largely redundant bounding box.

STRUCTURE
---------

Most of the internals of GSERIALIZED are anonymous. One thing that differs from SERIALIZED_LWGEOM is that the geometry type is no longer directly accessible from the structure (it was inside the one byte "type" at the top of the SERIALIZED_LWGEOM). To access the type in GSERIALIZED, you first have to figure out whether there is a an bounding box, how many dimensions that bounding box has, and move the data pointer appropriately before dereferencing. The gserialized_get_type(GSERIALIZED *s) function carries out this operation.

typedef struct
{
	uint32 size; /* For PgSQL use, use VAR* macros to manipulate. */
	uchar srid[3]; /* 24 bits of SRID */
	uchar flags; /* HasZ, HasM, HasBBox, IsGeodetic */
	uchar data[1]; /* See gserialized.txt */
} GSERIALIZED;

The standard header is as follows (using <> to denote 4-byte fields and [] to denote 8-byte fields):

<size> size  /* Used by PgSQL */
<srid        /* 3 bytes */
 flags>      /* 1 byte */
<bbox-xmin>  /* bounding box is optional */
<bbox-xmax>  /* number of dimensions is variable and indicated in the flags */
<bbox-ymin>
<bbox-ymax>

After the header comes the recursively searchable geometry representations. Each type is double aligned, so any combination is double aligned, and we start after a double aligned standard header, so we are golden:

<pointype>
<npoints>       /* 0 if empty, 1 otherwise */
[double]
[double]
[double]

<linestringtype>
<npoints>      /* 0 if empty, N otherwise */
[double]
...
[double]

<polygontype>
<nrings>        /* 0 if empty, N otherwise */
<npointsring1>
<npointsring2>
<?pad?>         /* pad if nrings % 2 > 0 */
[double]
...
[double]

<collectiontype>
<ngeoms>        /* 0 if empty, N otherwise */
[geom]
...
[geom]

<circularstringtype>
<npoints>       /* 0 if empty, N otherwise */
[double]
...
[double]

<compoundstringtype>
<ngeoms>        /* 0 if empty, N otherwise */
[geom]
...
[geom]

