]> granicus.if.org Git - postgis/commitdiff
Add support in liblwgeom for specifying a custom (or no) namespace/prefix for GML...
authorSandro Santilli <strk@keybit.net>
Mon, 22 Mar 2010 21:13:43 +0000 (21:13 +0000)
committerSandro Santilli <strk@keybit.net>
Mon, 22 Mar 2010 21:13:43 +0000 (21:13 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@5452 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/cunit/cu_out_gml.c
liblwgeom/liblwgeom.h
liblwgeom/lwout_gml.c
postgis/geography_inout.c
postgis/lwgeom_export.c

index b348564808492c38e8804b782d115096f8d60a72..ba24a3b058477db309e1e8839359a74065c1e24b 100644 (file)
@@ -24,7 +24,24 @@ static void do_gml2_test(char * in, char * out, char * srs, int precision)
        char *h;
 
        g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
-       h = lwgeom_to_gml2(lwgeom_serialize(g), srs, precision);
+       h = lwgeom_to_gml2(lwgeom_serialize(g), srs, precision, "gml:");
+
+       if (strcmp(h, out))
+               fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n", in, h, out);
+
+       CU_ASSERT_STRING_EQUAL(h, out);
+
+       lwgeom_free(g);
+       lwfree(h);
+}
+
+static void do_gml2_test_prefix(char * in, char * out, char * srs, int precision, const char *prefix)
+{
+       LWGEOM *g;
+       char *h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+       h = lwgeom_to_gml2(lwgeom_serialize(g), srs, precision, prefix);
 
        if (strcmp(h, out))
                fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n", in, h, out);
@@ -42,7 +59,24 @@ static void do_gml3_test(char * in, char * out, char * srs, int precision, int i
        char *h;
 
        g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
-       h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic);
+       h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic, "gml:");
+
+       if (strcmp(h, out))
+               fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n", in, h, out);
+
+       CU_ASSERT_STRING_EQUAL(h, out);
+
+       lwgeom_free(g);
+       lwfree(h);
+}
+
+static void do_gml3_test_prefix(char * in, char * out, char * srs, int precision, int is_geodetic, const char *prefix)
+{
+       LWGEOM *g;
+       char *h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+       h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic, prefix);
 
        if (strcmp(h, out))
                fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n", in, h, out);
@@ -59,7 +93,7 @@ static void do_gml2_unsupported(char * in, char * out)
        char *h;
 
        g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
-       h = lwgeom_to_gml2(lwgeom_serialize(g), NULL, 0);
+       h = lwgeom_to_gml2(lwgeom_serialize(g), NULL, 0, "");
 
        if (strcmp(cu_error_msg, out))
                fprintf(stderr, "\nGML 2 - In:   %s\nOut:  %s\nTheo: %s\n",
@@ -77,7 +111,7 @@ static void do_gml3_unsupported(char * in, char * out)
        char *h;
 
        g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
-       h = lwgeom_to_gml3(lwgeom_serialize(g), NULL, 0, 0);
+       h = lwgeom_to_gml3(lwgeom_serialize(g), NULL, 0, 0, "");
 
        if (strcmp(cu_error_msg, out))
                fprintf(stderr, "\nGML 3 - In:   %s\nOut:  %s\nTheo: %s\n",
@@ -466,6 +500,244 @@ static void out_gml_test_geoms(void)
            "lwgeom_to_gml3: 'MultiSurface' geometry type not supported");
 }
 
+static void out_gml_test_geoms_prefix(void)
+{
+       /* GML2 - Linestring */
+       do_gml2_test_prefix(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<custom:LineString><custom:coordinates>0,1 2,3 4,5</custom:coordinates></custom:LineString>",
+           NULL, 0, "custom:");
+
+       /* GML3 - Linestring */
+       do_gml3_test_prefix(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<custom:Curve><custom:segments><custom:LineStringSegment><custom:posList srsDimension=\"2\">0 1 2 3 4 5</custom:posList></custom:LineStringSegment></custom:segments></custom:Curve>",
+           NULL, 0, 0, "custom:");
+
+
+       /* GML2 Polygon */
+       do_gml2_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<custom:Polygon><custom:outerBoundaryIs><custom:LinearRing><custom:coordinates>0,1 2,3 4,5 0,1</custom:coordinates></custom:LinearRing></custom:outerBoundaryIs></custom:Polygon>",
+           NULL, 0, "custom:");
+
+       /* GML3 Polygon */
+       do_gml3_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<custom:Polygon><custom:exterior><custom:LinearRing><custom:posList srsDimension=\"2\">0 1 2 3 4 5 0 1</custom:posList></custom:LinearRing></custom:exterior></custom:Polygon>",
+           NULL, 0, 0, "custom:");
+
+
+       /* GML2 Polygon - with internal ring */
+       do_gml2_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
+           "<custom:Polygon><custom:outerBoundaryIs><custom:LinearRing><custom:coordinates>0,1 2,3 4,5 0,1</custom:coordinates></custom:LinearRing></custom:outerBoundaryIs><custom:innerBoundaryIs><custom:LinearRing><custom:coordinates>6,7 8,9 10,11 6,7</custom:coordinates></custom:LinearRing></custom:innerBoundaryIs></custom:Polygon>",
+           NULL, 0, "custom:");
+
+       /* GML3 Polygon - with internal ring */
+       do_gml3_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
+           "<custom:Polygon><custom:exterior><custom:LinearRing><custom:posList srsDimension=\"2\">0 1 2 3 4 5 0 1</custom:posList></custom:LinearRing></custom:exterior><custom:interior><custom:LinearRing><custom:posList srsDimension=\"2\">6 7 8 9 10 11 6 7</custom:posList></custom:LinearRing></custom:interior></custom:Polygon>",
+           NULL, 0, 0, "custom:");
+
+
+       /* GML2 MultiPoint */
+       do_gml2_test_prefix(
+           "MULTIPOINT(0 1,2 3)",
+           "<custom:MultiPoint><custom:pointMember><custom:Point><custom:coordinates>0,1</custom:coordinates></custom:Point></custom:pointMember><custom:pointMember><custom:Point><custom:coordinates>2,3</custom:coordinates></custom:Point></custom:pointMember></custom:MultiPoint>",
+           NULL, 0, "custom:");
+
+       /* GML3 MultiPoint */
+       do_gml3_test_prefix(
+           "MULTIPOINT(0 1,2 3)",
+           "<custom:MultiPoint><custom:pointMember><custom:Point><custom:pos srsDimension=\"2\">0 1</custom:pos></custom:Point></custom:pointMember><custom:pointMember><custom:Point><custom:pos srsDimension=\"2\">2 3</custom:pos></custom:Point></custom:pointMember></custom:MultiPoint>",
+           NULL, 0, 0, "custom:");
+
+
+       /* GML2 Multiline */
+       do_gml2_test_prefix(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<custom:MultiLineString><custom:lineStringMember><custom:LineString><custom:coordinates>0,1 2,3 4,5</custom:coordinates></custom:LineString></custom:lineStringMember><custom:lineStringMember><custom:LineString><custom:coordinates>6,7 8,9 10,11</custom:coordinates></custom:LineString></custom:lineStringMember></custom:MultiLineString>",
+           NULL, 0, "custom:");
+
+       /* GML3 Multiline */
+       do_gml3_test_prefix(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<custom:MultiCurve><custom:curveMember><custom:Curve><custom:segments><custom:LineStringSegment><custom:posList srsDimension=\"2\">0 1 2 3 4 5</custom:posList></custom:LineStringSegment></custom:segments></custom:Curve></custom:curveMember><custom:curveMember><custom:Curve><custom:segments><custom:LineStringSegment><custom:posList srsDimension=\"2\">6 7 8 9 10 11</custom:posList></custom:LineStringSegment></custom:segments></custom:Curve></custom:curveMember></custom:MultiCurve>",
+           NULL, 0, 0, "custom:");
+
+
+       /* GML2 MultiPolygon */
+       do_gml2_test_prefix(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<custom:MultiPolygon><custom:polygonMember><custom:Polygon><custom:outerBoundaryIs><custom:LinearRing><custom:coordinates>0,1 2,3 4,5 0,1</custom:coordinates></custom:LinearRing></custom:outerBoundaryIs></custom:Polygon></custom:polygonMember><custom:polygonMember><custom:Polygon><custom:outerBoundaryIs><custom:LinearRing><custom:coordinates>6,7 8,9 10,11 6,7</custom:coordinates></custom:LinearRing></custom:outerBoundaryIs></custom:Polygon></custom:polygonMember></custom:MultiPolygon>",
+           NULL, 0, "custom:");
+
+       /* GML3 MultiPolygon */
+       do_gml3_test_prefix(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<custom:MultiSurface><custom:surfaceMember><custom:Polygon><custom:exterior><custom:LinearRing><custom:posList srsDimension=\"2\">0 1 2 3 4 5 0 1</custom:posList></custom:LinearRing></custom:exterior></custom:Polygon></custom:surfaceMember><custom:surfaceMember><custom:Polygon><custom:exterior><custom:LinearRing><custom:posList srsDimension=\"2\">6 7 8 9 10 11 6 7</custom:posList></custom:LinearRing></custom:exterior></custom:Polygon></custom:surfaceMember></custom:MultiSurface>",
+           NULL, 0, 0, "custom:");
+
+
+       /* GML2 - GeometryCollection */
+       do_gml2_test_prefix(
+           "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
+           "<custom:MultiGeometry><custom:geometryMember><custom:Point><custom:coordinates>0,1</custom:coordinates></custom:Point></custom:geometryMember><custom:geometryMember><custom:LineString><custom:coordinates>2,3 4,5</custom:coordinates></custom:LineString></custom:geometryMember></custom:MultiGeometry>",
+           NULL, 0, "custom:");
+
+       /* GML3 - GeometryCollection */
+       do_gml3_test_prefix(
+           "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
+           "<custom:MultiGeometry><custom:geometryMember><custom:Point><custom:pos srsDimension=\"2\">0 1</custom:pos></custom:Point></custom:geometryMember><custom:geometryMember><custom:Curve><custom:segments><custom:LineStringSegment><custom:posList srsDimension=\"2\">2 3 4 5</custom:posList></custom:LineStringSegment></custom:segments></custom:Curve></custom:geometryMember></custom:MultiGeometry>",
+           NULL, 0, 0, "custom:");
+
+
+       /* GML2 - Empty GeometryCollection */
+       do_gml2_test_prefix(
+           "GEOMETRYCOLLECTION EMPTY",
+           "<custom:MultiGeometry></custom:MultiGeometry>",
+           NULL, 0, "custom:");
+
+       /* GML3 - Empty GeometryCollection */
+       do_gml3_test_prefix(
+           "GEOMETRYCOLLECTION EMPTY",
+           "<custom:MultiGeometry></custom:MultiGeometry>",
+           NULL, 0, 0, "custom:");
+
+       /* GML2 - Nested GeometryCollection */
+       do_gml2_test_prefix(
+           "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
+           "<custom:MultiGeometry><custom:geometryMember><custom:Point><custom:coordinates>0,1</custom:coordinates></custom:Point></custom:geometryMember><custom:geometryMember><custom:MultiGeometry><custom:geometryMember><custom:LineString><custom:coordinates>2,3 4,5</custom:coordinates></custom:LineString></custom:geometryMember></custom:MultiGeometry></custom:geometryMember></custom:MultiGeometry>",
+           NULL, 0, "custom:");
+
+       /* GML3 - Nested GeometryCollection */
+       do_gml3_test_prefix(
+           "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
+           "<custom:MultiGeometry><custom:geometryMember><custom:Point><custom:pos srsDimension=\"2\">0 1</custom:pos></custom:Point></custom:geometryMember><custom:geometryMember><custom:MultiGeometry><custom:geometryMember><custom:Curve><custom:segments><custom:LineStringSegment><custom:posList srsDimension=\"2\">2 3 4 5</custom:posList></custom:LineStringSegment></custom:segments></custom:Curve></custom:geometryMember></custom:MultiGeometry></custom:geometryMember></custom:MultiGeometry>",
+           NULL, 0, 0, "custom:");
+
+       /*------------- empty prefixes below ------------------------ */
+
+       /* GML2 - Linestring */
+       do_gml2_test_prefix(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<LineString><coordinates>0,1 2,3 4,5</coordinates></LineString>",
+           NULL, 0, "");
+
+       /* GML3 - Linestring */
+       do_gml3_test_prefix(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<Curve><segments><LineStringSegment><posList srsDimension=\"2\">0 1 2 3 4 5</posList></LineStringSegment></segments></Curve>",
+           NULL, 0, 0, "");
+
+
+       /* GML2 Polygon */
+       do_gml2_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<Polygon><outerBoundaryIs><LinearRing><coordinates>0,1 2,3 4,5 0,1</coordinates></LinearRing></outerBoundaryIs></Polygon>",
+           NULL, 0, "");
+
+       /* GML3 Polygon */
+       do_gml3_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<Polygon><exterior><LinearRing><posList srsDimension=\"2\">0 1 2 3 4 5 0 1</posList></LinearRing></exterior></Polygon>",
+           NULL, 0, 0, "");
+
+
+       /* GML2 Polygon - with internal ring */
+       do_gml2_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
+           "<Polygon><outerBoundaryIs><LinearRing><coordinates>0,1 2,3 4,5 0,1</coordinates></LinearRing></outerBoundaryIs><innerBoundaryIs><LinearRing><coordinates>6,7 8,9 10,11 6,7</coordinates></LinearRing></innerBoundaryIs></Polygon>",
+           NULL, 0, "");
+
+       /* GML3 Polygon - with internal ring */
+       do_gml3_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
+           "<Polygon><exterior><LinearRing><posList srsDimension=\"2\">0 1 2 3 4 5 0 1</posList></LinearRing></exterior><interior><LinearRing><posList srsDimension=\"2\">6 7 8 9 10 11 6 7</posList></LinearRing></interior></Polygon>",
+           NULL, 0, 0, "");
+
+
+       /* GML2 MultiPoint */
+       do_gml2_test_prefix(
+           "MULTIPOINT(0 1,2 3)",
+           "<MultiPoint><pointMember><Point><coordinates>0,1</coordinates></Point></pointMember><pointMember><Point><coordinates>2,3</coordinates></Point></pointMember></MultiPoint>",
+           NULL, 0, "");
+
+       /* GML3 MultiPoint */
+       do_gml3_test_prefix(
+           "MULTIPOINT(0 1,2 3)",
+           "<MultiPoint><pointMember><Point><pos srsDimension=\"2\">0 1</pos></Point></pointMember><pointMember><Point><pos srsDimension=\"2\">2 3</pos></Point></pointMember></MultiPoint>",
+           NULL, 0, 0, "");
+
+
+       /* GML2 Multiline */
+       do_gml2_test_prefix(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<MultiLineString><lineStringMember><LineString><coordinates>0,1 2,3 4,5</coordinates></LineString></lineStringMember><lineStringMember><LineString><coordinates>6,7 8,9 10,11</coordinates></LineString></lineStringMember></MultiLineString>",
+           NULL, 0, "");
+
+       /* GML3 Multiline */
+       do_gml3_test_prefix(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<MultiCurve><curveMember><Curve><segments><LineStringSegment><posList srsDimension=\"2\">0 1 2 3 4 5</posList></LineStringSegment></segments></Curve></curveMember><curveMember><Curve><segments><LineStringSegment><posList srsDimension=\"2\">6 7 8 9 10 11</posList></LineStringSegment></segments></Curve></curveMember></MultiCurve>",
+           NULL, 0, 0, "");
+
+
+       /* GML2 MultiPolygon */
+       do_gml2_test_prefix(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<MultiPolygon><polygonMember><Polygon><outerBoundaryIs><LinearRing><coordinates>0,1 2,3 4,5 0,1</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember><polygonMember><Polygon><outerBoundaryIs><LinearRing><coordinates>6,7 8,9 10,11 6,7</coordinates></LinearRing></outerBoundaryIs></Polygon></polygonMember></MultiPolygon>",
+           NULL, 0, "");
+
+       /* GML3 MultiPolygon */
+       do_gml3_test_prefix(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<MultiSurface><surfaceMember><Polygon><exterior><LinearRing><posList srsDimension=\"2\">0 1 2 3 4 5 0 1</posList></LinearRing></exterior></Polygon></surfaceMember><surfaceMember><Polygon><exterior><LinearRing><posList srsDimension=\"2\">6 7 8 9 10 11 6 7</posList></LinearRing></exterior></Polygon></surfaceMember></MultiSurface>",
+           NULL, 0, 0, "");
+
+
+       /* GML2 - GeometryCollection */
+       do_gml2_test_prefix(
+           "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
+           "<MultiGeometry><geometryMember><Point><coordinates>0,1</coordinates></Point></geometryMember><geometryMember><LineString><coordinates>2,3 4,5</coordinates></LineString></geometryMember></MultiGeometry>",
+           NULL, 0, "");
+
+       /* GML3 - GeometryCollection */
+       do_gml3_test_prefix(
+           "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
+           "<MultiGeometry><geometryMember><Point><pos srsDimension=\"2\">0 1</pos></Point></geometryMember><geometryMember><Curve><segments><LineStringSegment><posList srsDimension=\"2\">2 3 4 5</posList></LineStringSegment></segments></Curve></geometryMember></MultiGeometry>",
+           NULL, 0, 0, "");
+
+
+       /* GML2 - Empty GeometryCollection */
+       do_gml2_test_prefix(
+           "GEOMETRYCOLLECTION EMPTY",
+           "<MultiGeometry></MultiGeometry>",
+           NULL, 0, "");
+
+       /* GML3 - Empty GeometryCollection */
+       do_gml3_test_prefix(
+           "GEOMETRYCOLLECTION EMPTY",
+           "<MultiGeometry></MultiGeometry>",
+           NULL, 0, 0, "");
+
+       /* GML2 - Nested GeometryCollection */
+       do_gml2_test_prefix(
+           "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
+           "<MultiGeometry><geometryMember><Point><coordinates>0,1</coordinates></Point></geometryMember><geometryMember><MultiGeometry><geometryMember><LineString><coordinates>2,3 4,5</coordinates></LineString></geometryMember></MultiGeometry></geometryMember></MultiGeometry>",
+           NULL, 0, "");
+
+       /* GML3 - Nested GeometryCollection */
+       do_gml3_test_prefix(
+           "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
+           "<MultiGeometry><geometryMember><Point><pos srsDimension=\"2\">0 1</pos></Point></geometryMember><geometryMember><MultiGeometry><geometryMember><Curve><segments><LineStringSegment><posList srsDimension=\"2\">2 3 4 5</posList></LineStringSegment></segments></Curve></geometryMember></MultiGeometry></geometryMember></MultiGeometry>",
+           NULL, 0, 0, "");
+
+
+
+}
+
 /*
 ** Used by test harness to register the tests in this file.
 */
@@ -475,6 +747,7 @@ CU_TestInfo out_gml_tests[] = {
        PG_TEST(out_gml_test_dims),
        PG_TEST(out_gml_test_geodetic),
        PG_TEST(out_gml_test_geoms),
+       PG_TEST(out_gml_test_geoms_prefix),
        CU_TEST_INFO_NULL
 };
 CU_SuiteInfo out_gml_suite = {"GML Out Suite",  NULL,  NULL, out_gml_tests};
index 1c779225ef2d4ddb2d18c54dc00a05601f39c151..6f4c41b3276dd66029a7d624dc1c562c3dd6c334 100644 (file)
@@ -1418,8 +1418,8 @@ extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
 #define OUT_MAX_DOUBLE_PRECISION 15
 #define OUT_MAX_DIGS_DOUBLE (OUT_SHOW_DIGS_DOUBLE + 2) /* +2 mean add dot and sign */
 
-extern char* lwgeom_to_gml2(uchar *geom, char *srs, int precision);
-extern char* lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree);
+extern char* lwgeom_to_gml2(uchar *geom, char *srs, int precision, const char *prefix);
+extern char* lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, const char *prefix);
 extern char* lwgeom_to_kml2(uchar *geom, int precision);
 extern char* lwgeom_to_geojson(uchar *geom, char *srs, int precision, int has_bbox);
 extern char* lwgeom_to_svg(uchar *geom, int precision, int relative);
index 168276fd86f048ad5a03d1788e606e343c764a7d..b65c7c472380c3b7ef6671ef803a905a5110d1dd 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright 2010 Oslandia
  *
  * This is free software; you can redistribute and/or modify it under
- * the terms of hte GNU General Public Licence. See the COPYING file.
+ * the terms of the GNU General Public Licence. See the COPYING file.
  *
  **********************************************************************/
 
 #include "liblwgeom.h"
 #include "liblwgeom.h"
 
-static size_t asgml2_point_size(LWPOINT *point, char *srs, int precision);
-static char *asgml2_point(LWPOINT *point, char *srs, int precision);
-static size_t asgml2_line_size(LWLINE *line, char *srs, int precision);
-static char *asgml2_line(LWLINE *line, char *srs, int precision);
-static size_t asgml2_poly_size(LWPOLY *poly, char *srs, int precision);
-static char *asgml2_poly(LWPOLY *poly, char *srs, int precision);
-static size_t asgml2_multi_size(LWGEOM_INSPECTED *geom, char *srs, int precision);
-static char *asgml2_multi(LWGEOM_INSPECTED *geom, char *srs, int precision);
-static size_t asgml2_collection_size(LWGEOM_INSPECTED *geom, char *srs, int precision);
-static char *asgml2_collection(LWGEOM_INSPECTED *geom, char *srs, int precision);
+static size_t asgml2_point_size(LWPOINT *point, char *srs, int precision, const char *prefix);
+static char *asgml2_point(LWPOINT *point, char *srs, int precision, const char *prefix);
+static size_t asgml2_line_size(LWLINE *line, char *srs, int precision, const char *prefix);
+static char *asgml2_line(LWLINE *line, char *srs, int precision, const char *prefix);
+static size_t asgml2_poly_size(LWPOLY *poly, char *srs, int precision, const char *prefix);
+static char *asgml2_poly(LWPOLY *poly, char *srs, int precision, const char *prefix);
+static size_t asgml2_multi_size(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix);
+static char *asgml2_multi(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix);
+static size_t asgml2_collection_size(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix);
+static char *asgml2_collection(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix);
 static size_t pointArray_toGML2(POINTARRAY *pa, char *buf, int precision);
 
-static size_t asgml3_point_size(LWPOINT *point, char *srs, int precision);
-static char *asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree);
-static size_t asgml3_line_size(LWLINE *line, char *srs, int precision);
-static char *asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree);
-static size_t asgml3_poly_size(LWPOLY *poly, char *srs, int precision);
-static char *asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree);
-static size_t asgml3_multi_size(LWGEOM_INSPECTED *geom, char *srs, int precision);
-static char *asgml3_multi(LWGEOM_INSPECTED *geom, char *srs, int precision, int is_deegree);
-static size_t asgml3_collection_size(LWGEOM_INSPECTED *geom, char *srs, int precision);
-static char *asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree);
+static size_t asgml3_point_size(LWPOINT *point, char *srs, int precision, const char *prefix);
+static char *asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree, const char *prefix);
+static size_t asgml3_line_size(LWLINE *line, char *srs, int precision, const char *prefix);
+static char *asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree, const char *prefix);
+static size_t asgml3_poly_size(LWPOLY *poly, char *srs, int precision, const char *prefix);
+static char *asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree, const char *prefix);
+static size_t asgml3_multi_size(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix);
+static char *asgml3_multi(LWGEOM_INSPECTED *geom, char *srs, int precision, int is_deegree, const char *prefix);
+static size_t asgml3_collection_size(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix);
+static char *asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, const char *prefix);
 static size_t pointArray_toGML3(POINTARRAY *pa, char *buf, int precision, int is_deegree);
 
 static size_t pointArray_GMLsize(POINTARRAY *pa, int precision);
@@ -55,7 +55,7 @@ static size_t pointArray_GMLsize(POINTARRAY *pa, int precision);
  *     takes a GEOMETRY and returns a GML@ representation
  */
 extern char *
-lwgeom_to_gml2(uchar *geom, char *srs, int precision)
+lwgeom_to_gml2(uchar *geom, char *srs, int precision, const char* prefix)
 {
        int type;
        LWPOINT *point;
@@ -69,25 +69,25 @@ lwgeom_to_gml2(uchar *geom, char *srs, int precision)
        {
        case POINTTYPE:
                point = lwpoint_deserialize(geom);
-               return asgml2_point(point, srs, precision);
+               return asgml2_point(point, srs, precision, prefix);
 
        case LINETYPE:
                line = lwline_deserialize(geom);
-               return asgml2_line(line, srs, precision);
+               return asgml2_line(line, srs, precision, prefix);
 
        case POLYGONTYPE:
                poly = lwpoly_deserialize(geom);
-               return asgml2_poly(poly, srs, precision);
+               return asgml2_poly(poly, srs, precision, prefix);
 
        case MULTIPOINTTYPE:
        case MULTILINETYPE:
        case MULTIPOLYGONTYPE:
                inspected = lwgeom_inspect(geom);
-               return asgml2_multi(inspected, srs, precision);
+               return asgml2_multi(inspected, srs, precision, prefix);
 
        case COLLECTIONTYPE:
                inspected = lwgeom_inspect(geom);
-               return asgml2_collection(inspected, srs, precision);
+               return asgml2_collection(inspected, srs, precision, prefix);
 
        default:
                lwerror("lwgeom_to_gml2: '%s' geometry type not supported",
@@ -97,99 +97,104 @@ lwgeom_to_gml2(uchar *geom, char *srs, int precision)
 }
 
 static size_t
-asgml2_point_size(LWPOINT *point, char *srs, int precision)
+asgml2_point_size(LWPOINT *point, char *srs, int precision, const char* prefix)
 {
        int size;
+       size_t prefixlen = strlen(prefix);
+
        size = pointArray_GMLsize(point->point, precision);
-       size += sizeof("<gml:point><gml:coordinates>/") * 2;
+       size += ( sizeof("<point><coordinates>/") + (prefixlen*2) ) * 2;
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
        return size;
 }
 
 static size_t
-asgml2_point_buf(LWPOINT *point, char *srs, char *output, int precision)
+asgml2_point_buf(LWPOINT *point, char *srs, char *output, int precision, const char* prefix)
 {
        char *ptr = output;
 
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:Point srsName=\"%s\">", srs);
+               ptr += sprintf(ptr, "<%sPoint srsName=\"%s\">", prefix, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:Point>");
+               ptr += sprintf(ptr, "<%sPoint>", prefix);
        }
-       ptr += sprintf(ptr, "<gml:coordinates>");
+       ptr += sprintf(ptr, "<%scoordinates>", prefix);
        ptr += pointArray_toGML2(point->point, ptr, precision);
-       ptr += sprintf(ptr, "</gml:coordinates></gml:Point>");
+       ptr += sprintf(ptr, "</%scoordinates></%sPoint>", prefix, prefix);
 
        return (ptr-output);
 }
 
 static char *
-asgml2_point(LWPOINT *point, char *srs, int precision)
+asgml2_point(LWPOINT *point, char *srs, int precision, const char *prefix)
 {
        char *output;
        int size;
 
-       size = asgml2_point_size(point, srs, precision);
+       size = asgml2_point_size(point, srs, precision, prefix);
        output = lwalloc(size);
-       asgml2_point_buf(point, srs, output, precision);
+       asgml2_point_buf(point, srs, output, precision, prefix);
        return output;
 }
 
 static size_t
-asgml2_line_size(LWLINE *line, char *srs, int precision)
+asgml2_line_size(LWLINE *line, char *srs, int precision, const char *prefix)
 {
        int size;
+       size_t prefixlen = strlen(prefix);
+
        size = pointArray_GMLsize(line->points, precision);
-       size += sizeof("<gml:linestring><gml:coordinates>/") * 2;
+       size += ( sizeof("<linestring><coordinates>/") + (prefixlen*2) ) * 2;
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
        return size;
 }
 
 static size_t
-asgml2_line_buf(LWLINE *line, char *srs, char *output, int precision)
+asgml2_line_buf(LWLINE *line, char *srs, char *output, int precision,
+       const char *prefix)
 {
        char *ptr=output;
 
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:LineString srsName=\"%s\">", srs);
+               ptr += sprintf(ptr, "<%sLineString srsName=\"%s\">", prefix, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:LineString>");
+               ptr += sprintf(ptr, "<%sLineString>", prefix);
        }
-       ptr += sprintf(ptr, "<gml:coordinates>");
+       ptr += sprintf(ptr, "<%scoordinates>", prefix);
        ptr += pointArray_toGML2(line->points, ptr, precision);
-       ptr += sprintf(ptr, "</gml:coordinates></gml:LineString>");
+       ptr += sprintf(ptr, "</%scoordinates></%sLineString>", prefix, prefix);
 
        return (ptr-output);
 }
 
 static char *
-asgml2_line(LWLINE *line, char *srs, int precision)
+asgml2_line(LWLINE *line, char *srs, int precision, const char *prefix)
 {
        char *output;
        int size;
 
-       size = asgml2_line_size(line, srs, precision);
+       size = asgml2_line_size(line, srs, precision, prefix);
        output = lwalloc(size);
-       asgml2_line_buf(line, srs, output, precision);
+       asgml2_line_buf(line, srs, output, precision, prefix);
        return output;
 }
 
 static size_t
-asgml2_poly_size(LWPOLY *poly, char *srs, int precision)
+asgml2_poly_size(LWPOLY *poly, char *srs, int precision, const char *prefix)
 {
        size_t size;
        int i;
+       size_t prefixlen = strlen(prefix);
 
-       size = sizeof("<gml:polygon></gml:polygon>");
-       size += sizeof("<gml:outerboundaryis><gml:linearring><gml:coordinates>/") * 2;
-       size += sizeof("<gml:innerboundaryis><gml:linearring><gml:coordinates>/") * 2 *
-               poly->nrings;
+       size = sizeof("<polygon></polygon>") + prefixlen*2;
+       size += ( sizeof("<outerboundaryis><linearring><coordinates>/") + ( prefixlen*3) ) * 2;
+       size += ( sizeof("<innerboundaryis><linearring><coordinates>/") + ( prefixlen*2) ) * 2 * poly->nrings;
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
 
        for (i=0; i<poly->nrings; i++)
@@ -199,42 +204,44 @@ asgml2_poly_size(LWPOLY *poly, char *srs, int precision)
 }
 
 static size_t
-asgml2_poly_buf(LWPOLY *poly, char *srs, char *output, int precision)
+asgml2_poly_buf(LWPOLY *poly, char *srs, char *output, int precision,
+       const char *prefix)
 {
        int i;
        char *ptr=output;
 
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
+               ptr += sprintf(ptr, "<%sPolygon srsName=\"%s\">", prefix, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:Polygon>");
+               ptr += sprintf(ptr, "<%sPolygon>", prefix);
        }
-       ptr += sprintf(ptr, "<gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>");
+       ptr += sprintf(ptr, "<%souterBoundaryIs><%sLinearRing><%scoordinates>",
+               prefix, prefix, prefix);
        ptr += pointArray_toGML2(poly->rings[0], ptr, precision);
-       ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>");
+       ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%souterBoundaryIs>", prefix, prefix, prefix);
        for (i=1; i<poly->nrings; i++)
        {
-               ptr += sprintf(ptr, "<gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>");
+               ptr += sprintf(ptr, "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
                ptr += pointArray_toGML2(poly->rings[i], ptr, precision);
-               ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs>");
+               ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>", prefix, prefix, prefix);
        }
-       ptr += sprintf(ptr, "</gml:Polygon>");
+       ptr += sprintf(ptr, "</%sPolygon>", prefix);
 
        return (ptr-output);
 }
 
 static char *
-asgml2_poly(LWPOLY *poly, char *srs, int precision)
+asgml2_poly(LWPOLY *poly, char *srs, int precision, const char *prefix)
 {
        char *output;
        int size;
 
-       size = asgml2_poly_size(poly, srs, precision);
+       size = asgml2_poly_size(poly, srs, precision, prefix);
        output = lwalloc(size);
-       asgml2_poly_buf(poly, srs, output, precision);
+       asgml2_poly_buf(poly, srs, output, precision, prefix);
        return output;
 }
 
@@ -244,13 +251,16 @@ asgml2_poly(LWPOLY *poly, char *srs, int precision)
  * Don't call this with single-geoms inspected.
  */
 static size_t
-asgml2_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
+asgml2_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision,
+               const char *prefix)
 {
        int i;
        size_t size;
+       size_t prefixlen = strlen(prefix);
 
        /* the longest possible multi version */
-       size = sizeof("<gml:MultiLineString></gml:MultiLineString>");
+       size = sizeof("<MultiLineString></MultiLineString>");
+       size += 2*prefixlen;
 
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
 
@@ -262,20 +272,20 @@ asgml2_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       size += sizeof("<gml:pointMember>/") * 2;
-                       size += asgml2_point_size(point, 0, precision);
+                       size += ( sizeof("<pointMember>/") + prefixlen ) * 2;
+                       size += asgml2_point_size(point, 0, precision, prefix);
                        lwpoint_release(point);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       size += sizeof("<gml:lineStringMember>/") * 2;
-                       size += asgml2_line_size(line, 0, precision);
+                       size += ( sizeof("<lineStringMember>/") + prefixlen ) * 2;
+                       size += asgml2_line_size(line, 0, precision, prefix);
                        lwline_release(line);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       size += sizeof("<gml:polygonMember>/") * 2;
-                       size += asgml2_poly_size(poly, 0, precision);
+                       size += ( sizeof("<polygonMember>/") + prefixlen ) * 2;
+                       size += asgml2_poly_size(poly, 0, precision, prefix);
                        lwpoly_release(poly);
                }
        }
@@ -287,7 +297,8 @@ asgml2_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
  * Don't call this with single-geoms inspected!
  */
 static size_t
-asgml2_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
+asgml2_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output,
+       int precision, const char *prefix)
 {
        int type = lwgeom_getType(insp->serialized_form[0]);
        char *ptr, *gmltype;
@@ -303,11 +314,11 @@ asgml2_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
        /* Open outmost tag */
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:%s srsName=\"%s\">", gmltype, srs);
+               ptr += sprintf(ptr, "<%s%s srsName=\"%s\">", prefix, gmltype, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:%s>", gmltype);
+               ptr += sprintf(ptr, "<%s%s>", prefix, gmltype);
        }
 
        for (i=0; i<insp->ngeometries; i++)
@@ -318,29 +329,29 @@ asgml2_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
 
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       ptr += sprintf(ptr, "<gml:pointMember>");
-                       ptr += asgml2_point_buf(point, 0, ptr, precision);
+                       ptr += sprintf(ptr, "<%spointMember>", prefix);
+                       ptr += asgml2_point_buf(point, 0, ptr, precision, prefix);
                        lwpoint_release(point);
-                       ptr += sprintf(ptr, "</gml:pointMember>");
+                       ptr += sprintf(ptr, "</%spointMember>", prefix);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       ptr += sprintf(ptr, "<gml:lineStringMember>");
-                       ptr += asgml2_line_buf(line, 0, ptr, precision);
+                       ptr += sprintf(ptr, "<%slineStringMember>", prefix);
+                       ptr += asgml2_line_buf(line, 0, ptr, precision, prefix);
                        lwline_release(line);
-                       ptr += sprintf(ptr, "</gml:lineStringMember>");
+                       ptr += sprintf(ptr, "</%slineStringMember>", prefix);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       ptr += sprintf(ptr, "<gml:polygonMember>");
-                       ptr += asgml2_poly_buf(poly, 0, ptr, precision);
+                       ptr += sprintf(ptr, "<%spolygonMember>", prefix);
+                       ptr += asgml2_poly_buf(poly, 0, ptr, precision, prefix);
                        lwpoly_release(poly);
-                       ptr += sprintf(ptr, "</gml:polygonMember>");
+                       ptr += sprintf(ptr, "</%spolygonMember>", prefix);
                }
        }
 
        /* Close outmost tag */
-       ptr += sprintf(ptr, "</gml:%s>", gmltype);
+       ptr += sprintf(ptr, "</%s%s>", prefix, gmltype);
 
        return (ptr-output);
 }
@@ -349,25 +360,29 @@ asgml2_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
  * Don't call this with single-geoms inspected!
  */
 static char *
-asgml2_multi(LWGEOM_INSPECTED *insp, char *srs, int precision)
+asgml2_multi(LWGEOM_INSPECTED *insp, char *srs, int precision,
+               const char *prefix)
 {
        char *gml;
        size_t size;
 
-       size = asgml2_multi_size(insp, srs, precision);
+       size = asgml2_multi_size(insp, srs, precision, prefix);
        gml = lwalloc(size);
-       asgml2_multi_buf(insp, srs, gml, precision);
+       asgml2_multi_buf(insp, srs, gml, precision, prefix);
        return gml;
 }
 
 
 static size_t
-asgml2_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
+asgml2_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision,
+               const char *prefix)
 {
        int i;
        size_t size;
+       size_t prefixlen = strlen(prefix);
 
-       size = sizeof("<gml:MultiGeometry></gml:MultiGeometry>");
+       size = sizeof("<MultiGeometry></MultiGeometry>");
+       size += (prefixlen * 2);
 
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
 
@@ -379,27 +394,27 @@ asgml2_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
                LWGEOM_INSPECTED *subinsp;
                uchar *subgeom;
 
-               size += sizeof("<gml:geometryMember>/") * 2;
+               size += ( sizeof("<geometryMember>/") + prefixlen ) * 2;
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       size += asgml2_point_size(point, 0, precision);
+                       size += asgml2_point_size(point, 0, precision, prefix);
                        lwpoint_release(point);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       size += asgml2_line_size(line, 0, precision);
+                       size += asgml2_line_size(line, 0, precision, prefix);
                        lwline_release(line);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       size += asgml2_poly_size(poly, 0, precision);
+                       size += asgml2_poly_size(poly, 0, precision, prefix);
                        lwpoly_release(poly);
                }
                else
                {
                        subgeom = lwgeom_getsubgeometry_inspected(insp, i);
                        subinsp = lwgeom_inspect(subgeom);
-                       size += asgml2_collection_size(subinsp, 0, precision);
+                       size += asgml2_collection_size(subinsp, 0, precision, prefix);
                        lwinspected_release(subinsp);
                }
        }
@@ -411,7 +426,7 @@ asgml2_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
  * Don't call this with single-geoms inspected!
  */
 static size_t
-asgml2_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
+asgml2_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, const char *prefix)
 {
        char *ptr;
        int i;
@@ -421,11 +436,11 @@ asgml2_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
        /* Open outmost tag */
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:MultiGeometry srsName=\"%s\">", srs);
+               ptr += sprintf(ptr, "<%sMultiGeometry srsName=\"%s\">", prefix, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:MultiGeometry>");
+               ptr += sprintf(ptr, "<%sMultiGeometry>", prefix);
        }
 
        for (i=0; i<insp->ngeometries; i++)
@@ -436,20 +451,20 @@ asgml2_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
                LWGEOM_INSPECTED *subinsp;
                uchar *subgeom;
 
-               ptr += sprintf(ptr, "<gml:geometryMember>");
+               ptr += sprintf(ptr, "<%sgeometryMember>", prefix);
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       ptr += asgml2_point_buf(point, 0, ptr, precision);
+                       ptr += asgml2_point_buf(point, 0, ptr, precision, prefix);
                        lwpoint_release(point);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       ptr += asgml2_line_buf(line, 0, ptr, precision);
+                       ptr += asgml2_line_buf(line, 0, ptr, precision, prefix);
                        lwline_release(line);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       ptr += asgml2_poly_buf(poly, 0, ptr, precision);
+                       ptr += asgml2_poly_buf(poly, 0, ptr, precision, prefix);
                        lwpoly_release(poly);
                }
                else
@@ -457,16 +472,16 @@ asgml2_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
                        subgeom = lwgeom_getsubgeometry_inspected(insp, i);
                        subinsp = lwgeom_inspect(subgeom);
                        if (lwgeom_getType(subgeom[0]) == COLLECTIONTYPE)
-                               ptr += asgml2_collection_buf(subinsp, 0, ptr, precision);
+                               ptr += asgml2_collection_buf(subinsp, 0, ptr, precision, prefix);
                        else
-                               ptr += asgml2_multi_buf(subinsp, 0, ptr, precision);
+                               ptr += asgml2_multi_buf(subinsp, 0, ptr, precision, prefix);
                        lwinspected_release(subinsp);
                }
-               ptr += sprintf(ptr, "</gml:geometryMember>");
+               ptr += sprintf(ptr, "</%sgeometryMember>", prefix);
        }
 
        /* Close outmost tag */
-       ptr += sprintf(ptr, "</gml:MultiGeometry>");
+       ptr += sprintf(ptr, "</%sMultiGeometry>", prefix);
 
        return (ptr-output);
 }
@@ -475,14 +490,15 @@ asgml2_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
  * Don't call this with single-geoms inspected!
  */
 static char *
-asgml2_collection(LWGEOM_INSPECTED *insp, char *srs, int precision)
+asgml2_collection(LWGEOM_INSPECTED *insp, char *srs, int precision,
+               const char *prefix)
 {
        char *gml;
        size_t size;
 
-       size = asgml2_collection_size(insp, srs, precision);
+       size = asgml2_collection_size(insp, srs, precision, prefix);
        gml = lwalloc(size);
-       asgml2_collection_buf(insp, srs, gml, precision);
+       asgml2_collection_buf(insp, srs, gml, precision, prefix);
        return gml;
 }
 
@@ -562,7 +578,8 @@ pointArray_toGML2(POINTARRAY *pa, char *output, int precision)
 
 /* takes a GEOMETRY and returns a GML representation */
 extern char *
-lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree)
+lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree,
+               const char *prefix)
 {
        int type;
        LWPOINT *point;
@@ -576,25 +593,25 @@ lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree)
        {
        case POINTTYPE:
                point = lwpoint_deserialize(geom);
-               return asgml3_point(point, srs, precision, is_deegree);
+               return asgml3_point(point, srs, precision, is_deegree, prefix);
 
        case LINETYPE:
                line = lwline_deserialize(geom);
-               return asgml3_line(line, srs, precision, is_deegree);
+               return asgml3_line(line, srs, precision, is_deegree, prefix);
 
        case POLYGONTYPE:
                poly = lwpoly_deserialize(geom);
-               return asgml3_poly(poly, srs, precision, is_deegree);
+               return asgml3_poly(poly, srs, precision, is_deegree, prefix);
 
        case MULTIPOINTTYPE:
        case MULTILINETYPE:
        case MULTIPOLYGONTYPE:
                inspected = lwgeom_inspect(geom);
-               return asgml3_multi(inspected, srs, precision, is_deegree);
+               return asgml3_multi(inspected, srs, precision, is_deegree, prefix);
 
        case COLLECTIONTYPE:
                inspected = lwgeom_inspect(geom);
-               return asgml3_collection(inspected, srs, precision, is_deegree);
+               return asgml3_collection(inspected, srs, precision, is_deegree, prefix);
 
        default:
                lwerror("lwgeom_to_gml3: '%s' geometry type not supported", lwtype_name(type));
@@ -603,17 +620,20 @@ lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree)
 }
 
 static size_t
-asgml3_point_size(LWPOINT *point, char *srs, int precision)
+asgml3_point_size(LWPOINT *point, char *srs, int precision,
+               const char *prefix)
 {
        int size;
+       size_t prefixlen = strlen(prefix);
+
        size = pointArray_GMLsize(point->point, precision);
-       size += sizeof("<gml:point><gml:pos srsDimension='x'>/") * 2;
+       size += ( sizeof("<point><pos srsDimension='x'>/") + (prefixlen*2) ) * 2;
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
        return size;
 }
 
 static size_t
-asgml3_point_buf(LWPOINT *point, char *srs, char *output, int precision, int is_deegree)
+asgml3_point_buf(LWPOINT *point, char *srs, char *output, int precision, int is_deegree, const char *prefix)
 {
        char *ptr = output;
        int dimension=2;
@@ -621,45 +641,47 @@ asgml3_point_buf(LWPOINT *point, char *srs, char *output, int precision, int is_
        if (TYPE_HASZ(point->type)) dimension = 3;
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:Point srsName=\"%s\">", srs);
+               ptr += sprintf(ptr, "<%sPoint srsName=\"%s\">", prefix, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:Point>");
+               ptr += sprintf(ptr, "<%sPoint>", prefix);
        }
-       ptr += sprintf(ptr, "<gml:pos srsDimension=\"%d\">", dimension);
+       ptr += sprintf(ptr, "<%spos srsDimension=\"%d\">", prefix, dimension);
        ptr += pointArray_toGML3(point->point, ptr, precision, is_deegree);
-       ptr += sprintf(ptr, "</gml:pos></gml:Point>");
+       ptr += sprintf(ptr, "</%spos></%sPoint>", prefix, prefix);
 
        return (ptr-output);
 }
 
 static char *
-asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree)
+asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree, const char *prefix)
 {
        char *output;
        int size;
 
-       size = asgml3_point_size(point, srs, precision);
+       size = asgml3_point_size(point, srs, precision, prefix);
        output = lwalloc(size);
-       asgml3_point_buf(point, srs, output, precision, is_deegree);
+       asgml3_point_buf(point, srs, output, precision, is_deegree, prefix);
        return output;
 }
 
 
 static size_t
-asgml3_line_size(LWLINE *line, char *srs, int precision)
+asgml3_line_size(LWLINE *line, char *srs, int precision, const char *prefix)
 {
        int size;
+       size_t prefixlen = strlen(prefix);
+
        size = pointArray_GMLsize(line->points, precision);
-       size += sizeof("<gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>/") * 2;
+       size += ( sizeof("<Curve><segments><LineStringSegment><posList>/") + ( prefixlen * 4 ) ) * 2;
        size += sizeof(" srsDimension='x'");
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
        return size;
 }
 
 static size_t
-asgml3_line_buf(LWLINE *line, char *srs, char *output, int precision, int is_deegree)
+asgml3_line_buf(LWLINE *line, char *srs, char *output, int precision, int is_deegree, const char *prefix)
 {
        char *ptr=output;
        int dimension=2;
@@ -667,45 +689,46 @@ asgml3_line_buf(LWLINE *line, char *srs, char *output, int precision, int is_dee
        if (TYPE_HASZ(line->type)) dimension = 3;
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:Curve srsName=\"%s\">", srs);
+               ptr += sprintf(ptr, "<%sCurve srsName=\"%s\">", prefix, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:Curve>");
+               ptr += sprintf(ptr, "<%sCurve>", prefix);
        }
-       ptr += sprintf(ptr, "<gml:segments>");
-       ptr += sprintf(ptr, "<gml:LineStringSegment>");
-       ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", dimension);
+       ptr += sprintf(ptr, "<%ssegments>", prefix);
+       ptr += sprintf(ptr, "<%sLineStringSegment>", prefix);
+       ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension);
        ptr += pointArray_toGML3(line->points, ptr, precision, is_deegree);
-       ptr += sprintf(ptr, "</gml:posList></gml:LineStringSegment>");
-       ptr += sprintf(ptr, "</gml:segments>");
-       ptr += sprintf(ptr, "</gml:Curve>");
+       ptr += sprintf(ptr, "</%sposList></%sLineStringSegment>", prefix, prefix);
+       ptr += sprintf(ptr, "</%ssegments>", prefix);
+       ptr += sprintf(ptr, "</%sCurve>", prefix);
 
        return (ptr-output);
 }
 
 static char *
-asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree)
+asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree, const char *prefix)
 {
        char *output;
        int size;
 
-       size = asgml3_line_size(line, srs, precision);
+       size = asgml3_line_size(line, srs, precision, prefix);
        output = lwalloc(size);
-       asgml3_line_buf(line, srs, output, precision, is_deegree);
+       asgml3_line_buf(line, srs, output, precision, is_deegree, prefix);
        return output;
 }
 
 
 static size_t
-asgml3_poly_size(LWPOLY *poly, char *srs, int precision)
+asgml3_poly_size(LWPOLY *poly, char *srs, int precision, const char *prefix)
 {
        size_t size;
+       size_t prefixlen = strlen(prefix);
        int i;
 
-       size = sizeof("<gml:Polygon><gml:exterior><gml:LinearRing>///") * 2;
-       size += sizeof("<gml:interior><gml:LinearRing>//") * 2 * (poly->nrings - 1);
-       size += sizeof("<gml:posList srsDimension='x'></gml:posList>") * poly->nrings;
+       size = ( sizeof("<Polygon><exterior><LinearRing>///") + (prefixlen*3) ) * 2;
+       size += ( sizeof("<interior><LinearRing>//") + (prefixlen*2) ) * 2 * (poly->nrings - 1);
+       size += ( sizeof("<posList srsDimension='x'></posList>") + (prefixlen*2) ) * poly->nrings;
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
 
        for (i=0; i<poly->nrings; i++)
@@ -715,7 +738,7 @@ asgml3_poly_size(LWPOLY *poly, char *srs, int precision)
 }
 
 static size_t
-asgml3_poly_buf(LWPOLY *poly, char *srs, char *output, int precision, int is_deegree)
+asgml3_poly_buf(LWPOLY *poly, char *srs, char *output, int precision, int is_deegree, const char *prefix)
 {
        int i;
        char *ptr=output;
@@ -724,37 +747,39 @@ asgml3_poly_buf(LWPOLY *poly, char *srs, char *output, int precision, int is_dee
        if (TYPE_HASZ(poly->type)) dimension = 3;
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
+               ptr += sprintf(ptr, "<%sPolygon srsName=\"%s\">", prefix, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:Polygon>");
+               ptr += sprintf(ptr, "<%sPolygon>", prefix);
        }
-       ptr += sprintf(ptr, "<gml:exterior><gml:LinearRing>");
-       ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", dimension);
+       ptr += sprintf(ptr, "<%sexterior><%sLinearRing>", prefix, prefix);
+       ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension);
        ptr += pointArray_toGML3(poly->rings[0], ptr, precision, is_deegree);
-       ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:exterior>");
+       ptr += sprintf(ptr, "</%sposList></%sLinearRing></%sexterior>",
+               prefix, prefix, prefix);
        for (i=1; i<poly->nrings; i++)
        {
-               ptr += sprintf(ptr, "<gml:interior><gml:LinearRing>");
-               ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", dimension);
+               ptr += sprintf(ptr, "<%sinterior><%sLinearRing>", prefix, prefix);
+               ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension);
                ptr += pointArray_toGML3(poly->rings[i], ptr, precision, is_deegree);
-               ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:interior>");
+               ptr += sprintf(ptr, "</%sposList></%sLinearRing></%sinterior>",
+                       prefix, prefix, prefix);
        }
-       ptr += sprintf(ptr, "</gml:Polygon>");
+       ptr += sprintf(ptr, "</%sPolygon>", prefix);
 
        return (ptr-output);
 }
 
 static char *
-asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree)
+asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree, const char *prefix)
 {
        char *output;
        int size;
 
-       size = asgml3_poly_size(poly, srs, precision);
+       size = asgml3_poly_size(poly, srs, precision, prefix);
        output = lwalloc(size);
-       asgml3_poly_buf(poly, srs, output, precision, is_deegree);
+       asgml3_poly_buf(poly, srs, output, precision, is_deegree, prefix);
        return output;
 }
 
@@ -765,13 +790,14 @@ asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree)
  * Don't call this with single-geoms inspected.
  */
 static size_t
-asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
+asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision, const char *prefix)
 {
        int i;
        size_t size;
+       size_t prefixlen = strlen(prefix);
 
        /* the longest possible multi version */
-       size = sizeof("<gml:MultiLineString></gml:MultiLineString>");
+       size = sizeof("<MultiLineString></MultiLineString>") + prefixlen*2;
 
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
 
@@ -783,20 +809,20 @@ asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       size += sizeof("<gml:pointMember>/") * 2;
-                       size += asgml3_point_size(point, 0, precision);
+                       size += ( sizeof("<pointMember>/") + prefixlen ) * 2;
+                       size += asgml3_point_size(point, 0, precision, prefix);
                        lwpoint_release(point);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       size += sizeof("<gml:curveMember>/") * 2;
-                       size += asgml3_line_size(line, 0, precision);
+                       size += ( sizeof("<curveMember>/") + prefixlen ) * 2;
+                       size += asgml3_line_size(line, 0, precision, prefix);
                        lwline_release(line);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       size += sizeof("<gml:surfaceMember>/") * 2;
-                       size += asgml3_poly_size(poly, 0, precision);
+                       size += ( sizeof("<surfaceMember>/") + prefixlen ) * 2;
+                       size += asgml3_poly_size(poly, 0, precision, prefix);
                        lwpoly_release(poly);
                }
        }
@@ -808,7 +834,7 @@ asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
  * Don't call this with single-geoms inspected!
  */
 static size_t
-asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree)
+asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree, const char *prefix)
 {
        int type = lwgeom_getType(insp->serialized_form[0]);
        char *ptr, *gmltype;
@@ -824,11 +850,11 @@ asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision,
        /* Open outmost tag */
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:%s srsName=\"%s\">", gmltype, srs);
+               ptr += sprintf(ptr, "<%s%s srsName=\"%s\">", prefix, gmltype, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:%s>", gmltype);
+               ptr += sprintf(ptr, "<%s%s>", prefix, gmltype);
        }
 
        for (i=0; i<insp->ngeometries; i++)
@@ -839,29 +865,29 @@ asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision,
 
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       ptr += sprintf(ptr, "<gml:pointMember>");
-                       ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree);
+                       ptr += sprintf(ptr, "<%spointMember>", prefix);
+                       ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree, prefix);
                        lwpoint_release(point);
-                       ptr += sprintf(ptr, "</gml:pointMember>");
+                       ptr += sprintf(ptr, "</%spointMember>", prefix);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       ptr += sprintf(ptr, "<gml:curveMember>");
-                       ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree);
+                       ptr += sprintf(ptr, "<%scurveMember>", prefix);
+                       ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree, prefix);
                        lwline_release(line);
-                       ptr += sprintf(ptr, "</gml:curveMember>");
+                       ptr += sprintf(ptr, "</%scurveMember>", prefix);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       ptr += sprintf(ptr, "<gml:surfaceMember>");
-                       ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree);
+                       ptr += sprintf(ptr, "<%ssurfaceMember>", prefix);
+                       ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree, prefix);
                        lwpoly_release(poly);
-                       ptr += sprintf(ptr, "</gml:surfaceMember>");
+                       ptr += sprintf(ptr, "</%ssurfaceMember>", prefix);
                }
        }
 
        /* Close outmost tag */
-       ptr += sprintf(ptr, "</gml:%s>", gmltype);
+       ptr += sprintf(ptr, "</%s%s>", prefix, gmltype);
 
        return (ptr-output);
 }
@@ -870,25 +896,26 @@ asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision,
  * Don't call this with single-geoms inspected!
  */
 static char *
-asgml3_multi(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree)
+asgml3_multi(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, const char *prefix)
 {
        char *gml;
        size_t size;
 
-       size = asgml3_multi_size(insp, srs, precision);
+       size = asgml3_multi_size(insp, srs, precision, prefix);
        gml = lwalloc(size);
-       asgml3_multi_buf(insp, srs, gml, precision, is_deegree);
+       asgml3_multi_buf(insp, srs, gml, precision, is_deegree, prefix);
        return gml;
 }
 
 
 static size_t
-asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
+asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision, const char *prefix)
 {
        int i;
        size_t size;
+       size_t prefixlen = strlen(prefix);
 
-       size = sizeof("<gml:MultiGeometry></gml:MultiGeometry>");
+       size = sizeof("<MultiGeometry></MultiGeometry>") + prefixlen*2;
 
        if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
 
@@ -900,27 +927,27 @@ asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
                LWGEOM_INSPECTED *subinsp;
                uchar *subgeom;
 
-               size += sizeof("<gml:geometryMember>/") * 2;
+               size += ( sizeof("<geometryMember>/") + prefixlen ) * 2;
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       size += asgml3_point_size(point, 0, precision);
+                       size += asgml3_point_size(point, 0, precision, prefix);
                        lwpoint_release(point);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       size += asgml3_line_size(line, 0, precision);
+                       size += asgml3_line_size(line, 0, precision, prefix);
                        lwline_release(line);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       size += asgml3_poly_size(poly, 0, precision);
+                       size += asgml3_poly_size(poly, 0, precision, prefix);
                        lwpoly_release(poly);
                }
                else
                {
                        subgeom = lwgeom_getsubgeometry_inspected(insp, i);
                        subinsp = lwgeom_inspect(subgeom);
-                       size += asgml3_multi_size(subinsp, 0, precision);
+                       size += asgml3_multi_size(subinsp, 0, precision, prefix);
                        lwinspected_release(subinsp);
                }
        }
@@ -929,7 +956,7 @@ asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 }
 
 static size_t
-asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree)
+asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree, const char *prefix)
 {
        char *ptr;
        int i;
@@ -939,11 +966,11 @@ asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
        /* Open outmost tag */
        if ( srs )
        {
-               ptr += sprintf(ptr, "<gml:MultiGeometry srsName=\"%s\">", srs);
+               ptr += sprintf(ptr, "<%sMultiGeometry srsName=\"%s\">", prefix, srs);
        }
        else
        {
-               ptr += sprintf(ptr, "<gml:MultiGeometry>");
+               ptr += sprintf(ptr, "<%sMultiGeometry>", prefix);
        }
 
        for (i=0; i<insp->ngeometries; i++)
@@ -954,20 +981,20 @@ asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
                LWGEOM_INSPECTED *subinsp;
                uchar *subgeom;
 
-               ptr += sprintf(ptr, "<gml:geometryMember>");
+               ptr += sprintf(ptr, "<%sgeometryMember>", prefix);
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree);
+                       ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree, prefix);
                        lwpoint_release(point);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree);
+                       ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree, prefix);
                        lwline_release(line);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree);
+                       ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree, prefix);
                        lwpoly_release(poly);
                }
                else
@@ -975,16 +1002,16 @@ asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
                        subgeom = lwgeom_getsubgeometry_inspected(insp, i);
                        subinsp = lwgeom_inspect(subgeom);
                        if (lwgeom_getType(subgeom[0]) == COLLECTIONTYPE)
-                               ptr += asgml3_collection_buf(subinsp, 0, ptr, precision, is_deegree);
+                               ptr += asgml3_collection_buf(subinsp, 0, ptr, precision, is_deegree, prefix);
                        else
-                               ptr += asgml3_multi_buf(subinsp, 0, ptr, precision, is_deegree);
+                               ptr += asgml3_multi_buf(subinsp, 0, ptr, precision, is_deegree, prefix);
                        lwinspected_release(subinsp);
                }
-               ptr += sprintf(ptr, "</gml:geometryMember>");
+               ptr += sprintf(ptr, "</%sgeometryMember>", prefix);
        }
 
        /* Close outmost tag */
-       ptr += sprintf(ptr, "</gml:MultiGeometry>");
+       ptr += sprintf(ptr, "</%sMultiGeometry>", prefix);
 
        return (ptr-output);
 }
@@ -993,14 +1020,14 @@ asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
  * Don't call this with single-geoms inspected!
  */
 static char *
-asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree)
+asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, const char *prefix)
 {
        char *gml;
        size_t size;
 
-       size = asgml3_collection_size(insp, srs, precision);
+       size = asgml3_collection_size(insp, srs, precision, prefix);
        gml = lwalloc(size);
-       asgml3_collection_buf(insp, srs, gml, precision, is_deegree);
+       asgml3_collection_buf(insp, srs, gml, precision, is_deegree, prefix);
        return gml;
 }
 
index 01cd5567e2cc3f48ab1827cec8077803ee60b376..eb234925a7a00d7f1ab454555d04b662a72b8cf5 100644 (file)
@@ -510,6 +510,7 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
        int precision = OUT_MAX_DOUBLE_PRECISION;
        int option=0;
        int is_deegree=0;
+       const char *prefix = "gml:";
 
        /* Get the version */
        version = PG_GETARG_INT32(0);
@@ -551,9 +552,9 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
        if (option & 1) is_deegree = 1;
 
        if (version == 2)
-               gml = lwgeom_to_gml2(lwgeom_serialize(lwgeom), srs, precision);
+               gml = lwgeom_to_gml2(lwgeom_serialize(lwgeom), srs, precision, prefix);
        else
-               gml = lwgeom_to_gml3(lwgeom_serialize(lwgeom), srs, precision, is_deegree);
+               gml = lwgeom_to_gml3(lwgeom_serialize(lwgeom), srs, precision, is_deegree, prefix);
 
        PG_FREE_IF_COPY(lwgeom, 1);
 
index b17875fa6da8b304d9f368d0b261bcc36f8ffd96..69a13bd8c2e65f322e5537c4e903b79c28db3803 100644 (file)
@@ -107,6 +107,7 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
        int option = 0;
        int is_deegree = 0;
        int precision = OUT_MAX_DOUBLE_PRECISION;
+       const char* prefix = "gml:"; /* default prefix */
 
        /* Get the version */
        version = PG_GETARG_INT32(0);
@@ -141,9 +142,9 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
        if (option & 16) is_deegree = 1;
 
        if (version == 2)
-               gml = lwgeom_to_gml2(SERIALIZED_FORM(geom), srs, precision);
+               gml = lwgeom_to_gml2(SERIALIZED_FORM(geom), srs, precision, prefix);
        else
-               gml = lwgeom_to_gml3(SERIALIZED_FORM(geom), srs, precision, is_deegree);
+               gml = lwgeom_to_gml3(SERIALIZED_FORM(geom), srs, precision, is_deegree, prefix);
 
        PG_FREE_IF_COPY(geom, 1);