]> granicus.if.org Git - postgis/commitdiff
First implementation of #459. Still need unit tests and docs
authorOlivier Courtin <olivier.courtin@camptocamp.com>
Sat, 30 Apr 2011 22:26:18 +0000 (22:26 +0000)
committerOlivier Courtin <olivier.courtin@camptocamp.com>
Sat, 30 Apr 2011 22:26:18 +0000 (22:26 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@7077 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/liblwgeom.h
liblwgeom/lwout_gml.c
postgis/lwgeom_export.c

index 4b4f849fdb9b69bfeeb5c3c16464c06f379b95fb..f09b96f84905c66dfd1c28742e343bd2f0b20891 100644 (file)
@@ -1793,15 +1793,20 @@ extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
 #define LW_GML_IS_DEGREE   (1<<1)
 /** For GML3, use <LineString> rather than <Curve> 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);
index 98e4918f700bd2c410a7361a9518dbe9c0ba1e31..6246b2064d6b85b278cddd3cdd4e4307c989eba4 100644 (file)
@@ -5,7 +5,7 @@
  * http://postgis.refractions.net
  *
  * Copyright 2011 Sandro Santilli <strk@keybit.net>
- * 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("<Box><coordinates>/") + (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, "</%scoordinates></%sBox>", 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("<Envelope><lowerCorner><upperCorner>//") + (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, "</%slowerCorner>", 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, "</%supperCorner>", prefix);
+
+       ptr += sprintf(ptr, "</%sEnvelope>", 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;
 }
index baf948589ed267a774112ab8f10a891b2cb9b1c5..e5e8b97a0903b10322e59701c9452dc756043d19 100644 (file)
@@ -2,7 +2,7 @@
  * $Id:$\r
  *\r
  * PostGIS - Export functions for PostgreSQL/PostGIS\r
- * Copyright 2009-2010 Olivier Courtin <olivier.courtin@oslandia.com>\r
+ * Copyright 2009-2011 Olivier Courtin <olivier.courtin@oslandia.com>\r
  *\r
  * This is free software; you can redistribute and/or modify it under\r
  * the terms of the GNU General Public Licence. See the COPYING file.\r
@@ -166,12 +166,17 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
        if (option & 2)  lwopts &= ~LW_GML_IS_DIMS; \r
        if (option & 4)  lwopts |= LW_GML_SHORTLINE;\r
        if (option & 16) lwopts |= LW_GML_IS_DEGREE;\r
+        if (option & 32) lwopts |= LW_GML_EXTENT;\r
 \r
        lwgeom = pglwgeom_deserialize(geom);\r
 \r
-       if (version == 2)\r
+             if (version == 2 && lwopts & LW_GML_EXTENT)\r
+               gml = lwgeom_extent_to_gml2(lwgeom, srs, precision, prefix);\r
+       else if (version == 2)\r
                gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix);\r
-       else\r
+        else if (version == 3 && lwopts & LW_GML_EXTENT)\r
+               gml = lwgeom_extent_to_gml3(lwgeom, srs, precision, lwopts, prefix);\r
+       else if (version == 3)\r
                gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix);\r
 \r
        lwgeom_free(lwgeom);\r