PostGIS  3.0.6dev-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 893 of file gbox.c.

894 {
895  union floatuint {
896  uint32_t u;
897  float f;
898  };
899 
900  union floatuint x, y;
901 
902  /*
903  * Since in theory the bitwise representation of an IEEE
904  * float is sortable (exponents come before mantissa, etc)
905  * we just copy the bits directly into an int and then
906  * interleave those ints.
907  */
908  if (FLAGS_GET_GEODETIC(g->flags))
909  {
910  GEOGRAPHIC_POINT gpt;
911  POINT3D p;
912  p.x = (g->xmax + g->xmin) / 2.0;
913  p.y = (g->ymax + g->ymin) / 2.0;
914  p.z = (g->zmax + g->zmin) / 2.0;
915  normalize(&p);
916  cart2geog(&p, &gpt);
917  /* We know range for geography, so build the curve taking it into account */
918  x.f = 1.5 + gpt.lon / 512.0;
919  y.f = 1.5 + gpt.lat / 256.0;
920  }
921  else
922  {
923  x.f = (g->xmax + g->xmin) / 2;
924  y.f = (g->ymax + g->ymin) / 2;
925  /*
926  * Tweak for popular SRID values: push floating point values into 1..2 range,
927  * a region where exponent is constant and thus Hilbert curve
928  * doesn't have compression artifact when X or Y value is close to 0.
929  * If someone has out of bounds value it will still expose the arifact but not crash.
930  * TODO: reconsider when we will have machinery to properly get bounds by SRID.
931  */
932  if (srid == 3857 || srid == 3395)
933  {
934  x.f = 1.5 + x.f / 67108864.0;
935  y.f = 1.5 + y.f / 67108864.0;
936  }
937  else if (srid == 4326)
938  {
939  x.f = 1.5 + x.f / 512.0;
940  y.f = 1.5 + y.f / 256.0;
941  }
942  }
943 
944  return uint32_hilbert(y.u, x.u);
945 }
static uint64_t uint32_hilbert(uint32_t px, uint32_t py)
Definition: gbox.c:815
#define FLAGS_GET_GEODETIC(flags)
Definition: liblwgeom.h:182
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
double ymax
Definition: liblwgeom.h:343
double zmax
Definition: liblwgeom.h:345
double xmax
Definition: liblwgeom.h:341
double zmin
Definition: liblwgeom.h:344
double ymin
Definition: liblwgeom.h:342
double xmin
Definition: liblwgeom.h:340
lwflags_t flags
Definition: liblwgeom.h:339
Point in spherical coordinates on the world.
Definition: lwgeodetic.h:54
double z
Definition: liblwgeom.h:388
double x
Definition: liblwgeom.h:388
double y
Definition: liblwgeom.h:388

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: