PostGIS  3.6.1dev-r@@SVN_REVISION@@

◆ lwgeom_geohash_precision()

int lwgeom_geohash_precision ( GBOX  bbox,
GBOX bounds 
)

Definition at line 781 of file lwalgorithm.c.

782 {
783  double minx, miny, maxx, maxy;
784  double latmax, latmin, lonmax, lonmin;
785  double lonwidth, latwidth;
786  double latmaxadjust, lonmaxadjust, latminadjust, lonminadjust;
787  int precision = 0;
788 
789  /* Get the bounding box, return error if things don't work out. */
790  minx = bbox.xmin;
791  miny = bbox.ymin;
792  maxx = bbox.xmax;
793  maxy = bbox.ymax;
794 
795  if ( minx == maxx && miny == maxy )
796  {
797  /* It's a point. Doubles have 51 bits of precision.
798  ** 2 * 51 / 5 == 20 */
799  return 20;
800  }
801 
802  lonmin = -180.0;
803  latmin = -90.0;
804  lonmax = 180.0;
805  latmax = 90.0;
806 
807  /* Shrink a world bounding box until one of the edges interferes with the
808  ** bounds of our rectangle. */
809  while ( 1 )
810  {
811  lonwidth = lonmax - lonmin;
812  latwidth = latmax - latmin;
813  latmaxadjust = lonmaxadjust = latminadjust = lonminadjust = 0.0;
814 
815  if ( minx > lonmin + lonwidth / 2.0 )
816  {
817  lonminadjust = lonwidth / 2.0;
818  }
819  else if ( maxx < lonmax - lonwidth / 2.0 )
820  {
821  lonmaxadjust = -1 * lonwidth / 2.0;
822  }
823  if ( lonminadjust || lonmaxadjust )
824  {
825  lonmin += lonminadjust;
826  lonmax += lonmaxadjust;
827  /* Each adjustment cycle corresponds to 2 bits of storage in the
828  ** geohash. */
829  precision++;
830  }
831  else
832  {
833  break;
834  }
835 
836  if ( miny > latmin + latwidth / 2.0 )
837  {
838  latminadjust = latwidth / 2.0;
839  }
840  else if (maxy < latmax - latwidth / 2.0 )
841  {
842  latmaxadjust = -1 * latwidth / 2.0;
843  }
844  /* Only adjust if adjustments are legal (we haven't crossed any edges). */
845  if ( latminadjust || latmaxadjust )
846  {
847  latmin += latminadjust;
848  latmax += latmaxadjust;
849  /* Each adjustment cycle corresponds to 2 bits of storage in the
850  ** geohash. */
851  precision++;
852  }
853  else
854  {
855  break;
856  }
857  }
858 
859  /* Save the edges of our bounds, in case someone cares later. */
860  bounds->xmin = lonmin;
861  bounds->xmax = lonmax;
862  bounds->ymin = latmin;
863  bounds->ymax = latmax;
864 
865  /* Each geohash character (base32) can contain 5 bits of information.
866  ** We are returning the precision in characters, so here we divide. */
867  return precision / 5;
868 }
static uint8_t precision
Definition: cu_in_twkb.c:25
double ymax
Definition: liblwgeom.h:357
double xmax
Definition: liblwgeom.h:355
double ymin
Definition: liblwgeom.h:356
double xmin
Definition: liblwgeom.h:354

References precision, GBOX::xmax, GBOX::xmin, GBOX::ymax, and GBOX::ymin.

Referenced by lwgeom_geohash(), and test_geohash_precision().

Here is the caller graph for this function: