Example #1
0
static int lwcircstring_calculate_gbox(LWCIRCSTRING *curve, GBOX *gbox)
{
	uchar flags = gflags(TYPE_HASZ(curve->type), TYPE_HASM(curve->type), 0);
	GBOX tmp;
	POINT4D p1, p2, p3;
	int i;

	if ( ! curve ) return G_FAILURE;
	if ( curve->points->npoints < 3 ) return G_FAILURE;

	tmp.flags = flags;

	/* Initialize */
	gbox->xmin = gbox->ymin = gbox->zmin = gbox->mmin = MAXFLOAT;
	gbox->xmax = gbox->ymax = gbox->zmax = gbox->mmax = -1 * MAXFLOAT;

	for ( i = 2; i < curve->points->npoints; i += 2 )
	{
		getPoint4d_p(curve->points, i-2, &p1);
		getPoint4d_p(curve->points, i-1, &p2);
		getPoint4d_p(curve->points, i, &p3);

		if (lwcircle_calculate_gbox(p1, p2, p3, &tmp) == G_FAILURE)
			continue;

		gbox_merge(&tmp, gbox);
	}

	return G_SUCCESS;
}
Example #2
0
char compound_is_closed(LWCOMPOUND *compound)
{
	POINT3DZ sp, ep;
	LWGEOM *tmp;

	LWDEBUG(2, "compound_is_closed called.");

	tmp = compound->geoms[0];
	if (lwgeom_getType(tmp->type) == LINETYPE)
	{
		getPoint3dz_p(((LWLINE *)tmp)->points, 0, &sp);
	}
	else
	{
		getPoint3dz_p(((LWCIRCSTRING *)tmp)->points, 0, &sp);
	}

	tmp = compound->geoms[compound->ngeoms - 1];
	if (lwgeom_getType(tmp->type) == LINETYPE)
	{
		getPoint3dz_p(((LWLINE *)tmp)->points, ((LWLINE *)tmp)->points->npoints - 1, &ep);
	}
	else
	{
		getPoint3dz_p(((LWCIRCSTRING *)tmp)->points, ((LWCIRCSTRING *)tmp)->points->npoints - 1, &ep);
	}

	if (sp.x != ep.x) return 0;
	if (sp.y != ep.y) return 0;
	if (TYPE_HASZ(compound->type))
	{
		if (sp.z != ep.z) return 0;
	}
	return 1;
}
Example #3
0
/*
 * Construct a new LWCIRCSTRING.  points will *NOT* be copied
 * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
 */
LWCIRCSTRING *
lwcircstring_construct(int SRID, BOX2DFLOAT4 *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)
	{
		lwerror("lwcircstring_construct: invalid point count %d", points->npoints);
		return NULL;
	}

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

	result->type = lwgeom_makeType_full(
	                   TYPE_HASZ(points->dims),
	                   TYPE_HASM(points->dims),
	                   (SRID!=-1), CIRCSTRINGTYPE, 0);
	result->SRID = SRID;
	result->points = points;
	result->bbox = bbox;

	return result;
}
Example #4
0
/*
 * given the LWGEOM serialized form (or a pointer into a muli* one)
 * construct a proper LWLINE.
 * serialized_form should point to the 8bit type format (with type = 2)
 * See serialized form doc
 */
LWLINE *
lwline_deserialize(uchar *serialized_form)
{
	uchar type;
	LWLINE *result;
	uchar *loc =NULL;
	uint32 npoints;
	POINTARRAY *pa;

	type = (uchar) serialized_form[0];

	if ( lwgeom_getType(type) != LINETYPE)
	{
		lwerror("lwline_deserialize: attempt to deserialize a line which is really a %s", lwgeom_typename(type));
		return NULL;
	}

	result = (LWLINE*) lwalloc(sizeof(LWLINE)) ;
	result->type = type;

	loc = serialized_form+1;

	if (lwgeom_hasBBOX(type))
	{
		LWDEBUG(3, "lwline_deserialize: input has bbox");

		result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
		memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
		loc += sizeof(BOX2DFLOAT4);
	}
	else
	{
		result->bbox = NULL;
		/*lwnotice("line has NO bbox"); */
	}

	if ( lwgeom_hasSRID(type))
	{
		/*lwnotice("line has srid"); */
		result->SRID = lw_get_int32(loc);
		loc +=4; /* type + SRID */
	}
	else
	{
		/*lwnotice("line has NO srid"); */
		result->SRID = -1;
	}

	/* we've read the type (1 byte) and SRID (4 bytes, if present) */

	npoints = lw_get_uint32(loc);
	/*lwnotice("line npoints = %d", npoints); */
	loc +=4;
	pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints);
	result->points = pa;

	return result;
}
Example #5
0
Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom;
	LWGEOM_INSPECTED *inspected;
	LWLINE *line = NULL;
	POINTARRAY *pts;
	LWPOINT *point;
	PG_LWGEOM *result;
	int i, type;

	POSTGIS_DEBUG(2, "LWGEOM_startpoint_linestring called.");

	geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));

	/*
	 * Curved polygons and compound curves are both collections
	 * that should not be traversed looking for linestrings.
	 */
	type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]);
	if (type == CURVEPOLYTYPE || type == COMPOUNDTYPE)
	{
		PG_FREE_IF_COPY(geom, 0);
		PG_RETURN_NULL();
	}

	inspected = lwgeom_inspect(SERIALIZED_FORM(geom));

	for (i=0; i<inspected->ngeometries; i++)
	{
		line = lwgeom_getline_inspected(inspected, i);
		if ( line ) break;
	}

	if ( line == NULL )
	{
		PG_FREE_IF_COPY(geom, 0);
		PG_RETURN_NULL();
	}

	/* Ok, now we have a line.  */

	/* Construct a point array */
	pts = pointArray_construct(getPoint_internal(line->points, 0),
	                           TYPE_HASZ(line->type),
	                           TYPE_HASM(line->type), 1);
	lwgeom_release((LWGEOM *)line);

	/* Construct an LWPOINT */
	point = lwpoint_construct(pglwgeom_getSRID(geom), NULL, pts);

	/* Construct a PG_LWGEOM */
	result = pglwgeom_serialize((LWGEOM *)point);

	lwgeom_release((LWGEOM *)point);
	PG_FREE_IF_COPY(geom, 0);

	PG_RETURN_POINTER(result);
}
Example #6
0
/*
 * Given the LWPOINT serialized form (or a pointer into a muli* one)
 * construct a proper LWPOINT.
 * serialized_form should point to the 8bit type format (with type = 1)
 * See serialized form doc
 */
LWPOINT *
lwpoint_deserialize(uchar *serialized_form)
{
	uchar type;
	int geom_type;
	LWPOINT *result;
	uchar *loc = NULL;
	POINTARRAY *pa;

	LWDEBUG(2, "lwpoint_deserialize called");

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

	type = serialized_form[0];
	geom_type = lwgeom_getType(type);

	if ( geom_type != POINTTYPE)
	{
		lwerror("lwpoint_deserialize: attempt to deserialize a point which is really a %s", lwgeom_typename(geom_type));
		return NULL;
	}
	result->type = type;

	loc = serialized_form+1;

	if (lwgeom_hasBBOX(type))
	{
		LWDEBUG(3, "lwpoint_deserialize: input has bbox");

		result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
		memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
		loc += sizeof(BOX2DFLOAT4);
	}
	else
	{
		result->bbox = NULL;
	}

	if ( lwgeom_hasSRID(type))
	{
		LWDEBUG(3, "lwpoint_deserialize: input has SRID");

		result->SRID = lw_get_int32(loc);
		loc += 4; /* type + SRID */
	}
	else
	{
		result->SRID = -1;
	}

	/* we've read the type (1 byte) and SRID (4 bytes, if present) */

	pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), 1);

	result->point = pa;

	return result;
}
Example #7
0
/**
* Re-write the measure ordinate (or add one, if it isn't already there) interpolating
* the measure between the supplied start and end values.
*/
LWLINE*
lwline_measured_from_lwline(const LWLINE *lwline, double m_start, double m_end)
{
	int i = 0;
	int hasm = 0, hasz = 0;
	int npoints = 0;
	double length = 0.0;
	double length_so_far = 0.0;
	double m_range = m_end - m_start;
	double m;
	POINTARRAY *pa = NULL;
	POINT3DZ p1, p2;

	if ( TYPE_GETTYPE(lwline->type) != LINETYPE )
	{
		lwerror("lwline_construct_from_lwline: only line types supported");
		return NULL;
	}

	hasz = TYPE_HASZ(lwline->type);
	hasm = 1;

	/* Null points or npoints == 0 will result in empty return geometry */
	if ( lwline->points )
	{
		npoints = lwline->points->npoints;
		length = lwgeom_pointarray_length2d(lwline->points);
		getPoint3dz_p(lwline->points, 0, &p1);
	}

	pa = ptarray_construct(hasz, hasm, npoints);

	for ( i = 0; i < npoints; i++ )
	{
		POINT4D q;
		POINT2D a, b;
		getPoint3dz_p(lwline->points, i, &p2);
		a.x = p1.x;
		a.y = p1.y;
		b.x = p2.x;
		b.y = p2.y;
		length_so_far += distance2d_pt_pt(&a, &b);
		if ( length > 0.0 )
			m = m_start + m_range * length_so_far / length;
		else
			m = 0.0;
		q.x = p2.x;
		q.y = p2.y;
		q.z = p2.z;
		q.m = m;
		setPoint4d(pa, i, &q);
		p1 = p2;
	}

	return lwline_construct(lwline->SRID, NULL, pa);
}
Example #8
0
Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom;
	LWGEOM_INSPECTED *inspected;
	LWLINE *line = NULL;
	POINTARRAY *pts;
	LWGEOM *point;
	PG_LWGEOM *result;
	int i, type;

	POSTGIS_DEBUG(2, "LWGEOM_endpoint_linestring called.");

	geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]);
	if (type == CURVEPOLYTYPE || type == COMPOUNDTYPE)
	{
		PG_FREE_IF_COPY(geom, 0);
		PG_RETURN_NULL();
	}

	inspected = lwgeom_inspect(SERIALIZED_FORM(geom));

	for (i=0; i<inspected->ngeometries; i++)
	{
		line = lwgeom_getline_inspected(inspected, i);
		if ( line ) break;
	}
	lwinspected_release(inspected);

	if ( line == NULL )
	{
		PG_FREE_IF_COPY(geom, 0);
		PG_RETURN_NULL();
	}

	/* Ok, now we have a line.  */

	/* Construct a point array */
	pts = pointArray_construct(
	          getPoint_internal(line->points, line->points->npoints-1),
	          TYPE_HASZ(line->type),
	          TYPE_HASM(line->type), 1);
	lwgeom_release((LWGEOM *)line);

	/* Construct an LWPOINT */
	point = (LWGEOM *)lwpoint_construct(pglwgeom_getSRID(geom), NULL, pts);

	/* Serialize an PG_LWGEOM */
	result = pglwgeom_serialize(point);
	lwgeom_release(point);

	PG_FREE_IF_COPY(geom, 0);

	PG_RETURN_POINTER(result);
}
Example #9
0
Datum LWGEOM_getTYPE(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *lwgeom;
	char *text_ob;
	char *result;
	int32 size;
	uchar type;

	lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	text_ob = lwalloc(20+VARHDRSZ);
	result = text_ob+VARHDRSZ;

	type = lwgeom_getType(lwgeom->type);

	memset(VARDATA(text_ob), 0, 20);

	if (type == POINTTYPE)
		strcpy(result,"POINT");
	else if (type == MULTIPOINTTYPE)
		strcpy(result,"MULTIPOINT");
	else if (type == LINETYPE)
		strcpy(result,"LINESTRING");
	else if (type == CIRCSTRINGTYPE)
		strcpy(result,"CIRCULARSTRING");
	else if (type == COMPOUNDTYPE)
		strcpy(result, "COMPOUNDCURVE");
	else if (type == MULTILINETYPE)
		strcpy(result,"MULTILINESTRING");
	else if (type == MULTICURVETYPE)
		strcpy(result, "MULTICURVE");
	else if (type == POLYGONTYPE)
		strcpy(result,"POLYGON");
	else if (type == CURVEPOLYTYPE)
		strcpy(result,"CURVEPOLYGON");
	else if (type == MULTIPOLYGONTYPE)
		strcpy(result,"MULTIPOLYGON");
	else if (type == MULTISURFACETYPE)
		strcpy(result, "MULTISURFACE");
	else if (type == COLLECTIONTYPE)
		strcpy(result,"GEOMETRYCOLLECTION");
	else
		strcpy(result,"UNKNOWN");

	if ( TYPE_HASM(lwgeom->type) && ! TYPE_HASZ(lwgeom->type) )
		strcat(result, "M");

	size = strlen(result) + VARHDRSZ ;
	SET_VARSIZE(text_ob, size); /* size of string */

	PG_FREE_IF_COPY(lwgeom, 0);

	PG_RETURN_POINTER(text_ob);
}
Example #10
0
/*
 * Construct a LWLINE from an array of LWPOINTs
 * LWLINE dimensions are large enough to host all input dimensions.
 */
LWLINE *
lwline_from_lwpointarray(int SRID, unsigned int npoints, LWPOINT **points)
{
	int zmflag=0;
	unsigned int i;
	POINTARRAY *pa;
	uchar *newpoints, *ptr;
	size_t ptsize, size;

	/*
	 * Find output dimensions, check integrity
	 */
	for (i=0; i<npoints; i++)
	{
		if ( TYPE_GETTYPE(points[i]->type) != POINTTYPE )
		{
			lwerror("lwline_from_lwpointarray: invalid input type: %s",
			        lwgeom_typename(TYPE_GETTYPE(points[i]->type)));
			return NULL;
		}
		if ( TYPE_HASZ(points[i]->type) ) zmflag |= 2;
		if ( TYPE_HASM(points[i]->type) ) zmflag |= 1;
		if ( zmflag == 3 ) break;
	}

	if ( zmflag == 0 ) ptsize=2*sizeof(double);
	else if ( zmflag == 3 ) ptsize=4*sizeof(double);
	else ptsize=3*sizeof(double);

	/*
	 * Allocate output points array
	 */
	size = ptsize*npoints;
	newpoints = lwalloc(size);
	memset(newpoints, 0, size);

	ptr=newpoints;
	for (i=0; i<npoints; i++)
	{
		size=pointArray_ptsize(points[i]->point);
		memcpy(ptr, getPoint_internal(points[i]->point, 0), size);
		ptr+=ptsize;
	}

	pa = pointArray_construct(newpoints, zmflag&2, zmflag&1, npoints);

	return lwline_construct(SRID, NULL, pa);
}
Example #11
0
/*
 * Construct a new point.  point will not be copied
 * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
 */
LWPOINT *
lwpoint_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *point)
{
	LWPOINT *result ;

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

	result = lwalloc(sizeof(LWPOINT));
	result->type = lwgeom_makeType_full(TYPE_HASZ(point->dims), TYPE_HASM(point->dims), (SRID!=-1), POINTTYPE, 0);
	result->SRID = SRID;
	result->point = point;
	result->bbox = bbox;

	return result;
}
Example #12
0
char circstring_is_closed(LWCIRCSTRING *curve)
{
	POINT3DZ sp, ep;

	LWDEBUG(2, "circstring_is_closed called.");

	getPoint3dz_p(curve->points, 0, &sp);
	getPoint3dz_p(curve->points, curve->points->npoints-1, &ep);

	if (sp.x != ep.x) return 0;
	if (sp.y != ep.y) return 0;
	if (TYPE_HASZ(curve->type))
	{
		if (sp.z != ep.z) return 0;
	}
	return 1;
}
Example #13
0
char line_is_closed(LWLINE *line)
{
	POINT3DZ sp, ep;

	LWDEBUG(2, "line_is_closed called.");

	getPoint3dz_p(line->points, 0, &sp);
	getPoint3dz_p(line->points, line->points->npoints-1, &ep);

	if ( sp.x != ep.x ) return 0;
	if ( sp.y != ep.y ) return 0;
	if ( TYPE_HASZ(line->type) )
	{
		if ( sp.z != ep.z ) return 0;
	}

	return 1;
}
Example #14
0
/*
 * Convert this point into its serialize form writing it into
 * the given buffer, and returning number of bytes written into
 * the given int pointer.
 * result's first char will be the 8bit type.  See serialized form doc
 */
void
lwpoint_serialize_buf(LWPOINT *point, uchar *buf, size_t *retsize)
{
	int size=1;
	char hasSRID;
	uchar *loc;
	int ptsize = pointArray_ptsize(point->point);

	if ( TYPE_GETZM(point->type) != TYPE_GETZM(point->point->dims) )
		lwerror("Dimensions mismatch in lwpoint");

	LWDEBUGF(2, "lwpoint_serialize_buf(%p, %p) called", point, buf);
	/*printLWPOINT(point); */

	hasSRID = (point->SRID != -1);

	if (hasSRID) size +=4;  /*4 byte SRID */
	if (point->bbox) size += sizeof(BOX2DFLOAT4); /* bvol */

	size += sizeof(double)*TYPE_NDIMS(point->type);

	buf[0] = (uchar) lwgeom_makeType_full(
		TYPE_HASZ(point->type), TYPE_HASM(point->type),
		hasSRID, POINTTYPE, point->bbox?1:0);
	loc = buf+1;

	if (point->bbox)
	{
		memcpy(loc, point->bbox, sizeof(BOX2DFLOAT4));
		loc += sizeof(BOX2DFLOAT4);
	}

	if (hasSRID)
	{
		memcpy(loc, &point->SRID, sizeof(int32));
		loc += 4;
	}

	/* copy in points */
	memcpy(loc, getPoint_internal(point->point, 0), ptsize);

	if (retsize) *retsize = size;
}
Example #15
0
Datum LWGEOM_z_point(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom;
	LWPOINT *point = NULL;
	POINT3DZ p;

	geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));

	if ( TYPE_GETTYPE(geom->type) != POINTTYPE )
		lwerror("Argument to Z() must be a point");

	point = lwgeom_getpoint(SERIALIZED_FORM(geom), 0);

	/* no Z in input */
	if ( ! TYPE_HASZ(geom->type) ) PG_RETURN_NULL();

	getPoint3dz_p(point->point, 0, &p);

	PG_FREE_IF_COPY(geom, 0);

	PG_RETURN_FLOAT8(p.z);
}
Example #16
0
/*
 * Construct a new LWLINE.  points will *NOT* be copied
 * use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
 */
LWLINE *
lwline_construct(int SRID, BOX2DFLOAT4 *bbox, POINTARRAY *points)
{
	LWLINE *result;
	result = (LWLINE*) lwalloc(sizeof(LWLINE));

	LWDEBUG(2, "lwline_construct called.");

	result->type = lwgeom_makeType_full(
	                   TYPE_HASZ(points->dims),
	                   TYPE_HASM(points->dims),
	                   (SRID!=-1), LINETYPE,
	                   0);

	LWDEBUGF(3, "lwline_construct type=%d", result->type);

	result->SRID = SRID;
	result->points = points;
	result->bbox = bbox;

	return result;
}
Example #17
0
/*
 * convert this line into its serialize form writing it into
 * the given buffer, and returning number of bytes written into
 * the given int pointer.
 * result's first char will be the 8bit type.  See serialized form doc
 */
void
lwline_serialize_buf(LWLINE *line, uchar *buf, size_t *retsize)
{
	char hasSRID;
	uchar *loc;
	int ptsize;
	size_t size;

	LWDEBUGF(2, "lwline_serialize_buf(%p, %p, %p) called",
	         line, buf, retsize);

	if (line == NULL)
		lwerror("lwline_serialize:: given null line");

	if ( TYPE_GETZM(line->type) != TYPE_GETZM(line->points->dims) )
		lwerror("Dimensions mismatch in lwline");

	ptsize = pointArray_ptsize(line->points);

	hasSRID = (line->SRID != -1);

	buf[0] = (uchar) lwgeom_makeType_full(
	             TYPE_HASZ(line->type), TYPE_HASM(line->type),
	             hasSRID, LINETYPE, line->bbox ? 1 : 0);
	loc = buf+1;

	LWDEBUGF(3, "lwline_serialize_buf added type (%d)", line->type);

	if (line->bbox)
	{
		memcpy(loc, line->bbox, sizeof(BOX2DFLOAT4));
		loc += sizeof(BOX2DFLOAT4);

		LWDEBUG(3, "lwline_serialize_buf added BBOX");
	}

	if (hasSRID)
	{
		memcpy(loc, &line->SRID, sizeof(int32));
		loc += sizeof(int32);

		LWDEBUG(3, "lwline_serialize_buf added SRID");
	}

	memcpy(loc, &line->points->npoints, sizeof(uint32));
	loc += sizeof(uint32);

	LWDEBUGF(3, "lwline_serialize_buf added npoints (%d)",
	         line->points->npoints);

	/*copy in points */
	size = line->points->npoints*ptsize;
	memcpy(loc, getPoint_internal(line->points, 0), size);
	loc += size;

	LWDEBUGF(3, "lwline_serialize_buf copied serialized_pointlist (%d bytes)",
	         ptsize * line->points->npoints);

	if (retsize) *retsize = loc-buf;

	/*printBYTES((uchar *)result, loc-buf); */

	LWDEBUGF(3, "lwline_serialize_buf returning (loc: %p, size: %d)",
	         loc, loc-buf);
}
Example #18
0
Datum LWGEOM_pointn_linestring(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom;
	int32 wanted_index;
	LWGEOM_INSPECTED *inspected;
	LWLINE *line = NULL;
	LWCIRCSTRING *curve = NULL;
	LWGEOM *tmp = NULL;
	POINTARRAY *pts;
	LWPOINT *point;
	uchar *serializedpoint;
	PG_LWGEOM *result;
	int i, type;

	wanted_index = PG_GETARG_INT32(1);
	if ( wanted_index < 1 )
		PG_RETURN_NULL(); /* index out of range */

	geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	type = lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]);
	if (type == COMPOUNDTYPE || type == CURVEPOLYTYPE)
	{
		PG_FREE_IF_COPY(geom, 0);
		PG_RETURN_NULL();
	}
	else
	{
		inspected = lwgeom_inspect(SERIALIZED_FORM(geom));

		for (i=0; i<inspected->ngeometries; i++)
		{
			tmp = lwgeom_getgeom_inspected(inspected, i);
			if (lwgeom_getType(tmp->type) == LINETYPE ||
			        lwgeom_getType(tmp->type) == CIRCSTRINGTYPE)
				break;
		}

		if ( tmp == NULL )
		{
			lwinspected_release(inspected);
			PG_FREE_IF_COPY(geom, 0);
			PG_RETURN_NULL();
		}
		if (lwgeom_getType(tmp->type) == CIRCSTRINGTYPE)
		{
			curve = (LWCIRCSTRING *)tmp;
			if (wanted_index > curve->points->npoints)
			{
				lwinspected_release(inspected);
				PG_FREE_IF_COPY(geom, 0);
				lwgeom_release(tmp);
				PG_RETURN_NULL();
			}
			lwinspected_release(inspected);

			pts = pointArray_construct(getPoint_internal(
			                               curve->points,
			                               wanted_index-1),
			                           TYPE_HASZ(curve->type),
			                           TYPE_HASM(curve->type), 1);
		}
		else if (lwgeom_getType(tmp->type) == LINETYPE)
		{
			line = (LWLINE *)tmp;
			/* Ok, now we have a line. Let's see if it has enough points. */
			if ( wanted_index > line->points->npoints )
			{
				lwinspected_release(inspected);
				PG_FREE_IF_COPY(geom, 0);
				lwgeom_release(tmp);
				PG_RETURN_NULL();
			}
			lwinspected_release(inspected);

			/* Construct a point array */
			pts = pointArray_construct(getPoint_internal(line->points,
			                           wanted_index-1),
			                           TYPE_HASZ(line->type), TYPE_HASM(line->type), 1);
		}
		else
		{
			lwinspected_release(inspected);
			PG_FREE_IF_COPY(geom, 0);
			lwgeom_release(tmp);
			PG_RETURN_NULL();
		}
	}

	/* Construct an LWPOINT */
	point = lwpoint_construct(pglwgeom_getSRID(geom),
	                          NULL, pts);

	/* Serialized the point */
	serializedpoint = lwpoint_serialize(point);

	/* And we construct the line
	 * TODO: use serialize_buf above, instead ..
	 */
	result = PG_LWGEOM_construct(serializedpoint,
	                             pglwgeom_getSRID(geom), 0);

	pfree(point);
	pfree(serializedpoint);
	PG_FREE_IF_COPY(geom, 0);
	lwgeom_release(tmp);
	PG_RETURN_POINTER(result);
}
Example #19
0
/*
 * convert this circularstring into its serialized form writing it into
 * the given buffer, and returning number of bytes written into
 * the given int pointer.
 * result's first char will be the 8bit type.  See serialized form doc
 */
void lwcircstring_serialize_buf(LWCIRCSTRING *curve, uchar *buf, size_t *retsize)
{
	char hasSRID;
	uchar *loc;
	int ptsize;
	size_t size;

	LWDEBUGF(2, "lwcircstring_serialize_buf(%p, %p, %p) called",
	         curve, buf, retsize);

	if (curve == NULL)
	{
		lwerror("lwcircstring_serialize:: given null curve");
		return;
	}

	if (TYPE_GETZM(curve->type) != TYPE_GETZM(curve->points->dims))
	{
		lwerror("Dimensions mismatch in lwcircstring");
		return;
	}

	ptsize = pointArray_ptsize(curve->points);

	hasSRID = (curve->SRID != -1);

	buf[0] = (uchar)lwgeom_makeType_full(
	             TYPE_HASZ(curve->type), TYPE_HASM(curve->type),
	             hasSRID, CIRCSTRINGTYPE, curve->bbox ? 1 : 0);
	loc = buf+1;

	LWDEBUGF(3, "lwcircstring_serialize_buf added type (%d)", curve->type);

	if (curve->bbox)
	{
		memcpy(loc, curve->bbox, sizeof(BOX2DFLOAT4));
		loc += sizeof(BOX2DFLOAT4);

		LWDEBUG(3, "lwcircstring_serialize_buf added BBOX");
	}

	if (hasSRID)
	{
		memcpy(loc, &curve->SRID, sizeof(int32));
		loc += sizeof(int32);

		LWDEBUG(3, "lwcircstring_serialize_buf added SRID");
	}

	memcpy(loc, &curve->points->npoints, sizeof(uint32));
	loc += sizeof(uint32);

	LWDEBUGF(3, "lwcircstring_serialize_buf added npoints (%d)",
	         curve->points->npoints);

	/* copy in points */
	size = curve->points->npoints * ptsize;
	memcpy(loc, getPoint_internal(curve->points, 0), size);
	loc += size;

	LWDEBUGF(3, "lwcircstring_serialize_buf copied serialized_pointlist (%d bytes)",
	         ptsize * curve->points->npoints);

	if (retsize) *retsize = loc-buf;

	LWDEBUGF(3, "lwcircstring_serialize_buf returning (loc: %p, size: %d)",
	         loc, loc-buf);
}
Example #20
0
/*
 * given the LWGEOM serialized form (or a point into a multi* one)
 * construct a proper LWCIRCSTRING.
 * serialized_form should point to the 8bit type format (with type = 8)
 * See serialized form doc
 */
LWCIRCSTRING *
lwcircstring_deserialize(uchar *serialized_form)
{
	uchar type;
	LWCIRCSTRING *result;
	uchar *loc=NULL;
	uint32 npoints;
	POINTARRAY *pa;

	type = (uchar)serialized_form[0];
	if (lwgeom_getType(type) != CIRCSTRINGTYPE)
	{
		lwerror("lwcircstring_deserialize: attempt to deserialize a circularstring which is really a %s", lwgeom_typename(type));
		return NULL;
	}

	result = (LWCIRCSTRING*) lwalloc(sizeof(LWCIRCSTRING));
	result->type = type;

	loc = serialized_form + 1;

	if (lwgeom_hasBBOX(type))
	{
		LWDEBUG(3, "lwcircstring_deserialize: input has bbox");

		result->bbox = lwalloc(sizeof(BOX2DFLOAT4));
		memcpy(result->bbox, loc, sizeof(BOX2DFLOAT4));
		loc += sizeof(BOX2DFLOAT4);
	}
	else
	{
		LWDEBUG(3, "lwcircstring_deserialize: input lacks bbox");

		result->bbox = NULL;
	}

	if (lwgeom_hasSRID(type))
	{
		LWDEBUG(3, "lwcircstring_deserialize: input has srid");

		result->SRID = lw_get_int32(loc);
		loc += 4; /* type + SRID */
	}
	else
	{
		LWDEBUG(3, "lwcircstring_deserialize: input lacks srid");

		result->SRID = -1;
	}

	/* we've read the type (1 byte) and SRID (4 bytes, if present) */

	npoints = lw_get_uint32(loc);

	LWDEBUGF(3, "circstring npoints = %d", npoints);

	loc += 4;
	pa = pointArray_construct(loc, TYPE_HASZ(type), TYPE_HASM(type), npoints);
	result->points = pa;
	return result;
}