PostGIS  3.4.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 796 of file gbox.c.

797 {
798  union floatuint {
799  uint32_t u;
800  float f;
801  };
802 
803  union floatuint x, y;
804 
805  /*
806  * Since in theory the bitwise representation of an IEEE
807  * float is sortable (exponents come before mantissa, etc)
808  * we just copy the bits directly into an int and then
809  * interleave those ints.
810  */
811  if (FLAGS_GET_GEODETIC(g->flags))
812  {
813  GEOGRAPHIC_POINT gpt;
814  POINT3D p;
815  p.x = (g->xmax + g->xmin) / 2.0;
816  p.y = (g->ymax + g->ymin) / 2.0;
817  p.z = (g->zmax + g->zmin) / 2.0;
818  normalize(&p);
819  cart2geog(&p, &gpt);
820  /* We know range for geography, so build the curve taking it into account */
821  x.f = 1.5 + gpt.lon / 512.0;
822  y.f = 1.5 + gpt.lat / 256.0;
823  }
824  else
825  {
826  x.f = (g->xmax + g->xmin) / 2;
827  y.f = (g->ymax + g->ymin) / 2;
828  /*
829  * Tweak for popular SRID values: push floating point values into 1..2 range,
830  * a region where exponent is constant and thus Hilbert curve
831  * doesn't have compression artifact when X or Y value is close to 0.
832  * If someone has out of bounds value it will still expose the arifact but not crash.
833  * TODO: reconsider when we will have machinery to properly get bounds by SRID.
834  */
835  if (srid == 3857 || srid == 3395)
836  {
837  x.f = 1.5 + x.f / 67108864.0;
838  y.f = 1.5 + y.f / 67108864.0;
839  }
840  else if (srid == 4326)
841  {
842  x.f = 1.5 + x.f / 512.0;
843  y.f = 1.5 + y.f / 256.0;
844  }
845  }
846 
847  return uint32_hilbert(y.u, x.u);
848 }
#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:260
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: