]> granicus.if.org Git - postgis/commitdiff
First implementation of gml:id support for ST_AsGML. Related to #1823. Not yet really...
authorOlivier Courtin <olivier.courtin@camptocamp.com>
Mon, 21 May 2012 21:17:59 +0000 (21:17 +0000)
committerOlivier Courtin <olivier.courtin@camptocamp.com>
Mon, 21 May 2012 21:17:59 +0000 (21:17 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@9772 b70326c6-7e19-0410-871a-916f4a2858ee

doc/reference_output.xml
liblwgeom/liblwgeom.h.in
liblwgeom/lwout_gml.c
postgis/geography_inout.c
postgis/lwgeom_export.c
postgis/postgis.sql.in.c

index e5ec9ad68884026554aba65abead916decc3b32e..31c5b48131122cb80dac83474c0820d1f86c4d81 100644 (file)
@@ -385,6 +385,7 @@ st_asgeojson
                                <paramdef choice='opt'><type>integer </type> <parameter>maxdecimaldigits=15</parameter></paramdef>
                                <paramdef choice='opt'><type>integer </type> <parameter>options=0</parameter></paramdef>
                                <paramdef choice='opt'><type>text </type> <parameter>nprefix=null</parameter></paramdef>
+                               <paramdef choice='opt'><type>text </type> <parameter>id=null</parameter></paramdef>
                        </funcprototype>
 
                        <funcprototype>
@@ -394,6 +395,7 @@ st_asgeojson
                                <paramdef choice='opt'><type>integer </type> <parameter>maxdecimaldigits=15</parameter></paramdef>
                                <paramdef choice='opt'><type>integer </type> <parameter>options=0</parameter></paramdef>
                                <paramdef choice='opt'><type>text </type> <parameter>nprefix=null</parameter></paramdef>
+                               <paramdef choice='opt'><type>text </type> <parameter>id=null</parameter></paramdef>
                        </funcprototype>
                </funcsynopsis>
          </refsynopsisdiv>
@@ -446,6 +448,7 @@ namespace prefix or no prefix (if empty). If null or omitted 'gml' prefix is use
                  <para>Availability: 1.5.0 geography support was introduced.</para>
                  <para>Enhanced: 2.0.0 prefix support was introduced. Option 4 for GML3 was introduced to allow using LineString instead of Curve tag for lines. GML3 Support for Polyhedral surfaces and TINS was introduced. Option 32 was introduced to output the box.</para>
                  <para>Changed: 2.0.0 use default named args</para>
+                 <para>Availability: 2.0.1 id support was introduced, for GML 3.</para>
                 
                <note><para>Only version 3+ of ST_AsGML supports Polyhedral Surfaces and TINS.</para></note>
                <para>&Z_support;</para>
index 9c2293815513b8a3ba69c43e44d986b6aba4530d..98815bab9e911f8e27d111ffd1b65c54e5ac61c8 100644 (file)
@@ -1352,7 +1352,7 @@ extern char* lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int prec
  * @param opts output options bitfield, see LW_GML macros for meaning
  */
 extern char* lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix);
-extern char* lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix);
+extern char* lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id);
 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);
 extern char* lwgeom_to_svg(const LWGEOM *geom, int precision, int relative);
index 170ee336ae556c92b82b447a38b02d793209d970..ff77a2f7206870ca747244afffadea8aef0a1e21 100644 (file)
@@ -5,7 +5,7 @@
  * http://postgis.refractions.net
  *
  * Copyright 2011 Sandro Santilli <strk@keybit.net>
- * Copyright 2010-2011 Oslandia
+ * Copyright 2010-2012 Oslandia
  * Copyright 2001-2003 Refractions Research Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -35,20 +35,20 @@ static size_t asgml2_collection_size(const LWCOLLECTION *col, const char *srs, i
 static char *asgml2_collection(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix);
 static size_t pointArray_toGML2(POINTARRAY *pa, char *buf, int precision);
 
-static size_t asgml3_point_size(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix);
-static char *asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix);
-static size_t asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix);
-static char *asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix);
-static size_t asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, const char *prefix);
-static char *asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix);
-static size_t asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix);
-static char *asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix);
-static size_t asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix);
-static char *asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix);
-static char *asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix);
-static char *asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix);
-static size_t asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix);
-static char *asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix);
+static size_t asgml3_point_size(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static char *asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static size_t asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static char *asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static size_t asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static char *asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix, const char *id);
+static size_t asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static char *asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static size_t asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static char *asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static char *asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static char *asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static size_t asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id);
+static char *asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id);
 static size_t pointArray_toGML3(POINTARRAY *pa, char *buf, int precision, int opts);
 
 static size_t pointArray_GMLsize(POINTARRAY *pa, int precision);
@@ -708,7 +708,7 @@ pointArray_toGML2(POINTARRAY *pa, char *output, int precision)
 
 /* takes a GEOMETRY and returns a GML representation */
 extern char *
-lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix)
+lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        int type = geom->type;
 
@@ -719,30 +719,30 @@ lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, con
        switch (type)
        {
        case POINTTYPE:
-               return asgml3_point((LWPOINT*)geom, srs, precision, opts, prefix);
+               return asgml3_point((LWPOINT*)geom, srs, precision, opts, prefix, id);
 
        case LINETYPE:
-               return asgml3_line((LWLINE*)geom, srs, precision, opts, prefix);
+               return asgml3_line((LWLINE*)geom, srs, precision, opts, prefix, id);
 
        case POLYGONTYPE:
-               return asgml3_poly((LWPOLY*)geom, srs, precision, opts, 0, prefix);
+               return asgml3_poly((LWPOLY*)geom, srs, precision, opts, 0, prefix, id);
 
        case TRIANGLETYPE:
-               return asgml3_triangle((LWTRIANGLE*)geom, srs, precision, opts, prefix);
+               return asgml3_triangle((LWTRIANGLE*)geom, srs, precision, opts, prefix, id);
 
        case MULTIPOINTTYPE:
        case MULTILINETYPE:
        case MULTIPOLYGONTYPE:
-               return asgml3_multi((LWCOLLECTION*)geom, srs, precision, opts, prefix);
+               return asgml3_multi((LWCOLLECTION*)geom, srs, precision, opts, prefix, id);
 
        case POLYHEDRALSURFACETYPE:
-               return asgml3_psurface((LWPSURFACE*)geom, srs, precision, opts, prefix);
+               return asgml3_psurface((LWPSURFACE*)geom, srs, precision, opts, prefix, id);
 
        case TINTYPE:
-               return asgml3_tin((LWTIN*)geom, srs, precision, opts, prefix);
+               return asgml3_tin((LWTIN*)geom, srs, precision, opts, prefix, id);
 
        case COLLECTIONTYPE:
-               return asgml3_collection((LWCOLLECTION*)geom, srs, precision, opts, prefix);
+               return asgml3_collection((LWCOLLECTION*)geom, srs, precision, opts, prefix, id);
 
        default:
                lwerror("lwgeom_to_gml3: '%s' geometry type not supported", lwtype_name(type));
@@ -751,20 +751,21 @@ lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, con
 }
 
 static size_t
-asgml3_point_size(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix)
+asgml3_point_size(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        int size;
        size_t prefixlen = strlen(prefix);
 
        size = pointArray_GMLsize(point->point, precision);
        size += ( sizeof("<point><pos>/") + (prefixlen*2) ) * 2;
-       if (srs)     size += strlen(srs) + sizeof(" srsName=..");
+       if (srs) size += strlen(srs) + sizeof(" srsName=..");
+       if (id)  size += strlen(id) + strlen(prefix) + sizeof(" id=..");
        if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'");
        return size;
 }
 
 static size_t
-asgml3_point_buf(const LWPOINT *point, const char *srs, char *output, int precision, int opts, const char *prefix)
+asgml3_point_buf(const LWPOINT *point, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
 {
        char *ptr = output;
        int dimension=2;
@@ -773,6 +774,7 @@ asgml3_point_buf(const LWPOINT *point, const char *srs, char *output, int precis
 
        ptr += sprintf(ptr, "<%sPoint", prefix);
        if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if ( id )  ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
        if ( lwpoint_is_empty(point) ) {
                ptr += sprintf(ptr, "/>");
                return (ptr-output);
@@ -788,20 +790,20 @@ asgml3_point_buf(const LWPOINT *point, const char *srs, char *output, int precis
 }
 
 static char *
-asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix)
+asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        char *output;
        int size;
 
-       size = asgml3_point_size(point, srs, precision, opts, prefix);
+       size = asgml3_point_size(point, srs, precision, opts, prefix, id);
        output = lwalloc(size);
-       asgml3_point_buf(point, srs, output, precision, opts, prefix);
+       asgml3_point_buf(point, srs, output, precision, opts, prefix, id);
        return output;
 }
 
 
 static size_t
-asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix)
+asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        int size;
        size_t prefixlen = strlen(prefix);
@@ -821,13 +823,14 @@ asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, c
                  ( prefixlen * 4 )
                ) * 2;
        }
-       if (srs)     size += strlen(srs) + sizeof(" srsName=..");
+       if (srs) size += strlen(srs) + sizeof(" srsName=..");
+       if (id)  size += strlen(id) + strlen(prefix) + sizeof(" id=..");
        if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'");
        return size;
 }
 
 static size_t
-asgml3_line_buf(const LWLINE *line, const char *srs, char *output, int precision, int opts, const char *prefix)
+asgml3_line_buf(const LWLINE *line, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
 {
        char *ptr=output;
        int dimension=2;
@@ -841,9 +844,9 @@ asgml3_line_buf(const LWLINE *line, const char *srs, char *output, int precision
                ptr += sprintf(ptr, "<%sCurve", prefix);
        }
 
-       if ( srs ) {
-               ptr += sprintf(ptr, " srsName=\"%s\"", srs);
-       } 
+       if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (id)  ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
+
        if ( lwline_is_empty(line) ) {
                ptr += sprintf(ptr, "/>");
                return (ptr-output);
@@ -878,20 +881,20 @@ asgml3_line_buf(const LWLINE *line, const char *srs, char *output, int precision
 }
 
 static char *
-asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix)
+asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        char *output;
        int size;
 
-       size = asgml3_line_size(line, srs, precision, opts, prefix);
+       size = asgml3_line_size(line, srs, precision, opts, prefix, id);
        output = lwalloc(size);
-       asgml3_line_buf(line, srs, output, precision, opts, prefix);
+       asgml3_line_buf(line, srs, output, precision, opts, prefix, id);
        return output;
 }
 
 
 static size_t
-asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, const char *prefix)
+asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        size_t size;
        size_t prefixlen = strlen(prefix);
@@ -900,7 +903,8 @@ asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, c
        size = ( sizeof("<PolygonPatch><exterior><LinearRing>///") + (prefixlen*3) ) * 2;
        size += ( sizeof("<interior><LinearRing>//") + (prefixlen*2) ) * 2 * (poly->nrings - 1);
        size += ( sizeof("<posList></posList>") + (prefixlen*2) ) * poly->nrings;
-       if (srs)     size += strlen(srs) + sizeof(" srsName=..");
+       if (srs) size += strlen(srs) + sizeof(" srsName=..");
+       if (id)  size += strlen(id) + strlen(prefix) + sizeof(" id=..");
        if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'") * poly->nrings;
 
        for (i=0; i<poly->nrings; i++)
@@ -910,7 +914,7 @@ asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, c
 }
 
 static size_t
-asgml3_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision, int opts, int is_patch, const char *prefix)
+asgml3_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision, int opts, int is_patch, const char *prefix, const char *id)
 {
        int i;
        char *ptr=output;
@@ -928,6 +932,7 @@ asgml3_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision
        }
 
        if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (id)  ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
 
        if ( lwpoly_is_empty(poly) ) {
                ptr += sprintf(ptr, "/>");
@@ -958,27 +963,28 @@ asgml3_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision
 }
 
 static char *
-asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix)
+asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix, const char *id)
 {
        char *output;
        int size;
 
-       size = asgml3_poly_size(poly, srs, precision, opts, prefix);
+       size = asgml3_poly_size(poly, srs, precision, opts, prefix, id);
        output = lwalloc(size);
-       asgml3_poly_buf(poly, srs, output, precision, opts, is_patch, prefix);
+       asgml3_poly_buf(poly, srs, output, precision, opts, is_patch, prefix, id);
        return output;
 }
 
 
 static size_t
-asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix)
+asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        size_t size;
        size_t prefixlen = strlen(prefix);
 
        size =  ( sizeof("<Triangle><exterior><LinearRing>///") + (prefixlen*3) ) * 2;
        size +=   sizeof("<posList></posList>") + (prefixlen*2);
-       if (srs)     size += strlen(srs) + sizeof(" srsName=..");
+       if (srs) size += strlen(srs) + sizeof(" srsName=..");
+       if (id)  size += strlen(prefix) + strlen(id) + sizeof(" id=..");
        if (IS_DIMS(opts)) size += sizeof(" srsDimension='x'");
 
        size += pointArray_GMLsize(triangle->points, precision);
@@ -987,14 +993,16 @@ asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision,
 }
 
 static size_t
-asgml3_triangle_buf(const LWTRIANGLE *triangle, const char *srs, char *output, int precision, int opts, const char *prefix)
+asgml3_triangle_buf(const LWTRIANGLE *triangle, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
 {
        char *ptr=output;
        int dimension=2;
 
        if (FLAGS_GET_Z(triangle->flags)) dimension = 3;
-       if (srs) ptr += sprintf(ptr, "<%sTriangle srsName=\"%s\">", prefix, srs);
-       else     ptr += sprintf(ptr, "<%sTriangle>", prefix);
+       ptr += sprintf(ptr, "<%sTriangle", prefix);
+       if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (id)  ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
+       ptr += sprintf(ptr, ">");
 
        ptr += sprintf(ptr, "<%sexterior><%sLinearRing>", prefix, prefix);
        if (IS_DIMS(opts)) ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension);
@@ -1010,14 +1018,14 @@ asgml3_triangle_buf(const LWTRIANGLE *triangle, const char *srs, char *output, i
 }
 
 static char *
-asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix)
+asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        char *output;
        int size;
 
-       size = asgml3_triangle_size(triangle, srs, precision, opts, prefix);
+       size = asgml3_triangle_size(triangle, srs, precision, opts, prefix, id);
        output = lwalloc(size);
-       asgml3_triangle_buf(triangle, srs, output, precision, opts, prefix);
+       asgml3_triangle_buf(triangle, srs, output, precision, opts, prefix, id);
        return output;
 }
 
@@ -1028,7 +1036,7 @@ asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int
  * Don't call this with single-geoms inspected.
  */
 static size_t
-asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix)
+asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        int i;
        size_t size;
@@ -1038,7 +1046,8 @@ asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int o
        /* the longest possible multi version */
        size = sizeof("<MultiLineString></MultiLineString>") + prefixlen*2;
 
-       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+       if (srs) size += strlen(srs) + sizeof(" srsName=..");
+       if (id)  size += strlen(id) + strlen(prefix) + sizeof(" id=..");
 
        for (i=0; i<col->ngeoms; i++)
        {
@@ -1046,17 +1055,17 @@ asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int o
                if (subgeom->type == POINTTYPE)
                {
                        size += ( sizeof("<pointMember>/") + prefixlen ) * 2;
-                       size += asgml3_point_size((LWPOINT*)subgeom, 0, precision, opts, prefix);
+                       size += asgml3_point_size((LWPOINT*)subgeom, 0, precision, opts, prefix, id);
                }
                else if (subgeom->type == LINETYPE)
                {
                        size += ( sizeof("<curveMember>/") + prefixlen ) * 2;
-                       size += asgml3_line_size((LWLINE*)subgeom, 0, precision, opts, prefix);
+                       size += asgml3_line_size((LWLINE*)subgeom, 0, precision, opts, prefix, id);
                }
                else if (subgeom->type == POLYGONTYPE)
                {
                        size += ( sizeof("<surfaceMember>/") + prefixlen ) * 2;
-                       size += asgml3_poly_size((LWPOLY*)subgeom, 0, precision, opts, prefix);
+                       size += asgml3_poly_size((LWPOLY*)subgeom, 0, precision, opts, prefix, id);
                }
        }
 
@@ -1067,7 +1076,7 @@ asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int o
  * Don't call this with single-geoms inspected!
  */
 static size_t
-asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, int opts, const char *prefix)
+asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
 {
        int type = col->type;
        char *ptr, *gmltype;
@@ -1083,7 +1092,8 @@ asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int pre
 
        /* Open outmost tag */
        ptr += sprintf(ptr, "<%s%s", prefix, gmltype);
-       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (id)  ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
 
        if (!col->ngeoms) {
                ptr += sprintf(ptr, "/>");
@@ -1097,19 +1107,19 @@ asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int pre
                if (subgeom->type == POINTTYPE)
                {
                        ptr += sprintf(ptr, "<%spointMember>", prefix);
-                       ptr += asgml3_point_buf((LWPOINT*)subgeom, 0, ptr, precision, opts, prefix);
+                       ptr += asgml3_point_buf((LWPOINT*)subgeom, 0, ptr, precision, opts, prefix, id);
                        ptr += sprintf(ptr, "</%spointMember>", prefix);
                }
                else if (subgeom->type == LINETYPE)
                {
                        ptr += sprintf(ptr, "<%scurveMember>", prefix);
-                       ptr += asgml3_line_buf((LWLINE*)subgeom, 0, ptr, precision, opts, prefix);
+                       ptr += asgml3_line_buf((LWLINE*)subgeom, 0, ptr, precision, opts, prefix, id);
                        ptr += sprintf(ptr, "</%scurveMember>", prefix);
                }
                else if (subgeom->type == POLYGONTYPE)
                {
                        ptr += sprintf(ptr, "<%ssurfaceMember>", prefix);
-                       ptr += asgml3_poly_buf((LWPOLY*)subgeom, 0, ptr, precision, opts, 0, prefix);
+                       ptr += asgml3_poly_buf((LWPOLY*)subgeom, 0, ptr, precision, opts, 0, prefix, id);
                        ptr += sprintf(ptr, "</%ssurfaceMember>", prefix);
                }
        }
@@ -1124,31 +1134,32 @@ asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int pre
  * Don't call this with single-geoms inspected!
  */
 static char *
-asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix)
+asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        char *gml;
        size_t size;
 
-       size = asgml3_multi_size(col, srs, precision, opts, prefix);
+       size = asgml3_multi_size(col, srs, precision, opts, prefix, id);
        gml = lwalloc(size);
-       asgml3_multi_buf(col, srs, gml, precision, opts, prefix);
+       asgml3_multi_buf(col, srs, gml, precision, opts, prefix, id);
        return gml;
 }
 
 
 static size_t
-asgml3_psurface_size(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix)
+asgml3_psurface_size(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        int i;
        size_t size;
        size_t prefixlen = strlen(prefix);
 
        size = (sizeof("<PolyhedralSurface><polygonPatches>/") + prefixlen*2) * 2;
-       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+       if (srs) size += strlen(srs) + sizeof(" srsName=..");
+       if (id)  size += strlen(id) + strlen(prefix) + sizeof(" id=..");
 
        for (i=0; i<psur->ngeoms; i++)
        {
-               size += asgml3_poly_size(psur->geoms[i], 0, precision, opts, prefix);
+               size += asgml3_poly_size(psur->geoms[i], 0, precision, opts, prefix, id);
        }
 
        return size;
@@ -1159,7 +1170,7 @@ asgml3_psurface_size(const LWPSURFACE *psur, const char *srs, int precision, int
  * Don't call this with single-geoms inspected!
  */
 static size_t
-asgml3_psurface_buf(const LWPSURFACE *psur, const char *srs, char *output, int precision, int opts, const char *prefix)
+asgml3_psurface_buf(const LWPSURFACE *psur, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
 {
        char *ptr;
        int i;
@@ -1167,14 +1178,14 @@ asgml3_psurface_buf(const LWPSURFACE *psur, const char *srs, char *output, int p
        ptr = output;
 
        /* Open outmost tag */
-       if (srs) ptr += sprintf(ptr, "<%sPolyhedralSurface srsName=\"%s\"><%spolygonPatches>",
-                                       prefix, srs, prefix);
-       else     ptr += sprintf(ptr, "<%sPolyhedralSurface><%spolygonPatches>",
-                                    prefix, prefix);
+       ptr += sprintf(ptr, "<%sPolyhedralSurface", prefix);
+       if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (id)  ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
+       ptr += sprintf(ptr, "><%spolygonPatches>", prefix);
 
        for (i=0; i<psur->ngeoms; i++)
        {
-               ptr += asgml3_poly_buf(psur->geoms[i], 0, ptr, precision, opts, 1, prefix);
+               ptr += asgml3_poly_buf(psur->geoms[i], 0, ptr, precision, opts, 1, prefix, id);
        }
 
        /* Close outmost tag */
@@ -1188,31 +1199,32 @@ asgml3_psurface_buf(const LWPSURFACE *psur, const char *srs, char *output, int p
  * Don't call this with single-geoms inspected!
  */
 static char *
-asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix)
+asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        char *gml;
        size_t size;
 
-       size = asgml3_psurface_size(psur, srs, precision, opts, prefix);
+       size = asgml3_psurface_size(psur, srs, precision, opts, prefix, id);
        gml = lwalloc(size);
-       asgml3_psurface_buf(psur, srs, gml, precision, opts, prefix);
+       asgml3_psurface_buf(psur, srs, gml, precision, opts, prefix, id);
        return gml;
 }
 
 
 static size_t
-asgml3_tin_size(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix)
+asgml3_tin_size(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        int i;
        size_t size;
        size_t prefixlen = strlen(prefix);
 
        size = (sizeof("<Tin><trianglePatches>/") + prefixlen*2) * 2;
-       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+       if (srs) size += strlen(srs) + sizeof(" srsName=..");
+       if (id)  size += strlen(id) + strlen(prefix) + sizeof(" id=..");
 
        for (i=0; i<tin->ngeoms; i++)
        {
-               size += asgml3_triangle_size(tin->geoms[i], 0, precision, opts, prefix);
+               size += asgml3_triangle_size(tin->geoms[i], 0, precision, opts, prefix, id);
        }
 
        return size;
@@ -1223,7 +1235,7 @@ asgml3_tin_size(const LWTIN *tin, const char *srs, int precision, int opts, cons
  * Don't call this with single-geoms inspected!
  */
 static size_t
-asgml3_tin_buf(const LWTIN *tin, const char *srs, char *output, int precision, int opts, const char *prefix)
+asgml3_tin_buf(const LWTIN *tin, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
 {
        char *ptr;
        int i;
@@ -1231,15 +1243,15 @@ asgml3_tin_buf(const LWTIN *tin, const char *srs, char *output, int precision, i
        ptr = output;
 
        /* Open outmost tag */
-       if (srs) ptr += sprintf(ptr, "<%sTin srsName=\"%s\"><%strianglePatches>",
-                                       prefix, srs, prefix);
-       else     ptr += sprintf(ptr, "<%sTin><%strianglePatches>",
-                                    prefix, prefix);
+       ptr += sprintf(ptr, "<%sTin", prefix);
+       if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (id)  ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
+       else     ptr += sprintf(ptr, "><%strianglePatches>", prefix);
 
        for (i=0; i<tin->ngeoms; i++)
        {
                ptr += asgml3_triangle_buf(tin->geoms[i], 0, ptr, precision,
-                                          opts, prefix);
+                                          opts, prefix, id);
        }
 
        /* Close outmost tag */
@@ -1252,19 +1264,19 @@ asgml3_tin_buf(const LWTIN *tin, const char *srs, char *output, int precision, i
  * Don't call this with single-geoms inspected!
  */
 static char *
-asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix)
+asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        char *gml;
        size_t size;
 
-       size = asgml3_tin_size(tin, srs, precision, opts, prefix);
+       size = asgml3_tin_size(tin, srs, precision, opts, prefix, id);
        gml = lwalloc(size);
-       asgml3_tin_buf(tin, srs, gml, precision, opts, prefix);
+       asgml3_tin_buf(tin, srs, gml, precision, opts, prefix, id);
        return gml;
 }
 
 static size_t
-asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix)
+asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        int i;
        size_t size;
@@ -1273,7 +1285,8 @@ asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision,
 
        size = sizeof("<MultiGeometry></MultiGeometry>") + prefixlen*2;
 
-       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+       if (srs) size += strlen(srs) + sizeof(" srsName=..");
+       if (id)  size += strlen(id) + strlen(prefix) + sizeof(" id=..");
 
        for (i=0; i<col->ngeoms; i++)
        {
@@ -1281,19 +1294,19 @@ asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision,
                size += ( sizeof("<geometryMember>/") + prefixlen ) * 2;
                if ( subgeom->type == POINTTYPE )
                {
-                       size += asgml3_point_size((LWPOINT*)subgeom, 0, precision, opts, prefix);
+                       size += asgml3_point_size((LWPOINT*)subgeom, 0, precision, opts, prefix, id);
                }
                else if ( subgeom->type == LINETYPE )
                {
-                       size += asgml3_line_size((LWLINE*)subgeom, 0, precision, opts, prefix);
+                       size += asgml3_line_size((LWLINE*)subgeom, 0, precision, opts, prefix, id);
                }
                else if ( subgeom->type == POLYGONTYPE )
                {
-                       size += asgml3_poly_size((LWPOLY*)subgeom, 0, precision, opts, prefix);
+                       size += asgml3_poly_size((LWPOLY*)subgeom, 0, precision, opts, prefix, id);
                }
                else if ( lwgeom_is_collection(subgeom) )
                {
-                       size += asgml3_multi_size((LWCOLLECTION*)subgeom, 0, precision, opts, prefix);
+                       size += asgml3_multi_size((LWCOLLECTION*)subgeom, 0, precision, opts, prefix, id);
                }
                else
                        lwerror("asgml3_collection_size: unknown geometry type");
@@ -1303,7 +1316,7 @@ asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision,
 }
 
 static size_t
-asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, int opts, const char *prefix)
+asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, int precision, int opts, const char *prefix, const char *id)
 {
        char *ptr;
        int i;
@@ -1313,7 +1326,8 @@ asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, in
 
        /* Open outmost tag */
        ptr += sprintf(ptr, "<%sMultiGeometry", prefix);
-       if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (srs) ptr += sprintf(ptr, " srsName=\"%s\"", srs);
+       if (id)  ptr += sprintf(ptr, " %sid=\"%s\"", prefix, id);
 
        if (!col->ngeoms) {
                ptr += sprintf(ptr, "/>");
@@ -1327,22 +1341,22 @@ asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, in
                ptr += sprintf(ptr, "<%sgeometryMember>", prefix);
                if ( subgeom->type == POINTTYPE )
                {
-                       ptr += asgml3_point_buf((LWPOINT*)subgeom, 0, ptr, precision, opts, prefix);
+                       ptr += asgml3_point_buf((LWPOINT*)subgeom, 0, ptr, precision, opts, prefix, id);
                }
                else if ( subgeom->type == LINETYPE )
                {
-                       ptr += asgml3_line_buf((LWLINE*)subgeom, 0, ptr, precision, opts, prefix);
+                       ptr += asgml3_line_buf((LWLINE*)subgeom, 0, ptr, precision, opts, prefix, id);
                }
                else if ( subgeom->type == POLYGONTYPE )
                {
-                       ptr += asgml3_poly_buf((LWPOLY*)subgeom, 0, ptr, precision, opts, 0, prefix);
+                       ptr += asgml3_poly_buf((LWPOLY*)subgeom, 0, ptr, precision, opts, 0, prefix, id);
                }
                else if ( lwgeom_is_collection(subgeom) )
                {
                        if ( subgeom->type == COLLECTIONTYPE )
-                               ptr += asgml3_collection_buf((LWCOLLECTION*)subgeom, 0, ptr, precision, opts, prefix);
+                               ptr += asgml3_collection_buf((LWCOLLECTION*)subgeom, 0, ptr, precision, opts, prefix, id);
                        else
-                               ptr += asgml3_multi_buf((LWCOLLECTION*)subgeom, 0, ptr, precision, opts, prefix);
+                               ptr += asgml3_multi_buf((LWCOLLECTION*)subgeom, 0, ptr, precision, opts, prefix, id);
                }
                else 
                        lwerror("asgml3_collection_buf: unknown geometry type");
@@ -1360,14 +1374,14 @@ asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, in
  * Don't call this with single-geoms inspected!
  */
 static char *
-asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix)
+asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id)
 {
        char *gml;
        size_t size;
 
-       size = asgml3_collection_size(col, srs, precision, opts, prefix);
+       size = asgml3_collection_size(col, srs, precision, opts, prefix, id);
        gml = lwalloc(size);
-       asgml3_collection_buf(col, srs, gml, precision, opts, prefix);
+       asgml3_collection_buf(col, srs, gml, precision, opts, prefix, id);
        return gml;
 }
 
index 57f8c7ffa71afbdd1776f0c442058dde706f5313..af5d4fec7df015adf345a9d39a3d9906fa982051 100644 (file)
@@ -211,9 +211,10 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
        int option=0;
        int lwopts = LW_GML_IS_DIMS;
        static const char *default_prefix = "gml:";
-       char *prefixbuf;
-       const char* prefix = default_prefix;
-       text *prefix_text;
+       char *prefix_buf, *id_buf;
+       const char *prefix = default_prefix;
+       text *prefix_text, *id_text;
+       const char *id;
 
 
        /* Get the version */
@@ -256,13 +257,30 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
                else
                {
                        /* +2 is one for the ':' and one for term null */
-                       prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
-                       memcpy(prefixbuf, VARDATA(prefix_text),
+                       prefix_buf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
+                       memcpy(prefix_buf, VARDATA(prefix_text),
                               VARSIZE(prefix_text)-VARHDRSZ);
                        /* add colon and null terminate */
-                       prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] = ':';
-                       prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0';
-                       prefix = prefixbuf;
+                       prefix_buf[VARSIZE(prefix_text)-VARHDRSZ] = ':';
+                       prefix_buf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0';
+                       prefix = prefix_buf;
+               }
+       }
+
+       /* retrieve id */
+       if (PG_NARGS() >5 && !PG_ARGISNULL(5))
+       {
+               prefix_text = PG_GETARG_TEXT_P(5);
+               if ( VARSIZE(id_text)-VARHDRSZ == 0 )
+               {
+                       id = "";
+               }
+               else
+               {
+                       id_buf = palloc(VARSIZE(id_text)-VARHDRSZ+1);
+                       memcpy(id_buf, VARDATA(id_text), VARSIZE(id_text)-VARHDRSZ);
+                       prefix_buf[VARSIZE(id_text)-VARHDRSZ+1] = '\0';
+                       id = id_buf;
                }
        }
 
@@ -281,7 +299,7 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
        if (version == 2)
                gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix);
        else
-               gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix);
+               gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, id);
 
     lwgeom_free(lwgeom);
        PG_FREE_IF_COPY(g, 1);
index f8dcae18960ed3f5b9272ea0e66c7cced4e14ff6..94089de9e567377cd4d268042959084ea83b6e43 100644 (file)
@@ -173,9 +173,10 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
        int lwopts = LW_GML_IS_DIMS;
        int precision = OUT_MAX_DOUBLE_PRECISION;
        static const char* default_prefix = "gml:"; /* default prefix */
-       char *prefixbuf;
        const char* prefix = default_prefix;
-       text *prefix_text;
+       const char* gml_id;
+       char *prefix_buf, *gml_id_buf;
+       text *prefix_text, *gml_id_text;
 
        /* Get the version */
        version = PG_GETARG_INT32(0);
@@ -213,13 +214,29 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
                else
                {
                        /* +2 is one for the ':' and one for term null */
-                       prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
-                       memcpy(prefixbuf, VARDATA(prefix_text),
+                       prefix_buf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
+                       memcpy(prefix_buf, VARDATA(prefix_text),
                               VARSIZE(prefix_text)-VARHDRSZ);
                        /* add colon and null terminate */
-                       prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] = ':';
-                       prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0';
-                       prefix = prefixbuf;
+                       prefix_buf[VARSIZE(prefix_text)-VARHDRSZ] = ':';
+                       prefix_buf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0';
+                       prefix = prefix_buf;
+               }
+       }
+
+       if (PG_NARGS() >5 && !PG_ARGISNULL(5))
+       {
+               gml_id_text = PG_GETARG_TEXT_P(5);
+               if ( VARSIZE(gml_id_text)-VARHDRSZ == 0 )
+               {
+                       gml_id = "";
+               }
+               else
+               {
+                       gml_id_buf = palloc(VARSIZE(gml_id_text)-VARHDRSZ+1);
+                       memcpy(gml_id_buf, VARDATA(gml_id_text), VARSIZE(gml_id_text)-VARHDRSZ);
+                       gml_id_buf[VARSIZE(gml_id_text)-VARHDRSZ+1] = '\0';
+                       gml_id = gml_id_buf;
                }
        }
 
@@ -242,7 +259,7 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
        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);
+               gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, gml_id);
 
        lwgeom_free(lwgeom);
        PG_FREE_IF_COPY(geom, 1);
index 3ed4543c29a6cd26d9aa61dd4522d6d2c8ec10eb..b36708db8378251f4ec42893960c67c120a388d3 100644 (file)
@@ -3413,8 +3413,8 @@ CREATE OR REPLACE FUNCTION ST_AsSVG(geom geometry,rel int4 DEFAULT 0,maxdecimald
 -----------------------------------------------------------------------
 -- GML OUTPUT
 -----------------------------------------------------------------------
--- _ST_AsGML(version, geom, precision, option, prefix)
-CREATE OR REPLACE FUNCTION _ST_AsGML(int4, geometry, int4, int4, text)
+-- _ST_AsGML(version, geom, precision, option, prefix, id)
+CREATE OR REPLACE FUNCTION _ST_AsGML(int4, geometry, int4, int4, text, text)
        RETURNS TEXT
        AS 'MODULE_PATHNAME','LWGEOM_asGML'
        LANGUAGE 'c' IMMUTABLE;
@@ -3427,9 +3427,9 @@ CREATE OR REPLACE FUNCTION _ST_AsGML(int4, geometry, int4, int4, text)
 -- ST_AsGML (geom, precision, option) / version=2
 -- Availability: 1.4.0
 -- Changed: 2.0.0 to have default args
-CREATE OR REPLACE FUNCTION ST_AsGML(geom geometry, maxdecimaldigits int4 DEFAULT 15, options int4 DEFAULT 0)
+CREATE OR REPLACE FUNCTION ST_AsGML(geom geometry, maxdecimaldigits int4 DEFAULT 15, options int4 DEFAULT)
        RETURNS TEXT
-       AS $$ SELECT _ST_AsGML(2, $1, $2, $3, null); $$
+       AS $$ SELECT _ST_AsGML(2, $1, $2, $3, null, null); $$
        LANGUAGE 'sql' IMMUTABLE STRICT;
 
 -- ST_AsGML(version, geom, precision, option)
@@ -3437,9 +3437,11 @@ CREATE OR REPLACE FUNCTION ST_AsGML(geom geometry, maxdecimaldigits int4 DEFAULT
 -- ST_AsGML(version, geom, precision, option, prefix)
 -- Availability: 2.0.0
 -- Changed: 2.0.0 to use default and named args
-CREATE OR REPLACE FUNCTION ST_AsGML(version int4, geom geometry, maxdecimaldigits int4 DEFAULT 15, options int4 DEFAULT 0, nprefix text DEFAULT null)
+-- ST_AsGML(version, geom, precision, option, prefix, id)
+-- Availability: 2.0.1
+CREATE OR REPLACE FUNCTION ST_AsGML(version int4, geom geometry, maxdecimaldigits int4 DEFAULT 15, options int4 DEFAULT 0, nprefix text DEFAULT null, id text DEFAULT null)
        RETURNS TEXT
-       AS $$ SELECT _ST_AsGML($1, $2, $3, $4,$5); $$
+       AS $$ SELECT _ST_AsGML($1, $2, $3, $4, $5, $6); $$
        LANGUAGE 'sql' IMMUTABLE;
 
 -----------------------------------------------------------------------