/*
** 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;
}
示例#2
0
/**
* 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;
}
示例#3
0
/**
* 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;
}
示例#4
0
文件: g_box.c 项目: Vlczech/vtapi
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);
}
示例#5
0
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("}");
}
示例#6
0
文件: g_box.c 项目: Vlczech/vtapi
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;
}
示例#7
0
/**
* 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;
}
示例#8
0
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;
}
示例#10
0
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;
}
示例#11
0
/*
** 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;
}
示例#12
0
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;
}
示例#13
0
/*
** 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;
}
示例#14
0
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;
	}
}
示例#15
0
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;	
}
示例#16
0
/*
** 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;
}
示例#17
0
/*
 * 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;
}
示例#18
0
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;
}
示例#19
0
int gserialized_has_bbox(const GSERIALIZED *gser)
{
	return FLAGS_GET_BBOX(gser->flags);
}
示例#20
0
/*
* 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;
}