42 memset(gbox, 0,
sizeof(
GBOX));
48 memcpy(g, gbox,
sizeof(
GBOX));
137 if ( ( ! g1 ) && ( ! g2 ) )
141 memcpy(gout, g2,
sizeof(
GBOX));
146 memcpy(gout, g1,
sizeof(
GBOX));
200 if ( ! isfinite(gbox->
xmin) || isnan(gbox->
xmin) ||
201 ! isfinite(gbox->
xmax) || isnan(gbox->
xmax) )
205 if ( ! isfinite(gbox->
ymin) || isnan(gbox->
ymin) ||
206 ! isfinite(gbox->
ymax) || isnan(gbox->
ymax) )
212 if ( ! isfinite(gbox->
zmin) || isnan(gbox->
zmin) ||
213 ! isfinite(gbox->
zmax) || isnan(gbox->
zmax) )
220 if ( ! isfinite(gbox->
mmin) || isnan(gbox->
mmin) ||
221 ! isfinite(gbox->
mmax) || isnan(gbox->
mmax) )
288 lwerror(
"gbox_overlaps: cannot compare geodetic and non-geodetic boxes");
328 lwerror(
"gbox_overlaps: cannot compare geodetic and non-geodetic boxes");
352 if ( ( g->
xmin <= p->
x ) && ( g->
xmax >= p->
x ) &&
366 const char *ptr =
str;
368 char *gbox_start = strstr(
str,
"GBOX((");
370 if ( ! gbox_start )
return NULL;
372 gbox->
xmin = strtod(ptr, &nextptr);
373 if ( ptr == nextptr )
return NULL;
375 gbox->
ymin = strtod(ptr, &nextptr);
376 if ( ptr == nextptr )
return NULL;
378 gbox->
zmin = strtod(ptr, &nextptr);
379 if ( ptr == nextptr )
return NULL;
381 gbox->
xmax = strtod(ptr, &nextptr);
382 if ( ptr == nextptr )
return NULL;
384 gbox->
ymax = strtod(ptr, &nextptr);
385 if ( ptr == nextptr )
return NULL;
387 gbox->
zmax = strtod(ptr, &nextptr);
388 if ( ptr == nextptr )
return NULL;
394 const size_t sz = 138;
404 snprintf(
str, sz,
"GBOX((%.8g,%.8g,%.8g),(%.8g,%.8g,%.8g))", gbox->
xmin, gbox->
ymin, gbox->
zmin, gbox->
xmax, gbox->
ymax, gbox->
zmax);
409 snprintf(
str, sz,
"GBOX((%.8g,%.8g,%.8g,%.8g),(%.8g,%.8g,%.8g,%.8g))", gbox->
xmin, gbox->
ymin, gbox->
zmin, gbox->
mmin, gbox->
xmax, gbox->
ymax, gbox->
zmax, gbox->
mmax);
414 snprintf(
str, sz,
"GBOX((%.8g,%.8g,%.8g),(%.8g,%.8g,%.8g))", gbox->
xmin, gbox->
ymin, gbox->
zmin, gbox->
xmax, gbox->
ymax, gbox->
zmax);
419 snprintf(
str, sz,
"GBOX((%.8g,%.8g,%.8g),(%.8g,%.8g,%.8g))", gbox->
xmin, gbox->
ymin, gbox->
mmin, gbox->
xmax, gbox->
ymax, gbox->
mmax);
422 snprintf(
str, sz,
"GBOX((%.8g,%.8g),(%.8g,%.8g))", gbox->
xmin, gbox->
ymin, gbox->
xmax, gbox->
ymax);
429 memcpy(copy, box,
sizeof(
GBOX));
437 memcpy(duplicate, original,
sizeof(
GBOX));
443 return 6 *
sizeof(float);
455 POINT2D xmin, ymin, xmax, ymax;
460 LWDEBUG(2,
"lw_arc_calculate_gbox_cartesian_2d called.");
475 if ( A1->
x == A3->
x && A1->
y == A3->
y )
477 gbox->
xmin = C.
x - radius_A;
478 gbox->
ymin = C.
y - radius_A;
479 gbox->
xmax = C.
x + radius_A;
480 gbox->
ymax = C.
y + radius_A;
491 xmin.
x = C.
x - radius_A;
494 ymin.
y = C.
y - radius_A;
495 xmax.
x = C.
x + radius_A;
498 ymax.
y = C.
y + radius_A;
526 LWDEBUG(2,
"lw_arc_calculate_gbox_cartesian called.");
544 for (uint32_t i = 1; i < pa->
npoints; i++)
564 for (uint32_t i = 1; i < pa->
npoints; i++)
586 for (uint32_t i = 1; i < pa->
npoints; i++)
611 LWDEBUGF(4,
"ptarray_calculate_gbox Z: %d M: %d", has_z, has_m);
612 int coordinates = 2 + has_z + has_m;
629 double zmin = gbox->
zmin;
630 double zmax = gbox->
zmax;
712 if ( (coll->
ngeoms == 0) || !gbox)
717 for ( i = 0; i < coll->
ngeoms; i++ )
745 switch (lwgeom->
type)
795 inline static uint64_t
798 x = (
x | (
x << 16)) & 0x0000FFFF0000FFFFULL;
799 x = (
x | (
x << 8)) & 0x00FF00FF00FF00FFULL;
800 x = (
x | (
x << 4)) & 0x0F0F0F0F0F0F0F0FULL;
801 x = (
x | (
x << 2)) & 0x3333333333333333ULL;
802 x = (
x | (
x << 1)) & 0x5555555555555555ULL;
804 y = (
y | (
y << 16)) & 0x0000FFFF0000FFFFULL;
805 y = (
y | (
y << 8)) & 0x00FF00FF00FF00FFULL;
806 y = (
y | (
y << 4)) & 0x0F0F0F0F0F0F0F0FULL;
807 y = (
y | (
y << 2)) & 0x3333333333333333ULL;
808 y = (
y | (
y << 1)) & 0x5555555555555555ULL;
814 inline static uint64_t
825 uint64_t b = 0xFFFFFFFFULL ^ a;
826 uint64_t c = 0xFFFFFFFFULL ^ (
x |
y);
827 uint64_t d =
x & (
y ^ 0xFFFFFFFFULL);
831 C = ((c >> 1) ^ (b & (d >> 1))) ^ c;
832 D = ((a & (c >> 1)) ^ (d >> 1)) ^ d;
841 A = ((a & (a >> 2)) ^ (b & (b >> 2)));
842 B = ((a & (b >> 2)) ^ (b & ((a ^ b) >> 2)));
843 C ^= ((a & (c >> 2)) ^ (b & (d >> 2)));
844 D ^= ((b & (c >> 2)) ^ ((a ^ b) & (d >> 2)));
853 A = ((a & (a >> 4)) ^ (b & (b >> 4)));
854 B = ((a & (b >> 4)) ^ (b & ((a ^ b) >> 4)));
855 C ^= ((a & (c >> 4)) ^ (b & (d >> 4)));
856 D ^= ((b & (c >> 4)) ^ ((a ^ b) & (d >> 4)));
865 A = ((a & (a >> 8)) ^ (b & (b >> 8)));
866 B = ((a & (b >> 8)) ^ (b & ((a ^ b) >> 8)));
867 C ^= ((a & (c >> 8)) ^ (b & (d >> 8)));
868 D ^= ((b & (c >> 8)) ^ ((a ^ b) & (d >> 8)));
877 C ^= ((a & (c >> 16)) ^ (b & (d >> 16)));
878 D ^= ((b & (c >> 16)) ^ ((a ^ b) & (d >> 16)));
882 uint64_t a = C ^ (C >> 1);
883 uint64_t b = D ^ (D >> 1);
887 uint64_t i1 = b | (0xFFFFFFFFULL ^ (i0 | a));
900 union floatuint
x,
y;
918 x.f = 1.5 + gpt.
lon / 512.0;
919 y.f = 1.5 + gpt.
lat / 256.0;
932 if (srid == 3857 || srid == 3395)
934 x.f = 1.5 +
x.f / 67108864.0;
935 y.f = 1.5 +
y.f / 67108864.0;
937 else if (srid == 4326)
939 x.f = 1.5 +
x.f / 512.0;
940 y.f = 1.5 +
y.f / 256.0;
int gbox_merge(const GBOX *new_box, GBOX *merge_box)
Update the merged GBOX to be large enough to include itself and the new box.
int gbox_same(const GBOX *g1, const GBOX *g2)
Check if 2 given Gbox are the same.
int gbox_union(const GBOX *g1, const GBOX *g2, GBOX *gout)
Update the output GBOX to be large enough to include both inputs.
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_duplicate(const GBOX *original, GBOX *duplicate)
Copy the values of original GBOX into duplicate.
int gbox_same_2d(const GBOX *g1, const GBOX *g2)
Check if 2 given GBOX are the same in x and y.
GBOX * box3d_to_gbox(const BOX3D *b3d)
void gbox_expand(GBOX *g, double d)
Move the box minimums down and the maximums up by the distance provided.
int gbox_contains_point3d(const GBOX *gbox, const POINT3D *pt)
Return true if the point is inside the gbox.
static void ptarray_calculate_gbox_cartesian_2d(const POINTARRAY *pa, GBOX *gbox)
void gbox_float_round(GBOX *gbox)
Round given GBOX to float boundaries.
static uint64_t uint32_hilbert(uint32_t px, uint32_t py)
static int lwpoint_calculate_gbox_cartesian(LWPOINT *point, GBOX *gbox)
static int lwpoly_calculate_gbox_cartesian(LWPOLY *poly, GBOX *gbox)
static int lwtriangle_calculate_gbox_cartesian(LWTRIANGLE *triangle, GBOX *gbox)
int gbox_merge_point3d(const POINT3D *p, GBOX *gbox)
Update the GBOX to be large enough to include itself and the new point.
BOX3D * box3d_from_gbox(const GBOX *gbox)
int lwgeom_calculate_gbox_cartesian(const LWGEOM *lwgeom, GBOX *gbox)
Calculate the 2-4D bounding box of a geometry.
int gbox_overlaps(const GBOX *g1, const GBOX *g2)
Return LW_TRUE if the GBOX overlaps, LW_FALSE otherwise.
GBOX * gbox_new(lwflags_t flags)
Create a new gbox with the dimensionality indicated by the flags.
int gbox_overlaps_2d(const GBOX *g1, const GBOX *g2)
Return LW_TRUE if the GBOX overlaps on the 2d plane, LW_FALSE otherwise.
int gbox_contains_point2d(const GBOX *g, const POINT2D *p)
void gbox_init(GBOX *gbox)
Zero out all the entries in the GBOX.
void gbox_expand_xyzm(GBOX *g, double dx, double dy, double dz, double dm)
Move the box minimums down and the maximums up by the distances provided.
static void ptarray_calculate_gbox_cartesian_3d(const POINTARRAY *pa, GBOX *gbox)
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
static int lwline_calculate_gbox_cartesian(LWLINE *line, GBOX *gbox)
int gbox_init_point3d(const POINT3D *p, GBOX *gbox)
Initialize a GBOX using the values of the point.
int ptarray_calculate_gbox_cartesian(const POINTARRAY *pa, GBOX *gbox)
Calculate box (x/y) and add values to gbox.
uint64_t gbox_get_sortable_hash(const GBOX *g, const int32_t srid)
Return a sortable key based on the center point of the GBOX.
static int lwcircstring_calculate_gbox_cartesian(LWCIRCSTRING *curve, GBOX *gbox)
GBOX * gbox_from_string(const char *str)
Warning, this function is only good for x/y/z boxes, used in unit testing of geodetic box generation.
static int lwcollection_calculate_gbox_cartesian(LWCOLLECTION *coll, GBOX *gbox)
static uint64_t uint64_interleave_2(uint64_t x, uint64_t y)
static void ptarray_calculate_gbox_cartesian_4d(const POINTARRAY *pa, GBOX *gbox)
GBOX * gbox_clone(const GBOX *gbox)
int gbox_same_2d_float(const GBOX *g1, const GBOX *g2)
Check if two given GBOX are the same in x and y, or would round to the same GBOX in x and if serializ...
int gbox_is_valid(const GBOX *gbox)
Return false if any of the dimensions is NaN or infinite.
int gbox_contains_2d(const GBOX *g1, const GBOX *g2)
Return LW_TRUE if the first GBOX contains the second on the 2d plane, LW_FALSE otherwise.
char * gbox_to_string(const GBOX *gbox)
Allocate a string representation of the GBOX, based on dimensionality of flags.
int lw_arc_calculate_gbox_cartesian_2d(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3, GBOX *gbox)
static int lw_arc_calculate_gbox_cartesian(const POINT4D *p1, const POINT4D *p2, const POINT4D *p3, GBOX *gbox)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
#define FLAGS_GET_Z(flags)
#define FLAGS_NDIMS(flags)
#define POLYHEDRALSURFACETYPE
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 getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
#define FLAGS_GET_ZM(flags)
void * lwalloc(size_t size)
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 SRID_UNKNOWN
Unknown SRID value.
float next_float_down(double d)
#define FLAGS_GET_GEODETIC(flags)
char * lwstrdup(const char *a)
double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, POINT2D *result)
Determines the center of the circle defined by the three given points.
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
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.
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
static const POINT3D * getPoint3d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
static const POINT4D * getPoint4d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Point in spherical coordinates on the world.