예제 #1
0
/*
 * Construct a LWCIRCSTRING from a LWMPOINT
 */
LWCIRCSTRING *
lwcircstring_from_lwmpoint(int SRID, LWMPOINT *mpoint)
{
	unsigned int i;
	POINTARRAY *pa;
	char zmflag = TYPE_GETZM(mpoint->type);
	size_t ptsize, size;
	uchar *newpoints, *ptr;

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

	/* Allocate space for output points */
	size = ptsize * mpoint->ngeoms;
	newpoints = lwalloc(size);
	memset(newpoints, 0, size);

	ptr = newpoints;
	for (i = 0; i < mpoint->ngeoms; i++)
	{
		memcpy(ptr,
		       getPoint_internal(mpoint->geoms[i]->point, 0),
		       ptsize);
		ptr += ptsize;
	}

	pa = pointArray_construct(newpoints, zmflag&2, zmflag&1,
	                          mpoint->ngeoms);

	LWDEBUGF(3, "lwcurve_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag);

	return lwcircstring_construct(SRID, NULL, pa);
}
예제 #2
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);
}
예제 #3
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;
}
예제 #4
0
파일: lwline.c 프로젝트: Vlczech/vtapi
/*
 * 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;
}
예제 #5
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);
}
예제 #6
0
파일: lwline.c 프로젝트: Vlczech/vtapi
/*
 * 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);
}
예제 #7
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);
}
예제 #8
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;
}
예제 #9
0
Datum BOX2DFLOAT4_to_LWGEOM(PG_FUNCTION_ARGS)
{
	BOX2DFLOAT4 *box = (BOX2DFLOAT4 *)PG_GETARG_POINTER(0);
	POINTARRAY *pa;
	int wantbbox = 0;
	PG_LWGEOM *result;
	uchar *ser;


	/*
	 * Alter BOX2D cast so that a valid geometry is always
	 * returned depending upon the size of the BOX2D. The
	 * code makes the following assumptions:
	 *     - If the BOX2D is a single point then return a
	 *     POINT geometry
	 *     - If the BOX2D represents either a horizontal or
	 *     vertical line, return a LINESTRING geometry
	 *     - Otherwise return a POLYGON
	 */

	if (box->xmin == box->xmax &&
	        box->ymin == box->ymax)
	{
		/* Construct and serialize point */
		LWPOINT *point = make_lwpoint2d(-1, box->xmin, box->ymin);
		ser = lwpoint_serialize(point);
	}
	else if (box->xmin == box->xmax ||
	         box->ymin == box->ymax)
	{
		LWLINE *line;
		POINT2D *pts = palloc(sizeof(POINT2D)*2);

		/* Assign coordinates to POINT2D array */
		pts[0].x = box->xmin;
		pts[0].y = box->ymin;
		pts[1].x = box->xmax;
		pts[1].y = box->ymax;

		/* Construct point array */
		pa = pointArray_construct((uchar *)pts, 0, 0, 2);

		/* Construct and serialize linestring */
		line = lwline_construct(-1, NULL, pa);
		ser = lwline_serialize(line);
	}
	else
	{
		LWPOLY *poly;
		POINT2D *pts = palloc(sizeof(POINT2D)*5);

		/* Assign coordinates to POINT2D array */
		pts[0].x = box->xmin;
		pts[0].y = box->ymin;
		pts[1].x = box->xmin;
		pts[1].y = box->ymax;
		pts[2].x = box->xmax;
		pts[2].y = box->ymax;
		pts[3].x = box->xmax;
		pts[3].y = box->ymin;
		pts[4].x = box->xmin;
		pts[4].y = box->ymin;

		/* Construct point array */
		pa = pointArray_construct((uchar *)pts, 0, 0, 5);

		/* Construct polygon */
		poly = lwpoly_construct(-1, NULL, 1, &pa);

		/* Serialize polygon */
		ser = lwpoly_serialize(poly);
	}

	/* Construct PG_LWGEOM  */
	result = PG_LWGEOM_construct(ser, -1, wantbbox);

	PG_RETURN_POINTER(result);
}