/* ** Peak into a geography to find the bounding box. If the ** box is there, copy it out and return it. If not, calculate the box from the ** full geography and return the box based on that. If no box is available, ** return G_FAILURE, otherwise G_SUCCESS. */ int geography_gidx(GSERIALIZED *g, GIDX *gidx) { int result = G_SUCCESS; POSTGIS_DEBUG(4, "entered function"); POSTGIS_DEBUGF(4, "got flags %d", g->flags); if ( FLAGS_GET_BBOX(g->flags) && FLAGS_GET_GEODETIC(g->flags) ) { const size_t size = 2 * 3 * sizeof(float); POSTGIS_DEBUG(4, "copying box out of serialization"); memcpy(gidx->c, g->data, size); SET_VARSIZE(gidx, VARHDRSZ + size); } else { GBOX gbox; POSTGIS_DEBUG(4, "calculating new box from scratch"); if ( gserialized_calculate_gbox_geocentric_p(g, &gbox) == G_FAILURE ) { POSTGIS_DEBUG(4, "calculated null bbox, returning null"); return G_FAILURE; } result = gidx_from_gbox_p(gbox, gidx); } if ( result == G_SUCCESS ) { POSTGIS_DEBUGF(4, "got gidx %s", gidx_to_string(gidx)); } return result; }
/** * Remove the bounding box from a #GSERIALIZED. Returns a freshly * allocated #GSERIALIZED every time. */ GSERIALIZED* gserialized_drop_gidx(GSERIALIZED *g) { int g_ndims = FLAGS_NDIMS_BOX(g->flags); size_t box_size = 2 * g_ndims * sizeof(float); size_t g_out_size = VARSIZE(g) - box_size; GSERIALIZED *g_out = palloc(g_out_size); /* Copy the contents while omitting the box */ if ( FLAGS_GET_BBOX(g->flags) ) { uint8_t *outptr = (uint8_t*)g_out; uint8_t *inptr = (uint8_t*)g; /* Copy the header (size+type) of g into place */ memcpy(outptr, inptr, 8); outptr += 8; inptr += 8 + box_size; /* Copy parts after the box into place */ memcpy(outptr, inptr, g_out_size - 8); FLAGS_SET_BBOX(g_out->flags, 0); SET_VARSIZE(g_out, g_out_size); } /* No box? Nothing to do but copy and return. */ else { memcpy(g_out, g, g_out_size); } return g_out; }
/** * Peak into a #GSERIALIZED datum to find the bounding box. If the * box is there, copy it out and return it. If not, calculate the box from the * full object and return the box based on that. If no box is available, * return #LW_FAILURE, otherwise #LW_SUCCESS. */ int gserialized_datum_get_gidx_p(Datum gsdatum, GIDX *gidx) { GSERIALIZED *gpart; int result = LW_SUCCESS; POSTGIS_DEBUG(4, "entered function"); /* ** The most info we need is the 8 bytes of serialized header plus the 32 bytes ** of floats necessary to hold the 8 floats of the largest XYZM index ** bounding box, so 40 bytes. */ gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 40); POSTGIS_DEBUGF(4, "got flags %d", gpart->flags); /* Do we even have a serialized bounding box? */ if ( FLAGS_GET_BBOX(gpart->flags) ) { /* Yes! Copy it out into the GIDX! */ size_t size = gbox_serialized_size(gpart->flags); POSTGIS_DEBUG(4, "copying box out of serialization"); memcpy(gidx->c, gpart->data, size); /* if M is present but Z is not, pad Z and shift M */ if ( FLAGS_GET_M(gpart->flags) && ! FLAGS_GET_Z(gpart->flags) ) { size += 2 * sizeof(float); GIDX_SET_MIN(gidx,3,GIDX_GET_MIN(gidx,2)); GIDX_SET_MAX(gidx,3,GIDX_GET_MAX(gidx,2)); GIDX_SET_MIN(gidx,2,-1*FLT_MAX); GIDX_SET_MAX(gidx,2,FLT_MAX); } SET_VARSIZE(gidx, VARHDRSZ + size); result = LW_SUCCESS; } else { /* No, we need to calculate it from the full object. */ GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum); LWGEOM *lwgeom = lwgeom_from_gserialized(g); GBOX gbox; if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE ) { POSTGIS_DEBUG(4, "could not calculate bbox, returning failure"); lwgeom_free(lwgeom); return LW_FAILURE; } lwgeom_free(lwgeom); result = gidx_from_gbox_p(gbox, gidx); } if ( result == LW_SUCCESS ) { POSTGIS_DEBUGF(4, "got gidx %s", gidx_to_string(gidx)); } return result; }
size_t gbox_serialized_size(uchar flags) { if ( ! FLAGS_GET_BBOX(flags) ) return 0; if ( FLAGS_GET_GEODETIC(flags) ) return 6 * sizeof(float); else return 2 * FLAGS_NDIMS(flags) * sizeof(float); }
void printLWPOINT(LWPOINT *point) { lwnotice("LWPOINT {"); lwnotice(" ndims = %i", (int)FLAGS_NDIMS(point->flags)); lwnotice(" BBOX = %i", FLAGS_GET_BBOX(point->flags) ? 1 : 0 ); lwnotice(" SRID = %i", (int)point->srid); printPA(point->point); lwnotice("}"); }
int gbox_from_gserialized(const GSERIALIZED *g, GBOX *gbox) { /* Null input! */ if ( ! g ) return G_FAILURE; /* Initialize the flags on the box */ gbox->flags = g->flags; if ( FLAGS_GET_BBOX(g->flags) ) { int i = 0; float *fbox = (float*)(g->data); gbox->xmin = fbox[i]; i++; gbox->xmax = fbox[i]; i++; gbox->ymin = fbox[i]; i++; gbox->ymax = fbox[i]; i++; if ( FLAGS_GET_GEODETIC(g->flags) ) { gbox->zmin = fbox[i]; i++; gbox->zmax = fbox[i]; i++; return G_SUCCESS; } if ( FLAGS_GET_Z(g->flags) ) { gbox->zmin = fbox[i]; i++; gbox->zmax = fbox[i]; i++; } if ( FLAGS_GET_M(g->flags) ) { gbox->mmin = fbox[i]; i++; gbox->mmax = fbox[i]; i++; } return G_SUCCESS; } LWDEBUG(4, "calculating new box from scratch"); if ( gserialized_calculate_gbox_geocentric_p(g, gbox) == G_FAILURE ) { LWDEBUG(4, "calculated null bbox, returning failure"); return G_FAILURE; } return G_SUCCESS; }
/** * Peak into a #GSERIALIZED datum to find the bounding box. If the * box is there, copy it out and return it. If not, calculate the box from the * full object and return the box based on that. If no box is available, * return #LW_FAILURE, otherwise #LW_SUCCESS. */ static int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df) { GSERIALIZED *gpart; uint8_t flags; int result = 0; /* ** The most info we need is the 8 bytes of serialized header plus the ** of floats necessary to hold the bounding box. */ if (VARATT_IS_EXTENDED(gsdatum)) { gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 8 + sizeof(BOX2DF)); } else { gpart = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum); } flags = gpart->flags; /* Do we even have a serialized bounding box? */ if ( FLAGS_GET_BBOX(flags) ) { /* Yes! Copy it out into the box! */ memcpy(box2df, gpart->data, sizeof(BOX2DF)); result = 1; } else { /* No, we need to calculate it from the full object. */ GBOX gbox; GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum); /* LWGEOM *lwgeom = lwgeom_from_gserialized(g); if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE ) { POSTGIS_DEBUG(4, "could not calculate bbox, returning failure"); lwgeom_free(lwgeom); return LW_FAILURE; } lwgeom_free(lwgeom); */ // result = box2df_from_gbox_p(&gbox, box2df); } printf("BOX2DF(%f %f, %f %f)\n", box2df->xmin, box2df->ymin, box2df->xmax, box2df->ymax); return result; }
uint32_t gserialized_get_type(const GSERIALIZED *s) { uint32_t *ptr; assert(s); ptr = (uint32_t*)(s->data); LWDEBUG(4,"entered"); if ( FLAGS_GET_BBOX(s->flags) ) { LWDEBUGF(4,"skipping forward past bbox (%d bytes)",gbox_serialized_size(s->flags)); ptr += (gbox_serialized_size(s->flags) / sizeof(uint32_t)); } return *ptr; }
/** * Peak into a #GSERIALIZED datum to find the bounding box. If the * box is there, copy it out and return it. If not, calculate the box from the * full object and return the box based on that. If no box is available, * return #LW_FAILURE, otherwise #LW_SUCCESS. */ static int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df) { GSERIALIZED *gpart; uint8_t flags; int result = LW_SUCCESS; POSTGIS_DEBUG(4, "entered function"); /* ** The most info we need is the 8 bytes of serialized header plus the ** of floats necessary to hold the bounding box. */ gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 8 + sizeof(BOX2DF)); flags = gpart->flags; POSTGIS_DEBUGF(4, "got flags %d", gpart->flags); /* Do we even have a serialized bounding box? */ if ( FLAGS_GET_BBOX(flags) ) { /* Yes! Copy it out into the box! */ POSTGIS_DEBUG(4, "copying box out of serialization"); memcpy(box2df, gpart->data, sizeof(BOX2DF)); result = LW_SUCCESS; } else { /* No, we need to calculate it from the full object. */ GBOX gbox; GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum); LWGEOM *lwgeom = lwgeom_from_gserialized(g); if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE ) { POSTGIS_DEBUG(4, "could not calculate bbox, returning failure"); lwgeom_free(lwgeom); return LW_FAILURE; } lwgeom_free(lwgeom); result = box2df_from_gbox_p(&gbox, box2df); } if ( result == LW_SUCCESS ) { POSTGIS_DEBUGF(4, "got box2df %s", box2df_to_string(box2df)); } return result; }
LWGEOM* lwgeom_from_gserialized(const GSERIALIZED *g) { uint8_t g_flags = 0; int32_t g_srid = 0; uint32_t g_type = 0; uint8_t *data_ptr = NULL; LWGEOM *lwgeom = NULL; GBOX bbox; size_t g_size = 0; assert(g); g_srid = gserialized_get_srid(g); g_flags = g->flags; g_type = gserialized_get_type(g); LWDEBUGF(4, "Got type %d (%s), srid=%d", g_type, lwtype_name(g_type), g_srid); data_ptr = (uint8_t*)g->data; if ( FLAGS_GET_BBOX(g_flags) ) data_ptr += gbox_serialized_size(g_flags); lwgeom = lwgeom_from_gserialized_buffer(data_ptr, g_flags, &g_size); if ( ! lwgeom ) lwerror("lwgeom_from_gserialized: unable create geometry"); /* Ooops! */ lwgeom->type = g_type; lwgeom->flags = g_flags; if ( gserialized_read_gbox_p(g, &bbox) == LW_SUCCESS ) { lwgeom->bbox = gbox_copy(&bbox); } else if ( lwgeom_needs_bbox(lwgeom) && (lwgeom_calculate_gbox(lwgeom, &bbox) == LW_SUCCESS) ) { lwgeom->bbox = gbox_copy(&bbox); } else { lwgeom->bbox = NULL; } lwgeom_set_srid(lwgeom, g_srid); return lwgeom; }
/* ** Make a copy of a GSERIALIZED, with a new bounding box value embedded. */ GSERIALIZED* gidx_insert_into_gserialized(GSERIALIZED *g, GIDX *gidx) { int g_ndims = (FLAGS_GET_GEODETIC(g->flags) ? 3 : FLAGS_NDIMS(g->flags)); int box_ndims = GIDX_NDIMS(gidx); GSERIALIZED *g_out = NULL; size_t box_size = 2 * g_ndims * sizeof(float); /* The dimensionality of the inputs has to match or we are SOL. */ if ( g_ndims != box_ndims ) { return NULL; } /* Serialized already has room for a box. We just need to copy it and write the new values into place. */ if ( FLAGS_GET_BBOX(g->flags) ) { g_out = palloc(VARSIZE(g)); memcpy(g_out, g, VARSIZE(g)); } /* Serialized has no box. We need to allocate enough space for the old data plus the box, and leave a gap in the memory segment to write the new values into. */ else { size_t varsize_new = VARSIZE(g) + box_size; uchar *ptr; g_out = palloc(varsize_new); /* Copy the head of g into place */ memcpy(g_out, g, 8); /* Copy the body of g into place after leaving space for the box */ ptr = g_out->data; ptr += box_size; memcpy(ptr, g->data, VARSIZE(g) - 8); FLAGS_SET_BBOX(g_out->flags, 1); SET_VARSIZE(g_out, varsize_new); } /* Now write the gidx values into the memory segement */ memcpy(g_out->data, gidx->c, box_size); return g_out; }
int gserialized_read_gbox_p(const GSERIALIZED *g, GBOX *gbox) { /* Null input! */ if ( ! ( g && gbox ) ) return LW_FAILURE; /* Initialize the flags on the box */ gbox->flags = g->flags; /* Has pre-calculated box */ if ( FLAGS_GET_BBOX(g->flags) ) { int i = 0; float *fbox = (float*)(g->data); gbox->xmin = fbox[i++]; gbox->xmax = fbox[i++]; gbox->ymin = fbox[i++]; gbox->ymax = fbox[i++]; /* Geodetic? Read next dimension (geocentric Z) and return */ if ( FLAGS_GET_GEODETIC(g->flags) ) { gbox->zmin = fbox[i++]; gbox->zmax = fbox[i++]; return LW_SUCCESS; } /* Cartesian? Read extra dimensions (if there) and return */ if ( FLAGS_GET_Z(g->flags) ) { gbox->zmin = fbox[i++]; gbox->zmax = fbox[i++]; } if ( FLAGS_GET_M(g->flags) ) { gbox->mmin = fbox[i++]; gbox->mmax = fbox[i++]; } return LW_SUCCESS; } return LW_FAILURE; }
/* ** Peak into a geography (gserialized) datum to find the bounding box. If the ** box is there, copy it out and return it. If not, calculate the box from the ** full geography and return the box based on that. If no box is available, ** return G_FAILURE, otherwise G_SUCCESS. */ int geography_datum_gidx(Datum geography_datum, GIDX *gidx) { GSERIALIZED *gpart; int result = G_SUCCESS; POSTGIS_DEBUG(4, "entered function"); /* ** The most info we need is the 8 bytes of serialized header plus the 24 bytes ** of floats necessary to hold the 6 floats of the geocentric index ** bounding box, so 32 bytes. */ gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(geography_datum, 0, 32); POSTGIS_DEBUGF(4, "got flags %d", gpart->flags); if ( FLAGS_GET_BBOX(gpart->flags) && FLAGS_GET_GEODETIC(gpart->flags) ) { const size_t size = 2 * 3 * sizeof(float); POSTGIS_DEBUG(4, "copying box out of serialization"); memcpy(gidx->c, gpart->data, size); SET_VARSIZE(gidx, VARHDRSZ + size); } else { GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(geography_datum); GBOX gbox; POSTGIS_DEBUG(4, "calculating new box from scratch"); if ( gserialized_calculate_gbox_geocentric_p(g, &gbox) == G_FAILURE ) { POSTGIS_DEBUG(4, "calculated null bbox, returning null"); return G_FAILURE; } result = gidx_from_gbox_p(gbox, gidx); } if ( result == G_SUCCESS ) { POSTGIS_DEBUGF(4, "got gidx %s", gidx_to_string(gidx)); } return result; }
LWGEOM* lwgeom_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size) { uint32_t type; assert(data_ptr); type = lw_get_uint32_t(data_ptr); LWDEBUGF(2, "Got type %d (%s), hasz=%d hasm=%d geodetic=%d hasbox=%d", type, lwtype_name(type), FLAGS_GET_Z(g_flags), FLAGS_GET_M(g_flags), FLAGS_GET_GEODETIC(g_flags), FLAGS_GET_BBOX(g_flags)); switch (type) { case POINTTYPE: return (LWGEOM *)lwpoint_from_gserialized_buffer(data_ptr, g_flags, g_size); case LINETYPE: return (LWGEOM *)lwline_from_gserialized_buffer(data_ptr, g_flags, g_size); case CIRCSTRINGTYPE: return (LWGEOM *)lwcircstring_from_gserialized_buffer(data_ptr, g_flags, g_size); case POLYGONTYPE: return (LWGEOM *)lwpoly_from_gserialized_buffer(data_ptr, g_flags, g_size); case TRIANGLETYPE: return (LWGEOM *)lwtriangle_from_gserialized_buffer(data_ptr, g_flags, g_size); case MULTIPOINTTYPE: case MULTILINETYPE: case MULTIPOLYGONTYPE: case COMPOUNDTYPE: case CURVEPOLYTYPE: case MULTICURVETYPE: case MULTISURFACETYPE: case POLYHEDRALSURFACETYPE: case TINTYPE: case COLLECTIONTYPE: return (LWGEOM *)lwcollection_from_gserialized_buffer(data_ptr, g_flags, g_size); default: lwerror("Unknown geometry type: %d - %s", type, lwtype_name(type)); return NULL; } }
int gserialized_is_empty(const GSERIALIZED *g) { uint8_t *p = (uint8_t*)g; int i; assert(g); p += 8; /* Skip varhdr and srid/flags */ if( FLAGS_GET_BBOX(g->flags) ) p += gbox_serialized_size(g->flags); /* Skip the box */ p += 4; /* Skip type number */ /* For point/line/circstring this is npoints */ /* For polygons this is nrings */ /* For collections this is ngeoms */ memcpy(&i, p, sizeof(int)); /* If it is non-zero, it's not empty */ if ( i > 0 ) return LW_FALSE; else return LW_TRUE; }
/* ** Peak into a geography to find the bounding box. If the ** box is there, copy it out and return it. If not, calculate the box from the ** full geography and return the box based on that. If no box is available, ** return LW_FAILURE, otherwise LW_SUCCESS. */ int gserialized_get_gidx_p(GSERIALIZED *g, GIDX *gidx) { int result = LW_SUCCESS; POSTGIS_DEBUG(4, "entered function"); POSTGIS_DEBUGF(4, "got flags %d", g->flags); if ( FLAGS_GET_BBOX(g->flags) ) { int ndims = FLAGS_NDIMS_GIDX(g->flags); const size_t size = 2 * ndims * sizeof(float); POSTGIS_DEBUG(4, "copying box out of serialization"); memcpy(gidx->c, g->data, size); SET_VARSIZE(gidx, VARHDRSZ + size); } else { /* No, we need to calculate it from the full object. */ LWGEOM *lwgeom = lwgeom_from_gserialized(g); GBOX gbox; if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE ) { POSTGIS_DEBUG(4, "could not calculate bbox, returning failure"); lwgeom_free(lwgeom); return LW_FAILURE; } lwgeom_free(lwgeom); result = gidx_from_gbox_p(gbox, gidx); } if ( result == LW_SUCCESS ) { POSTGIS_DEBUGF(4, "got gidx %s", gidx_to_string(gidx)); } return result; }
/* * Deserialize a TSERIALIZED struct and * return a TGEOM pointer */ TGEOM * tgeom_deserialize(TSERIALIZED *serialized_form) { uint8_t type, flags; TGEOM *result; uint8_t *loc, *data; int i, j; assert(serialized_form); assert(serialized_form->data); data = serialized_form->data; /* type and flags */ type = data[0]; flags = data[1]; result = tgeom_new(type, FLAGS_GET_Z(flags), FLAGS_GET_M(flags)); loc = data + 2; /* srid */ result->srid = lw_get_int32_t(loc); loc += 4; /* bbox */ if (FLAGS_GET_BBOX(flags)) { result->bbox = lwalloc(sizeof(BOX3D)); memcpy(result->bbox, loc, sizeof(BOX3D)); loc += sizeof(BOX3D); } else result->bbox = NULL; /* edges number (0=> EMPTY) */ result->nedges = lw_get_int32_t(loc); loc += 4; /* edges */ result->edges = lwalloc(sizeof(TEDGE*) * (result->nedges + 1)); for (i=1 ; i <= result->nedges ; i++) { result->edges[i] = lwalloc(sizeof(TEDGE)); result->edges[i]->s = lwalloc(sizeof(POINT4D)); result->edges[i]->e = lwalloc(sizeof(POINT4D)); /* 3DM specific handle */ if (!FLAGS_GET_Z(result->flags) && FLAGS_GET_M(result->flags)) { memcpy(result->edges[i]->s, loc, sizeof(double) * 2); loc += sizeof(double) * 2; memcpy(&(result->edges[i]->s->m), loc, sizeof(double)); loc += sizeof(double); memcpy(result->edges[i]->e, loc, sizeof(double) * 2); loc += sizeof(double) * 2; memcpy(&(result->edges[i]->e->m), loc, sizeof(double)); loc += sizeof(double); } else /* 2D,3DZ && 4D */ { memcpy(result->edges[i]->s, loc, sizeof(double) * FLAGS_NDIMS(flags)); loc += sizeof(double) * FLAGS_NDIMS(flags); result->edges[i]->e = lwalloc(sizeof(POINT4D)); memcpy(result->edges[i]->e, loc, sizeof(double) * FLAGS_NDIMS(flags)); loc += sizeof(double) * FLAGS_NDIMS(flags); } result->edges[i]->count = lw_get_int32_t(loc); loc += 4; } /* faces number */ result->nfaces = lw_get_int32_t(loc); loc += 4; /* faces */ result->faces = lwalloc(sizeof(TFACE*) * result->nfaces); for (i=0 ; i < result->nfaces ; i++) { result->faces[i] = lwalloc(sizeof(TFACE)); /* number of edges */ result->faces[i]->nedges = lw_get_int32_t(loc); loc += 4; /* edges array */ result->faces[i]->edges = lwalloc(sizeof(TEDGE*) * result->faces[i]->nedges); memcpy(result->faces[i]->edges, loc, sizeof(TEDGE*) * result->faces[i]->nedges); loc += 4 * result->faces[i]->nedges; /* number of rings */ result->faces[i]->nrings = lw_get_int32_t(loc); loc += 4; if (result->faces[i]->nrings) result->faces[i]->rings = lwalloc(sizeof(POINTARRAY*) * result->faces[i]->nrings); for (j=0 ; j < result->faces[i]->nrings ; j++) { int npoints; /* number of points */ npoints = lw_get_int32_t(loc); loc += 4; /* pointarray */ result->faces[i]->rings[j] = ptarray_construct_reference_data(FLAGS_GET_Z(flags), FLAGS_GET_M(flags), npoints, loc); loc += sizeof(double)* FLAGS_NDIMS(flags) * npoints; } } return result; }
char *WTBtree_convertGeoHash(GISTENTRY *entry, int size) { char *minPnt, *maxPnt, *cvtGeoHash; BOX2DF *box2df; box2df = (BOX2DF *) palloc(sizeof(BOX2DF)); GSERIALIZED *gpart; uint8_t flags; if (VARATT_IS_EXTENDED(entry->key)) { printf("true\n"); gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(entry->key, 0, 8 + sizeof(BOX2DF)); printf("gpart->size : %d\n", gpart->size); printf("gpart->flags : %d\n", gpart->flags); flags = gpart->flags; } else { printf("false\n"); // gpart = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum); } if ( FLAGS_GET_BBOX(flags) ) { printf("IsFlags : %d\n", flags); memcpy(box2df, gpart->data, sizeof(BOX2DF)); //result = LW_SUCCESS; printf("----------------: %f\n", box2df->xmin); printf("----------------: %f\n", box2df->ymin); printf("----------------: %f\n", box2df->xmax); printf("----------------: %f\n", box2df->ymax); minPnt = (char*) palloc(size); maxPnt = (char*) palloc(size); cvtGeoHash = (char*) palloc(size); memcpy(minPnt, geohash_encode((double) box2df->ymin, (double) box2df->xmin, size), size); memcpy(maxPnt, geohash_encode((double) box2df->ymax, (double) box2df->xmax, size), size); cvtGeoHash = convert_GeoHash_from_box2d(minPnt, maxPnt, size); printf("-----------geohash_encode : %s\n", cvtGeoHash); } else { printf("NotFlags : %d\n", flags); /* GBOX gbox; GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(entry->key); LWGEOM *lwgeom = lwgeom_from_gserialized(g); if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE ) { POSTGIS_DEBUG(4, "could not calculate bbox, returning failure"); lwgeom_free(lwgeom); return LW_FAILURE; } lwgeom_free(lwgeom); result = box2df_from_gbox_p(&gbox, box2df); */ } return cvtGeoHash; }
int gserialized_has_bbox(const GSERIALIZED *gser) { return FLAGS_GET_BBOX(gser->flags); }
/* * Populate a bounding box *without* allocating an LWGEOM. Useful * for some performance purposes. */ static int gserialized_peek_gbox_p(const GSERIALIZED *g, GBOX *gbox) { uint32_t type = gserialized_get_type(g); /* Peeking doesn't help if you already have a box or are geodetic */ if ( FLAGS_GET_GEODETIC(g->flags) || FLAGS_GET_BBOX(g->flags) ) { return LW_FAILURE; } /* Boxes of points are easy peasy */ if ( type == POINTTYPE ) { int i = 1; /* Start past <pointtype><padding> */ double *dptr = (double*)(g->data); /* Read the empty flag */ int *iptr = (int*)(g->data); int isempty = (iptr[1] == 0); /* EMPTY point has no box */ if ( isempty ) return LW_FAILURE; gbox->xmin = gbox->xmax = dptr[i++]; gbox->ymin = gbox->ymax = dptr[i++]; if ( FLAGS_GET_Z(g->flags) ) { gbox->zmin = gbox->zmax = dptr[i++]; } if ( FLAGS_GET_M(g->flags) ) { gbox->mmin = gbox->mmax = dptr[i++]; } gbox_float_round(gbox); return LW_SUCCESS; } /* We can calculate the box of a two-point cartesian line trivially */ else if ( type == LINETYPE ) { int ndims = FLAGS_NDIMS(g->flags); int i = 0; /* Start at <linetype><npoints> */ double *dptr = (double*)(g->data); int *iptr = (int*)(g->data); int npoints = iptr[1]; /* Read the npoints */ /* This only works with 2-point lines */ if ( npoints != 2 ) return LW_FAILURE; /* Advance to X */ /* Past <linetype><npoints> */ i++; gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]); gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]); /* Advance to Y */ i++; gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]); gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]); if ( FLAGS_GET_Z(g->flags) ) { /* Advance to Z */ i++; gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]); gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]); } if ( FLAGS_GET_M(g->flags) ) { /* Advance to M */ i++; gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]); gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]); } gbox_float_round(gbox); return LW_SUCCESS; } /* We can also do single-entry multi-points */ else if ( type == MULTIPOINTTYPE ) { int i = 0; /* Start at <multipointtype><ngeoms> */ double *dptr = (double*)(g->data); int *iptr = (int*)(g->data); int ngeoms = iptr[1]; /* Read the ngeoms */ /* This only works with single-entry multipoints */ if ( ngeoms != 1 ) return LW_FAILURE; /* Move forward two doubles (four ints) */ /* Past <multipointtype><ngeoms> */ /* Past <pointtype><emtpyflat> */ i += 2; /* Read the doubles from the one point */ gbox->xmin = gbox->xmax = dptr[i++]; gbox->ymin = gbox->ymax = dptr[i++]; if ( FLAGS_GET_Z(g->flags) ) { gbox->zmin = gbox->zmax = dptr[i++]; } if ( FLAGS_GET_M(g->flags) ) { gbox->mmin = gbox->mmax = dptr[i++]; } gbox_float_round(gbox); return LW_SUCCESS; } /* And we can do single-entry multi-lines with two vertices (!!!) */ else if ( type == MULTILINETYPE ) { int ndims = FLAGS_NDIMS(g->flags); int i = 0; /* Start at <multilinetype><ngeoms> */ double *dptr = (double*)(g->data); int *iptr = (int*)(g->data); int ngeoms = iptr[1]; /* Read the ngeoms */ int npoints; /* This only works with 1-line multilines */ if ( ngeoms != 1 ) return LW_FAILURE; /* Npoints is at <multilinetype><ngeoms><linetype><npoints> */ npoints = iptr[3]; if ( npoints != 2 ) return LW_FAILURE; /* Advance to X */ /* Move forward two doubles (four ints) */ /* Past <multilinetype><ngeoms> */ /* Past <linetype><npoints> */ i += 2; gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]); gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]); /* Advance to Y */ i++; gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]); gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]); if ( FLAGS_GET_Z(g->flags) ) { /* Advance to Z */ i++; gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]); gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]); } if ( FLAGS_GET_M(g->flags) ) { /* Advance to M */ i++; gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]); gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]); } gbox_float_round(gbox); return LW_SUCCESS; } return LW_FAILURE; }