PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ lwgeom_geohash_precision()

int lwgeom_geohash_precision ( GBOX  bbox,
GBOX bounds 
)

Definition at line 750 of file lwalgorithm.c.

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

Referenced by lwgeom_geohash(), and test_geohash_precision().

751 {
752  double minx, miny, maxx, maxy;
753  double latmax, latmin, lonmax, lonmin;
754  double lonwidth, latwidth;
755  double latmaxadjust, lonmaxadjust, latminadjust, lonminadjust;
756  int precision = 0;
757 
758  /* Get the bounding box, return error if things don't work out. */
759  minx = bbox.xmin;
760  miny = bbox.ymin;
761  maxx = bbox.xmax;
762  maxy = bbox.ymax;
763 
764  if ( minx == maxx && miny == maxy )
765  {
766  /* It's a point. Doubles have 51 bits of precision.
767  ** 2 * 51 / 5 == 20 */
768  return 20;
769  }
770 
771  lonmin = -180.0;
772  latmin = -90.0;
773  lonmax = 180.0;
774  latmax = 90.0;
775 
776  /* Shrink a world bounding box until one of the edges interferes with the
777  ** bounds of our rectangle. */
778  while ( 1 )
779  {
780  lonwidth = lonmax - lonmin;
781  latwidth = latmax - latmin;
782  latmaxadjust = lonmaxadjust = latminadjust = lonminadjust = 0.0;
783 
784  if ( minx > lonmin + lonwidth / 2.0 )
785  {
786  lonminadjust = lonwidth / 2.0;
787  }
788  else if ( maxx < lonmax - lonwidth / 2.0 )
789  {
790  lonmaxadjust = -1 * lonwidth / 2.0;
791  }
792  if ( lonminadjust || lonmaxadjust )
793  {
794  lonmin += lonminadjust;
795  lonmax += lonmaxadjust;
796  /* Each adjustment cycle corresponds to 2 bits of storage in the
797  ** geohash. */
798  precision++;
799  }
800  else
801  {
802  break;
803  }
804 
805  if ( miny > latmin + latwidth / 2.0 )
806  {
807  latminadjust = latwidth / 2.0;
808  }
809  else if (maxy < latmax - latwidth / 2.0 )
810  {
811  latmaxadjust = -1 * latwidth / 2.0;
812  }
813  /* Only adjust if adjustments are legal (we haven't crossed any edges). */
814  if ( latminadjust || latmaxadjust )
815  {
816  latmin += latminadjust;
817  latmax += latmaxadjust;
818  /* Each adjustment cycle corresponds to 2 bits of storage in the
819  ** geohash. */
820  precision++;
821  }
822  else
823  {
824  break;
825  }
826  }
827 
828  /* Save the edges of our bounds, in case someone cares later. */
829  bounds->xmin = lonmin;
830  bounds->xmax = lonmax;
831  bounds->ymin = latmin;
832  bounds->ymax = latmax;
833 
834  /* Each geohash character (base32) can contain 5 bits of information.
835  ** We are returning the precision in characters, so here we divide. */
836  return precision / 5;
837 }
double xmax
Definition: liblwgeom.h:293
double ymin
Definition: liblwgeom.h:294
double xmin
Definition: liblwgeom.h:292
uint8_t precision
Definition: cu_in_twkb.c:25
double ymax
Definition: liblwgeom.h:295
Here is the caller graph for this function: