From: Olivier Courtin Date: Sat, 30 Apr 2011 22:26:18 +0000 (+0000) Subject: First implementation of #459. Still need unit tests and docs X-Git-Tag: 2.0.0alpha1~1730 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3a2e168d32978c0d6a4838ebbc31974cb12ee638;p=postgis First implementation of #459. Still need unit tests and docs git-svn-id: http://svn.osgeo.org/postgis/trunk@7077 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index 4b4f849fd..f09b96f84 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -1793,15 +1793,20 @@ extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist); #define LW_GML_IS_DEGREE (1<<1) /** For GML3, use rather than for lines */ #define LW_GML_SHORTLINE (1<<2) +/** For GML2 and GML3, output only extent of geometry */ +#define LW_GML_EXTENT (1<<4) + #define IS_DIMS(x) ((x) & LW_GML_IS_DIMS) #define IS_DEGREE(x) ((x) & LW_GML_IS_DEGREE) /** @} */ extern char* lwgeom_to_gml2(const LWGEOM *geom, char *srs, int precision, const char *prefix); +extern char* lwgeom_extent_to_gml2(const LWGEOM *geom, char *srs, int precision, const char *prefix); /** * @param opts output options bitfield, see LW_GML macros for meaning */ +extern char* lwgeom_extent_to_gml3(const LWGEOM *geom, char *srs, int precision, int opts, const char *prefix); extern char* lwgeom_to_gml3(const LWGEOM *geom, char *srs, int precision, int opts, const char *prefix); extern char* lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix); extern char* lwgeom_to_geojson(const LWGEOM *geo, char *srs, int precision, int has_bbox); diff --git a/liblwgeom/lwout_gml.c b/liblwgeom/lwout_gml.c index 98e4918f7..6246b2064 100644 --- a/liblwgeom/lwout_gml.c +++ b/liblwgeom/lwout_gml.c @@ -5,7 +5,7 @@ * http://postgis.refractions.net * * Copyright 2011 Sandro Santilli - * Copyright 2010 Oslandia + * Copyright 2010-2011 Oslandia * Copyright 2001-2003 Refractions Research Inc. * * This is free software; you can redistribute and/or modify it under @@ -56,6 +56,125 @@ static size_t pointArray_GMLsize(POINTARRAY *pa, int precision); +extern char * +lwgeom_extent_to_gml2(const LWGEOM *geom, char *srs, int precision, const char *prefix) +{ + int size; + POINT4D pt; + POINTARRAY *pa; + char *ptr, *output; + size_t prefixlen = strlen(prefix); + + switch (geom->type) + { + case POINTTYPE: + case LINETYPE: + case POLYGONTYPE: + case MULTIPOINTTYPE: + case MULTILINETYPE: + case MULTIPOLYGONTYPE: + case COLLECTIONTYPE: + break; + + default: + lwerror("lwgeom_extent_to_gml2: '%s' geometry type not supported", lwtype_name(geom->type)); + return NULL; + } + + pa = ptarray_construct_empty(FLAGS_GET_Z(geom->flags), 0, 2); + + pt.x = geom->bbox->xmin; + pt.y = geom->bbox->ymin; + if (FLAGS_GET_Z(geom->flags)) pt.z = geom->bbox->zmin; + ptarray_append_point(pa, &pt, REPEATED_POINTS_OK); + + pt.x = geom->bbox->xmax; + pt.y = geom->bbox->ymax; + if (FLAGS_GET_Z(geom->flags)) pt.z = geom->bbox->zmax; + ptarray_append_point(pa, &pt, REPEATED_POINTS_OK); + + size = pointArray_GMLsize(pa, precision); + size += ( sizeof("/") + (prefixlen*2) ) * 2; + if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); + + ptr = output = lwalloc(size); + + if ( srs ) ptr += sprintf(ptr, "<%sBox srsName=\"%s\">", prefix, srs); + else ptr += sprintf(ptr, "<%sBox>", prefix); + + ptr += sprintf(ptr, "<%scoordinates>", prefix); + ptr += pointArray_toGML2(pa, ptr, precision); + ptr += sprintf(ptr, "", prefix, prefix); + + ptarray_free(pa); + + return output; +} + + +extern char * +lwgeom_extent_to_gml3(const LWGEOM *geom, char *srs, int precision, int opts, const char *prefix) +{ + int size; + POINT4D pt; + POINTARRAY *pa; + char *ptr, *output; + size_t prefixlen = strlen(prefix); + + switch (geom->type) + { + case POINTTYPE: + case LINETYPE: + case POLYGONTYPE: + case MULTIPOINTTYPE: + case MULTILINETYPE: + case MULTIPOLYGONTYPE: + case COLLECTIONTYPE: + break; + + default: + lwerror("lwgeom_extent_to_gml3: '%s' geometry type not supported", lwtype_name(geom->type)); + return NULL; + } + + pa = ptarray_construct_empty(FLAGS_GET_Z(geom->flags), 0, 1); + + pt.x = geom->bbox->xmin; + pt.y = geom->bbox->ymin; + if (FLAGS_GET_Z(geom->flags)) pt.z = geom->bbox->zmin; + ptarray_append_point(pa, &pt, REPEATED_POINTS_OK); + + size = pointArray_GMLsize(pa, precision) * 2; + size += ( sizeof("//") + (prefixlen*3) ) * 2; + if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); + + ptr = output = lwalloc(size); + + if ( srs ) ptr += sprintf(ptr, "<%sEnvelope srsName=\"%s\">", prefix, srs); + else ptr += sprintf(ptr, "<%sEnvelope>", prefix); + + ptr += sprintf(ptr, "<%slowerCorner>", prefix); + ptr += pointArray_toGML3(pa, ptr, precision, opts); + ptr += sprintf(ptr, "", prefix); + + ptarray_remove_point(pa, 0); + pt.x = geom->bbox->xmax; + pt.y = geom->bbox->ymax; + if (FLAGS_GET_Z(geom->flags)) pt.z = geom->bbox->zmax; + ptarray_append_point(pa, &pt, REPEATED_POINTS_OK); + + ptr += sprintf(ptr, "<%supperCorner>", prefix); + ptr += pointArray_toGML3(pa, ptr, precision, opts); + ptr += sprintf(ptr, "", prefix); + + ptr += sprintf(ptr, "", prefix); + + ptarray_free(pa); + + return output; +} + + /** * @brief VERSION GML 2 * takes a GEOMETRY and returns a GML2 representation @@ -1290,8 +1409,7 @@ static size_t pointArray_GMLsize(POINTARRAY *pa, int precision) { if (FLAGS_NDIMS(pa->flags) == 2) - return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", ")) - * 2 * pa->npoints; + return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 2 * pa->npoints; return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints; } diff --git a/postgis/lwgeom_export.c b/postgis/lwgeom_export.c index baf948589..e5e8b97a0 100644 --- a/postgis/lwgeom_export.c +++ b/postgis/lwgeom_export.c @@ -2,7 +2,7 @@ * $Id:$ * * PostGIS - Export functions for PostgreSQL/PostGIS - * Copyright 2009-2010 Olivier Courtin + * Copyright 2009-2011 Olivier Courtin * * This is free software; you can redistribute and/or modify it under * the terms of the GNU General Public Licence. See the COPYING file. @@ -166,12 +166,17 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS) if (option & 2) lwopts &= ~LW_GML_IS_DIMS; if (option & 4) lwopts |= LW_GML_SHORTLINE; if (option & 16) lwopts |= LW_GML_IS_DEGREE; + if (option & 32) lwopts |= LW_GML_EXTENT; lwgeom = pglwgeom_deserialize(geom); - if (version == 2) + if (version == 2 && lwopts & LW_GML_EXTENT) + gml = lwgeom_extent_to_gml2(lwgeom, srs, precision, prefix); + else if (version == 2) gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix); - else + else if (version == 3 && lwopts & LW_GML_EXTENT) + gml = lwgeom_extent_to_gml3(lwgeom, srs, precision, lwopts, prefix); + else if (version == 3) gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix); lwgeom_free(lwgeom);