static void test_geohash_precision(void) { GBOX bbox; GBOX bounds; int precision = 0; gbox_init(&bbox); gbox_init(&bounds); bbox.xmin = 23.0; bbox.xmax = 23.0; bbox.ymin = 25.2; bbox.ymax = 25.2; precision = lwgeom_geohash_precision(bbox, &bounds); //printf("\nprecision %d\n",precision); CU_ASSERT_EQUAL(precision, 20); bbox.xmin = 23.0; bbox.ymin = 23.0; bbox.xmax = 23.1; bbox.ymax = 23.1; precision = lwgeom_geohash_precision(bbox, &bounds); //printf("precision %d\n",precision); CU_ASSERT_EQUAL(precision, 3); bbox.xmin = 23.0; bbox.ymin = 23.0; bbox.xmax = 23.0001; bbox.ymax = 23.0001; precision = lwgeom_geohash_precision(bbox, &bounds); //printf("precision %d\n",precision); CU_ASSERT_EQUAL(precision, 7); }
/* ** Return a geohash string for the geometry. <http://geohash.org> ** Where the precision is non-positive, calculate a precision based on the ** bounds of the feature. Big features have loose precision. ** Small features have tight precision. */ char *lwgeom_geohash(const LWGEOM *lwgeom, int precision) { GBOX gbox; GBOX gbox_bounds; double lat, lon; int result; gbox_init(&gbox); gbox_init(&gbox_bounds); result = lwgeom_calculate_gbox(lwgeom, &gbox); if ( result == LW_FAILURE ) return NULL; /* Return error if we are being fed something outside our working bounds */ if ( gbox.xmin < -180 || gbox.ymin < -90 || gbox.xmax > 180 || gbox.ymax > 90 ) { lwerror("Geohash requires inputs in decimal degrees."); return NULL; } /* What is the center of our geometry bounds? We'll use that to ** approximate location. */ lon = gbox.xmin + (gbox.xmax - gbox.xmin) / 2; lat = gbox.ymin + (gbox.ymax - gbox.ymin) / 2; if ( precision <= 0 ) { precision = lwgeom_geohash_precision(gbox, &gbox_bounds); } /* ** Return the geohash of the center, with a precision determined by the ** extent of the bounds. ** Possible change: return the point at the center of the precision bounds? */ return geohash_point(lon, lat, precision); }