60 uint8_t gflags = g->
gflags;
68 memcpy(&xflags, g->
data,
sizeof(uint64_t));
77 return (
lwflags & (~core_lwflags)) != 0;
84 return 6 *
sizeof(float);
103static inline uint8_t *
106 uint32_t extra_data_bytes = 0;
108 extra_data_bytes +=
sizeof(uint64_t);
113 return ((uint8_t *)g->
data) + extra_data_bytes;
131 return *((uint32_t*)loc);
134uint8_t
g2flags(
int has_z,
int has_m,
int is_geodetic)
178 static const intptr_t size_of_gserialized_up_to_data = (intptr_t) & ((
GSERIALIZED *)NULL)->data;
180 return size_of_gserialized_up_to_data + 8 *
sizeof(float) +
sizeof(uint64_t) +
sizeof(uint32_t);
187 return *((uint32_t*)(ptr));
193 srid = srid | (g->
srid[0] << 16);
194 srid = srid | (g->
srid[1] << 8);
195 srid = srid | (g->
srid[2]);
198 srid = (srid<<11)>>11;
209 LWDEBUGF(3,
"%s called with srid = %d", __func__, srid);
218 g->
srid[0] = (srid & 0x001F0000) >> 16;
219 g->
srid[1] = (srid & 0x0000FF00) >> 8;
220 g->
srid[2] = (srid & 0x000000FF);
226 uint32_t type = 0, num = 0;
229 if (!*isempty)
return 0;
232 memcpy(&num, p+4, 4);
238 for ( uint32_t i = 0; i < num; i++ )
262 for ( uint32_t i = 0; i < num; i++ )
265 memcpy(&lrnum, p+lz, 4);
298void hashlittle2(
const void *key,
size_t length, uint32_t *pc, uint32_t *pb);
304 int32_t pb = 0, pc = 0;
307 uint8_t *b1 = (uint8_t *)g1 + hsz1;
310 size_t bsz1 = sz1 - hsz1;
313 size_t bsz2 = bsz1 +
sizeof(int);
316 memcpy(b2, &srid,
sizeof(
int));
318 memcpy(b2+
sizeof(
int), b1, bsz1);
320 hashlittle2(b2, bsz2, (uint32_t *)&pb, (uint32_t *)&pc);
329 uint8_t *ptr = (uint8_t*)(g->
data);
343 return (
const float *)(ptr);
348 uint8_t gflags = g->
gflags;
360 gbox->
xmin = fbox[i++];
361 gbox->
xmax = fbox[i++];
362 gbox->
ymin = fbox[i++];
363 gbox->
ymax = fbox[i++];
368 gbox->
zmin = fbox[i++];
369 gbox->
zmax = fbox[i++];
375 gbox->
zmin = fbox[i++];
376 gbox->
zmax = fbox[i++];
380 gbox->
mmin = fbox[i++];
381 gbox->
mmax = fbox[i++];
397 double *dptr = (
double *)(geometry_start);
398 int32_t *iptr = (int32_t *)(geometry_start);
412 int isempty = (iptr[1] == 0);
417 gbox->
xmin = gbox->
xmax = dptr[i++];
418 gbox->
ymin = gbox->
ymax = dptr[i++];
422 gbox->
zmin = gbox->
zmax = dptr[i++];
426 gbox->
mmin = gbox->
mmax = dptr[i++];
436 int npoints = iptr[1];
475 int ngeoms = iptr[1];
496 gbox->
xmin = gbox->
xmax = dptr[i++];
497 gbox->
ymin = gbox->
ymax = dptr[i++];
501 gbox->
zmin = gbox->
zmax = dptr[i++];
505 gbox->
mmin = gbox->
mmax = dptr[i++];
515 int ngeoms = iptr[1];
567 out_point->
x = dptr[dim++];
568 out_point->
y = dptr[dim++];
572 out_point->
z = dptr[dim++];
576 out_point->
m = dptr[dim];
585 uint32_t isEmpty = (((uint32_t *)geometry_start)[1]) == 0;
591 uint32_t type = (((uint32_t *)geometry_start)[0]);
593 double *double_array_start = NULL;
598 double_array_start = (
double *)(geometry_start + 2 *
sizeof(uint32_t));
602 lwerror(
"%s is currently not implemented for type %d", __func__, type);
682 LWDEBUGF(3,
"point size = %d", size);
696 LWDEBUGF(3,
"linestring size = %d", size);
710 LWDEBUGF(3,
"triangle size = %d", size);
726 for (i = 0; i < poly->
nrings; i++)
732 LWDEBUGF(3,
"polygon size = %d", size);
746 LWDEBUGF(3,
"circstring size = %d", size);
760 for (i = 0; i < col->
ngeoms; i++)
764 LWDEBUGF(3,
"lwcollection subgeom(%d) size = %d", i, subsize);
767 LWDEBUGF(3,
"lwcollection size = %d", size);
821 LWDEBUGF(3,
"%s size = %d", __func__, size);
844 lwerror(
"Dimensions mismatch in lwpoint");
846 LWDEBUGF(2,
"%s (%p, %p) called", __func__, point, buf);
851 memcpy(loc, &type,
sizeof(uint32_t));
852 loc +=
sizeof(uint32_t);
854 memcpy(loc, &(point->
point->
npoints),
sizeof(uint32_t));
855 loc +=
sizeof(uint32_t);
864 return (
size_t)(loc - buf);
877 LWDEBUGF(2,
"%s (%p, %p) called", __func__, line, buf);
880 lwerror(
"Dimensions mismatch in lwline");
887 memcpy(loc, &type,
sizeof(uint32_t));
888 loc +=
sizeof(uint32_t);
892 loc +=
sizeof(uint32_t);
905 return (
size_t)(loc - buf);
924 memcpy(loc, &type,
sizeof(uint32_t));
925 loc +=
sizeof(uint32_t);
928 memcpy(loc, &(poly->
nrings),
sizeof(uint32_t));
929 loc +=
sizeof(uint32_t);
932 for (i = 0; i < poly->
nrings; i++)
934 memcpy(loc, &(poly->
rings[i]->
npoints),
sizeof(uint32_t));
935 loc +=
sizeof(uint32_t);
941 memset(loc, 0,
sizeof(uint32_t));
942 loc +=
sizeof(uint32_t);
946 for (i = 0; i < poly->
nrings; i++)
952 lwerror(
"Dimensions mismatch in lwpoly");
959 return (
size_t)(loc - buf);
972 LWDEBUGF(2,
"%s (%p, %p) called", __func__, triangle, buf);
975 lwerror(
"Dimensions mismatch in lwtriangle");
982 memcpy(loc, &type,
sizeof(uint32_t));
983 loc +=
sizeof(uint32_t);
987 loc +=
sizeof(uint32_t);
998 LWDEBUGF(3,
"%s copied serialized_pointlist (%d bytes)", __func__, ptsize * triangle->
points->
npoints);
1000 return (
size_t)(loc - buf);
1014 lwerror(
"Dimensions mismatch in lwcircstring");
1021 memcpy(loc, &type,
sizeof(uint32_t));
1022 loc +=
sizeof(uint32_t);
1026 loc +=
sizeof(uint32_t);
1036 return (
size_t)(loc - buf);
1053 memcpy(loc, &type,
sizeof(uint32_t));
1054 loc +=
sizeof(uint32_t);
1057 memcpy(loc, &coll->
ngeoms,
sizeof(uint32_t));
1058 loc +=
sizeof(uint32_t);
1061 for (i = 0; i < coll->
ngeoms; i++)
1064 lwerror(
"Dimensions mismatch in lwcollection");
1069 return (
size_t)(loc - buf);
1077 LWDEBUGF(2,
"Input type (%d) %s, hasz: %d hasm: %d",
1080 LWDEBUGF(2,
"LWGEOM(%p) uint8_t(%p)", geom, buf);
1116 uint64_t xflags = 0;
1124 memcpy(buf, &xflags,
sizeof(uint64_t));
1125 return sizeof(uint64_t);
1139 memcpy(loc, &f,
sizeof(
float));
1140 loc +=
sizeof(float);
1143 memcpy(loc, &f,
sizeof(
float));
1144 loc +=
sizeof(float);
1147 memcpy(loc, &f,
sizeof(
float));
1148 loc +=
sizeof(float);
1151 memcpy(loc, &f,
sizeof(
float));
1152 loc +=
sizeof(float);
1157 memcpy(loc, &f,
sizeof(
float));
1158 loc +=
sizeof(float);
1161 memcpy(loc, &f,
sizeof(
float));
1162 loc +=
sizeof(float);
1164 return_size = (size_t)(loc - buf);
1165 LWDEBUGF(4,
"returning size %d", return_size);
1172 memcpy(loc, &f,
sizeof(
float));
1173 loc +=
sizeof(float);
1176 memcpy(loc, &f,
sizeof(
float));
1177 loc +=
sizeof(float);
1184 memcpy(loc, &f,
sizeof(
float));
1185 loc +=
sizeof(float);
1188 memcpy(loc, &f,
sizeof(
float));
1189 loc +=
sizeof(float);
1191 return_size = (size_t)(loc - buf);
1192 LWDEBUGF(4,
"returning size %d", return_size);
1200 size_t expected_size = 0;
1201 size_t return_size = 0;
1202 uint8_t *ptr = NULL;
1247 return_size = ptr - (uint8_t*)g;
1249 if (expected_size != return_size)
1251 lwerror(
"Return size (%lu) not equal to expected size (%lu)!", return_size, expected_size);
1256 *size = return_size;
1271 uint8_t *start_ptr = data_ptr;
1273 uint32_t npoints = 0;
1295 *size = data_ptr - start_ptr;
1302 uint8_t *start_ptr = data_ptr;
1304 uint32_t npoints = 0;
1327 *size = data_ptr - start_ptr;
1334 uint8_t *start_ptr = data_ptr;
1336 uint8_t *ordinate_ptr;
1337 uint32_t nrings = 0;
1351 LWDEBUGF(4,
"nrings = %d", nrings);
1354 ordinate_ptr = data_ptr;
1359 ordinate_ptr += nrings * 4;
1369 for (i = 0; i < nrings; i++)
1371 uint32_t npoints = 0;
1384 *size = ordinate_ptr - start_ptr;
1391 uint8_t *start_ptr = data_ptr;
1393 uint32_t npoints = 0;
1399 triangle->
bbox = NULL;
1415 *size = data_ptr - start_ptr;
1422 uint8_t *start_ptr = data_ptr;
1424 uint32_t npoints = 0;
1430 circstring->
bbox = NULL;
1446 *size = data_ptr - start_ptr;
1454 uint8_t *start_ptr = data_ptr;
1456 uint32_t ngeoms = 0;
1466 collection->
bbox = NULL;
1467 collection->
type = type;
1471 collection->
ngeoms = ngeoms;
1481 collection->
geoms = NULL;
1488 for (i = 0; i < ngeoms; i++)
1500 data_ptr += subsize;
1504 *size = data_ptr - start_ptr;
1517 LWDEBUGF(2,
"Got type %d (%s), hasz=%d hasm=%d geodetic=%d hasbox=%d", type,
lwtype_name(type),
1553 uint32_t lwtype = 0;
1554 uint8_t *data_ptr = NULL;
1567 data_ptr = (uint8_t*)g->
data;
1572 data_ptr +=
sizeof(uint64_t);
1582 lwerror(
"%s: unable create geometry", __func__);
1584 lwgeom->
type = lwtype;
1597 lwgeom->
bbox = NULL;
1619 size_t box_size = 2 * g_ndims *
sizeof(float);
1624 if (g_ndims != box_ndims)
1641 size_t varsize_out = varsize_in + box_size;
1642 uint8_t *ptr_out, *ptr_in, *ptr;
1644 ptr_out = (uint8_t*)g_out;
1645 ptr = ptr_in = (uint8_t*)g;
1647 memcpy(ptr_out, ptr_in, 8); ptr_out += 8; ptr_in += 8;
1651 memcpy(ptr_out, ptr_in, 8); ptr_out += 8; ptr_in += 8;
1654 ptr_out += box_size;
1655 memcpy(ptr_out, ptr_in, varsize_in - (ptr_in - ptr));
1663 fbox = (
float*)(g_out->
data);
1665 fbox[fbox_pos++] = gbox->
xmin;
1666 fbox[fbox_pos++] = gbox->
xmax;
1667 fbox[fbox_pos++] = gbox->
ymin;
1668 fbox[fbox_pos++] = gbox->
ymax;
1672 fbox[fbox_pos++] = gbox->
zmin;
1673 fbox[fbox_pos++] = gbox->
zmax;
1677 fbox[fbox_pos++] = gbox->
mmin;
1678 fbox[fbox_pos++] = gbox->
mmax;
1692 size_t box_size = 2 * g_ndims *
sizeof(float);
1699 uint8_t *outptr = (uint8_t*)g_out;
1700 uint8_t *inptr = (uint8_t*)g;
1702 memcpy(outptr, inptr, 8); outptr += 8; inptr += 8;
1706 memcpy(outptr, inptr, 8); outptr += 8; inptr += 8;
1711 memcpy(outptr, inptr, g_out_size - 8);
1718 memcpy(g_out, g, g_out_size);
size_t gbox_serialized_size(lwflags_t flags)
Return the number of bytes necessary to hold a GBOX of this dimension in serialized form.
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.
static LWPOINT * lwpoint_from_gserialized2_buffer(uint8_t *data_ptr, lwflags_t lwflags, size_t *size)
static size_t gserialized2_header_size(const GSERIALIZED *g)
static size_t gserialized2_box_size(const GSERIALIZED *g)
static int gserialized2_read_gbox_p(const GSERIALIZED *g, GBOX *gbox)
static LWTRIANGLE * lwtriangle_from_gserialized2_buffer(uint8_t *data_ptr, lwflags_t lwflags, size_t *size)
LWGEOM * lwgeom_from_gserialized2(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int gserialized2_fast_gbox_p(const GSERIALIZED *g, GBOX *box)
Read the bounding box off a serialization and fail if it is not already there.
int32_t gserialized2_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
int gserialized2_is_geodetic(const GSERIALIZED *g)
Check if a GSERIALIZED is a geography.
void gserialized2_set_srid(GSERIALIZED *g, int32_t srid)
Write the SRID into the serialized form (it is packed into three bytes so this is a handy function).
int gserialized2_has_z(const GSERIALIZED *g)
Check if a GSERIALIZED has a Z ordinate.
void hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb)
static uint32_t gserialized2_get_uint32_t(const uint8_t *loc)
int32_t gserialized2_hash(const GSERIALIZED *g1)
Returns a hash code for the srid/type/geometry information in the GSERIALIZED.
GSERIALIZED * gserialized2_drop_gbox(GSERIALIZED *g)
Remove the bounding box from a GSERIALIZED.
static size_t gserialized2_from_gbox(const GBOX *gbox, uint8_t *buf)
static size_t gserialized2_from_lwcircstring_size(const LWCIRCSTRING *curve)
static size_t gserialized2_from_lwpoly_size(const LWPOLY *poly)
uint32_t gserialized2_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
int gserialized2_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
int gserialized2_peek_first_point(const GSERIALIZED *g, POINT4D *out_point)
GSERIALIZED * gserialized2_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
static int lwflags_uses_extended_flags(lwflags_t lwflags)
int gserialized2_ndims(const GSERIALIZED *g)
Return the number of dimensions (2, 3, 4) in a geometry.
int gserialized2_peek_gbox_p(const GSERIALIZED *g, GBOX *gbox)
static LWCIRCSTRING * lwcircstring_from_gserialized2_buffer(uint8_t *data_ptr, lwflags_t lwflags, size_t *size)
uint8_t lwflags_get_g2flags(lwflags_t lwflags)
static size_t gserialized2_from_lwcollection(const LWCOLLECTION *coll, uint8_t *buf)
static size_t gserialized2_from_lwgeom_any(const LWGEOM *geom, uint8_t *buf)
int gserialized2_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 gserialized2_from_lwcircstring(const LWCIRCSTRING *curve, uint8_t *buf)
static size_t gserialized2_is_empty_recurse(const uint8_t *p, int *isempty)
static size_t gserialized2_from_lwpoint_size(const LWPOINT *point)
size_t gserialized2_from_lwgeom_size(const LWGEOM *geom)
Return the memory size a GSERIALIZED will occupy for a given LWGEOM.
static LWLINE * lwline_from_gserialized2_buffer(uint8_t *data_ptr, lwflags_t lwflags, size_t *size)
static LWGEOM * lwgeom_from_gserialized2_buffer(uint8_t *data_ptr, lwflags_t lwflags, size_t *size)
static size_t gserialized2_from_lwtriangle_size(const LWTRIANGLE *triangle)
static size_t gserialized2_from_lwpoly(const LWPOLY *poly, uint8_t *buf)
static size_t gserialized2_from_lwtriangle(const LWTRIANGLE *triangle, uint8_t *buf)
const float * gserialized2_get_float_box_p(const GSERIALIZED *g, size_t *ndims)
Point into the float box area of the serialization.
static size_t gserialized2_from_lwcollection_size(const LWCOLLECTION *col)
static size_t gserialized2_from_lwline(const LWLINE *line, uint8_t *buf)
GSERIALIZED * gserialized2_set_gbox(GSERIALIZED *g, GBOX *gbox)
Update the bounding box of a GSERIALIZED, allocating a fresh one if there is not enough space to just...
int gserialized2_has_extended(const GSERIALIZED *g)
Check if a GSERIALIZED has an extended flags section.
static size_t gserialized2_from_lwpoint(const LWPOINT *point, uint8_t *buf)
static void gserialized2_copy_point(double *dptr, lwflags_t flags, POINT4D *out_point)
int gserialized2_has_m(const GSERIALIZED *g)
Check if a GSERIALIZED has an M ordinate.
static uint8_t * gserialized2_get_geometry_p(const GSERIALIZED *g)
static LWPOLY * lwpoly_from_gserialized2_buffer(uint8_t *data_ptr, lwflags_t lwflags, size_t *size)
uint32_t gserialized2_max_header_size(void)
Returns the size in bytes to read from toast to get the basic information from a geometry: GSERIALIZE...
static size_t gserialized2_from_extended_flags(lwflags_t lwflags, uint8_t *buf)
static size_t gserialized2_from_any_size(const LWGEOM *geom)
lwflags_t gserialized2_get_lwflags(const GSERIALIZED *g)
Read the flags from a GSERIALIZED and return a standard lwflag integer.
uint8_t g2flags(int has_z, int has_m, int is_geodetic)
static size_t gserialized2_from_lwline_size(const LWLINE *line)
int gserialized2_has_bbox(const GSERIALIZED *g)
Check if a GSERIALIZED has a bounding box without deserializing first.
static LWCOLLECTION * lwcollection_from_gserialized2_buffer(uint8_t *data_ptr, lwflags_t lwflags, size_t *size)
#define G2FLAGS_SET_Z(gflags, value)
#define G2FLAGS_SET_EXTENDED(gflags, value)
#define G2FLAGS_SET_VERSION(gflags, value)
#define G2FLAGS_NDIMS_BOX(gflags)
#define G2FLAGS_GET_BBOX(gflags)
#define G2FLAG_X_SOLID
Macros for the extended 'flags' uint64_t.
#define G2FLAGS_SET_M(gflags, value)
#define G2FLAGS_GET_GEODETIC(gflags)
#define G2FLAGS_GET_Z(gflags)
#define G2FLAGS_GET_EXTENDED(gflags)
#define G2FLAGS_SET_GEODETIC(gflags, value)
#define G2FLAGS_GET_M(gflags)
#define G2FLAGS_SET_BBOX(gflags, value)
#define G2FLAGS_NDIMS(gflags)
int gserialized_has_bbox(const GSERIALIZED *g)
Check if a GSERIALIZED has a bounding box without deserializing first.
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
void lwgeom_free(LWGEOM *geom)
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.
#define FLAGS_NDIMS_BOX(flags)
#define FLAGS_GET_BBOX(flags)
#define LWFLAG_Z
Macros for manipulating the 'flags' byte.
#define FLAGS_SET_BBOX(flags, value)
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)
void * lwalloc(size_t size)
#define FLAGS_NDIMS(flags)
#define POLYHEDRALSURFACETYPE
#define FLAGS_GET_M(flags)
#define FLAGS_GET_SOLID(flags)
#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...
#define FLAGS_SET_GEODETIC(flags, value)
float next_float_up(double d)
lwflags_t lwflags(int hasz, int hasm, int geodetic)
Construct a new flags bitmask.
#define LW_TRUE
Return types for functions with status returns.
#define FLAGS_SET_M(flags, value)
#define SRID_UNKNOWN
Unknown SRID value.
#define FLAGS_SET_Z(flags, value)
#define FLAGS_SET_SOLID(flags, value)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
float next_float_down(double d)
#define FLAGS_GET_GEODETIC(flags)
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
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...
#define SIZE_GET(varsize)
Macro for reading the size from the GSERIALIZED size attribute.
#define SIZE_SET(varsize, len)
int lwcollection_allows_subtype(int collectiontype, int subtype)
Check if subtype is allowed in collectiontype.
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
static size_t ptarray_point_size(const POINTARRAY *pa)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)