PostGIS  3.2.2dev-r@@SVN_REVISION@@

◆ lwgeom_geohash_precision()

int lwgeom_geohash_precision ( GBOX  bbox,
GBOX bounds 
)

Definition at line 774 of file lwalgorithm.c.

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

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: