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] =
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;
317 double *dptr = (
double*)(g1->
data);
322 dptr = (
double*)(g2->
data);
340 size_t bsz1 = sz1 - hsz1;
341 size_t bsz2 = sz2 - hsz2;
342 size_t bsz = bsz1 < bsz2 ? bsz1 : bsz2;
350 if (g1_is_empty && g2_is_empty)
356 return t1 == t2 ? 0 : (t1 < t2 ? -1 : 1);
368 cmp = memcmp(b1, b2, bsz);
369 if ( bsz1 == bsz2 && cmp_srid == 0 && cmp == 0 )
380 else if ( hash1 < hash2 )
409 else if (hsz1 > hsz2)
413 return cmp == 0 ? 0 : (cmp > 0 ? 1 : -1);
429 float *fbox = (
float*)(g->
data);
430 gbox->
xmin = fbox[i++];
431 gbox->
xmax = fbox[i++];
432 gbox->
ymin = fbox[i++];
433 gbox->
ymax = fbox[i++];
438 gbox->
zmin = fbox[i++];
439 gbox->
zmax = fbox[i++];
445 gbox->
zmin = fbox[i++];
446 gbox->
zmax = fbox[i++];
450 gbox->
mmin = fbox[i++];
451 gbox->
mmax = fbox[i++];
477 double *dptr = (
double*)(g->
data);
480 int *iptr = (
int*)(g->
data);
481 int isempty = (iptr[1] == 0);
486 gbox->
xmin = gbox->
xmax = dptr[i++];
487 gbox->
ymin = gbox->
ymax = dptr[i++];
491 gbox->
zmin = gbox->
zmax = dptr[i++];
495 gbox->
mmin = gbox->
mmax = dptr[i++];
505 double *dptr = (
double*)(g->
data);
506 int *iptr = (
int*)(g->
data);
507 int npoints = iptr[1];
546 double *dptr = (
double*)(g->
data);
547 int *iptr = (
int*)(g->
data);
548 int ngeoms = iptr[1];
569 gbox->
xmin = gbox->
xmax = dptr[i++];
570 gbox->
ymin = gbox->
ymax = dptr[i++];
574 gbox->
zmin = gbox->
zmax = dptr[i++];
578 gbox->
mmin = gbox->
mmax = dptr[i++];
588 double *dptr = (
double*)(g->
data);
589 int *iptr = (
int*)(g->
data);
590 int ngeoms = iptr[1];
685 LWDEBUGF(3,
"point size = %d", size);
699 LWDEBUGF(3,
"linestring size = %d", size);
713 LWDEBUGF(3,
"triangle size = %d", size);
729 for ( i = 0; i < poly->
nrings; i++ )
735 LWDEBUGF(3,
"polygon size = %d", size);
749 LWDEBUGF(3,
"circstring size = %d", size);
763 for ( i = 0; i < col->
ngeoms; i++ )
767 LWDEBUGF(3,
"lwcollection subgeom(%d) size = %d", i, subsize);
770 LWDEBUGF(3,
"lwcollection size = %d", size);
819 LWDEBUGF(3,
"g_serialize size = %d", size);
842 lwerror(
"Dimensions mismatch in lwpoint");
844 LWDEBUGF(2,
"lwpoint_to_gserialized(%p, %p) called", point, buf);
849 memcpy(loc, &type,
sizeof(
uint32_t));
862 return (
size_t)(loc - buf);
875 LWDEBUGF(2,
"lwline_to_gserialized(%p, %p) called", line, buf);
878 lwerror(
"Dimensions mismatch in lwline");
885 memcpy(loc, &type,
sizeof(
uint32_t));
901 LWDEBUGF(3,
"lwline_to_gserialized copied serialized_pointlist (%d bytes)", ptsize * line->
points->
npoints);
903 return (
size_t)(loc - buf);
916 LWDEBUG(2,
"lwpoly_to_gserialized called");
922 memcpy(loc, &type,
sizeof(
uint32_t));
930 for ( i = 0; i < poly->
nrings; i++ )
944 for ( i = 0; i < poly->
nrings; i++ )
950 lwerror(
"Dimensions mismatch in lwpoly");
957 return (
size_t)(loc - buf);
970 LWDEBUGF(2,
"lwtriangle_to_gserialized(%p, %p) called", triangle, buf);
973 lwerror(
"Dimensions mismatch in lwtriangle");
980 memcpy(loc, &type,
sizeof(
uint32_t));
996 LWDEBUGF(3,
"lwtriangle_to_gserialized copied serialized_pointlist (%d bytes)", ptsize * triangle->
points->
npoints);
998 return (
size_t)(loc - buf);
1012 lwerror(
"Dimensions mismatch in lwcircstring");
1019 memcpy(loc, &type,
sizeof(
uint32_t));
1034 return (
size_t)(loc - buf);
1051 memcpy(loc, &type,
sizeof(
uint32_t));
1059 for ( i=0; i<coll->
ngeoms; i++ )
1062 lwerror(
"Dimensions mismatch in lwcollection");
1067 return (
size_t)(loc - buf);
1075 LWDEBUGF(2,
"Input type (%d) %s, hasz: %d hasm: %d",
1078 LWDEBUGF(2,
"LWGEOM(%p) uint8_t(%p)", geom, buf);
1119 memcpy(loc, &f,
sizeof(
float));
1120 loc +=
sizeof(float);
1123 memcpy(loc, &f,
sizeof(
float));
1124 loc +=
sizeof(float);
1127 memcpy(loc, &f,
sizeof(
float));
1128 loc +=
sizeof(float);
1131 memcpy(loc, &f,
sizeof(
float));
1132 loc +=
sizeof(float);
1137 memcpy(loc, &f,
sizeof(
float));
1138 loc +=
sizeof(float);
1141 memcpy(loc, &f,
sizeof(
float));
1142 loc +=
sizeof(float);
1144 return_size = (size_t)(loc - buf);
1145 LWDEBUGF(4,
"returning size %d", return_size);
1152 memcpy(loc, &f,
sizeof(
float));
1153 loc +=
sizeof(float);
1156 memcpy(loc, &f,
sizeof(
float));
1157 loc +=
sizeof(float);
1164 memcpy(loc, &f,
sizeof(
float));
1165 loc +=
sizeof(float);
1168 memcpy(loc, &f,
sizeof(
float));
1169 loc +=
sizeof(float);
1171 return_size = (size_t)(loc - buf);
1172 LWDEBUGF(4,
"returning size %d", return_size);
1180 size_t expected_size = 0;
1181 size_t return_size = 0;
1205 serialized =
lwalloc(expected_size);
1219 return_size = ptr - serialized;
1221 if ( expected_size != return_size )
1223 lwerror(
"Return size (%d) not equal to expected size (%d)!", return_size, expected_size);
1228 *size = return_size;
1236 g->
size = return_size << 2;
1254 uint8_t *start_ptr = data_ptr;
1264 point->
flags = g_flags;
1275 data_ptr += npoints *
FLAGS_NDIMS(g_flags) *
sizeof(double);
1278 *g_size = data_ptr - start_ptr;
1285 uint8_t *start_ptr = data_ptr;
1295 line->
flags = g_flags;
1307 data_ptr +=
FLAGS_NDIMS(g_flags) * npoints *
sizeof(double);
1310 *g_size = data_ptr - start_ptr;
1317 uint8_t *start_ptr = data_ptr;
1329 poly->
flags = g_flags;
1334 LWDEBUGF(4,
"nrings = %d", nrings);
1337 ordinate_ptr = data_ptr;
1341 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;
1458 collection->
geoms = NULL;
1463 for ( i = 0; i < ngeoms; i++ )
1475 data_ptr += subsize;
1479 *g_size = data_ptr - start_ptr;
1492 LWDEBUGF(2,
"Got type %d (%s), hasz=%d hasm=%d geodetic=%d hasbox=%d", type,
lwtype_name(type),
1548 lwerror(
"lwgeom_from_gserialized: unable create geometry");
1550 lwgeom->
type = g_type;
1551 lwgeom->
flags = g_flags;
1563 lwgeom->
bbox = NULL;
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.
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"...
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
static LWLINE * lwline_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...
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
int gserialized_read_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Pull a GBOX from the header of a GSERIALIZED, if one is available.
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...
static LWTRIANGLE * lwtriangle_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
static LWCIRCSTRING * lwcircstring_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
static LWCOLLECTION * lwcollection_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
static int gserialized_cmp_srid(const GSERIALIZED *s1, const GSERIALIZED *s2)
void normalize(POINT3D *p)
Normalize to a unit vector.
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
static size_t gserialized_from_lwcollection(const LWCOLLECTION *coll, uint8_t *buf)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int gserialized_has_m(const GSERIALIZED *gser)
Check if a GSERIALIZED has an M ordinate.
static LWPOLY * lwpoly_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)
static int gserialized_peek_gbox_p(const GSERIALIZED *g, GBOX *gbox)
#define FLAGS_GET_GEODETIC(flags)
static size_t gserialized_from_lwpoint_size(const LWPOINT *point)
void lwgeom_free(LWGEOM *geom)
void cart2geog(const POINT3D *p, GEOGRAPHIC_POINT *g)
Convert cartesion coordinates on unit sphere to spherical coordinates.
static size_t gserialized_from_gbox(const GBOX *gbox, uint8_t *buf)
int gserialized_ndims(const GSERIALIZED *gser)
Return the number of dimensions (2, 3, 4) in a geometry.
#define FLAGS_GET_ZM(flags)
#define LWDEBUG(level, msg)
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)...
#define POLYHEDRALSURFACETYPE
float next_float_down(double d)
GSERIALIZED * gserialized_copy(const GSERIALIZED *g)
Return a copy of the input serialized geometry.
int gserialized_has_bbox(const GSERIALIZED *gser)
Check if a GSERIALIZED has a bounding box without deserializing first.
Point in spherical coordinates on the world.
int gserialized_has_z(const GSERIALIZED *gser)
Check if a GSERIALIZED has a Z ordinate.
static size_t gserialized_from_lwline_size(const LWLINE *line)
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
static size_t gserialized_from_lwtriangle(const LWTRIANGLE *triangle, uint8_t *buf)
uint64_t gbox_get_sortable_hash(const GBOX *g)
Return a sortable key based on the center point of the GBOX.
float next_float_up(double d)
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 gbox_float_round(GBOX *gbox)
Round given GBOX to float boundaries.
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
static size_t gserialized_from_lwpoly(const LWPOLY *poly, uint8_t *buf)
static size_t gserialized_is_empty_recurse(const uint8_t *p, int *isempty)
static uint64_t uint32_interleave_2(uint32_t u1, uint32_t u2)
static size_t gserialized_from_lwpoint(const LWPOINT *point, uint8_t *buf)
#define FLAGS_GET_BBOX(flags)
#define LW_TRUE
Return types for functions with status returns.
#define SRID_UNKNOWN
Unknown SRID value.
uint8_t * getPoint_internal(const POINTARRAY *pa, int n)
int ptarray_point_size(const POINTARRAY *pa)
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.
static size_t gserialized_from_any_size(const LWGEOM *geom)
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
static LWGEOM * lwgeom_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
int gserialized_get_zm(const GSERIALIZED *gser)
Return a number indicating presence of Z and M coordinates.
#define FLAGS_SET_BBOX(flags, value)
#define SIZE_GET(varsize)
Macro for reading the size from the GSERIALIZED size attribute.
static size_t gserialized_from_lwcollection_size(const LWCOLLECTION *col)
size_t gserialized_from_lwgeom_size(const LWGEOM *geom)
Calculate required memory segment to contain a serialized form of the LWGEOM.
static size_t gserialized_from_lwpoly_size(const LWPOLY *poly)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
char * gserialized_to_string(const GSERIALIZED *g)
Return a WKT representation of the gserialized geometry.
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
#define FLAGS_GET_M(flags)
static size_t gserialized_from_lwgeom_any(const LWGEOM *geom, uint8_t *buf)
int gserialized_is_geodetic(const GSERIALIZED *gser)
Check if a GSERIALIZED is a geography.
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...
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...
int lwcollection_allows_subtype(int collectiontype, int subtype)
Check if subtype is allowed in collectiontype.
void * lwalloc(size_t size)
static size_t gserialized_from_lwcircstring(const LWCIRCSTRING *curve, uint8_t *buf)
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
static uint32_t gserialized_get_uint32_t(const uint8_t *loc)
#define LWDEBUGF(level, msg,...)
#define FLAGS_NDIMS(flags)
static size_t gserialized_from_lwline(const LWLINE *line, uint8_t *buf)
int lwgeom_needs_bbox(const LWGEOM *geom)
Check whether or not a lwgeom is big enough to warrant a bounding box.
static LWPOINT * lwpoint_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
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)...
static size_t gserialized_from_lwtriangle_size(const LWTRIANGLE *triangle)
size_t gbox_serialized_size(uint8_t flags)
Return the number of bytes necessary to hold a GBOX of this dimension in serialized form...
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...