File: gserialized.txt

package info (click to toggle)
postgis 3.5.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 70,052 kB
  • sloc: ansic: 162,204; sql: 93,950; xml: 53,121; cpp: 12,646; perl: 5,658; sh: 5,369; makefile: 3,434; python: 1,205; yacc: 447; lex: 151; pascal: 58
file content (183 lines) | stat: -rw-r--r-- 5,748 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

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

The serialized form is a byte array, that holds all the information
stored in an LWGEOM, but in a flat structure, rather than an
in-memory tree. As with all such formats, trade-offs much be
made between size, data alignment, and convenience of access.

* It is understood that GSERIALIZED is to 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.
* 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.
* 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. The start of the
"data" member can be the type number, or the bounding box, or an extended
flags area. Or some combination of the above.

typedef struct
{
  uint32 size; /* Use LWSIZE_SET() and LWSIZE_GET() macros to manipulate. */
  uchar srid[3]; /* 21 bits of SRID (and 3 spare bits) */
  uchar flags; /* High priority information */
  uchar data[1]; /* See gserialized.txt */
} GSERIALIZED;

SIZE
----

The first four bytes in the "size" member are meant to be compatible with
the PostgreSQL VARLENA header. Use SIZE_SET() and SIZE_GET() macros to
manipulate the "size". Be careful not to mis-set the size, or operations
in PostgreSQL will end up scribbling on memory it should not.

FLAGS (V1)
----------

In the v1 serialization we have used up all of our flags except the version
bits.

* HasZ        (0x01)
* HasM        (0x02)
* HasBBox     (0x04)
* IsGeodetic  (0x08)
* ReadOnly    (0x10)
* IsSolid     (0x20)
* VersionBit1 (0x40)
* VersionBit2 (0x80)

FLAGS (V2)
----------

The v2 serialization recovers the flag space used by less-important flags
and moves those flags to a new optional flag area.

* HasZ             (0x01)
* HasM             (0x02)
* HasBBox          (0x04)
* IsGeodetic       (0x08)
* Reserved         (0x10)
* HasExtendedFlags (0x20)
* VersionBit1      (0x40)
* VersionBit2      (0x80)

Potential uses of the reserved flag:

* IsLightPoint: signals that the geometry type is point, and that the
  double coordinates will begin immediately in the "data" member without
  the usual type number and padding bytes. Allows 2D points to be
  represented in a minimum of 24 bytes, rather than the current 32.

OPTIONAL ELEMENTS (V1)
----------------------

If the HasBBox flag is set, the serialization contains the optional BBox
section, which is 2*ndims*sizeof(float) in size, and consists of the
bounding box. Since the box consists of pairs of floats, the presence
or absence of the box does not affect the double alignment of the
geometry coordinates.

* 2D:  <xmin><xmax><ymin><ymax>
* 3D:  <xmin><xmax><ymin><ymax><zmin><zmax>
* 3DM: <xmin><xmax><ymin><ymax><mmin><mmax>
* 4D:  <xmin><xmax><ymin><ymax><zmin><zmax><mmin><mmax>

OPTIONAL ELEMENTS (V2)
----------------------

The v2 serialization has a lot more flag space, and therefore a lot of
extra room to flag potential optional elements in the serialization.

In order to keep the double coordinates in the geometry section
double aligned, optional elements should themselves be multiples of
8 bytes.

* ExtendedFlags: If the HasExtendedFlags flag is set, then 8 bytes
  of extra flag space (uint64_t) are inserted prior to the (optional) BBox
* BBox: See V1 above.

EXTENDED FLAGS (V2)
-------------------

The extended flags are not heavily used at present, but can be used
to expand the serialization with options in the future. Extended flags
use 8 bytes of space, to ensure that that the coordinates in the
geometry section (see below) remain double-aligned for direct
memory access.

* IsSolid (0x01)

Potential extra uses of extended flags are:

* IsValidChecked/IsValid: a pair of flags used to cache validity state
  in the serialization to make ST_IsValid() checks blindingly fast.
* HasGeometryHash: signals presence of optional hash value that provides
  a small identity check that can be used in prepared geometry cache
  management to determine of the cache is dirty without requiring
  a full read and comparison of the geometry.

GEOMETRY (V1 & V2)
------------------

After the header and optional elements 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]