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); }
GBOX* gbox_new(uint8_t flags) { GBOX *g = (GBOX*)lwalloc(sizeof(GBOX)); gbox_init(g); g->flags = flags; return g; }
Datum BOX2D_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); int nitems; double tmp; GBOX box; gbox_init(&box); if (strstr(str,"BOX(") != str ) { elog(ERROR,"box2d parser - doesnt start with BOX("); PG_RETURN_NULL(); } nitems = sscanf(str,"BOX(%lf %lf,%lf %lf)", &box.xmin, &box.ymin, &box.xmax, &box.ymax); if (nitems != 4) { elog(ERROR,"box2d parser - couldnt parse. It should look like: BOX(xmin ymin,xmax ymax)"); PG_RETURN_NULL(); } if (box.xmin > box.xmax) { tmp = box.xmin; box.xmin = box.xmax; box.xmax = tmp; } if (box.ymin > box.ymax) { tmp = box.ymin; box.ymin = box.ymax; box.ymax = tmp; } PG_RETURN_POINTER(gbox_copy(&box)); }
Datum BOX2D_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); int nitems; double tmp; GBOX box; int i; gbox_init(&box); for(i = 0; str[i]; i++) { str[i] = tolower(str[i]); } nitems = sscanf(str,"box(%lf %lf,%lf %lf)", &box.xmin, &box.ymin, &box.xmax, &box.ymax); if (nitems != 4) { elog(ERROR,"box2d parser - couldnt parse. It should look like: BOX(xmin ymin,xmax ymax)"); PG_RETURN_NULL(); } if (box.xmin > box.xmax) { tmp = box.xmin; box.xmin = box.xmax; box.xmax = tmp; } if (box.ymin > box.ymax) { tmp = box.ymin; box.ymin = box.ymax; box.ymax = tmp; } PG_RETURN_POINTER(gbox_copy(&box)); }
/* ** 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); }