73 return sizeof(
GSERIALIZED) + 8 *
sizeof(
float) +
sizeof(int);
103 srid = srid | (
s->srid[0] << 16);
104 srid = srid | (
s->srid[1] << 8);
105 srid = srid |
s->srid[2];
108 srid = (srid<<11)>>11;
119 LWDEBUGF(3,
"Called with srid = %d", srid);
128 s->srid[0] = (srid & 0x001F0000) >> 16;
129 s->srid[1] = (srid & 0x0000FF00) >> 8;
130 s->srid[2] = (srid & 0x000000FF);
158 memcpy(&num, p+4, 4);
163 for ( i = 0; i < num; i++ )
210 uint64_t x_mask = 0x5555555555555555;
211 uint64_t y_mask = 0xAAAAAAAAAAAAAAAA;
212 return _pdep_u64(
x, x_mask) | _pdep_u64(
y, y_mask);
218 uint64_t
x = u1 & 0x1FFFFF;
219 uint64_t
y = u2 & 0x1FFFFF;
220 uint64_t z = u3 & 0x1FFFFF;
221 uint64_t x_mask = 0x9249249249249249;
222 uint64_t y_mask = 0x2492492492492492;
223 uint64_t z_mask = 0x4924924924924924;
224 return _pdep_u64(
x, x_mask) | _pdep_u64(
y, y_mask) | _pdep_u64(z, z_mask);
234 static uint64_t B[5] =
236 0x5555555555555555ULL,
237 0x3333333333333333ULL,
238 0x0F0F0F0F0F0F0F0FULL,
239 0x00FF00FF00FF00FFULL,
240 0x0000FFFF0000FFFFULL
242 static uint64_t S[5] = { 1, 2, 4, 8, 16 };
244 for ( i = 4; i >= 0; i-- )
246 x = (
x | (
x << S[i])) & B[i];
247 y = (
y | (
y << S[i])) & B[i];
296 int g1_is_empty, g2_is_empty, cmp;
298 uint64_t hash1, hash2;
315 double *dptr = (
double*)(g1->
data +
sizeof(
double));
320 dptr = (
double*)(g2->
data +
sizeof(
double));
344 size_t bsz1 = sz1 - hsz1;
345 size_t bsz2 = sz2 - hsz2;
346 size_t bsz = bsz1 < bsz2 ? bsz1 : bsz2;
354 if (g1_is_empty && !g2_is_empty)
358 if (!g1_is_empty && g2_is_empty)
362 cmp = memcmp(b1, b2, bsz);
363 if ( bsz1 == bsz2 && cmp_srid == 0 && cmp == 0 )
366 if (!g1_is_empty && !g2_is_empty)
376 else if ( hash1 < hash2 )
404 if (bsz1 != bsz2 && cmp == 0)
408 else if (bsz1 > bsz2)
411 return cmp > 0 ? 1 : -1;
427 float *fbox = (
float*)(g->
data);
428 gbox->
xmin = fbox[i++];
429 gbox->
xmax = fbox[i++];
430 gbox->
ymin = fbox[i++];
431 gbox->
ymax = fbox[i++];
436 gbox->
zmin = fbox[i++];
437 gbox->
zmax = fbox[i++];
443 gbox->
zmin = fbox[i++];
444 gbox->
zmax = fbox[i++];
448 gbox->
mmin = fbox[i++];
449 gbox->
mmax = fbox[i++];
475 double *dptr = (
double*)(g->
data);
478 int *iptr = (
int*)(g->
data);
479 int isempty = (iptr[1] == 0);
484 gbox->
xmin = gbox->
xmax = dptr[i++];
485 gbox->
ymin = gbox->
ymax = dptr[i++];
489 gbox->
zmin = gbox->
zmax = dptr[i++];
493 gbox->
mmin = gbox->
mmax = dptr[i++];
503 double *dptr = (
double*)(g->
data);
504 int *iptr = (
int*)(g->
data);
505 int npoints = iptr[1];
544 double *dptr = (
double*)(g->
data);
545 int *iptr = (
int*)(g->
data);
546 int ngeoms = iptr[1];
567 gbox->
xmin = gbox->
xmax = dptr[i++];
568 gbox->
ymin = gbox->
ymax = dptr[i++];
572 gbox->
zmin = gbox->
zmax = dptr[i++];
576 gbox->
mmin = gbox->
mmax = dptr[i++];
586 double *dptr = (
double*)(g->
data);
587 int *iptr = (
int*)(g->
data);
588 int ngeoms = iptr[1];
683 LWDEBUGF(3,
"point size = %d", size);
697 LWDEBUGF(3,
"linestring size = %d", size);
711 LWDEBUGF(3,
"triangle size = %d", size);
727 for ( i = 0; i < poly->
nrings; i++ )
733 LWDEBUGF(3,
"polygon size = %d", size);
747 LWDEBUGF(3,
"circstring size = %d", size);
761 for ( i = 0; i < col->
ngeoms; i++ )
765 LWDEBUGF(3,
"lwcollection subgeom(%d) size = %d", i, subsize);
768 LWDEBUGF(3,
"lwcollection size = %d", size);
817 LWDEBUGF(3,
"g_serialize size = %d", size);
840 lwerror(
"Dimensions mismatch in lwpoint");
842 LWDEBUGF(2,
"lwpoint_to_gserialized(%p, %p) called", point, buf);
860 return (
size_t)(loc - buf);
873 LWDEBUGF(2,
"lwline_to_gserialized(%p, %p) called", line, buf);
876 lwerror(
"Dimensions mismatch in lwline");
899 LWDEBUGF(3,
"lwline_to_gserialized copied serialized_pointlist (%d bytes)", ptsize * line->
points->
npoints);
901 return (
size_t)(loc - buf);
914 LWDEBUG(2,
"lwpoly_to_gserialized called");
928 for ( i = 0; i < poly->
nrings; i++ )
942 for ( i = 0; i < poly->
nrings; i++ )
948 lwerror(
"Dimensions mismatch in lwpoly");
955 return (
size_t)(loc - buf);
968 LWDEBUGF(2,
"lwtriangle_to_gserialized(%p, %p) called", triangle, buf);
971 lwerror(
"Dimensions mismatch in lwtriangle");
994 LWDEBUGF(3,
"lwtriangle_to_gserialized copied serialized_pointlist (%d bytes)", ptsize * triangle->
points->
npoints);
996 return (
size_t)(loc - buf);
1010 lwerror(
"Dimensions mismatch in lwcircstring");
1032 return (
size_t)(loc - buf);
1057 for ( i=0; i<coll->
ngeoms; i++ )
1060 lwerror(
"Dimensions mismatch in lwcollection");
1065 return (
size_t)(loc - buf);
1073 LWDEBUGF(2,
"Input type (%d) %s, hasz: %d hasm: %d",
1076 LWDEBUGF(2,
"LWGEOM(%p) uint8_t(%p)", geom, buf);
1117 memcpy(loc, &
f,
sizeof(
float));
1118 loc +=
sizeof(float);
1121 memcpy(loc, &
f,
sizeof(
float));
1122 loc +=
sizeof(float);
1125 memcpy(loc, &
f,
sizeof(
float));
1126 loc +=
sizeof(float);
1129 memcpy(loc, &
f,
sizeof(
float));
1130 loc +=
sizeof(float);
1135 memcpy(loc, &
f,
sizeof(
float));
1136 loc +=
sizeof(float);
1139 memcpy(loc, &
f,
sizeof(
float));
1140 loc +=
sizeof(float);
1142 return_size = (size_t)(loc - buf);
1143 LWDEBUGF(4,
"returning size %d", return_size);
1150 memcpy(loc, &
f,
sizeof(
float));
1151 loc +=
sizeof(float);
1154 memcpy(loc, &
f,
sizeof(
float));
1155 loc +=
sizeof(float);
1162 memcpy(loc, &
f,
sizeof(
float));
1163 loc +=
sizeof(float);
1166 memcpy(loc, &
f,
sizeof(
float));
1167 loc +=
sizeof(float);
1169 return_size = (size_t)(loc - buf);
1170 LWDEBUGF(4,
"returning size %d", return_size);
1178 size_t expected_size = 0;
1179 size_t return_size = 0;
1203 serialized =
lwalloc(expected_size);
1217 return_size = ptr - serialized;
1219 if ( expected_size != return_size )
1221 lwerror(
"Return size (%d) not equal to expected size (%d)!", return_size, expected_size);
1226 *size = return_size;
1234 g->
size = return_size << 2;
1252 uint8_t *start_ptr = data_ptr;
1262 point->
flags = g_flags;
1273 data_ptr += npoints *
FLAGS_NDIMS(g_flags) *
sizeof(double);
1276 *
g_size = data_ptr - start_ptr;
1283 uint8_t *start_ptr = data_ptr;
1293 line->
flags = g_flags;
1305 data_ptr +=
FLAGS_NDIMS(g_flags) * npoints *
sizeof(double);
1308 *
g_size = data_ptr - start_ptr;
1315 uint8_t *start_ptr = data_ptr;
1327 poly->
flags = g_flags;
1332 LWDEBUGF(4,
"nrings = %d", nrings);
1335 ordinate_ptr = data_ptr;
1340 ordinate_ptr += nrings * 4;
1350 for ( i = 0; i < nrings; i++ )
1361 ordinate_ptr +=
sizeof(double) *
FLAGS_NDIMS(g_flags) * npoints;
1365 *
g_size = ordinate_ptr - start_ptr;
1372 uint8_t *start_ptr = data_ptr;
1380 triangle->
bbox = NULL;
1382 triangle->
flags = g_flags;
1393 data_ptr +=
FLAGS_NDIMS(g_flags) * npoints *
sizeof(double);
1396 *
g_size = data_ptr - start_ptr;
1403 uint8_t *start_ptr = data_ptr;
1411 circstring->
bbox = NULL;
1413 circstring->
flags = g_flags;
1424 data_ptr +=
FLAGS_NDIMS(g_flags) * npoints *
sizeof(double);
1427 *
g_size = data_ptr - start_ptr;
1435 uint8_t *start_ptr = data_ptr;
1447 collection->
bbox = NULL;
1449 collection->
flags = g_flags;
1452 collection->
ngeoms = ngeoms;
1462 collection->
geoms = NULL;
1469 for ( i = 0; i < ngeoms; i++ )
1481 data_ptr += subsize;
1485 *
g_size = data_ptr - start_ptr;
1554 lwerror(
"lwgeom_from_gserialized: unable create geometry");
1556 lwgeom->
type = g_type;
1557 lwgeom->
flags = g_flags;
1569 lwgeom->
bbox = NULL;
void gbox_float_round(GBOX *gbox)
Round given GBOX to float boundaries.
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
size_t gbox_serialized_size(uint8_t flags)
Return the number of bytes necessary to hold a GBOX of this dimension in serialized form.
static size_t gserialized_from_lwtriangle_size(const LWTRIANGLE *triangle)
size_t gserialized_from_lwgeom_size(const LWGEOM *geom)
Calculate required memory segment to contain a serialized form of the LWGEOM.
static uint32_t gserialized_get_uint32_t(const uint8_t *loc)
static int gserialized_peek_gbox_p(const GSERIALIZED *g, GBOX *gbox)
static int gserialized_cmp_srid(const GSERIALIZED *s1, const GSERIALIZED *s2)
static size_t gserialized_from_lwtriangle(const LWTRIANGLE *triangle, uint8_t *buf)
static uint64_t uint32_interleave_2(uint32_t u1, uint32_t u2)
static size_t gserialized_from_lwpoly(const LWPOLY *poly, uint8_t *buf)
static size_t gserialized_from_lwcollection(const LWCOLLECTION *coll, uint8_t *buf)
int32_t gserialized_get_srid(const GSERIALIZED *s)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
void gserialized_set_srid(GSERIALIZED *s, int32_t srid)
Write the SRID into the serialized form (it is packed into three bytes so this is a handy function).
static LWPOINT * lwpoint_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
static size_t gserialized_from_lwline(const LWLINE *line, uint8_t *buf)
int gserialized_has_z(const GSERIALIZED *gser)
Check if a GSERIALIZED has a Z ordinate.
static size_t gserialized_from_gbox(const GBOX *gbox, uint8_t *buf)
static size_t gserialized_from_lwpoint_size(const LWPOINT *point)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int gserialized_get_zm(const GSERIALIZED *gser)
Return a number indicating presence of Z and M coordinates.
static LWCIRCSTRING * lwcircstring_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
static size_t gserialized_from_lwcircstring_size(const LWCIRCSTRING *curve)
char * gserialized_to_string(const GSERIALIZED *g)
Return a WKT representation of the gserialized geometry.
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
static size_t gserialized_from_any_size(const LWGEOM *geom)
static size_t gserialized_from_lwpoly_size(const LWPOLY *poly)
GSERIALIZED * gserialized_copy(const GSERIALIZED *g)
Return a copy of the input serialized geometry.
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *box)
Read the bounding box off a serialization and calculate one if it is not already there.
static size_t gserialized_from_lwcollection_size(const LWCOLLECTION *col)
uint32_t gserialized_header_size(const GSERIALIZED *gser)
Returns the size in bytes of the header, from the start of the object up to the type number.
static LWTRIANGLE * lwtriangle_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
int gserialized_is_geodetic(const GSERIALIZED *gser)
Check if a GSERIALIZED is a geography.
static size_t gserialized_from_lwpoint(const LWPOINT *point, uint8_t *buf)
static LWCOLLECTION * lwcollection_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
int gserialized_ndims(const GSERIALIZED *gser)
Return the number of dimensions (2, 3, 4) in a geometry.
int gserialized_has_m(const GSERIALIZED *gser)
Check if a GSERIALIZED has an M ordinate.
int gserialized_has_bbox(const GSERIALIZED *gser)
Check if a GSERIALIZED has a bounding box without deserializing first.
uint32_t gserialized_max_header_size(void)
Returns the size in bytes to read from toast to get the basic information from a geometry: GSERIALIZE...
static LWGEOM * lwgeom_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
static LWLINE * lwline_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
int gserialized_read_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Pull a GBOX from the header of a GSERIALIZED, if one is available.
static LWPOLY * lwpoly_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
static size_t gserialized_is_empty_recurse(const uint8_t *p, int *isempty)
static size_t gserialized_from_lwcircstring(const LWCIRCSTRING *curve, uint8_t *buf)
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
uint64_t gbox_get_sortable_hash(const GBOX *g)
Return a sortable key based on the center point of the GBOX.
int gserialized_cmp(const GSERIALIZED *g1, const GSERIALIZED *g2)
Return -1 if g1 is "less than" g2, 1 if g1 is "greater than" g2 and 0 if g1 and g2 are the "same".
static size_t gserialized_from_lwline_size(const LWLINE *line)
static size_t gserialized_from_lwgeom_any(const LWGEOM *geom, uint8_t *buf)
POINTARRAY * ptarray_construct_reference_data(char hasz, char hasm, uint32_t npoints, uint8_t *ptlist)
Construct a new POINTARRAY, referencing to the data from ptlist.
void lwgeom_free(LWGEOM *geom)
uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
#define FLAGS_GET_BBOX(flags)
#define FLAGS_SET_BBOX(flags, value)
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
int lwgeom_needs_bbox(const LWGEOM *geom)
Check whether or not a lwgeom is big enough to warrant a bounding box.
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
#define FLAGS_NDIMS(flags)
size_t ptarray_point_size(const POINTARRAY *pa)
#define POLYHEDRALSURFACETYPE
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
#define FLAGS_GET_M(flags)
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
#define FLAGS_GET_ZM(flags)
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
void * lwalloc(size_t size)
float next_float_up(double d)
#define LW_TRUE
Return types for functions with status returns.
#define SRID_UNKNOWN
Unknown SRID value.
void lwgeom_set_srid(LWGEOM *geom, int srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
float next_float_down(double d)
#define FLAGS_GET_GEODETIC(flags)
#define SIZE_GET(varsize)
Macro for reading the size from the GSERIALIZED size attribute.
int lwcollection_allows_subtype(int collectiontype, int subtype)
Check if subtype is allowed in collectiontype.
void normalize(POINT3D *p)
Normalize to a unit vector.
void cart2geog(const POINT3D *p, GEOGRAPHIC_POINT *g)
Convert cartesian coordinates on unit sphere to spherical coordinates.
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Point in spherical coordinates on the world.