PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ gbox_get_sortable_hash()

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.

Definition at line 808 of file gbox.c.

809 {
810  union floatuint {
811  uint32_t u;
812  float f;
813  };
814 
815  union floatuint x, y;
816 
817  /*
818  * Since in theory the bitwise representation of an IEEE
819  * float is sortable (exponents come before mantissa, etc)
820  * we just copy the bits directly into an int and then
821  * interleave those ints.
822  */
823  if (FLAGS_GET_GEODETIC(g->flags))
824  {
825  GEOGRAPHIC_POINT gpt;
826  POINT3D p;
827  p.x = (g->xmax + g->xmin) / 2.0;
828  p.y = (g->ymax + g->ymin) / 2.0;
829  p.z = (g->zmax + g->zmin) / 2.0;
830  normalize(&p);
831  cart2geog(&p, &gpt);
832  /* We know range for geography, so build the curve taking it into account */
833  x.f = 1.5 + gpt.lon / 512.0;
834  y.f = 1.5 + gpt.lat / 256.0;
835  }
836  else
837  {
838  x.f = (g->xmax + g->xmin) / 2;
839  y.f = (g->ymax + g->ymin) / 2;
840  /*
841  * Tweak for popular SRID values: push floating point values into 1..2 range,
842  * a region where exponent is constant and thus Hilbert curve
843  * doesn't have compression artifact when X or Y value is close to 0.
844  * If someone has out of bounds value it will still expose the arifact but not crash.
845  * TODO: reconsider when we will have machinery to properly get bounds by SRID.
846  */
847  if (srid == 3857 || srid == 3395)
848  {
849  x.f = 1.5 + x.f / 67108864.0;
850  y.f = 1.5 + y.f / 67108864.0;
851  }
852  else if (srid == 4326)
853  {
854  x.f = 1.5 + x.f / 512.0;
855  y.f = 1.5 + y.f / 256.0;
856  }
857  }
858 
859  return uint32_hilbert(y.u, x.u);
860 }
#define FLAGS_GET_GEODETIC(flags)
Definition: liblwgeom.h:168
void normalize(POINT3D *p)
Normalize to a unit vector.
Definition: lwgeodetic.c:615
void cart2geog(const POINT3D *p, GEOGRAPHIC_POINT *g)
Convert cartesian coordinates on unit sphere to spherical coordinates.
Definition: lwgeodetic.c:414
static uint64_t uint32_hilbert(uint32_t px, uint32_t py)
Definition: lwinline.h:256
double ymax
Definition: liblwgeom.h:357
double zmax
Definition: liblwgeom.h:359
double xmax
Definition: liblwgeom.h:355
double zmin
Definition: liblwgeom.h:358
double ymin
Definition: liblwgeom.h:356
double xmin
Definition: liblwgeom.h:354
lwflags_t flags
Definition: liblwgeom.h:353
Point in spherical coordinates on the world.
Definition: lwgeodetic.h:54
double z
Definition: liblwgeom.h:402
double x
Definition: liblwgeom.h:402
double y
Definition: liblwgeom.h:402

References cart2geog(), GBOX::flags, FLAGS_GET_GEODETIC, GEOGRAPHIC_POINT::lat, GEOGRAPHIC_POINT::lon, normalize(), uint32_hilbert(), POINT3D::x, pixval::x, GBOX::xmax, GBOX::xmin, POINT3D::y, pixval::y, GBOX::ymax, GBOX::ymin, POINT3D::z, GBOX::zmax, and GBOX::zmin.

Referenced by gserialized_cmp(), gserialized_get_sortable_hash(), and rect_node_cmp().

Here is the call graph for this function:
Here is the caller graph for this function: