Internal BLOB-Geometry format [as extended since version 2.4]

SpatiaLite internally stores geometry values using ordinary SQLite's BLOB columns in a format that is very closely related to WKB format, but not exactly identical.

The main rationale to adopt this modified WKB format was initially based on absence of any Spatial Index on earlier versions, and is still now preserved so to avoid any unpleasant cross-version compatibility issue.
Any SpatiaLite's BLOB-Geometry includes an explicitly defined MBR; this helps a lot in order to grant a quick access to entities selected on a spatial basis, even when no Spatial Index is available.

The second good reason to use a purposely encoded format is needing to be sure that a generic BLOB value really corresponds to a valid SpatiaLite GEOMETRY; remember that one of SQLite specific features is to offer a very weak column-type enforcement.
So SpatiaLite simply relies on ordinary SQLite general support to check that one column value contains a generic BLOB, and then implements on its own any further check if this may be considered as a valid GEOMETRY value. To do this, SpatiaLite inserts some special markers at predictable and strategic positions.

The following is the general internal BLOB format for GEOMETRY used by SpatiaLite:

Byte Offset Content Notes
0 START [hex 00] a GEOMETRY encoded BLOB value must always start with a 0x00 byte
1 ENDIAN
[hex 00 or hex 01]
if this GEOMETRY is BIG_ENDIAN ordered must contain a 0x00 byte value
otherwise, if this GEOMETRY is LITTLE_ENDIAN ordered must contain a 0x01 byte value
Any other value [neither 0x00 nor 0x01], means that this BLOB cannot be a valid GEOMETRY
2 - 5 SRID a 32-bits integer value [little- big-endian ordered, accordingly with the precedent one]
corresponding to the SRID for this GEOMETRY
6 - 13 MBR_MIN_X a double value [little- big-endian ordered, accordingly with the precedent one]
corresponding to the MBR minimum X coordinate for this GEOMETRY
14 - 21 MBR_MIN_Y a double value corresponding to the MBR minimum Y coordinate
22 - 29 MBR_MAX_X a double value corresponding to the MBR maximum X coordinate
30 - 37 MBR_MAX_Y a double value corresponding to the MBR maximum Y coordinate
38 MBR_END [hex 7C] a GEOMETRY encoded BLOB value must always have an 0x7C byte in this position
39 - 42 CLASS TYPE a 32-bits integer; must identify a valid WKB class, i.e.
  • XY coordinates
    • 1 = POINT
    • 2 = LINESTRING
    • 3 = POLYGON
    • 4 = MULTIPOINT
    • 5 = MULTILINESTRING
    • 6 = MULTIPOLYGON
    • 7 = GEOMETRYCOLLECTION
Please note well: the above 2D [XY] WKB classes are supported indifferently by any SpatiaLite version.
Using recent versions (v.2.4 or any subsequent) the following extended classes are supported as well:
  • XYZ coordinates
    • 1001 = POINT Z
    • 1002 = LINESTRING Z
    • 1003 = POLYGON Z
    • 1004 = MULTIPOINT Z
    • 1005 = MULTILINESTRING Z
    • 1006 = MULTIPOLYGON Z
    • 1007 = GEOMETRYCOLLECTION Z
  • XYM coordinates
    • 2001 = POINT M
    • 2002 = LINESTRING M
    • 2003 = POLYGON M
    • 2004 = MULTIPOINT M
    • 2005 = MULTILINESTRING M
    • 2006 = MULTIPOLYGON M
    • 2007 = GEOMETRYCOLLECTION M
  • XYZM coordinates
    • 3001 = POINT ZM
    • 3002 = LINESTRING ZM
    • 3003 = POLYGON ZM
    • 3004 = MULTIPOINT ZM
    • 3005 = MULTILINESTRING ZM
    • 3006 = MULTIPOLYGON ZM
    • 3007 = GEOMETRYCOLLECTION ZM
  • compressed geometries
    • 1000002 = COMPRESSED LINESTRING
    • 1000003 = COMPRESSED POLYGON
    • 1001002 = COMPRESSED LINESTRING Z
    • 1001002 = COMPRESSED POLYGON Z
    • 1002002 = COMPRESSED LINESTRING M
    • 1002002 = COMPRESSED POLYGON M
    • 1003002 = COMPRESSED LINESTRING ZM
    • 1003002 = COMPRESSED POLYGON ZM
All following bytes are interpreted accordingly to this one class declaration; any other value in this position causes the current one to be considered as an invalid GEOMETRY.
43 - ... geometry class specific length and content depends on geometry class [POINT, LINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION etc]
LAST END [hex FE] a GEOMETRY encoded BLOB value must always end with a 0xFE byte

The preceding one is the general format that SpatiaLite uses for internal representations of any BLOB encoded GEOMETRY.
Specific formats for the various classes of GEOMETRY 2D [XY] are strictly based upon WKB, as follows:
GEOMETRY class
Format
Byte Offset Content Notes
POINT
0 - 7 X coordinate a double value corresponding to the X coordinate for this POINT
8 - 15 Y coordinate a double value corresponding to the Y coordinate for this POINT
LINESTRING
0 - 3 number of POINTs a 32-bits integer specifying the number of POINTs in this LINESTRING
4 - ... POINTs a corresponding sequence of POINTs
POLYGON
0 - 3 number of RINGs a 32-bits integer specifying the number of RINGs in this POLYGON
4 - ... RINGs a corresponding sequence of RINGs [LINESTRINGs]
MULTIPOINT
0 - 3 number of POINTs a 32-bits integer specifying the number of POINTs in this MULTIPOINT
4 - ... collection entities a corresponding sequence of collection entities, all of the POINT type
MULTILINESTRING
0 - 3 number of LINESTRINGs a 32-bits integer specifying the number of LINESTRINGs in this MULTILINESTRING
4 - ... collection entities a corresponding sequence of collection entities, all of the LINESTRING type
MULTIPOLYGON
0 - 3 number of POLYGONSs a 32-bits integer specifying the number of POLYGONs in this MULTIPOLYGON
4 - ... collection entities a corresponding sequence of collection entities, all of the POLYGON type
GEOMETRYCOLLECTION
0 - 3 number of collection entities a 32-bits integer specifying the number of collection entities in this GEOMETRYCOLLECTION
4 - ... collection entities a corresponding sequence of collection entities, of any supported kind

The following is the format expected for each one collection entity:
Byte Offset Content Notes
0 ENTITY [hex 69] a GEOMETRY encoded BLOB value must always have an 0x69 byte in this position
1 - 4 CLASS TYPE a 32-bits integer; must identify a valid WKB class that can be included within a collection, i.e.
  • 1 = POINT
  • 2 = LINESTRING
  • 3 = POLYGON
All following bytes are interpreted accordingly to this one class declaration; any other value in this position causes the current one to be considered as an invalid GEOMETRY.
5 - ... geometry class specific Length and content depends on geometry class [POINT, LINESTRING or POLYGON]

Extended 2.5D [XYZ, XYM and XYZM] Geometries

The original encoding schema adopted by earlier versions for 2D [XY] Geometries is simply extended in the most regular and easily predictable way so to support extended 2.5D as well.

XYZ Geometries

XYZ GEOMETRY class
Format
Byte Offset Content Notes
POINT Z
0 - 7 X coordinate a double value corresponding to the X coordinate for this POINT Z
8 - 15 Y coordinate a double value corresponding to the Y coordinate for this POINT Z
16 - 23 Z coordinate a double value corresponding to the Z coordinate for this POINT Z
LINESTRING Z
0 - 3 number of POINTZs a 32-bits integer specifying the number of POINTZs in this LINESTRING Z
4 - ... POINTZs a corresponding sequence of POINTZs
POLYGON Z
0 - 3 number of RINGZs a 32-bits integer specifying the number of RINGZs in this POLYGON Z
4 - ... RINGZs a corresponding sequence of RINGZs [LINESTRINGZs]
MULTIPOINT Z
0 - 3 number of POINTZs a 32-bits integer specifying the number of POINTZs in this MULTIPOINT Z
4 - ... collection Z-entities a corresponding sequence of collection Z-entities, all of the POINT Z type
MULTILINESTRING Z
0 - 3 number of LINESTRINGZs a 32-bits integer specifying the number of LINESTRINGZs in this MULTILINESTRING Z
4 - ... collection Z-entities a corresponding sequence of collection Z-entities, all of the LINESTRING Z type
MULTIPOLYGON Z
0 - 3 number of POLYGONSZs a 32-bits integer specifying the number of POLYGONZs in this MULTIPOLYGON Z
4 - ... collection Z-entities a corresponding sequence of collection Z-entities, all of the POLYGON Z type
GEOMETRYCOLLECTION Z
0 - 3 number of collection Z-entities a 32-bits integer specifying the number of collection Z-entities in this GEOMETRYCOLLECTION Z
4 - ... collection Z-entities a corresponding sequence of collection Z-entities, of any supported kind

The following is the format expected for each one collection Z-entity:
Byte Offset Content Notes
0 ENTITY [hex 69] a GEOMETRY encoded BLOB value must always have an 0x69 byte in this position
1 - 4 CLASS TYPE a 32-bits integer; must identify a valid WKB class that can be included within a collection, i.e.
  • 1001 = POINT Z
  • 1002 = LINESTRING Z
  • 1003 = POLYGON Z
All following bytes are interpreted accordingly to this one class declaration; any other value in this position causes the current one to be considered as an invalid GEOMETRY Z.
5 - ... geometry class specific Length and content depends on geometry class [POINT Z, LINESTRING Z or POLYGON Z]


XYM Geometries

XYM GEOMETRY class
Format
Byte Offset Content Notes
POINT M
0 - 7 X coordinate a double value corresponding to the X coordinate for this POINT M
8 - 15 Y coordinate a double value corresponding to the Y coordinate for this POINT M
16 - 23 M measure a double value corresponding to the M measure for this POINT M
Please note well: M is a measured value, not a geometric dimension !!!
LINESTRING M
0 - 3 number of POINTMs a 32-bits integer specifying the number of POINTMs in this LINESTRING M
4 - ... POINTMs a corresponding sequence of POINTMs
POLYGON M
0 - 3 number of RINGMs a 32-bits integer specifying the number of RINGMs in this POLYGON M
4 - ... RINGMs a corresponding sequence of RINGMs [LINESTRINGMs]
MULTIPOINT M
0 - 3 number of POINTMs a 32-bits integer specifying the number of POINTMs in this MULTIPOINT M
4 - ... collection M-entities a corresponding sequence of collection M-entities, all of the POINT M type
MULTILINESTRING M
0 - 3 number of LINESTRINGMs a 32-bits integer specifying the number of LINESTRINGMs in this MULTILINESTRING M
4 - ... collection M-entities a corresponding sequence of collection M-entities, all of the LINESTRING M type
MULTIPOLYGON M
0 - 3 number of POLYGONSMs a 32-bits integer specifying the number of POLYGONMs in this MULTIPOLYGON M
4 - ... collection M-entities a corresponding sequence of collection M-entities, all of the POLYGON M type
GEOMETRYCOLLECTION M
0 - 3 number of collection M-entities a 32-bits integer specifying the number of collection M-entities in this GEOMETRYCOLLECTION M
4 - ... collection M-entities a corresponding sequence of collection M-entities, of any supported kind

The following is the format expected for each one collection M-entity:
Byte Offset Content Notes
0 ENTITY [hex 69] a GEOMETRY encoded BLOB value must always have an 0x69 byte in this position
1 - 4 CLASS TYPE a 32-bits integer; must identify a valid WKB class that can be included within a collection, i.e.
  • 2001 = POINT M
  • 2002 = LINESTRING M
  • 2003 = POLYGON M
All following bytes are interpreted accordingly to this one class declaration; any other value in this position causes the current one to be considered as an invalid GEOMETRY M.
5 - ... geometry class specific Length and content depends on geometry class [POINT M, LINESTRING M or POLYGON M]


XYZM Geometries

XYZM GEOMETRY class
Format
Byte Offset Content Notes
POINT ZM
0 - 7 X coordinate a double value corresponding to the X coordinate for this POINT ZM
8 - 15 Y coordinate a double value corresponding to the Y coordinate for this POINT ZM
16 - 23 Z coordinate a double value corresponding to the Z coordinate for this POINT ZM
24 - 31 M measure a double value corresponding to the M measure for this POINT ZM
Please note well: M is a measured value, not a geometric dimension !!!
LINESTRING ZM
0 - 3 number of POINTZMs a 32-bits integer specifying the number of POINTZMs in this LINESTRING ZM
4 - ... POINTZMs a corresponding sequence of POINTZMs
POLYGON ZM
0 - 3 number of RINGZMs a 32-bits integer specifying the number of RINGZMs in this POLYGON ZM
4 - ... RINGZMs a corresponding sequence of RINGZMs [LINESTRINGZMs]
MULTIPOINT ZM
0 - 3 number of POINTZMs a 32-bits integer specifying the number of POINTZMs in this MULTIPOINT ZM
4 - ... collection ZM-entities a corresponding sequence of collection ZM-entities, all of the POINT ZM type
MULTILINESTRING ZM
0 - 3 number of LINESTRINGZs a 32-bits integer specifying the number of LINESTRINGZs in this MULTILINESTRING ZM
4 - ... collection ZM-entities a corresponding sequence of collection ZM-entities, all of the LINESTRING ZM type
MULTIPOLYGON ZM
0 - 3 number of POLYGONSZMs a 32-bits integer specifying the number of POLYGONZMs in this MULTIPOLYGON ZM
4 - ... collection ZM-entities a corresponding sequence of collection ZM-entities, all of the POLYGON ZM type
GEOMETRYCOLLECTION ZM
0 - 3 number of collection ZM-entities a 32-bits integer specifying the number of collection ZM-entities in this GEOMETRYCOLLECTION ZM
4 - ... collection ZM-entities a corresponding sequence of collection ZM-entities, of any supported kind

The following is the format expected for each one collection ZM-entity:
Byte Offset Content Notes
0 ENTITY [hex 69] a GEOMETRY encoded BLOB value must always have an 0x69 byte in this position
1 - 4 CLASS TYPE a 32-bits integer; must identify a valid WKB class that can be included within a collection, i.e.
  • 3001 = POINT ZM
  • 3002 = LINESTRING ZM
  • 3003 = POLYGON ZM
All following bytes are interpreted accordingly to this one class declaration; any other value in this position causes the current one to be considered as an invalid GEOMETRY ZM.
5 - ... geometry class specific Length and content depends on geometry class [POINT ZM, LINESTRING ZM or POLYGON ZM]


Compressed Geometries

Any LINESTRING or POLYGON (of any dimension model) can be actually replaced by its compressed equivalent.
The following table shows supported correspondences:
Uncompressed Class Compressed Class
2 = LINESTRING 1000002 = COMPRESSED LINESTRING
3 = POLYGON 1000003 = COMPRESSED POLYGON
1002 = LINESTRING Z 1001002 = COMPRESSED LINESTRING Z
1003 = POLYGON Z 1001003 = COMPRESSED POLYGON Z
2002 = LINESTRING M 1002002 = COMPRESSED LINESTRING M
2003 = POLYGON M 1002003 = COMPRESSED POLYGON M
3002 = LINESTRING ZM 1003002 = COMPRESSED LINESTRING ZM
3003 = POLYGON ZM 1003003 = COMPRESSED POLYGON ZM


Compressed LINESTRING [XY]

Byte Offset Content Notes
0 - 3 number of POINTs a 32-bits integer specifying the number of POINTs in this compressed LINESTRING
4 - 19 first POINT first POINT always is uncompressed
20 - ... compressed POINTs
Format
Byte Offset Content Notes
0 - 3 X coordinate a float value corresponding to the X differential coordinate for this compressed POINT:
expected to be computed as: diffX[n] = X[n] - X[n-1]
4 - 7 Y coordinate a float value corresponding to the Y differential coordinate for this compressed POINT
expected to be computed as: diffY[n] = Y[n] - Y[n-1]

any further POINT [except the last one] always is expected to be compressed
END-16 - END last POINT last POINT always is uncompressed so to fully preserve topological consistency

Compressed POLYGON [XY]

Byte Offset Content Notes
0 - 3 number of RINGs a 32-bits integer specifying the number of RINGs in this compressed POLYGON
4 - ... RINGs a corresponding sequence of compressed RINGs [ compressed LINESTRINGs]


Compressed LINESTRING [XYZ]

Byte Offset Content Notes
0 - 3 number of POINTZs a 32-bits integer specifying the number of POINTZs in this compressed LINESTRING Z
4 - 27 first POINT Z first POINT Z always is uncompressed
28 - ... compressed POINTZs
Format
Byte Offset Content Notes
0 - 3 X coordinate a float value corresponding to the X differential coordinate for this compressed POINT Z:
expected to be computed as: diffX[n] = X[n] - X[n-1]
4 - 7 Y coordinate a float value corresponding to the Y differential coordinate for this compressed POINT Z
expected to be computed as: diffY[n] = Y[n] - Y[n-1]
8 - 11 Z coordinate a float value corresponding to the Z differential coordinate for this compressed POINT Z
expected to be computed as: diffZ[n] = Z[n] - Z[n-1]

any further POINT Z [except the last one] always is expected to be compressed
END-24 - END last POINT Z last POINT Z always is uncompressed so to fully preserve topological consistency

Compressed POLYGON [XYZ]

Byte Offset Content Notes
0 - 3 number of RINGZs a 32-bits integer specifying the number of RINGZs in this compressed POLYGON Z
4 - ... RINGZs a corresponding sequence of compressed RINGZs [ compressed LINESTRINGZs]


Compressed LINESTRING [XYM]

Byte Offset Content Notes
0 - 3 number of POINTMs a 32-bits integer specifying the number of POINTMs in this compressed LINESTRING M
4 - 27 first POINT M first POINT M always is uncompressed
28 - ... compressed POINTMs
Format
Byte Offset Content Notes
0 - 3 X coordinate a float value corresponding to the X differential coordinate for this compressed POINT M:
expected to be computed as: diffX[n] = X[n] - X[n-1]
4 - 7 Y coordinate a float value corresponding to the Y differential coordinate for this compressed POINT M
expected to be computed as: diffY[n] = Y[n] - Y[n-1]
8 - 15 M measure a double value corresponding to the M measure for this compressed POINT M

any further POINT M [except the last one] always is expected to be compressed
END-24 - END last POINT M last POINT M always is uncompressed so to fully preserve topological consistency

Compressed POLYGON [XYM]

Byte Offset Content Notes
0 - 3 number of RINGMs a 32-bits integer specifying the number of RINGMs in this compressed POLYGON M
4 - ... RINGMs a corresponding sequence of compressed RINGMs [ compressed LINESTRINGMs]


Compressed LINESTRING [XYZM]

Byte Offset Content Notes
0 - 3 number of POINTZMs a 32-bits integer specifying the number of POINTZMs in this compressed LINESTRING ZM
4 - 35 first POINT ZM first POINT ZM always is uncompressed
36 - ... compressed POINTZMs
Format
Byte Offset Content Notes
0 - 3 X coordinate a float value corresponding to the X differential coordinate for this compressed POINT ZM:
expected to be computed as: diffX[n] = X[n] - X[n-1]
4 - 7 Y coordinate a float value corresponding to the Y differential coordinate for this compressed POINT ZM
expected to be computed as: diffY[n] = Y[n] - Y[n-1]
8 - 11 Z coordinate a float value corresponding to the Z differential coordinate for this compressed POINT ZM
expected to be computed as: diffZ[n] = Z[n] - Z[n-1]
12 - 19 M measure a double value corresponding to the M measure for this compressed POINT ZM

any further POINT ZM [except the last one] always is expected to be compressed
END-32 - END last POINT ZM last POINT ZM always is uncompressed so to fully preserve topological consistency

Compressed POLYGON [XYZM]

Byte Offset Content Notes
0 - 3 number of RINGZMs a 32-bits integer specifying the number of RINGZMs in this compressed POLYGON ZM
4 - ... RINGZMs a corresponding sequence of compressed RINGZMs [ compressed LINESTRINGZMs]