Ejemplo n.º 1
0
/*
 * Construct a new LWCIRCSTRING.  points will *NOT* be copied
 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
 */
LWCIRCSTRING *
lwcircstring_construct(int srid, GBOX *bbox, POINTARRAY *points)
{
	LWCIRCSTRING *result;

	/*
	        * The first arc requires three points.  Each additional
	        * arc requires two more points.  Thus the minimum point count
	        * is three, and the count must be odd.
	        */
	if (points->npoints % 2 != 1 || points->npoints < 3)
	{
		lwnotice("lwcircstring_construct: invalid point count %d", points->npoints);
	}

	result = (LWCIRCSTRING*) lwalloc(sizeof(LWCIRCSTRING));

	result->type = CIRCSTRINGTYPE;
	
	result->flags = points->flags;
	FLAGS_SET_BBOX(result->flags, bbox?1:0);

	result->srid = srid;
	result->points = points;
	result->bbox = bbox;

	return result;
}
Ejemplo n.º 2
0
void 
lwgeom_add_bbox_deep(LWGEOM *lwgeom, GBOX *gbox)
{
	if ( lwgeom_is_empty(lwgeom) ) return;

	FLAGS_SET_BBOX(lwgeom->flags, 1);
	
	if ( ! ( gbox || lwgeom->bbox ) )
	{
		lwgeom->bbox = gbox_new(lwgeom->flags);
		lwgeom_calculate_gbox(lwgeom, lwgeom->bbox);		
	}
	else if ( gbox && ! lwgeom->bbox )
	{
		lwgeom->bbox = gbox_clone(gbox);
	}
	
	if ( lwgeom_is_collection(lwgeom) )
	{
		int i;
		LWCOLLECTION *lwcol = (LWCOLLECTION*)lwgeom;

		for ( i = 0; i < lwcol->ngeoms; i++ )
		{
			lwgeom_add_bbox_deep(lwcol->geoms[i], lwgeom->bbox);
		}
	}
}
Ejemplo n.º 3
0
void
lwgeom_drop_bbox(LWGEOM *lwgeom)
{
	if ( lwgeom->bbox ) lwfree(lwgeom->bbox);
	lwgeom->bbox = NULL;
	FLAGS_SET_BBOX(lwgeom->flags, 0);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/**
 * Ensure there's a box in the LWGEOM.
 * If the box is already there just return,
 * else compute it.
 */
void
lwgeom_add_bbox(LWGEOM *lwgeom)
{
	/* an empty LWGEOM has no bbox */
	if ( lwgeom_is_empty(lwgeom) ) return;

	if ( lwgeom->bbox ) return;
	FLAGS_SET_BBOX(lwgeom->flags, 1);
	lwgeom->bbox = gbox_new(lwgeom->flags);
	lwgeom_calculate_gbox(lwgeom, lwgeom->bbox);
}
Ejemplo n.º 6
0
static LWCOLLECTION* lwcollection_from_gserialized_buffer(uint8_t *data_ptr, uint8_t g_flags, size_t *g_size)
{
	uint32_t type;
	uint8_t *start_ptr = data_ptr;
	LWCOLLECTION *collection;
	uint32_t ngeoms = 0;
	int i = 0;

	assert(data_ptr);

	type = lw_get_uint32_t(data_ptr);
	data_ptr += 4; /* Skip past the type. */

	collection = (LWCOLLECTION*)lwalloc(sizeof(LWCOLLECTION));
	collection->srid = SRID_UNKNOWN; /* Default */
	collection->bbox = NULL;
	collection->type = type;
	collection->flags = g_flags;

	ngeoms = lw_get_uint32_t(data_ptr);
	collection->ngeoms = ngeoms; /* Zero => empty geometry */
	data_ptr += 4; /* Skip past the ngeoms. */

	if ( ngeoms > 0 )
		collection->geoms = lwalloc(sizeof(LWGEOM*) * ngeoms);
	else
		collection->geoms = NULL;

	/* Sub-geometries are never de-serialized with boxes (#1254) */
	FLAGS_SET_BBOX(g_flags, 0);

	for ( i = 0; i < ngeoms; i++ )
	{
		uint32_t subtype = lw_get_uint32_t(data_ptr);
		size_t subsize = 0;

		if ( ! lwcollection_allows_subtype(type, subtype) )
		{
			lwerror("Invalid subtype (%s) for collection type (%s)", lwtype_name(subtype), lwtype_name(type));
			lwfree(collection);
			return NULL;
		}
		collection->geoms[i] = lwgeom_from_gserialized_buffer(data_ptr, g_flags, &subsize);
		data_ptr += subsize;
	}

	if ( g_size )
		*g_size = data_ptr - start_ptr;

	return collection;
}
Ejemplo n.º 7
0
LWCOLLECTION *
lwcollection_construct(uint8_t type, int srid, GBOX *bbox,
                       uint32_t ngeoms, LWGEOM **geoms)
{
	LWCOLLECTION *ret;
	int hasz, hasm;
#ifdef CHECK_LWGEOM_ZM
	char zm;
	uint32_t i;
#endif

	LWDEBUGF(2, "lwcollection_construct called with %d, %d, %p, %d, %p.", type, srid, bbox, ngeoms, geoms);

	if( ! lwtype_is_collection(type) )
		lwerror("Non-collection type specified in collection constructor!");

	hasz = 0;
	hasm = 0;
	if ( ngeoms > 0 )
	{
		hasz = FLAGS_GET_Z(geoms[0]->flags);
		hasm = FLAGS_GET_M(geoms[0]->flags);
#ifdef CHECK_LWGEOM_ZM
		zm = FLAGS_GET_ZM(geoms[0]->flags);

		LWDEBUGF(3, "lwcollection_construct type[0]=%d", geoms[0]->type);

		for (i=1; i<ngeoms; i++)
		{
			LWDEBUGF(3, "lwcollection_construct type=[%d]=%d", i, geoms[i]->type);

			if ( zm != FLAGS_GET_ZM(geoms[i]->flags) )
				lwerror("lwcollection_construct: mixed dimension geometries: %d/%d", zm, FLAGS_GET_ZM(geoms[i]->flags));
		}
#endif
	}


	ret = lwalloc(sizeof(LWCOLLECTION));
	ret->type = type;
	ret->flags = gflags(hasz,hasm,0);
	FLAGS_SET_BBOX(ret->flags, bbox?1:0);
	ret->srid = srid;
	ret->ngeoms = ngeoms;
	ret->maxgeoms = ngeoms;
	ret->geoms = geoms;
	ret->bbox = bbox;

	return ret;
}
Ejemplo n.º 8
0
/* construct a new LWTRIANGLE.
 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
 */
LWTRIANGLE*
lwtriangle_construct(int srid, GBOX *bbox, POINTARRAY *points)
{
	LWTRIANGLE *result;

	result = (LWTRIANGLE*) lwalloc(sizeof(LWTRIANGLE));
	result->type = TRIANGLETYPE;

	result->flags = points->flags;
	FLAGS_SET_BBOX(result->flags, bbox?1:0);
	
	result->srid = srid;
	result->points = points;
	result->bbox = bbox;

	return result;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
/*
 * Construct a new point.  point will not be copied
 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
 */
LWPOINT *
lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
{
	LWPOINT *result;
	uint8_t flags = 0;

	if (point == NULL)
		return NULL; /* error */

	result = lwalloc(sizeof(LWPOINT));
	result->type = POINTTYPE;
	FLAGS_SET_Z(flags, FLAGS_GET_Z(point->flags));
	FLAGS_SET_M(flags, FLAGS_GET_M(point->flags));
	FLAGS_SET_BBOX(flags, bbox?1:0);
	result->flags = flags;
	result->srid = srid;
	result->point = point;
	result->bbox = bbox;

	return result;
}
Ejemplo n.º 11
0
/* construct a new LWPOLY.  arrays (points/points per ring) will NOT be copied
 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
 */
LWPOLY*
lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
{
	LWPOLY *result;
	int hasz, hasm;
#ifdef CHECK_POLY_RINGS_ZM
	char zm;
	uint32_t i;
#endif

	if ( nrings < 1 ) lwerror("lwpoly_construct: need at least 1 ring");

	hasz = FLAGS_GET_Z(points[0]->flags);
	hasm = FLAGS_GET_M(points[0]->flags);

#ifdef CHECK_POLY_RINGS_ZM
	zm = FLAGS_GET_ZM(points[0]->flags);
	for (i=1; i<nrings; i++)
	{
		if ( zm != FLAGS_GET_ZM(points[i]->flags) )
			lwerror("lwpoly_construct: mixed dimensioned rings");
	}
#endif

	result = (LWPOLY*) lwalloc(sizeof(LWPOLY));
	result->type = POLYGONTYPE;
	result->flags = gflags(hasz, hasm, 0);
	FLAGS_SET_BBOX(result->flags, bbox?1:0);
	result->srid = srid;
	result->nrings = nrings;
	result->maxrings = nrings;
	result->rings = points;
	result->bbox = bbox;

	return result;
}
Ejemplo n.º 12
0
GSERIALIZED* gserialized_from_lwgeom(LWGEOM *geom, int is_geodetic, size_t *size)
{
	size_t expected_size = 0;
	size_t return_size = 0;
	uint8_t *serialized = NULL;
	uint8_t *ptr = NULL;
	GSERIALIZED *g = NULL;
	assert(geom);

	/*
	** See if we need a bounding box, add one if we don't have one.
	*/
	if ( (! geom->bbox) && lwgeom_needs_bbox(geom) && (!lwgeom_is_empty(geom)) )
	{
		lwgeom_add_bbox(geom);
	}
	
	/*
	** Harmonize the flags to the state of the lwgeom 
	*/
	if ( geom->bbox )
		FLAGS_SET_BBOX(geom->flags, 1);

	/* Set up the uint8_t buffer into which we are going to write the serialized geometry. */
	expected_size = gserialized_from_lwgeom_size(geom);
	serialized = lwalloc(expected_size);
	ptr = serialized;

	/* Move past size, srid and flags. */
	ptr += 8;

	/* Write in the serialized form of the gbox, if necessary. */
	if ( geom->bbox )
		ptr += gserialized_from_gbox(geom->bbox, ptr);

	/* Write in the serialized form of the geometry. */
	ptr += gserialized_from_lwgeom_any(geom, ptr);

	/* Calculate size as returned by data processing functions. */
	return_size = ptr - serialized;

	if ( expected_size != return_size ) /* Uh oh! */
	{
		lwerror("Return size (%d) not equal to expected size (%d)!", return_size, expected_size);
		return NULL;
	}

	if ( size ) /* Return the output size to the caller if necessary. */
		*size = return_size;

	g = (GSERIALIZED*)serialized;

	/*
	** We are aping PgSQL code here, PostGIS code should use
	** VARSIZE to set this for real.
	*/
	g->size = return_size << 2;

	/* Set the SRID! */
	gserialized_set_srid(g, geom->srid);

	g->flags = geom->flags;

	return g;
}