Esempio n. 1
0
Datum ST_AddMeasure(PG_FUNCTION_ARGS)
{
	GSERIALIZED *gin = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	GSERIALIZED *gout;
	double start_measure = PG_GETARG_FLOAT8(1);
	double end_measure = PG_GETARG_FLOAT8(2);
	LWGEOM *lwin, *lwout;
	int type = gserialized_get_type(gin);

	/* Raise an error if input is not a linestring or multilinestring */
	if ( type != LINETYPE && type != MULTILINETYPE )
	{
		lwerror("Only LINESTRING and MULTILINESTRING are supported");
		PG_RETURN_NULL();
	}

	lwin = lwgeom_from_gserialized(gin);
	if ( type == LINETYPE )
		lwout = (LWGEOM*)lwline_measured_from_lwline((LWLINE*)lwin, start_measure, end_measure);
	else
		lwout = (LWGEOM*)lwmline_measured_from_lwmline((LWMLINE*)lwin, start_measure, end_measure);

	lwgeom_release(lwin);

	if ( lwout == NULL )
		PG_RETURN_NULL();

	gout = geometry_serialize(lwout);
	lwgeom_release(lwout);

	PG_RETURN_POINTER(gout);
}
Esempio n. 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);
}
Esempio n. 3
0
Datum LWGEOM_locate_between_m(PG_FUNCTION_ARGS)
{
	GSERIALIZED *gin = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	GSERIALIZED *gout;
	double start_measure = PG_GETARG_FLOAT8(1);
	double end_measure = PG_GETARG_FLOAT8(2);
	LWGEOM *lwin, *lwout;
	int hasz = gserialized_has_z(gin);
	int hasm = gserialized_has_m(gin);
	int type;

	if ( end_measure < start_measure )
	{
		lwerror("locate_between_m: 2nd arg must be bigger then 1st arg");
		PG_RETURN_NULL();
	}
	
	/*
	 * Return error if input doesn't have a measure
	 */
	if ( ! hasm )
	{
		lwerror("Geometry argument does not have an 'M' ordinate");
		PG_RETURN_NULL();
	}

	/*
	 * Raise an error if input is a polygon, a multipolygon
	 * or a collection
	 */
	type = gserialized_get_type(gin);

	if ( type == POLYGONTYPE || type == MULTIPOLYGONTYPE || type == COLLECTIONTYPE )
	{
		lwerror("Areal or Collection types are not supported");
		PG_RETURN_NULL();
	}

	lwin = lwgeom_from_gserialized(gin);

	lwout = lwgeom_locate_between_m(lwin,
	                                start_measure, end_measure);

	lwgeom_release(lwin);

	if ( lwout == NULL )
	{
		lwout = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, 
		            gserialized_get_srid(gin), hasz, hasm);
	}

	gout = geometry_serialize(lwout);
	lwgeom_release(lwout);

	PG_RETURN_POINTER(gout);
}
Esempio n. 4
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);
}
Esempio n. 5
0
Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	LWPOLY *poly = NULL;
	LWCURVEPOLY *curvepoly = NULL;
	POINTARRAY *extring;
	LWGEOM *ring;
	LWLINE *line;
	PG_LWGEOM *result;
	BOX2DFLOAT4 *bbox=NULL;

	POSTGIS_DEBUG(2, "LWGEOM_exteriorring_polygon called.");

	if ( TYPE_GETTYPE(geom->type) != POLYGONTYPE &&
	        TYPE_GETTYPE(geom->type) != CURVEPOLYTYPE)
	{
		elog(ERROR, "ExteriorRing: geom is not a polygon");
		PG_RETURN_NULL();
	}
	if (lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]) == POLYGONTYPE)
	{
		poly = lwpoly_deserialize(SERIALIZED_FORM(geom));

		/* Ok, now we have a polygon. Here is its exterior ring. */
		extring = poly->rings[0];

		/*
		* This is a LWLINE constructed by exterior ring POINTARRAY
		* If the input geom has a bbox, use it for
		* the output geom, as exterior ring makes it up !
		*/
		if ( poly->bbox ) bbox=box2d_clone(poly->bbox);
		line = lwline_construct(poly->SRID, bbox, extring);

		result = pglwgeom_serialize((LWGEOM *)line);

		lwgeom_release((LWGEOM *)line);
		lwgeom_release((LWGEOM *)poly);
	}
	else
	{
		curvepoly = lwcurvepoly_deserialize(SERIALIZED_FORM(geom));
		ring = curvepoly->rings[0];
		result = pglwgeom_serialize(ring);
		lwgeom_release(ring);
	}

	PG_FREE_IF_COPY(geom, 0);


	PG_RETURN_POINTER(result);
}
Esempio n. 6
0
Datum LWGEOM_from_text(PG_FUNCTION_ARGS)
{
	text *wkttext = PG_GETARG_TEXT_P(0);
	char *wkt, fc;
	size_t size;
	LWGEOM_PARSER_RESULT lwg_parser_result;
	PG_LWGEOM *geom_result = NULL;
	LWGEOM *lwgeom;
	int result;

	POSTGIS_DEBUG(2, "LWGEOM_from_text");

	size = VARSIZE(wkttext)-VARHDRSZ;

	POSTGIS_DEBUGF(3, "size: %d", (int)size);

	if ( size < 10 )
	{
		lwerror("Invalid OGC WKT (too short)");
		PG_RETURN_NULL();
	}

	fc=*(VARDATA(wkttext));

	wkt = lwalloc(size+1);
	memcpy(wkt, VARDATA(wkttext), size);
	wkt[size]='\0';

	POSTGIS_DEBUGF(3, "wkt: [%s]", wkt);

	result = serialized_lwgeom_from_ewkt(&lwg_parser_result, wkt, PARSER_CHECK_ALL);
	if (result)
		PG_PARSER_ERROR(lwg_parser_result);

	lwgeom = lwgeom_deserialize(lwg_parser_result.serialized_lwgeom);

	if ( lwgeom->SRID != -1 || TYPE_GETZM(lwgeom->type) != 0 )
	{
		elog(WARNING, "OGC WKT expected, EWKT provided - use GeomFromEWKT() for this");
	}

	/* read user-requested SRID if any */
	if ( PG_NARGS() > 1 ) lwgeom->SRID = PG_GETARG_INT32(1);

	geom_result = pglwgeom_serialize(lwgeom);
	lwgeom_release(lwgeom);

	PG_RETURN_POINTER(geom_result);
}
Esempio n. 7
0
Datum LWGEOM_geometryn_collection(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	PG_LWGEOM *result;
	int type = lwgeom_getType(geom->type);
	int32 idx;
	LWCOLLECTION *coll;
	LWGEOM *subgeom;

	POSTGIS_DEBUG(2, "LWGEOM_geometryn_collection called.");

	/* elog(NOTICE, "GeometryN called"); */

	/* call is valid on multi* geoms only */
	if (type==POINTTYPE || type==LINETYPE || type==CIRCSTRINGTYPE ||
	        type==COMPOUNDTYPE || type==POLYGONTYPE || type==CURVEPOLYTYPE)
	{
		/* elog(NOTICE, "geometryn: geom is of type %d, requires >=4", type); */
		PG_RETURN_NULL();
	}

	idx = PG_GETARG_INT32(1);
	idx -= 1; /* index is 1-based */

	coll = (LWCOLLECTION *)lwgeom_deserialize(SERIALIZED_FORM(geom));

	if ( idx < 0 ) PG_RETURN_NULL();
	if ( idx >= coll->ngeoms ) PG_RETURN_NULL();

	subgeom = coll->geoms[idx];
	subgeom->SRID = coll->SRID;

	/* COMPUTE_BBOX==TAINTING */
	if ( coll->bbox ) lwgeom_add_bbox(subgeom);

	result = pglwgeom_serialize(subgeom);

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

	PG_RETURN_POINTER(result);

}
Esempio n. 8
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);
}
Esempio n. 9
0
Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom;
	int32 wanted_index;
	LWCURVEPOLY *curvepoly = NULL;
	LWPOLY *poly = NULL;
	POINTARRAY *ring;
	LWLINE *line;
	PG_LWGEOM *result;
	BOX2DFLOAT4 *bbox = NULL;

	POSTGIS_DEBUG(2, "LWGEOM_interierringn_polygon called.");

	wanted_index = PG_GETARG_INT32(1);
	if ( wanted_index < 1 )
	{
		/* elog(ERROR, "InteriorRingN: ring number is 1-based"); */
		PG_RETURN_NULL(); /* index out of range */
	}

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

	if ( TYPE_GETTYPE(geom->type) != POLYGONTYPE &&
	        TYPE_GETTYPE(geom->type) != CURVEPOLYTYPE )
	{
		PG_FREE_IF_COPY(geom, 0);
		elog(ERROR, "InteriorRingN: geom is not a polygon");
		PG_RETURN_NULL();
	}
	if ( TYPE_GETTYPE(geom->type) == POLYGONTYPE)
	{
		poly = lwpoly_deserialize(SERIALIZED_FORM(geom));

		/* Ok, now we have a polygon. Let's see if it has enough holes */
		if ( wanted_index >= poly->nrings )
		{
			PG_FREE_IF_COPY(geom, 0);
			lwgeom_release((LWGEOM *)poly);
			PG_RETURN_NULL();
		}

		ring = poly->rings[wanted_index];

		/* COMPUTE_BBOX==TAINTING */
		if ( poly->bbox ) bbox = ptarray_compute_box2d(ring);

		/* This is a LWLINE constructed by interior ring POINTARRAY */
		line = lwline_construct(poly->SRID, bbox, ring);

		/* Copy SRID from polygon */
		line->SRID = poly->SRID;

		result = pglwgeom_serialize((LWGEOM *)line);
		lwgeom_release((LWGEOM *)line);
		lwgeom_release((LWGEOM *)poly);
	}
	else
	{
		curvepoly = lwcurvepoly_deserialize(SERIALIZED_FORM(geom));

		if (wanted_index >= curvepoly->nrings)
		{
			PG_FREE_IF_COPY(geom, 0);
			lwgeom_release((LWGEOM *)curvepoly);
			PG_RETURN_NULL();
		}

		result = pglwgeom_serialize(curvepoly->rings[wanted_index]);
		lwgeom_release((LWGEOM *)curvepoly);
	}


	PG_FREE_IF_COPY(geom, 0);

	PG_RETURN_POINTER(result);
}
Esempio n. 10
0
Datum LWGEOM_numinteriorrings_polygon(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	LWGEOM_INSPECTED *inspected = NULL;
	LWGEOM *tmp = NULL;
	LWPOLY *poly = NULL;
	LWCURVEPOLY *curvepoly = NULL;
	int32 result;
	int i;

	POSTGIS_DEBUG(2, "LWGEOM_numinteriorrings called.");

	if (lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]) == CURVEPOLYTYPE)
	{
		tmp = (LWGEOM *)lwcurvepoly_deserialize(SERIALIZED_FORM(geom));
	}
	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) == POLYGONTYPE ||
			        lwgeom_getType(tmp->type) == CURVEPOLYTYPE) break;
		}
	}

	if ( tmp == NULL )
	{
		PG_FREE_IF_COPY(geom, 0);
		lwinspected_release(inspected);
		PG_RETURN_NULL();
	}

	POSTGIS_DEBUGF(3, "Geometry of type %d found.", lwgeom_getType(tmp->type));

	if (lwgeom_getType(tmp->type) == POLYGONTYPE)
	{
		poly = (LWPOLY *)tmp;

		/* Ok, now we have a polygon. Here is its number of holes */
		result = poly->nrings-1;
	}
	else if (lwgeom_getType(tmp->type) == CURVEPOLYTYPE)
	{
		POSTGIS_DEBUG(3, "CurvePolygon found.");

		curvepoly = (LWCURVEPOLY *)tmp;
		result = curvepoly->nrings-1;
	}
	else
	{
		PG_FREE_IF_COPY(geom, 0);
		lwinspected_release(inspected);
		PG_RETURN_NULL();
	}
	PG_FREE_IF_COPY(geom, 0);
	if (inspected != NULL) lwinspected_release(inspected);
	lwgeom_release((LWGEOM *)tmp);

	PG_RETURN_INT32(result);
}
Esempio n. 11
0
Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom;
	int32 wanted_index;
	LWCURVEPOLY *curvepoly = NULL;
	LWPOLY *poly = NULL;
	POINTARRAY *ring;
	LWLINE *line;
	LWGEOM *lwgeom;
	GSERIALIZED *result;
	GBOX *bbox = NULL;
	int type;

	POSTGIS_DEBUG(2, "LWGEOM_interierringn_polygon called.");

	wanted_index = PG_GETARG_INT32(1);
	if ( wanted_index < 1 )
	{
		/* elog(ERROR, "InteriorRingN: ring number is 1-based"); */
		PG_RETURN_NULL(); /* index out of range */
	}

	geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	type = gserialized_get_type(geom);

	if ( (type != POLYGONTYPE) && (type != CURVEPOLYTYPE) )
	{
		elog(ERROR, "InteriorRingN: geom is not a polygon");
		PG_FREE_IF_COPY(geom, 0);
		PG_RETURN_NULL();
	}
	
	lwgeom = lwgeom_from_gserialized(geom);
	if( lwgeom_is_empty(lwgeom) )
	{
		lwpoly_free(poly);
		PG_FREE_IF_COPY(geom, 0);
		PG_RETURN_NULL();
	}
	
	if ( type == POLYGONTYPE)
	{
		poly = lwgeom_as_lwpoly(lwgeom_from_gserialized(geom));

		/* Ok, now we have a polygon. Let's see if it has enough holes */
		if ( wanted_index >= poly->nrings )
		{
			lwpoly_free(poly);
			PG_FREE_IF_COPY(geom, 0);
			PG_RETURN_NULL();
		}

		ring = poly->rings[wanted_index];

		/* COMPUTE_BBOX==TAINTING */
		if ( poly->bbox ) 
		{
			bbox = lwalloc(sizeof(GBOX));
			ptarray_calculate_gbox_cartesian(ring, bbox);
		}

		/* This is a LWLINE constructed by interior ring POINTARRAY */
		line = lwline_construct(poly->srid, bbox, ring);


		result = geometry_serialize((LWGEOM *)line);
		lwline_release(line);
		lwpoly_free(poly);
	}
	else
	{
		curvepoly = lwgeom_as_lwcurvepoly(lwgeom_from_gserialized(geom));

		if (wanted_index >= curvepoly->nrings)
		{
			PG_FREE_IF_COPY(geom, 0);
			lwgeom_release((LWGEOM *)curvepoly);
			PG_RETURN_NULL();
		}

		result = geometry_serialize(curvepoly->rings[wanted_index]);
		lwgeom_free((LWGEOM*)curvepoly);
	}

	PG_FREE_IF_COPY(geom, 0);
	PG_RETURN_POINTER(result);
}
Esempio n. 12
0
void
lwmpoint_release(LWMPOINT *lwmpoint)
{
	lwgeom_release(lwmpoint_as_lwgeom(lwmpoint));
}
Esempio n. 13
0
void
lwcollection_release(LWCOLLECTION *lwcollection)
{
	lwgeom_release(lwcollection_as_lwgeom(lwcollection));
}
Esempio n. 14
0
void
lwcircstring_release(LWCIRCSTRING *lwcirc)
{
	lwgeom_release(lwcircstring_as_lwgeom(lwcirc));
}
Esempio n. 15
0
Datum geom_from_kml(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom;
	LWGEOM *lwgeom, *hlwgeom;
	xmlDocPtr xmldoc;
	text *xml_input;
	int xml_size;
	char *xml;
	bool hasz=true;
	xmlNodePtr xmlroot=NULL;


	/* Get the KML stream */
	if (PG_ARGISNULL(0)) PG_RETURN_NULL();
	xml_input = PG_GETARG_TEXT_P(0);
	xml = text2cstring(xml_input);
	xml_size = VARSIZE(xml_input) - VARHDRSZ;

	/* Begin to Parse XML doc */
	xmlInitParser();
	xmldoc = xmlParseMemory(xml, xml_size);
	if (!xmldoc || (xmlroot = xmlDocGetRootElement(xmldoc)) == NULL)
	{
		xmlFreeDoc(xmldoc);
		xmlCleanupParser();
		lwerror("invalid KML representation");
	}

	lwgeom = parse_kml(xmlroot, &hasz);

	/* Homogenize geometry result if needed */
	if (lwgeom->type == COLLECTIONTYPE)
	{
		hlwgeom = lwgeom_homogenize(lwgeom);
		lwgeom_release(lwgeom);
		lwgeom = hlwgeom;
	}

	lwgeom_add_bbox(lwgeom);

	/* KML geometries could be either 2 or 3D
	 *
	 * So we deal with 3D in all structures allocation, and flag hasz
	 * to false if we met once a missing Z dimension
	 * In this case, we force recursive 2D.
	 */
	if (!hasz)
	{
		LWGEOM *tmp = lwgeom_force_2d(lwgeom);
		lwgeom_free(lwgeom);
		lwgeom = tmp;
	}

	geom = geometry_serialize(lwgeom);
	lwgeom_free(lwgeom);

	xmlFreeDoc(xmldoc);
	xmlCleanupParser();

	PG_RETURN_POINTER(geom);
}
Esempio n. 16
0
void
lwtriangle_release(LWTRIANGLE *lwtriangle)
{
	lwgeom_release(lwtriangle_as_lwgeom(lwtriangle));
}
Esempio n. 17
0
void
lwpoly_release(LWPOLY *lwpoly)
{
	lwgeom_release(lwpoly_as_lwgeom(lwpoly));
}
Esempio n. 18
0
Datum LWGEOM_isclosed_linestring(PG_FUNCTION_ARGS)
{
	PG_LWGEOM *geom;
	LWGEOM_INSPECTED *inspected;
	LWGEOM *sub = NULL;
	LWCOMPOUND *compound = NULL;
	int linesfound=0;
	int i;

	POSTGIS_DEBUG(2, "LWGEOM_isclosed_linestring called.");

	geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	if (lwgeom_getType((uchar)SERIALIZED_FORM(geom)[0]) == COMPOUNDTYPE)
	{
		compound = lwcompound_deserialize(SERIALIZED_FORM(geom));
		if (compound_is_closed(compound))
		{
			lwgeom_release((LWGEOM *)compound);
			PG_FREE_IF_COPY(geom, 0);
			PG_RETURN_BOOL(TRUE);
		}
		else
		{
			lwgeom_release((LWGEOM *)compound);
			PG_FREE_IF_COPY(geom, 0);
			PG_RETURN_BOOL(FALSE);
		}
	}

	inspected = lwgeom_inspect(SERIALIZED_FORM(geom));

	for (i=0; i<inspected->ngeometries; i++)
	{
		sub = lwgeom_getgeom_inspected(inspected, i);
		if ( sub == NULL ) continue;
		else if (lwgeom_getType(sub->type) == LINETYPE &&
		         !line_is_closed((LWLINE *)sub))
		{
			lwgeom_release(sub);
			lwinspected_release(inspected);
			PG_FREE_IF_COPY(geom, 0);
			PG_RETURN_BOOL(FALSE);
		}
		else if (lwgeom_getType(sub->type) == CIRCSTRINGTYPE &&
		         !circstring_is_closed((LWCIRCSTRING *)sub))
		{
			lwgeom_release(sub);
			lwinspected_release(inspected);
			PG_FREE_IF_COPY(geom, 0);
			PG_RETURN_BOOL(FALSE);
		}
		else if (lwgeom_getType(sub->type) == COMPOUNDTYPE &&
		         !compound_is_closed((LWCOMPOUND *)sub))
		{
			lwgeom_release(sub);
			lwinspected_release(inspected);
			PG_FREE_IF_COPY(geom, 0);
			PG_RETURN_BOOL(FALSE);
		}
		lwgeom_release(sub);
		linesfound++;
	}
	lwinspected_release(inspected);

	if ( ! linesfound )
	{
		PG_FREE_IF_COPY(geom, 0);
		PG_RETURN_NULL();
	}
	PG_FREE_IF_COPY(geom, 0);
	PG_RETURN_BOOL(TRUE);

}
Esempio n. 19
0
void
lwmline_release(LWMLINE *lwmline)
{
	lwgeom_release(lwmline_as_lwgeom(lwmline));
}
Esempio n. 20
0
Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	GSERIALIZED *result;
	POINTARRAY *extring;
	LWGEOM *lwgeom;
	LWLINE *line;
	GBOX *bbox=NULL;
	int type = gserialized_get_type(geom);

	POSTGIS_DEBUG(2, "LWGEOM_exteriorring_polygon called.");

	if ( (type != POLYGONTYPE) &&
	     (type != CURVEPOLYTYPE) &&
	     (type != TRIANGLETYPE))
	{
		elog(ERROR, "ExteriorRing: geom is not a polygon");
		PG_RETURN_NULL();
	}
	
	lwgeom = lwgeom_from_gserialized(geom);
	
	if( lwgeom_is_empty(lwgeom) )
	{
		line = lwline_construct_empty(lwgeom->srid,
		                              lwgeom_has_z(lwgeom),
		                              lwgeom_has_m(lwgeom));
		result = geometry_serialize(lwline_as_lwgeom(line));
	}
	else if ( lwgeom->type == POLYGONTYPE )
	{
		LWPOLY *poly = lwgeom_as_lwpoly(lwgeom);

		/* Ok, now we have a polygon. Here is its exterior ring. */
		extring = poly->rings[0];

		/*
		* This is a LWLINE constructed by exterior ring POINTARRAY
		* If the input geom has a bbox, use it for
		* the output geom, as exterior ring makes it up !
		*/
		if ( poly->bbox ) 
			bbox = gbox_copy(poly->bbox);

		line = lwline_construct(poly->srid, bbox, extring);
		result = geometry_serialize((LWGEOM *)line);

		lwgeom_release((LWGEOM *)line);
	}
	else if ( lwgeom->type == TRIANGLETYPE )
	{
		LWTRIANGLE *triangle = lwgeom_as_lwtriangle(lwgeom);

		/*
		* This is a LWLINE constructed by exterior ring POINTARRAY
		* If the input geom has a bbox, use it for
		* the output geom, as exterior ring makes it up !
		*/
		if ( triangle->bbox ) 
			bbox = gbox_copy(triangle->bbox);
		line = lwline_construct(triangle->srid, bbox, triangle->points);

		result = geometry_serialize((LWGEOM *)line);

		lwgeom_release((LWGEOM *)line);
	}
	else
	{
		LWCURVEPOLY *curvepoly = lwgeom_as_lwcurvepoly(lwgeom);
		result = geometry_serialize(curvepoly->rings[0]);
	}

	lwgeom_free(lwgeom);
	PG_FREE_IF_COPY(geom, 0);
	PG_RETURN_POINTER(result);
}