]> granicus.if.org Git - postgis/commitdiff
Move ST_AsKML from postgis to liblwgeom dir. Use as most cunit test as possible....
authorOlivier Courtin <olivier.courtin@camptocamp.com>
Sun, 21 Feb 2010 20:32:11 +0000 (20:32 +0000)
committerOlivier Courtin <olivier.courtin@camptocamp.com>
Sun, 21 Feb 2010 20:32:11 +0000 (20:32 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@5277 b70326c6-7e19-0410-871a-916f4a2858ee

15 files changed:
liblwgeom/Makefile.in
liblwgeom/cunit/Makefile.in
liblwgeom/cunit/cu_out_gml.c [new file with mode: 0644]
liblwgeom/cunit/cu_out_gml.h [new file with mode: 0644]
liblwgeom/cunit/cu_out_kml.c [new file with mode: 0644]
liblwgeom/cunit/cu_out_kml.h [new file with mode: 0644]
liblwgeom/cunit/cu_tester.c
liblwgeom/cunit/cu_tester.h
liblwgeom/liblwgeom.h
liblwgeom/lwout_gml.c
liblwgeom/lwout_kml.c [new file with mode: 0644]
postgis/geography_inout.c
postgis/lwgeom_kml.c
regress/kml.sql
regress/kml_expected

index f5b5b4c189b6f6e2a589b7be6699d307e9f9972c..04c155cb19a64b6307becf66c653db2a4cc1c7e5 100644 (file)
@@ -53,7 +53,8 @@ SA_OBJS = \
        g_util.o \
        lwgeodetic.o \
        lwtree.o \
-       lwout_gml.o
+       lwout_gml.o \
+       lwout_kml.o
 
 NM_OBJS = \
        lwspheroid.o 
index 7cd26f8cb463c54e82a71dbc965b97c504cfa085..24ba5aa499bfdf899b56ba7a1c2047640ff74a7f 100644 (file)
@@ -23,6 +23,7 @@ OBJS= \
        cu_libgeom.o \
        cu_homogenize.o \
        cu_out_gml.o \
+       cu_out_kml.o \
        cu_tester.o 
 
 # If we couldn't find the cunit library then display a helpful message
diff --git a/liblwgeom/cunit/cu_out_gml.c b/liblwgeom/cunit/cu_out_gml.c
new file mode 100644 (file)
index 0000000..108204b
--- /dev/null
@@ -0,0 +1,486 @@
+/**********************************************************************
+ * $Id$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2010 Olivier Courtin <olivier.courtin@oslandia.com>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include "cu_out_gml.h"
+
+/*
+** Called from test harness to register the tests in this file.
+*/
+CU_pSuite register_out_gml_suite(void)
+{
+       CU_pSuite pSuite;
+       pSuite = CU_add_suite("GML Out Suite", init_out_gml_suite, clean_out_gml_suite);
+       if (NULL == pSuite)
+       {
+               CU_cleanup_registry();
+               return NULL;
+       }
+
+       if (
+           (NULL == CU_add_test(pSuite, "test_precision()", out_gml_test_precision)) ||
+           (NULL == CU_add_test(pSuite, "test_srid()", out_gml_test_srid)) ||
+           (NULL == CU_add_test(pSuite, "test_dims()", out_gml_test_dims)) ||
+           (NULL == CU_add_test(pSuite, "test_geodetic()", out_gml_test_geodetic)) ||
+           (NULL == CU_add_test(pSuite, "test_geoms()", out_gml_test_geoms))
+       )
+       {
+               CU_cleanup_registry();
+               return NULL;
+       }
+       return pSuite;
+}
+
+/*
+** The suite initialization function.
+** Create any re-used objects.
+*/
+int init_out_gml_suite(void)
+{
+       return 0;
+}
+
+/*
+** The suite cleanup function.
+** Frees any global objects.
+*/
+int clean_out_gml_suite(void)
+{
+       return 0;
+}
+
+static void do_gml2_test(char * in, char * out, char * srs, int precision)
+{
+       LWGEOM *g, *h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+       h = lwgeom_to_gml2(lwgeom_serialize(g), srs, precision);
+
+       if (strcmp(lwgeom_to_gml2(lwgeom_serialize(g), srs, precision), out))
+               fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n",
+                       in,
+                       lwgeom_to_gml2(lwgeom_serialize(g), srs, precision),
+                       out);
+
+       CU_ASSERT_STRING_EQUAL(h, out);
+
+       lwgeom_free(g);
+       lwfree(h);
+}
+
+
+static void do_gml3_test(char * in, char * out, char * srs, int precision, int is_geodetic)
+{
+       LWGEOM *g, *h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+       h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic);
+
+       if (strcmp(
+                   lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic),
+                   out))
+               fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n",
+                       in,
+                       lwgeom_to_gml3(lwgeom_serialize(g),
+                                      srs, precision, is_geodetic),
+                       out);
+
+       CU_ASSERT_STRING_EQUAL(h, out);
+
+       lwgeom_free(g);
+       lwfree(h);
+}
+
+static void do_gml2_unsupported(char * in, char * out)
+{
+       LWGEOM *g, *h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+
+       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",
+                       in, cu_error_msg, out);
+       CU_ASSERT_STRING_EQUAL(out, cu_error_msg);
+       cu_error_msg_reset();
+
+       lwfree(h);
+       lwgeom_free(g);
+}
+
+static void do_gml3_unsupported(char * in, char * out)
+{
+       LWGEOM *g, *h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+       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",
+                       in, cu_error_msg, out);
+
+       CU_ASSERT_STRING_EQUAL(out, cu_error_msg);
+       cu_error_msg_reset();
+
+       lwfree(h);
+       lwgeom_free(g);
+}
+
+
+void out_gml_test_precision(void)
+{
+       /* GML2 - 0 precision, i.e a round */
+       do_gml2_test(
+           "POINT(1.1111111111111 1.1111111111111)",
+           "<gml:Point><gml:coordinates>1,1</gml:coordinates></gml:Point>",
+           NULL, 0);
+
+       /* GML3 - 0 precision, i.e a round */
+       do_gml3_test(
+           "POINT(1.1111111111111 1.1111111111111)",
+           "<gml:Point><gml:pos srsDimension=\"2\">1 1</gml:pos></gml:Point>",
+           NULL, 0, 0);
+
+
+       /* GML2 - 3 digits precision */
+       do_gml2_test(
+           "POINT(1.1111111111111 1.1111111111111)",
+           "<gml:Point><gml:coordinates>1.111,1.111</gml:coordinates></gml:Point>",
+           NULL, 3);
+
+       /* GML3 - 3 digits precision */
+       do_gml3_test(
+           "POINT(1.1111111111111 1.1111111111111)",
+           "<gml:Point><gml:pos srsDimension=\"2\">1.111 1.111</gml:pos></gml:Point>",
+           NULL, 3, 0);
+
+
+       /* GML2 - huge digits precision, limit is in fact 15 */
+       do_gml2_test(
+           "POINT(1.2345678901234 1.2345678901234)",
+           "<gml:Point><gml:coordinates>1.23456789,1.23456789</gml:coordinates></gml:Point>",
+           NULL, 9);
+
+       /* GML3 - huge digits precision, limit is in fact 15 */
+       do_gml3_test(
+           "POINT(1.2345678901234 1.2345678901234)",
+           "<gml:Point><gml:pos srsDimension=\"2\">1.23456789 1.23456789</gml:pos></gml:Point>",
+           NULL, 9, 0);
+
+
+       /* GML2 - huge data */
+       do_gml2_test(
+           "POINT(1E300 -1E300)",
+           "<gml:Point><gml:coordinates>1e+300,-1e+300</gml:coordinates></gml:Point>",
+           NULL, 0);
+
+       /* GML3 - huge data */
+       do_gml3_test(
+           "POINT(1E300 -1E300)",
+           "<gml:Point><gml:pos srsDimension=\"2\">1e+300 -1e+300</gml:pos></gml:Point>",
+           NULL, 0, 0);
+}
+
+void out_gml_test_srid(void)
+{
+       /* GML2 - Point with SRID */
+       do_gml2_test(
+           "POINT(0 1)",
+           "<gml:Point srsName=\"EPSG:4326\"><gml:coordinates>0,1</gml:coordinates></gml:Point>",
+           "EPSG:4326", 0);
+
+       /* GML3 - Point with SRID */
+       do_gml3_test(
+           "POINT(0 1)",
+           "<gml:Point srsName=\"EPSG:4326\"><gml:pos srsDimension=\"2\">0 1</gml:pos></gml:Point>",
+           "EPSG:4326", 0, 0);
+
+
+       /* GML2 - Linestring with SRID */
+       do_gml2_test(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<gml:LineString srsName=\"EPSG:4326\"><gml:coordinates>0,1 2,3 4,5</gml:coordinates></gml:LineString>",
+           "EPSG:4326", 0);
+
+       /* GML3 - Linestring with SRID */
+       do_gml3_test(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<gml:Curve srsName=\"EPSG:4326\"><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">0 1 2 3 4 5</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve>",
+           "EPSG:4326", 0, 0);
+
+
+       /* GML2 Polygon with SRID */
+       do_gml2_test(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<gml:Polygon srsName=\"EPSG:4326\"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>0,1 2,3 4,5 0,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>",
+           "EPSG:4326", 0);
+
+       /* GML3 Polygon with SRID */
+       do_gml3_test(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<gml:Polygon srsName=\"EPSG:4326\"><gml:exterior><gml:LinearRing><gml:posList srsDimension=\"2\">0 1 2 3 4 5 0 1</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon>",
+           "EPSG:4326", 0, 0);
+
+
+       /* GML2 Multiline with SRID */
+       do_gml2_test(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<gml:MultiLineString srsName=\"EPSG:4326\"><gml:lineStringMember><gml:LineString><gml:coordinates>0,1 2,3 4,5</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>6,7 8,9 10,11</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString>",
+           "EPSG:4326", 0);
+
+
+       /* GML3 Multiline with SRID */
+       do_gml3_test(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<gml:MultiCurve srsName=\"EPSG:4326\"><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">0 1 2 3 4 5</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">6 7 8 9 10 11</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve>",
+           "EPSG:4326", 0, 0);
+
+
+       /* GML2 MultiPolygon with SRID */
+       do_gml2_test(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<gml:MultiPolygon srsName=\"EPSG:4326\"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>0,1 2,3 4,5 0,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6,7 8,9 10,11 6,7</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon>",
+           "EPSG:4326", 0);
+
+       /* GML3 MultiPolygon with SRID */
+       do_gml3_test(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<gml:MultiSurface srsName=\"EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList srsDimension=\"2\">0 1 2 3 4 5 0 1</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList srsDimension=\"2\">6 7 8 9 10 11 6 7</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface>",
+           "EPSG:4326", 0, 0);
+
+       /* GML2 GeometryCollection with SRID */
+       do_gml2_test(
+           "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
+           "<gml:MultiGeometry srsName=\"EPSG:4326\"><gml:geometryMember><gml:Point><gml:coordinates>0,1</gml:coordinates></gml:Point></gml:geometryMember><gml:geometryMember><gml:LineString><gml:coordinates>2,3 4,5</gml:coordinates></gml:LineString></gml:geometryMember></gml:MultiGeometry>",
+           "EPSG:4326", 0);
+
+       /* GML3 GeometryCollection with SRID */
+       do_gml3_test(
+           "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
+           "<gml:MultiGeometry srsName=\"EPSG:4326\"><gml:geometryMember><gml:Point><gml:pos srsDimension=\"2\">0 1</gml:pos></gml:Point></gml:geometryMember><gml:geometryMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">2 3 4 5</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:geometryMember></gml:MultiGeometry>",
+           "EPSG:4326", 0, 0);
+}
+
+
+void out_gml_test_geodetic(void)
+{
+       /* GML3 - Geodetic Point */
+       do_gml3_test(
+           "POINT(0 1)",
+           "<gml:Point srsName=\"urn:ogc:def:crs:EPSG:4326\"><gml:pos srsDimension=\"2\">1 0</gml:pos></gml:Point>",
+           "urn:ogc:def:crs:EPSG:4326", 0, 1);
+
+       /* GML3 - 3D Geodetic Point */
+       do_gml3_test(
+           "POINT(0 1 2)",
+           "<gml:Point srsName=\"urn:ogc:def:crs:EPSG:4326\"><gml:pos srsDimension=\"3\">1 0 2</gml:pos></gml:Point>",
+           "urn:ogc:def:crs:EPSG:4326", 0, 1);
+}
+
+
+void out_gml_test_dims(void)
+{
+       /* GML2 - 3D */
+       do_gml2_test(
+           "POINT(0 1 2)",
+           "<gml:Point><gml:coordinates>0,1,2</gml:coordinates></gml:Point>",
+           NULL, 0);
+
+       /* GML3 - 3D */
+       do_gml3_test(
+           "POINT(0 1 2)",
+           "<gml:Point><gml:pos srsDimension=\"3\">0 1 2</gml:pos></gml:Point>",
+           NULL, 0, 0);
+
+
+       /* GML2 - 3DM */
+       do_gml2_test(
+           "POINTM(0 1 2)",
+           "<gml:Point><gml:coordinates>0,1</gml:coordinates></gml:Point>",
+           NULL, 0);
+
+       /* GML3 - 3DM */
+       do_gml3_test(
+           "POINTM(0 1 2)",
+           "<gml:Point><gml:pos srsDimension=\"2\">0 1</gml:pos></gml:Point>",
+           NULL, 0, 0);
+
+
+       /* GML2 - 4D */
+       do_gml2_test(
+           "POINT(0 1 2 3)",
+           "<gml:Point><gml:coordinates>0,1,2</gml:coordinates></gml:Point>",
+           NULL, 0);
+
+       /* GML3 - 4D */
+       do_gml3_test(
+           "POINT(0 1 2 3)",
+           "<gml:Point><gml:pos srsDimension=\"3\">0 1 2</gml:pos></gml:Point>",
+           NULL, 0, 0);
+}
+
+
+void out_gml_test_geoms(void)
+{
+       /* GML2 - Linestring */
+       do_gml2_test(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<gml:LineString><gml:coordinates>0,1 2,3 4,5</gml:coordinates></gml:LineString>",
+           NULL, 0);
+
+       /* GML3 - Linestring */
+       do_gml3_test(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<gml:Curve><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">0 1 2 3 4 5</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve>",
+           NULL, 0, 0);
+
+
+       /* GML2 Polygon */
+       do_gml2_test(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>0,1 2,3 4,5 0,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>",
+           NULL, 0);
+
+       /* GML3 Polygon */
+       do_gml3_test(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<gml:Polygon><gml:exterior><gml:LinearRing><gml:posList srsDimension=\"2\">0 1 2 3 4 5 0 1</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon>",
+           NULL, 0, 0);
+
+
+       /* GML2 Polygon - with internal ring */
+       do_gml2_test(
+           "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
+           "<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>0,1 2,3 4,5 0,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>6,7 8,9 10,11 6,7</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>",
+           NULL, 0);
+
+       /* GML3 Polygon - with internal ring */
+       do_gml3_test(
+           "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
+           "<gml:Polygon><gml:exterior><gml:LinearRing><gml:posList srsDimension=\"2\">0 1 2 3 4 5 0 1</gml:posList></gml:LinearRing></gml:exterior><gml:interior><gml:LinearRing><gml:posList srsDimension=\"2\">6 7 8 9 10 11 6 7</gml:posList></gml:LinearRing></gml:interior></gml:Polygon>",
+           NULL, 0, 0);
+
+
+       /* GML2 Multiline */
+       do_gml2_test(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<gml:MultiLineString><gml:lineStringMember><gml:LineString><gml:coordinates>0,1 2,3 4,5</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates>6,7 8,9 10,11</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString>",
+           NULL, 0);
+
+       /* GML3 Multiline */
+       do_gml3_test(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<gml:MultiCurve><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">0 1 2 3 4 5</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">6 7 8 9 10 11</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve>",
+           NULL, 0, 0);
+
+
+       /* GML2 MultiPolygon */
+       do_gml2_test(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<gml:MultiPolygon><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>0,1 2,3 4,5 0,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6,7 8,9 10,11 6,7</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon>",
+           NULL, 0);
+
+       /* GML3 MultiPolygon */
+       do_gml3_test(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<gml:MultiSurface><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList srsDimension=\"2\">0 1 2 3 4 5 0 1</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList srsDimension=\"2\">6 7 8 9 10 11 6 7</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface>",
+           NULL, 0, 0);
+
+
+       /* GML2 - GeometryCollection */
+       do_gml2_test(
+           "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
+           "<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:coordinates>0,1</gml:coordinates></gml:Point></gml:geometryMember><gml:geometryMember><gml:LineString><gml:coordinates>2,3 4,5</gml:coordinates></gml:LineString></gml:geometryMember></gml:MultiGeometry>",
+           NULL, 0);
+
+       /* GML3 - GeometryCollection */
+       do_gml3_test(
+           "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))",
+           "<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:pos srsDimension=\"2\">0 1</gml:pos></gml:Point></gml:geometryMember><gml:geometryMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">2 3 4 5</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:geometryMember></gml:MultiGeometry>",
+           NULL, 0, 0);
+
+
+       /* GML2 - Empty GeometryCollection */
+       do_gml2_test(
+           "GEOMETRYCOLLECTION EMPTY",
+           "<gml:MultiGeometry></gml:MultiGeometry>",
+           NULL, 0);
+
+       /* GML3 - Empty GeometryCollection */
+       do_gml3_test(
+           "GEOMETRYCOLLECTION EMPTY",
+           "<gml:MultiGeometry></gml:MultiGeometry>",
+           NULL, 0, 0);
+
+       /* GML2 - Nested GeometryCollection */
+       do_gml2_test(
+           "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
+           "<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:coordinates>0,1</gml:coordinates></gml:Point></gml:geometryMember><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:LineString><gml:coordinates>2,3 4,5</gml:coordinates></gml:LineString></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry>",
+           NULL, 0);
+
+       /* GML3 - Nested GeometryCollection */
+       do_gml3_test(
+           "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))",
+           "<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:pos srsDimension=\"2\">0 1</gml:pos></gml:Point></gml:geometryMember><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList srsDimension=\"2\">2 3 4 5</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry>",
+           NULL, 0, 0);
+
+
+
+       /* GML2 - CircularString */
+       do_gml2_unsupported(
+           "CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)",
+           "lwgeom_to_gml2: 'CircularString' geometry type not supported");
+       /* GML3 - CircularString */
+       do_gml3_unsupported(
+           "CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)",
+           "lwgeom_to_gml3: 'CircularString' geometry type not supported");
+
+       /* GML2 - CompoundString */
+       do_gml2_unsupported(
+           "COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))",
+           "lwgeom_to_gml2: 'CompoundString' geometry type not supported");
+       /* GML3 - CompoundString */
+       do_gml3_unsupported(
+           "COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))",
+           "lwgeom_to_gml3: 'CompoundString' geometry type not supported");
+
+       /* GML2 - CurvePolygon */
+       do_gml2_unsupported(
+           "CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))",
+           "lwgeom_to_gml2: 'CurvePolygon' geometry type not supported");
+
+       /* GML3 - CurvePolygon */
+       do_gml3_unsupported(
+           "CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))",
+           "lwgeom_to_gml3: 'CurvePolygon' geometry type not supported");
+
+
+       /* GML2 - MultiCurve */
+       do_gml2_unsupported(
+           "MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))",
+           "lwgeom_to_gml2: 'MultiCurve' geometry type not supported");
+
+       /* GML3 - MultiCurve */
+       do_gml3_unsupported(
+           "MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))",
+           "lwgeom_to_gml3: 'MultiCurve' geometry type not supported");
+
+       /* GML2 - MultiSurface */
+       do_gml2_unsupported(
+           "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))",
+           "lwgeom_to_gml2: 'MultiSurface' geometry type not supported");
+
+       /* GML3 - MultiSurface */
+       do_gml3_unsupported(
+           "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))",
+           "lwgeom_to_gml3: 'MultiSurface' geometry type not supported");
+}
diff --git a/liblwgeom/cunit/cu_out_gml.h b/liblwgeom/cunit/cu_out_gml.h
new file mode 100644 (file)
index 0000000..58c746c
--- /dev/null
@@ -0,0 +1,29 @@
+/**********************************************************************
+ * $Id:$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2010 Olivier Courtin <olivier.courtin@oslandia.com>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "CUnit/Basic.h"
+
+#include "libgeom.h"
+#include "cu_tester.h"
+
+/**********************************************************************/
+
+
+/* Test functions */
+void out_gml_test_precision(void);
+void out_gml_test_srid(void);
+void out_gml_test_geodetic(void);
+void out_gml_test_geoms(void);
+void out_gml_test_dims(void);
diff --git a/liblwgeom/cunit/cu_out_kml.c b/liblwgeom/cunit/cu_out_kml.c
new file mode 100644 (file)
index 0000000..25d3c8f
--- /dev/null
@@ -0,0 +1,207 @@
+/**********************************************************************
+ * $Id$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2010 Olivier Courtin <olivier.courtin@oslandia.com>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include "cu_out_kml.h"
+
+/*
+** Called from test harness to register the tests in this file.
+*/
+CU_pSuite register_out_kml_suite(void)
+{
+       CU_pSuite pSuite;
+       pSuite = CU_add_suite("KML Out Suite", init_out_kml_suite, clean_out_kml_suite);
+       if (NULL == pSuite)
+       {
+               CU_cleanup_registry();
+               return NULL;
+       }
+
+       if (
+           (NULL == CU_add_test(pSuite, "test_precision()", out_kml_test_precision)) ||
+           (NULL == CU_add_test(pSuite, "test_dims()", out_kml_test_dims)) ||
+           (NULL == CU_add_test(pSuite, "test_geoms()", out_kml_test_geoms))
+       )
+       {
+               CU_cleanup_registry();
+               return NULL;
+       }
+       return pSuite;
+}
+
+/*
+** The suite initialization function.
+** Create any re-used objects.
+*/
+int init_out_kml_suite(void)
+{
+       return 0;
+}
+
+/*
+** The suite cleanup function.
+** Frees any global objects.
+*/
+int clean_out_kml_suite(void)
+{
+       return 0;
+}
+
+static void do_kml_test(char * in, char * out, int precision)
+{
+       LWGEOM *g;
+       char * h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+       h = lwgeom_to_kml2(lwgeom_serialize(g), precision);
+
+       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_kml_unsupported(char * in, char * out)
+{
+       LWGEOM *g;
+       char *h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+       h = lwgeom_to_kml2(lwgeom_serialize(g), 0);
+
+       if (strcmp(cu_error_msg, out))
+               fprintf(stderr, "\nGML 2 - In:   %s\nOut:  %s\nTheo: %s\n",
+                       in, cu_error_msg, out);
+
+       CU_ASSERT_STRING_EQUAL(out, cu_error_msg);
+       cu_error_msg_reset();
+
+       lwfree(h);
+       lwgeom_free(g);
+}
+
+
+void out_kml_test_precision(void)
+{
+       /* 0 precision, i.e a round */
+       do_kml_test(
+           "POINT(1.1111111111111 1.1111111111111)",
+           "<Point><coordinates>1,1</coordinates></Point>",
+           0);
+
+       /* 3 digits precision */
+       do_kml_test(
+           "POINT(1.1111111111111 1.1111111111111)",
+           "<Point><coordinates>1.111,1.111</coordinates></Point>",
+           3);
+
+       /* huge digits precision, limit is in fact 15 */
+       do_kml_test(
+           "POINT(1.2345678901234 1.2345678901234)",
+           "<Point><coordinates>1.23456789,1.23456789</coordinates></Point>",
+           9);
+
+       /* huge data */
+       do_kml_test(
+           "POINT(1E300 -1E300)",
+           "<Point><coordinates>1e+300,-1e+300</coordinates></Point>",
+           0);
+}
+
+
+void out_kml_test_dims(void)
+{
+       /* 3D */
+       do_kml_test(
+           "POINT(0 1 2)",
+           "<Point><coordinates>0,1,2</coordinates></Point>",
+           0);
+
+       /* 3DM */
+       do_kml_test(
+           "POINTM(0 1 2)",
+           "<Point><coordinates>0,1</coordinates></Point>",
+           0);
+
+       /* 4D */
+       do_kml_test(
+           "POINT(0 1 2 3)",
+           "<Point><coordinates>0,1,2</coordinates></Point>",
+           0);
+}
+
+
+void out_kml_test_geoms(void)
+{
+       /* Linestring */
+       do_kml_test(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<LineString><coordinates>0,1 2,3 4,5</coordinates></LineString>",
+           0);
+
+       /* Polygon */
+       do_kml_test(
+           "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>",
+           0);
+
+       /* Polygon - with internal ring */
+       do_kml_test(
+           "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>",
+           0);
+
+       /* Multiline */
+       do_kml_test(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<MultiGeometry><LineString><coordinates>0,1 2,3 4,5</coordinates></LineString><LineString><coordinates>6,7 8,9 10,11</coordinates></LineString></MultiGeometry>",
+           0);
+
+       /* MultiPolygon */
+       do_kml_test(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>0,1 2,3 4,5 0,1</coordinates></LinearRing></outerBoundaryIs></Polygon><Polygon><outerBoundaryIs><LinearRing><coordinates>6,7 8,9 10,11 6,7</coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>",
+           0);
+
+       /* GeometryCollection */
+       do_kml_unsupported(
+           "GEOMETRYCOLLECTION(POINT(0 1))",
+           "lwgeom_to_kml2: 'GeometryCollection' geometry type not supported");
+
+       /* CircularString */
+       do_kml_unsupported(
+           "CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)",
+           "lwgeom_to_kml2: 'CircularString' geometry type not supported");
+
+       /* CompoundString */
+       do_kml_unsupported(
+           "COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))",
+           "lwgeom_to_kml2: 'CompoundString' geometry type not supported");
+
+       /* CurvePolygon */
+       do_kml_unsupported(
+           "CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))",
+           "lwgeom_to_kml2: 'CurvePolygon' geometry type not supported");
+
+       /* MultiCurve */
+       do_kml_unsupported(
+           "MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))",
+           "lwgeom_to_kml2: 'MultiCurve' geometry type not supported");
+
+       /* GML2 - MultiSurface */
+       do_kml_unsupported(
+           "MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))",
+           "lwgeom_to_kml2: 'MultiSurface' geometry type not supported");
+}
diff --git a/liblwgeom/cunit/cu_out_kml.h b/liblwgeom/cunit/cu_out_kml.h
new file mode 100644 (file)
index 0000000..7f33c1c
--- /dev/null
@@ -0,0 +1,27 @@
+/**********************************************************************
+ * $Id:$
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2010 Olivier Courtin <olivier.courtin@oslandia.com>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "CUnit/Basic.h"
+
+#include "libgeom.h"
+#include "cu_tester.h"
+
+/**********************************************************************/
+
+
+/* Test functions */
+void out_kml_test_precision(void);
+void out_kml_test_geoms(void);
+void out_kml_test_dims(void);
index e3d1b3df07dffd3a623beeaf59cf435440678fb0..fd02e7d55cbb354ed77dc8599f1e70fc08d8fb38 100644 (file)
@@ -57,7 +57,6 @@ void lwgeom_init_allocators(void)
        lwfree_var = default_freeor;
        lwnotice_var = default_noticereporter;
        lwerror_var = cu_errorreporter;
-
 }
 
 /*
@@ -107,18 +106,24 @@ int main()
                return CU_get_error();
        }
 
-       /* Add the homogenize suite to the registry */
+       /* Add the gml suite to the registry */
        if (NULL == register_out_gml_suite())
        {
                CU_cleanup_registry();
                return CU_get_error();
        }
 
+       /* Add the kml suite to the registry */
+       if (NULL == register_out_kml_suite())
+       {
+               CU_cleanup_registry();
+               return CU_get_error();
+       }
+
        /* Run all tests using the CUnit Basic interface */
        CU_basic_set_mode(CU_BRM_VERBOSE);
        CU_basic_run_tests();
        CU_cleanup_registry();
 
        return CU_get_error();
-
 }
index 37c6266b78b7c7c7f3f447b7b4c2b105dacba8fa..1cd146c3f36f37355818194dcce5bb16f69bc4fa 100644 (file)
@@ -8,6 +8,7 @@ CU_pSuite register_libgeom_suite(void);
 CU_pSuite register_cg_suite(void);
 CU_pSuite register_homogenize_suite(void);
 CU_pSuite register_out_gml_suite(void);
+CU_pSuite register_out_kml_suite(void);
 
 int init_measures_suite(void);
 int init_geodetic_suite(void);
@@ -15,6 +16,7 @@ int init_libgeom_suite(void);
 int init_cg_suite(void);
 int init_homogenize_suite(void);
 int init_out_gml_suite(void);
+int init_out_kml_suite(void);
 
 int clean_measures_suite(void);
 int clean_geodetic_suite(void);
@@ -22,4 +24,5 @@ int clean_libgeom_suite(void);
 int clean_cg_suite(void);
 int clean_homogenize_suite(void);
 int clean_out_gml_suite(void);
+int clean_out_kml_suite(void);
 
index 1da0184e73d156f7785278fc477f92ce1887f382..f20f75f9d22fcb73e2c2abf75c3ae4dd87e7c40f 100644 (file)
@@ -1408,6 +1408,7 @@ extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
 
 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_kml2(uchar *geom, int precision);
 
 
 extern uchar parse_hex(char *str);
index bbebd1c467884a1df6396dadf057f7429081c1d1..655f982679b49f9e402218d34c3cacc54e829c0f 100644 (file)
@@ -57,185 +57,185 @@ static size_t pointArray_GMLsize(POINTARRAY *pa, int precision);
 extern char *
 lwgeom_to_gml2(uchar *geom, char *srs, int precision)
 {
-    int type;
-    LWPOINT *point;
-    LWLINE *line;
-    LWPOLY *poly;
-    LWGEOM_INSPECTED *inspected;
-
-    type = lwgeom_getType(geom[0]);
-
-    switch (type)
-    {
-    case POINTTYPE:
-        point = lwpoint_deserialize(geom);
-        return asgml2_point(point, srs, precision);
-
-    case LINETYPE:
-        line = lwline_deserialize(geom);
-        return asgml2_line(line, srs, precision);
-
-    case POLYGONTYPE:
-        poly = lwpoly_deserialize(geom);
-        return asgml2_poly(poly, srs, precision);
-
-    case MULTIPOINTTYPE:
-    case MULTILINETYPE:
-    case MULTIPOLYGONTYPE:
-        inspected = lwgeom_inspect(geom);
-        return asgml2_multi(inspected, srs, precision);
-
-    case COLLECTIONTYPE:
-        inspected = lwgeom_inspect(geom);
-        return asgml2_collection(inspected, srs, precision);
-
-    default:
-        lwerror("lwgeom_to_gml2: '%s' geometry type not supported",
-                lwgeom_typename(type));
-        return NULL;
-    }
+       int type;
+       LWPOINT *point;
+       LWLINE *line;
+       LWPOLY *poly;
+       LWGEOM_INSPECTED *inspected;
+
+       type = lwgeom_getType(geom[0]);
+
+       switch (type)
+       {
+       case POINTTYPE:
+               point = lwpoint_deserialize(geom);
+               return asgml2_point(point, srs, precision);
+
+       case LINETYPE:
+               line = lwline_deserialize(geom);
+               return asgml2_line(line, srs, precision);
+
+       case POLYGONTYPE:
+               poly = lwpoly_deserialize(geom);
+               return asgml2_poly(poly, srs, precision);
+
+       case MULTIPOINTTYPE:
+       case MULTILINETYPE:
+       case MULTIPOLYGONTYPE:
+               inspected = lwgeom_inspect(geom);
+               return asgml2_multi(inspected, srs, precision);
+
+       case COLLECTIONTYPE:
+               inspected = lwgeom_inspect(geom);
+               return asgml2_collection(inspected, srs, precision);
+
+       default:
+               lwerror("lwgeom_to_gml2: '%s' geometry type not supported",
+                       lwgeom_typename(type));
+               return NULL;
+       }
 }
 
 static size_t
 asgml2_point_size(LWPOINT *point, char *srs, int precision)
 {
-    int size;
-    size = pointArray_GMLsize(point->point, precision);
-    size += sizeof("<gml:point><gml:coordinates>/") * 2;
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
-    return size;
+       int size;
+       size = pointArray_GMLsize(point->point, precision);
+       size += sizeof("<gml:point><gml:coordinates>/") * 2;
+       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+       return size;
 }
 
 static size_t
 asgml2_point_buf(LWPOINT *point, char *srs, char *output, int precision)
 {
-    char *ptr = output;
-
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:Point srsName=\"%s\">", srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:Point>");
-    }
-    ptr += sprintf(ptr, "<gml:coordinates>");
-    ptr += pointArray_toGML2(point->point, ptr, precision);
-    ptr += sprintf(ptr, "</gml:coordinates></gml:Point>");
-
-    return (ptr-output);
+       char *ptr = output;
+
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:Point srsName=\"%s\">", srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:Point>");
+       }
+       ptr += sprintf(ptr, "<gml:coordinates>");
+       ptr += pointArray_toGML2(point->point, ptr, precision);
+       ptr += sprintf(ptr, "</gml:coordinates></gml:Point>");
+
+       return (ptr-output);
 }
 
 static char *
 asgml2_point(LWPOINT *point, char *srs, int precision)
 {
-    char *output;
-    int size;
+       char *output;
+       int size;
 
-    size = asgml2_point_size(point, srs, precision);
-    output = lwalloc(size);
-    asgml2_point_buf(point, srs, output, precision);
-    return output;
+       size = asgml2_point_size(point, srs, precision);
+       output = lwalloc(size);
+       asgml2_point_buf(point, srs, output, precision);
+       return output;
 }
 
 static size_t
 asgml2_line_size(LWLINE *line, char *srs, int precision)
 {
-    int size;
-    size = pointArray_GMLsize(line->points, precision);
-    size += sizeof("<gml:linestring><gml:coordinates>/") * 2;
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
-    return size;
+       int size;
+       size = pointArray_GMLsize(line->points, precision);
+       size += sizeof("<gml:linestring><gml:coordinates>/") * 2;
+       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+       return size;
 }
 
 static size_t
 asgml2_line_buf(LWLINE *line, char *srs, char *output, int precision)
 {
-    char *ptr=output;
-
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:LineString srsName=\"%s\">", srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:LineString>");
-    }
-    ptr += sprintf(ptr, "<gml:coordinates>");
-    ptr += pointArray_toGML2(line->points, ptr, precision);
-    ptr += sprintf(ptr, "</gml:coordinates></gml:LineString>");
-
-    return (ptr-output);
+       char *ptr=output;
+
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:LineString srsName=\"%s\">", srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:LineString>");
+       }
+       ptr += sprintf(ptr, "<gml:coordinates>");
+       ptr += pointArray_toGML2(line->points, ptr, precision);
+       ptr += sprintf(ptr, "</gml:coordinates></gml:LineString>");
+
+       return (ptr-output);
 }
 
 static char *
 asgml2_line(LWLINE *line, char *srs, int precision)
 {
-    char *output;
-    int size;
+       char *output;
+       int size;
 
-    size = asgml2_line_size(line, srs, precision);
-    output = lwalloc(size);
-    asgml2_line_buf(line, srs, output, precision);
-    return output;
+       size = asgml2_line_size(line, srs, precision);
+       output = lwalloc(size);
+       asgml2_line_buf(line, srs, output, precision);
+       return output;
 }
 
 static size_t
 asgml2_poly_size(LWPOLY *poly, char *srs, int precision)
 {
-    size_t size;
-    int i;
+       size_t size;
+       int i;
 
-    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;
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+       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;
+       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
 
-    for (i=0; i<poly->nrings; i++)
-        size += pointArray_GMLsize(poly->rings[i], precision);
+       for (i=0; i<poly->nrings; i++)
+               size += pointArray_GMLsize(poly->rings[i], precision);
 
-    return size;
+       return size;
 }
 
 static size_t
 asgml2_poly_buf(LWPOLY *poly, char *srs, char *output, int precision)
 {
-    int i;
-    char *ptr=output;
-
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:Polygon>");
-    }
-    ptr += sprintf(ptr, "<gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>");
-    ptr += pointArray_toGML2(poly->rings[0], ptr, precision);
-    ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>");
-    for (i=1; i<poly->nrings; i++)
-    {
-        ptr += sprintf(ptr, "<gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>");
-        ptr += pointArray_toGML2(poly->rings[i], ptr, precision);
-        ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs>");
-    }
-    ptr += sprintf(ptr, "</gml:Polygon>");
-
-    return (ptr-output);
+       int i;
+       char *ptr=output;
+
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:Polygon>");
+       }
+       ptr += sprintf(ptr, "<gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>");
+       ptr += pointArray_toGML2(poly->rings[0], ptr, precision);
+       ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>");
+       for (i=1; i<poly->nrings; i++)
+       {
+               ptr += sprintf(ptr, "<gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>");
+               ptr += pointArray_toGML2(poly->rings[i], ptr, precision);
+               ptr += sprintf(ptr, "</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs>");
+       }
+       ptr += sprintf(ptr, "</gml:Polygon>");
+
+       return (ptr-output);
 }
 
 static char *
 asgml2_poly(LWPOLY *poly, char *srs, int precision)
 {
-    char *output;
-    int size;
+       char *output;
+       int size;
 
-    size = asgml2_poly_size(poly, srs, precision);
-    output = lwalloc(size);
-    asgml2_poly_buf(poly, srs, output, precision);
-    return output;
+       size = asgml2_poly_size(poly, srs, precision);
+       output = lwalloc(size);
+       asgml2_poly_buf(poly, srs, output, precision);
+       return output;
 }
 
 /*
@@ -246,41 +246,41 @@ asgml2_poly(LWPOLY *poly, char *srs, int precision)
 static size_t
 asgml2_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 {
-    int i;
-    size_t size;
-
-    /* the longest possible multi version */
-    size = sizeof("<gml:MultiLineString></gml:MultiLineString>");
-
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
-
-    for (i=0; i<insp->ngeometries; i++)
-    {
-        LWPOINT *point;
-        LWLINE *line;
-        LWPOLY *poly;
-
-        if ((point=lwgeom_getpoint_inspected(insp, i)))
-        {
-            size += sizeof("<gml:pointMember>/") * 2;
-            size += asgml2_point_size(point, 0, precision);
-            lwpoint_release(point);
-        }
-        else if ((line=lwgeom_getline_inspected(insp, i)))
-        {
-            size += sizeof("<gml:lineStringMember>/") * 2;
-            size += asgml2_line_size(line, 0, precision);
-            lwline_release(line);
-        }
-        else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-        {
-            size += sizeof("<gml:polygonMember>/") * 2;
-            size += asgml2_poly_size(poly, 0, precision);
-            lwpoly_release(poly);
-        }
-    }
-
-    return size;
+       int i;
+       size_t size;
+
+       /* the longest possible multi version */
+       size = sizeof("<gml:MultiLineString></gml:MultiLineString>");
+
+       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       size += sizeof("<gml:pointMember>/") * 2;
+                       size += asgml2_point_size(point, 0, precision);
+                       lwpoint_release(point);
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       size += sizeof("<gml:lineStringMember>/") * 2;
+                       size += asgml2_line_size(line, 0, precision);
+                       lwline_release(line);
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       size += sizeof("<gml:polygonMember>/") * 2;
+                       size += asgml2_poly_size(poly, 0, precision);
+                       lwpoly_release(poly);
+               }
+       }
+
+       return size;
 }
 
 /*
@@ -289,60 +289,60 @@ asgml2_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 static size_t
 asgml2_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
 {
-    int type = lwgeom_getType(insp->serialized_form[0]);
-    char *ptr, *gmltype;
-    int i;
-
-    ptr = output;
-    gmltype="";
-
-    if         (type == MULTIPOINTTYPE)   gmltype = "MultiPoint";
-    else if (type == MULTILINETYPE)       gmltype = "MultiLineString";
-    else if (type == MULTIPOLYGONTYPE) gmltype = "MultiPolygon";
-
-    /* Open outmost tag */
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:%s srsName=\"%s\">", gmltype, srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:%s>", gmltype);
-    }
-
-    for (i=0; i<insp->ngeometries; i++)
-    {
-        LWPOINT *point;
-        LWLINE *line;
-        LWPOLY *poly;
-
-        if ((point=lwgeom_getpoint_inspected(insp, i)))
-        {
-            ptr += sprintf(ptr, "<gml:pointMember>");
-            ptr += asgml2_point_buf(point, 0, ptr, precision);
-            lwpoint_release(point);
-            ptr += sprintf(ptr, "</gml:pointMember>");
-        }
-        else if ((line=lwgeom_getline_inspected(insp, i)))
-        {
-            ptr += sprintf(ptr, "<gml:lineStringMember>");
-            ptr += asgml2_line_buf(line, 0, ptr, precision);
-            lwline_release(line);
-            ptr += sprintf(ptr, "</gml:lineStringMember>");
-        }
-        else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-        {
-            ptr += sprintf(ptr, "<gml:polygonMember>");
-            ptr += asgml2_poly_buf(poly, 0, ptr, precision);
-            lwpoly_release(poly);
-            ptr += sprintf(ptr, "</gml:polygonMember>");
-        }
-    }
-
-    /* Close outmost tag */
-    ptr += sprintf(ptr, "</gml:%s>", gmltype);
-
-    return (ptr-output);
+       int type = lwgeom_getType(insp->serialized_form[0]);
+       char *ptr, *gmltype;
+       int i;
+
+       ptr = output;
+       gmltype="";
+
+       if      (type == MULTIPOINTTYPE)   gmltype = "MultiPoint";
+       else if (type == MULTILINETYPE)    gmltype = "MultiLineString";
+       else if (type == MULTIPOLYGONTYPE) gmltype = "MultiPolygon";
+
+       /* Open outmost tag */
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:%s srsName=\"%s\">", gmltype, srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:%s>", gmltype);
+       }
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       ptr += sprintf(ptr, "<gml:pointMember>");
+                       ptr += asgml2_point_buf(point, 0, ptr, precision);
+                       lwpoint_release(point);
+                       ptr += sprintf(ptr, "</gml:pointMember>");
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       ptr += sprintf(ptr, "<gml:lineStringMember>");
+                       ptr += asgml2_line_buf(line, 0, ptr, precision);
+                       lwline_release(line);
+                       ptr += sprintf(ptr, "</gml:lineStringMember>");
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       ptr += sprintf(ptr, "<gml:polygonMember>");
+                       ptr += asgml2_poly_buf(poly, 0, ptr, precision);
+                       lwpoly_release(poly);
+                       ptr += sprintf(ptr, "</gml:polygonMember>");
+               }
+       }
+
+       /* Close outmost tag */
+       ptr += sprintf(ptr, "</gml:%s>", gmltype);
+
+       return (ptr-output);
 }
 
 /*
@@ -351,60 +351,60 @@ asgml2_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
 static char *
 asgml2_multi(LWGEOM_INSPECTED *insp, char *srs, int precision)
 {
-    char *gml;
-    size_t size;
+       char *gml;
+       size_t size;
 
-    size = asgml2_multi_size(insp, srs, precision);
-    gml = lwalloc(size);
-    asgml2_multi_buf(insp, srs, gml, precision);
-    return gml;
+       size = asgml2_multi_size(insp, srs, precision);
+       gml = lwalloc(size);
+       asgml2_multi_buf(insp, srs, gml, precision);
+       return gml;
 }
 
 
 static size_t
 asgml2_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 {
-    int i;
-    size_t size;
-
-    size = sizeof("<gml:MultiGeometry></gml:MultiGeometry>");
-
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
-
-    for (i=0; i<insp->ngeometries; i++)
-    {
-        LWPOINT *point;
-        LWLINE *line;
-        LWPOLY *poly;
-        LWGEOM_INSPECTED *subinsp;
-        uchar *subgeom;
-
-        size += sizeof("<gml:geometryMember>/") * 2;
-        if ((point=lwgeom_getpoint_inspected(insp, i)))
-        {
-            size += asgml2_point_size(point, 0, precision);
-            lwpoint_release(point);
-        }
-        else if ((line=lwgeom_getline_inspected(insp, i)))
-        {
-            size += asgml2_line_size(line, 0, precision);
-            lwline_release(line);
-        }
-        else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-        {
-            size += asgml2_poly_size(poly, 0, precision);
-            lwpoly_release(poly);
-        }
-        else
-        {
-            subgeom = lwgeom_getsubgeometry_inspected(insp, i);
-            subinsp = lwgeom_inspect(subgeom);
-            size += asgml2_collection_size(subinsp, 0, precision);
-            lwinspected_release(subinsp);
-        }
-    }
-
-    return size;
+       int i;
+       size_t size;
+
+       size = sizeof("<gml:MultiGeometry></gml:MultiGeometry>");
+
+       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+               LWGEOM_INSPECTED *subinsp;
+               uchar *subgeom;
+
+               size += sizeof("<gml:geometryMember>/") * 2;
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       size += asgml2_point_size(point, 0, precision);
+                       lwpoint_release(point);
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       size += asgml2_line_size(line, 0, precision);
+                       lwline_release(line);
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       size += asgml2_poly_size(poly, 0, precision);
+                       lwpoly_release(poly);
+               }
+               else
+               {
+                       subgeom = lwgeom_getsubgeometry_inspected(insp, i);
+                       subinsp = lwgeom_inspect(subgeom);
+                       size += asgml2_collection_size(subinsp, 0, precision);
+                       lwinspected_release(subinsp);
+               }
+       }
+
+       return size;
 }
 
 /*
@@ -413,62 +413,62 @@ asgml2_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 static size_t
 asgml2_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision)
 {
-    char *ptr;
-    int i;
-
-    ptr = output;
-
-    /* Open outmost tag */
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:MultiGeometry srsName=\"%s\">", srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:MultiGeometry>");
-    }
-
-    for (i=0; i<insp->ngeometries; i++)
-    {
-        LWPOINT *point;
-        LWLINE *line;
-        LWPOLY *poly;
-        LWGEOM_INSPECTED *subinsp;
-        uchar *subgeom;
-
-        ptr += sprintf(ptr, "<gml:geometryMember>");
-        if ((point=lwgeom_getpoint_inspected(insp, i)))
-        {
-            ptr += asgml2_point_buf(point, 0, ptr, precision);
-            lwpoint_release(point);
-        }
-        else if ((line=lwgeom_getline_inspected(insp, i)))
-        {
-            ptr += asgml2_line_buf(line, 0, ptr, precision);
-            lwline_release(line);
-        }
-        else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-        {
-            ptr += asgml2_poly_buf(poly, 0, ptr, precision);
-            lwpoly_release(poly);
-        }
-        else
-        {
-            subgeom = lwgeom_getsubgeometry_inspected(insp, i);
-            subinsp = lwgeom_inspect(subgeom);
-            if (lwgeom_getType(subgeom[0]) == COLLECTIONTYPE)
-                ptr += asgml2_collection_buf(subinsp, 0, ptr, precision);
-            else
-                ptr += asgml2_multi_buf(subinsp, 0, ptr, precision);
-            lwinspected_release(subinsp);
-        }
-        ptr += sprintf(ptr, "</gml:geometryMember>");
-    }
-
-    /* Close outmost tag */
-    ptr += sprintf(ptr, "</gml:MultiGeometry>");
-
-    return (ptr-output);
+       char *ptr;
+       int i;
+
+       ptr = output;
+
+       /* Open outmost tag */
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:MultiGeometry srsName=\"%s\">", srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:MultiGeometry>");
+       }
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+               LWGEOM_INSPECTED *subinsp;
+               uchar *subgeom;
+
+               ptr += sprintf(ptr, "<gml:geometryMember>");
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       ptr += asgml2_point_buf(point, 0, ptr, precision);
+                       lwpoint_release(point);
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       ptr += asgml2_line_buf(line, 0, ptr, precision);
+                       lwline_release(line);
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       ptr += asgml2_poly_buf(poly, 0, ptr, precision);
+                       lwpoly_release(poly);
+               }
+               else
+               {
+                       subgeom = lwgeom_getsubgeometry_inspected(insp, i);
+                       subinsp = lwgeom_inspect(subgeom);
+                       if (lwgeom_getType(subgeom[0]) == COLLECTIONTYPE)
+                               ptr += asgml2_collection_buf(subinsp, 0, ptr, precision);
+                       else
+                               ptr += asgml2_multi_buf(subinsp, 0, ptr, precision);
+                       lwinspected_release(subinsp);
+               }
+               ptr += sprintf(ptr, "</gml:geometryMember>");
+       }
+
+       /* Close outmost tag */
+       ptr += sprintf(ptr, "</gml:MultiGeometry>");
+
+       return (ptr-output);
 }
 
 /*
@@ -477,81 +477,81 @@ asgml2_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
 static char *
 asgml2_collection(LWGEOM_INSPECTED *insp, char *srs, int precision)
 {
-    char *gml;
-    size_t size;
+       char *gml;
+       size_t size;
 
-    size = asgml2_collection_size(insp, srs, precision);
-    gml = lwalloc(size);
-    asgml2_collection_buf(insp, srs, gml, precision);
-    return gml;
+       size = asgml2_collection_size(insp, srs, precision);
+       gml = lwalloc(size);
+       asgml2_collection_buf(insp, srs, gml, precision);
+       return gml;
 }
 
 
 static size_t
 pointArray_toGML2(POINTARRAY *pa, char *output, int precision)
 {
-    int i;
-    char *ptr;
-    char x[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
-    char y[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
-    char z[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
-
-    ptr = output;
-
-    if ( ! TYPE_HASZ(pa->dims) )
-    {
-        for (i=0; i<pa->npoints; i++)
-        {
-            POINT2D pt;
-            getPoint2d_p(pa, i, &pt);
-
-            if (fabs(pt.x) < OUT_MAX_DOUBLE)
-                sprintf(x, "%.*f", precision, pt.x);
-            else
-                sprintf(x, "%g", pt.x);
-            trim_trailing_zeros(x);
-
-            if (fabs(pt.y) < OUT_MAX_DOUBLE)
-                sprintf(y, "%.*f", precision, pt.y);
-            else
-                sprintf(y, "%g", pt.y);
-            trim_trailing_zeros(y);
-
-            if ( i ) ptr += sprintf(ptr, " ");
-            ptr += sprintf(ptr, "%s,%s", x, y);
-        }
-    }
-    else
-    {
-        for (i=0; i<pa->npoints; i++)
-        {
-            POINT4D pt;
-            getPoint4d_p(pa, i, &pt);
-
-            if (fabs(pt.x) < OUT_MAX_DOUBLE)
-                sprintf(x, "%.*f", precision, pt.x);
-            else
-                sprintf(x, "%g", pt.x);
-            trim_trailing_zeros(x);
-
-            if (fabs(pt.y) < OUT_MAX_DOUBLE)
-                sprintf(y, "%.*f", precision, pt.y);
-            else
-                sprintf(y, "%g", pt.y);
-            trim_trailing_zeros(y);
-
-            if (fabs(pt.z) < OUT_MAX_DOUBLE)
-                sprintf(z, "%.*f", precision, pt.z);
-            else
-                sprintf(z, "%g", pt.z);
-            trim_trailing_zeros(z);
-
-            if ( i ) ptr += sprintf(ptr, " ");
-            ptr += sprintf(ptr, "%s,%s,%s", x, y, z);
-        }
-    }
-
-    return ptr-output;
+       int i;
+       char *ptr;
+       char x[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+       char y[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+       char z[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+
+       ptr = output;
+
+       if ( ! TYPE_HASZ(pa->dims) )
+       {
+               for (i=0; i<pa->npoints; i++)
+               {
+                       POINT2D pt;
+                       getPoint2d_p(pa, i, &pt);
+
+                       if (fabs(pt.x) < OUT_MAX_DOUBLE)
+                               sprintf(x, "%.*f", precision, pt.x);
+                       else
+                               sprintf(x, "%g", pt.x);
+                       trim_trailing_zeros(x);
+
+                       if (fabs(pt.y) < OUT_MAX_DOUBLE)
+                               sprintf(y, "%.*f", precision, pt.y);
+                       else
+                               sprintf(y, "%g", pt.y);
+                       trim_trailing_zeros(y);
+
+                       if ( i ) ptr += sprintf(ptr, " ");
+                       ptr += sprintf(ptr, "%s,%s", x, y);
+               }
+       }
+       else
+       {
+               for (i=0; i<pa->npoints; i++)
+               {
+                       POINT4D pt;
+                       getPoint4d_p(pa, i, &pt);
+
+                       if (fabs(pt.x) < OUT_MAX_DOUBLE)
+                               sprintf(x, "%.*f", precision, pt.x);
+                       else
+                               sprintf(x, "%g", pt.x);
+                       trim_trailing_zeros(x);
+
+                       if (fabs(pt.y) < OUT_MAX_DOUBLE)
+                               sprintf(y, "%.*f", precision, pt.y);
+                       else
+                               sprintf(y, "%g", pt.y);
+                       trim_trailing_zeros(y);
+
+                       if (fabs(pt.z) < OUT_MAX_DOUBLE)
+                               sprintf(z, "%.*f", precision, pt.z);
+                       else
+                               sprintf(z, "%g", pt.z);
+                       trim_trailing_zeros(z);
+
+                       if ( i ) ptr += sprintf(ptr, " ");
+                       ptr += sprintf(ptr, "%s,%s,%s", x, y, z);
+               }
+       }
+
+       return ptr-output;
 }
 
 
@@ -564,198 +564,198 @@ pointArray_toGML2(POINTARRAY *pa, char *output, int precision)
 extern char *
 lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree)
 {
-    int type;
-    LWPOINT *point;
-    LWLINE *line;
-    LWPOLY *poly;
-    LWGEOM_INSPECTED *inspected;
-
-    type = lwgeom_getType(geom[0]);
-
-    switch (type)
-    {
-    case POINTTYPE:
-        point = lwpoint_deserialize(geom);
-        return asgml3_point(point, srs, precision, is_deegree);
-
-    case LINETYPE:
-        line = lwline_deserialize(geom);
-        return asgml3_line(line, srs, precision, is_deegree);
-
-    case POLYGONTYPE:
-        poly = lwpoly_deserialize(geom);
-        return asgml3_poly(poly, srs, precision, is_deegree);
-
-    case MULTIPOINTTYPE:
-    case MULTILINETYPE:
-    case MULTIPOLYGONTYPE:
-        inspected = lwgeom_inspect(geom);
-        return asgml3_multi(inspected, srs, precision, is_deegree);
-
-    case COLLECTIONTYPE:
-        inspected = lwgeom_inspect(geom);
-        return asgml3_collection(inspected, srs, precision, is_deegree);
-
-    default:
-        lwerror("lwgeom_to_gml3: '%s' geometry type not supported", lwgeom_typename(type));
-        return NULL;
-    }
+       int type;
+       LWPOINT *point;
+       LWLINE *line;
+       LWPOLY *poly;
+       LWGEOM_INSPECTED *inspected;
+
+       type = lwgeom_getType(geom[0]);
+
+       switch (type)
+       {
+       case POINTTYPE:
+               point = lwpoint_deserialize(geom);
+               return asgml3_point(point, srs, precision, is_deegree);
+
+       case LINETYPE:
+               line = lwline_deserialize(geom);
+               return asgml3_line(line, srs, precision, is_deegree);
+
+       case POLYGONTYPE:
+               poly = lwpoly_deserialize(geom);
+               return asgml3_poly(poly, srs, precision, is_deegree);
+
+       case MULTIPOINTTYPE:
+       case MULTILINETYPE:
+       case MULTIPOLYGONTYPE:
+               inspected = lwgeom_inspect(geom);
+               return asgml3_multi(inspected, srs, precision, is_deegree);
+
+       case COLLECTIONTYPE:
+               inspected = lwgeom_inspect(geom);
+               return asgml3_collection(inspected, srs, precision, is_deegree);
+
+       default:
+               lwerror("lwgeom_to_gml3: '%s' geometry type not supported", lwgeom_typename(type));
+               return NULL;
+       }
 }
 
 static size_t
 asgml3_point_size(LWPOINT *point, char *srs, int precision)
 {
-    int size;
-    size = pointArray_GMLsize(point->point, precision);
-    size += sizeof("<gml:point><gml:pos srsDimension='x'>/") * 2;
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
-    return size;
+       int size;
+       size = pointArray_GMLsize(point->point, precision);
+       size += sizeof("<gml:point><gml:pos srsDimension='x'>/") * 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)
 {
-    char *ptr = output;
-    int dimension=2;
-
-    if (TYPE_HASZ(point->type)) dimension = 3;
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:Point srsName=\"%s\">", srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:Point>");
-    }
-    ptr += sprintf(ptr, "<gml:pos srsDimension=\"%d\">", dimension);
-    ptr += pointArray_toGML3(point->point, ptr, precision, is_deegree);
-    ptr += sprintf(ptr, "</gml:pos></gml:Point>");
-
-    return (ptr-output);
+       char *ptr = output;
+       int dimension=2;
+
+       if (TYPE_HASZ(point->type)) dimension = 3;
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:Point srsName=\"%s\">", srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:Point>");
+       }
+       ptr += sprintf(ptr, "<gml:pos srsDimension=\"%d\">", dimension);
+       ptr += pointArray_toGML3(point->point, ptr, precision, is_deegree);
+       ptr += sprintf(ptr, "</gml:pos></gml:Point>");
+
+       return (ptr-output);
 }
 
 static char *
 asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree)
 {
-    char *output;
-    int size;
+       char *output;
+       int size;
 
-    size = asgml3_point_size(point, srs, precision);
-    output = lwalloc(size);
-    asgml3_point_buf(point, srs, output, precision, is_deegree);
-    return output;
+       size = asgml3_point_size(point, srs, precision);
+       output = lwalloc(size);
+       asgml3_point_buf(point, srs, output, precision, is_deegree);
+       return output;
 }
 
 
 static size_t
 asgml3_line_size(LWLINE *line, char *srs, int precision)
 {
-    int size;
-    size = pointArray_GMLsize(line->points, precision);
-    size += sizeof("<gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>/") * 2;
-    size += sizeof(" srsDimension='x'");
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
-    return size;
+       int size;
+       size = pointArray_GMLsize(line->points, precision);
+       size += sizeof("<gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>/") * 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)
 {
-    char *ptr=output;
-    int dimension=2;
-
-    if (TYPE_HASZ(line->type)) dimension = 3;
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:Curve srsName=\"%s\">", srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:Curve>");
-    }
-    ptr += sprintf(ptr, "<gml:segments>");
-    ptr += sprintf(ptr, "<gml:LineStringSegment>");
-    ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", 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>");
-
-    return (ptr-output);
+       char *ptr=output;
+       int dimension=2;
+
+       if (TYPE_HASZ(line->type)) dimension = 3;
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:Curve srsName=\"%s\">", srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:Curve>");
+       }
+       ptr += sprintf(ptr, "<gml:segments>");
+       ptr += sprintf(ptr, "<gml:LineStringSegment>");
+       ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", 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>");
+
+       return (ptr-output);
 }
 
 static char *
 asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree)
 {
-    char *output;
-    int size;
+       char *output;
+       int size;
 
-    size = asgml3_line_size(line, srs, precision);
-    output = lwalloc(size);
-    asgml3_line_buf(line, srs, output, precision, is_deegree);
-    return output;
+       size = asgml3_line_size(line, srs, precision);
+       output = lwalloc(size);
+       asgml3_line_buf(line, srs, output, precision, is_deegree);
+       return output;
 }
 
 
 static size_t
 asgml3_poly_size(LWPOLY *poly, char *srs, int precision)
 {
-    size_t size;
-    int i;
+       size_t size;
+       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;
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+       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;
+       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
 
-    for (i=0; i<poly->nrings; i++)
-        size += pointArray_GMLsize(poly->rings[i], precision);
+       for (i=0; i<poly->nrings; i++)
+               size += pointArray_GMLsize(poly->rings[i], precision);
 
-    return size;
+       return size;
 }
 
 static size_t
 asgml3_poly_buf(LWPOLY *poly, char *srs, char *output, int precision, int is_deegree)
 {
-    int i;
-    char *ptr=output;
-    int dimension=2;
-
-    if (TYPE_HASZ(poly->type)) dimension = 3;
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:Polygon>");
-    }
-    ptr += sprintf(ptr, "<gml:exterior><gml:LinearRing>");
-    ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", dimension);
-    ptr += pointArray_toGML3(poly->rings[0], ptr, precision, is_deegree);
-    ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:exterior>");
-    for (i=1; i<poly->nrings; i++)
-    {
-        ptr += sprintf(ptr, "<gml:interior><gml:LinearRing>");
-        ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", dimension);
-        ptr += pointArray_toGML3(poly->rings[i], ptr, precision, is_deegree);
-        ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:interior>");
-    }
-    ptr += sprintf(ptr, "</gml:Polygon>");
-
-    return (ptr-output);
+       int i;
+       char *ptr=output;
+       int dimension=2;
+
+       if (TYPE_HASZ(poly->type)) dimension = 3;
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:Polygon srsName=\"%s\">", srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:Polygon>");
+       }
+       ptr += sprintf(ptr, "<gml:exterior><gml:LinearRing>");
+       ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", dimension);
+       ptr += pointArray_toGML3(poly->rings[0], ptr, precision, is_deegree);
+       ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:exterior>");
+       for (i=1; i<poly->nrings; i++)
+       {
+               ptr += sprintf(ptr, "<gml:interior><gml:LinearRing>");
+               ptr += sprintf(ptr, "<gml:posList srsDimension=\"%d\">", dimension);
+               ptr += pointArray_toGML3(poly->rings[i], ptr, precision, is_deegree);
+               ptr += sprintf(ptr, "</gml:posList></gml:LinearRing></gml:interior>");
+       }
+       ptr += sprintf(ptr, "</gml:Polygon>");
+
+       return (ptr-output);
 }
 
 static char *
 asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree)
 {
-    char *output;
-    int size;
+       char *output;
+       int size;
 
-    size = asgml3_poly_size(poly, srs, precision);
-    output = lwalloc(size);
-    asgml3_poly_buf(poly, srs, output, precision, is_deegree);
-    return output;
+       size = asgml3_poly_size(poly, srs, precision);
+       output = lwalloc(size);
+       asgml3_poly_buf(poly, srs, output, precision, is_deegree);
+       return output;
 }
 
 
@@ -767,41 +767,41 @@ asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree)
 static size_t
 asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 {
-    int i;
-    size_t size;
-
-    /* the longest possible multi version */
-    size = sizeof("<gml:MultiLineString></gml:MultiLineString>");
-
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
-
-    for (i=0; i<insp->ngeometries; i++)
-    {
-        LWPOINT *point;
-        LWLINE *line;
-        LWPOLY *poly;
-
-        if ((point=lwgeom_getpoint_inspected(insp, i)))
-        {
-            size += sizeof("<gml:pointMember>/") * 2;
-            size += asgml3_point_size(point, 0, precision);
-            lwpoint_release(point);
-        }
-        else if ((line=lwgeom_getline_inspected(insp, i)))
-        {
-            size += sizeof("<gml:curveMember>/") * 2;
-            size += asgml3_line_size(line, 0, precision);
-            lwline_release(line);
-        }
-        else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-        {
-            size += sizeof("<gml:surfaceMember>/") * 2;
-            size += asgml3_poly_size(poly, 0, precision);
-            lwpoly_release(poly);
-        }
-    }
-
-    return size;
+       int i;
+       size_t size;
+
+       /* the longest possible multi version */
+       size = sizeof("<gml:MultiLineString></gml:MultiLineString>");
+
+       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       size += sizeof("<gml:pointMember>/") * 2;
+                       size += asgml3_point_size(point, 0, precision);
+                       lwpoint_release(point);
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       size += sizeof("<gml:curveMember>/") * 2;
+                       size += asgml3_line_size(line, 0, precision);
+                       lwline_release(line);
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       size += sizeof("<gml:surfaceMember>/") * 2;
+                       size += asgml3_poly_size(poly, 0, precision);
+                       lwpoly_release(poly);
+               }
+       }
+
+       return size;
 }
 
 /*
@@ -810,60 +810,60 @@ asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 static size_t
 asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree)
 {
-    int type = lwgeom_getType(insp->serialized_form[0]);
-    char *ptr, *gmltype;
-    int i;
-
-    ptr = output;
-    gmltype="";
-
-    if         (type == MULTIPOINTTYPE)   gmltype = "MultiPoint";
-    else if (type == MULTILINETYPE)    gmltype = "MultiCurve";
-    else if (type == MULTIPOLYGONTYPE) gmltype = "MultiSurface";
-
-    /* Open outmost tag */
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:%s srsName=\"%s\">", gmltype, srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:%s>", gmltype);
-    }
-
-    for (i=0; i<insp->ngeometries; i++)
-    {
-        LWPOINT *point;
-        LWLINE *line;
-        LWPOLY *poly;
-
-        if ((point=lwgeom_getpoint_inspected(insp, i)))
-        {
-            ptr += sprintf(ptr, "<gml:pointMember>");
-            ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree);
-            lwpoint_release(point);
-            ptr += sprintf(ptr, "</gml:pointMember>");
-        }
-        else if ((line=lwgeom_getline_inspected(insp, i)))
-        {
-            ptr += sprintf(ptr, "<gml:curveMember>");
-            ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree);
-            lwline_release(line);
-            ptr += sprintf(ptr, "</gml:curveMember>");
-        }
-        else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-        {
-            ptr += sprintf(ptr, "<gml:surfaceMember>");
-            ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree);
-            lwpoly_release(poly);
-            ptr += sprintf(ptr, "</gml:surfaceMember>");
-        }
-    }
-
-    /* Close outmost tag */
-    ptr += sprintf(ptr, "</gml:%s>", gmltype);
-
-    return (ptr-output);
+       int type = lwgeom_getType(insp->serialized_form[0]);
+       char *ptr, *gmltype;
+       int i;
+
+       ptr = output;
+       gmltype="";
+
+       if      (type == MULTIPOINTTYPE)   gmltype = "MultiPoint";
+       else if (type == MULTILINETYPE)    gmltype = "MultiCurve";
+       else if (type == MULTIPOLYGONTYPE) gmltype = "MultiSurface";
+
+       /* Open outmost tag */
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:%s srsName=\"%s\">", gmltype, srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:%s>", gmltype);
+       }
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       ptr += sprintf(ptr, "<gml:pointMember>");
+                       ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree);
+                       lwpoint_release(point);
+                       ptr += sprintf(ptr, "</gml:pointMember>");
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       ptr += sprintf(ptr, "<gml:curveMember>");
+                       ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree);
+                       lwline_release(line);
+                       ptr += sprintf(ptr, "</gml:curveMember>");
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       ptr += sprintf(ptr, "<gml:surfaceMember>");
+                       ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree);
+                       lwpoly_release(poly);
+                       ptr += sprintf(ptr, "</gml:surfaceMember>");
+               }
+       }
+
+       /* Close outmost tag */
+       ptr += sprintf(ptr, "</gml:%s>", gmltype);
+
+       return (ptr-output);
 }
 
 /*
@@ -872,121 +872,121 @@ asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision,
 static char *
 asgml3_multi(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree)
 {
-    char *gml;
-    size_t size;
+       char *gml;
+       size_t size;
 
-    size = asgml3_multi_size(insp, srs, precision);
-    gml = lwalloc(size);
-    asgml3_multi_buf(insp, srs, gml, precision, is_deegree);
-    return gml;
+       size = asgml3_multi_size(insp, srs, precision);
+       gml = lwalloc(size);
+       asgml3_multi_buf(insp, srs, gml, precision, is_deegree);
+       return gml;
 }
 
 
 static size_t
 asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision)
 {
-    int i;
-    size_t size;
-
-    size = sizeof("<gml:MultiGeometry></gml:MultiGeometry>");
-
-    if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
-
-    for (i=0; i<insp->ngeometries; i++)
-    {
-        LWPOINT *point;
-        LWLINE *line;
-        LWPOLY *poly;
-        LWGEOM_INSPECTED *subinsp;
-        uchar *subgeom;
-
-        size += sizeof("<gml:geometryMember>/") * 2;
-        if ((point=lwgeom_getpoint_inspected(insp, i)))
-        {
-            size += asgml3_point_size(point, 0, precision);
-            lwpoint_release(point);
-        }
-        else if ((line=lwgeom_getline_inspected(insp, i)))
-        {
-            size += asgml3_line_size(line, 0, precision);
-            lwline_release(line);
-        }
-        else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-        {
-            size += asgml3_poly_size(poly, 0, precision);
-            lwpoly_release(poly);
-        }
-        else
-        {
-            subgeom = lwgeom_getsubgeometry_inspected(insp, i);
-            subinsp = lwgeom_inspect(subgeom);
-            size += asgml3_multi_size(subinsp, 0, precision);
-            lwinspected_release(subinsp);
-        }
-    }
-
-    return size;
+       int i;
+       size_t size;
+
+       size = sizeof("<gml:MultiGeometry></gml:MultiGeometry>");
+
+       if ( srs ) size += strlen(srs) + sizeof(" srsName=..");
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+               LWGEOM_INSPECTED *subinsp;
+               uchar *subgeom;
+
+               size += sizeof("<gml:geometryMember>/") * 2;
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       size += asgml3_point_size(point, 0, precision);
+                       lwpoint_release(point);
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       size += asgml3_line_size(line, 0, precision);
+                       lwline_release(line);
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       size += asgml3_poly_size(poly, 0, precision);
+                       lwpoly_release(poly);
+               }
+               else
+               {
+                       subgeom = lwgeom_getsubgeometry_inspected(insp, i);
+                       subinsp = lwgeom_inspect(subgeom);
+                       size += asgml3_multi_size(subinsp, 0, precision);
+                       lwinspected_release(subinsp);
+               }
+       }
+
+       return size;
 }
 
 static size_t
 asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree)
 {
-    char *ptr;
-    int i;
-
-    ptr = output;
-
-    /* Open outmost tag */
-    if ( srs )
-    {
-        ptr += sprintf(ptr, "<gml:MultiGeometry srsName=\"%s\">", srs);
-    }
-    else
-    {
-        ptr += sprintf(ptr, "<gml:MultiGeometry>");
-    }
-
-    for (i=0; i<insp->ngeometries; i++)
-    {
-        LWPOINT *point;
-        LWLINE *line;
-        LWPOLY *poly;
-        LWGEOM_INSPECTED *subinsp;
-        uchar *subgeom;
-
-        ptr += sprintf(ptr, "<gml:geometryMember>");
-        if ((point=lwgeom_getpoint_inspected(insp, i)))
-        {
-            ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree);
-            lwpoint_release(point);
-        }
-        else if ((line=lwgeom_getline_inspected(insp, i)))
-        {
-            ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree);
-            lwline_release(line);
-        }
-        else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-        {
-            ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree);
-            lwpoly_release(poly);
-        }
-        else
-        {
-            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);
-            else
-                ptr += asgml3_multi_buf(subinsp, 0, ptr, precision, is_deegree);
-            lwinspected_release(subinsp);
-        }
-        ptr += sprintf(ptr, "</gml:geometryMember>");
-    }
-
-    /* Close outmost tag */
-    ptr += sprintf(ptr, "</gml:MultiGeometry>");
-
-    return (ptr-output);
+       char *ptr;
+       int i;
+
+       ptr = output;
+
+       /* Open outmost tag */
+       if ( srs )
+       {
+               ptr += sprintf(ptr, "<gml:MultiGeometry srsName=\"%s\">", srs);
+       }
+       else
+       {
+               ptr += sprintf(ptr, "<gml:MultiGeometry>");
+       }
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+               LWGEOM_INSPECTED *subinsp;
+               uchar *subgeom;
+
+               ptr += sprintf(ptr, "<gml:geometryMember>");
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree);
+                       lwpoint_release(point);
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree);
+                       lwline_release(line);
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree);
+                       lwpoly_release(poly);
+               }
+               else
+               {
+                       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);
+                       else
+                               ptr += asgml3_multi_buf(subinsp, 0, ptr, precision, is_deegree);
+                       lwinspected_release(subinsp);
+               }
+               ptr += sprintf(ptr, "</gml:geometryMember>");
+       }
+
+       /* Close outmost tag */
+       ptr += sprintf(ptr, "</gml:MultiGeometry>");
+
+       return (ptr-output);
 }
 
 /*
@@ -995,13 +995,13 @@ asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci
 static char *
 asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree)
 {
-    char *gml;
-    size_t size;
+       char *gml;
+       size_t size;
 
-    size = asgml3_collection_size(insp, srs, precision);
-    gml = lwalloc(size);
-    asgml3_collection_buf(insp, srs, gml, precision, is_deegree);
-    return gml;
+       size = asgml3_collection_size(insp, srs, precision);
+       gml = lwalloc(size);
+       asgml3_collection_buf(insp, srs, gml, precision, is_deegree);
+       return gml;
 }
 
 
@@ -1011,74 +1011,74 @@ asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegr
 static size_t
 pointArray_toGML3(POINTARRAY *pa, char *output, int precision, int is_deegree)
 {
-    int i;
-    char *ptr;
-    char x[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
-    char y[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
-    char z[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
-
-    ptr = output;
-
-    if ( ! TYPE_HASZ(pa->dims) )
-    {
-        for (i=0; i<pa->npoints; i++)
-        {
-            POINT2D pt;
-            getPoint2d_p(pa, i, &pt);
-
-            if (fabs(pt.x) < OUT_MAX_DOUBLE)
-                sprintf(x, "%.*f", precision, pt.x);
-            else
-                sprintf(x, "%g", pt.x);
-            trim_trailing_zeros(x);
-
-            if (fabs(pt.y) < OUT_MAX_DOUBLE)
-                sprintf(y, "%.*f", precision, pt.y);
-            else
-                sprintf(y, "%g", pt.y);
-            trim_trailing_zeros(y);
-
-            if ( i ) ptr += sprintf(ptr, " ");
-            if (is_deegree)
-                ptr += sprintf(ptr, "%s %s", y, x);
-            else
-                ptr += sprintf(ptr, "%s %s", x, y);
-        }
-    }
-    else
-    {
-        for (i=0; i<pa->npoints; i++)
-        {
-            POINT4D pt;
-            getPoint4d_p(pa, i, &pt);
-
-            if (fabs(pt.x) < OUT_MAX_DOUBLE)
-                sprintf(x, "%.*f", precision, pt.x);
-            else
-                sprintf(x, "%g", pt.x);
-            trim_trailing_zeros(x);
-
-            if (fabs(pt.y) < OUT_MAX_DOUBLE)
-                sprintf(y, "%.*f", precision, pt.y);
-            else
-                sprintf(y, "%g", pt.y);
-            trim_trailing_zeros(y);
-
-            if (fabs(pt.z) < OUT_MAX_DOUBLE)
-                sprintf(z, "%.*f", precision, pt.z);
-            else
-                sprintf(z, "%g", pt.z);
-            trim_trailing_zeros(z);
-
-            if ( i ) ptr += sprintf(ptr, " ");
-            if (is_deegree)
-                ptr += sprintf(ptr, "%s %s %s", y, x, z);
-            else
-                ptr += sprintf(ptr, "%s %s %s", x, y, z);
-        }
-    }
-
-    return ptr-output;
+       int i;
+       char *ptr;
+       char x[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+       char y[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+       char z[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+
+       ptr = output;
+
+       if ( ! TYPE_HASZ(pa->dims) )
+       {
+               for (i=0; i<pa->npoints; i++)
+               {
+                       POINT2D pt;
+                       getPoint2d_p(pa, i, &pt);
+
+                       if (fabs(pt.x) < OUT_MAX_DOUBLE)
+                               sprintf(x, "%.*f", precision, pt.x);
+                       else
+                               sprintf(x, "%g", pt.x);
+                       trim_trailing_zeros(x);
+
+                       if (fabs(pt.y) < OUT_MAX_DOUBLE)
+                               sprintf(y, "%.*f", precision, pt.y);
+                       else
+                               sprintf(y, "%g", pt.y);
+                       trim_trailing_zeros(y);
+
+                       if ( i ) ptr += sprintf(ptr, " ");
+                       if (is_deegree)
+                               ptr += sprintf(ptr, "%s %s", y, x);
+                       else
+                               ptr += sprintf(ptr, "%s %s", x, y);
+               }
+       }
+       else
+       {
+               for (i=0; i<pa->npoints; i++)
+               {
+                       POINT4D pt;
+                       getPoint4d_p(pa, i, &pt);
+
+                       if (fabs(pt.x) < OUT_MAX_DOUBLE)
+                               sprintf(x, "%.*f", precision, pt.x);
+                       else
+                               sprintf(x, "%g", pt.x);
+                       trim_trailing_zeros(x);
+
+                       if (fabs(pt.y) < OUT_MAX_DOUBLE)
+                               sprintf(y, "%.*f", precision, pt.y);
+                       else
+                               sprintf(y, "%g", pt.y);
+                       trim_trailing_zeros(y);
+
+                       if (fabs(pt.z) < OUT_MAX_DOUBLE)
+                               sprintf(z, "%.*f", precision, pt.z);
+                       else
+                               sprintf(z, "%g", pt.z);
+                       trim_trailing_zeros(z);
+
+                       if ( i ) ptr += sprintf(ptr, " ");
+                       if (is_deegree)
+                               ptr += sprintf(ptr, "%s %s %s", y, x, z);
+                       else
+                               ptr += sprintf(ptr, "%s %s %s", x, y, z);
+               }
+       }
+
+       return ptr-output;
 }
 
 
@@ -1089,9 +1089,9 @@ pointArray_toGML3(POINTARRAY *pa, char *output, int precision, int is_deegree)
 static size_t
 pointArray_GMLsize(POINTARRAY *pa, int precision)
 {
-    if (TYPE_NDIMS(pa->dims) == 2)
-        return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", "))
-               * 2 * pa->npoints;
+       if (TYPE_NDIMS(pa->dims) == 2)
+               return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", "))
+                      * 2 * pa->npoints;
 
-    return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints;
+       return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints;
 }
diff --git a/liblwgeom/lwout_kml.c b/liblwgeom/lwout_kml.c
new file mode 100644 (file)
index 0000000..dfb1c7a
--- /dev/null
@@ -0,0 +1,403 @@
+/**********************************************************************
+ * $Id: lwgeom_kml.c 4682 2009-10-27 21:39:35Z colivier $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of hte GNU General Public Licence. See the COPYING file.
+ *
+ **********************************************************************/
+
+/**
+* @file
+* KML output routines based on lwgeom_gml.c
+* Written by: Eduin Carrillo <yecarrillo@cas.gov.co>
+*             © 2006 Corporacion Autonoma Regional de Santander - CAS
+*
+**********************************************************************/
+
+#include "liblwgeom.h"
+#include <math.h>      /* fabs */
+
+char *lwgeom_to_kml2(uchar *srl, int precision);
+
+static size_t askml2_point_size(LWPOINT *point, int precision);
+static char *askml2_point(LWPOINT *point, int precision);
+static size_t askml2_line_size(LWLINE *line, int precision);
+static char *askml2_line(LWLINE *line, int precision);
+static size_t askml2_poly_size(LWPOLY *poly, int precision);
+static char *askml2_poly(LWPOLY *poly, int precision);
+static size_t askml2_inspected_size(LWGEOM_INSPECTED *geom, int precision);
+static char *askml2_inspected(LWGEOM_INSPECTED *geom, int precision);
+static size_t pointArray_toKML2(POINTARRAY *pa, char *buf, int precision);
+
+static size_t pointArray_KMLsize(POINTARRAY *pa, int precision);
+
+
+/*
+ * KML 2.2.0
+ */
+
+/* takes a GEOMETRY and returns a KML representation */
+char *
+lwgeom_to_kml2(uchar *geom, int precision)
+{
+       int type;
+       LWPOINT *point;
+       LWLINE *line;
+       LWPOLY *poly;
+       LWGEOM_INSPECTED *inspected;
+
+       type = lwgeom_getType(geom[0]);
+
+       switch (type)
+       {
+
+       case POINTTYPE:
+               point = lwpoint_deserialize(geom);
+               return askml2_point(point, precision);
+
+       case LINETYPE:
+               line = lwline_deserialize(geom);
+               return askml2_line(line, precision);
+
+       case POLYGONTYPE:
+               poly = lwpoly_deserialize(geom);
+               return askml2_poly(poly, precision);
+
+       case MULTIPOINTTYPE:
+       case MULTILINETYPE:
+       case MULTIPOLYGONTYPE:
+               inspected = lwgeom_inspect(geom);
+               return askml2_inspected(inspected, precision);
+
+       default:
+               lwerror("lwgeom_to_kml2: '%s' geometry type not supported",
+                       lwgeom_typename(type));
+               return NULL;
+       }
+}
+
+static size_t
+askml2_point_size(LWPOINT *point, int precision)
+{
+       int size;
+       size = pointArray_KMLsize(point->point, precision);
+       size += sizeof("<point><coordinates>/") * 2;
+       return size;
+}
+
+static size_t
+askml2_point_buf(LWPOINT *point, char *output, int precision)
+{
+       char *ptr = output;
+
+       ptr += sprintf(ptr, "<Point>");
+       ptr += sprintf(ptr, "<coordinates>");
+       ptr += pointArray_toKML2(point->point, ptr, precision);
+       ptr += sprintf(ptr, "</coordinates></Point>");
+
+       return (ptr-output);
+}
+
+static char *
+askml2_point(LWPOINT *point, int precision)
+{
+       char *output;
+       int size;
+
+       size = askml2_point_size(point, precision);
+       output = lwalloc(size);
+       askml2_point_buf(point, output, precision);
+       return output;
+}
+
+static size_t
+askml2_line_size(LWLINE *line, int precision)
+{
+       int size;
+       size = pointArray_KMLsize(line->points, precision);
+       size += sizeof("<linestring><coordinates>/") * 2;
+       return size;
+}
+
+static size_t
+askml2_line_buf(LWLINE *line, char *output, int precision)
+{
+       char *ptr=output;
+
+       ptr += sprintf(ptr, "<LineString>");
+       ptr += sprintf(ptr, "<coordinates>");
+       ptr += pointArray_toKML2(line->points, ptr, precision);
+       ptr += sprintf(ptr, "</coordinates></LineString>");
+
+       return (ptr-output);
+}
+
+static char *
+askml2_line(LWLINE *line, int precision)
+{
+       char *output;
+       int size;
+
+       size = askml2_line_size(line, precision);
+       output = lwalloc(size);
+       askml2_line_buf(line, output, precision);
+       return output;
+}
+
+static size_t
+askml2_poly_size(LWPOLY *poly, int precision)
+{
+       size_t size;
+       int i;
+
+       size = sizeof("<polygon></polygon>");
+       size += sizeof("<outerboundaryis><linearring><coordinates>/") * 2;
+       size += sizeof("<innerboundaryis><linearring><coordinates>/") * 2 *
+               poly->nrings;
+
+       for (i=0; i<poly->nrings; i++)
+               size += pointArray_KMLsize(poly->rings[i], precision);
+
+       return size;
+}
+
+static size_t
+askml2_poly_buf(LWPOLY *poly, char *output, int precision)
+{
+       int i;
+       char *ptr=output;
+
+       ptr += sprintf(ptr, "<Polygon>");
+       ptr += sprintf(ptr, "<outerBoundaryIs><LinearRing><coordinates>");
+       ptr += pointArray_toKML2(poly->rings[0], ptr, precision);
+       ptr += sprintf(ptr, "</coordinates></LinearRing></outerBoundaryIs>");
+       for (i=1; i<poly->nrings; i++)
+       {
+               ptr += sprintf(ptr, "<innerBoundaryIs><LinearRing><coordinates>");
+               ptr += pointArray_toKML2(poly->rings[i], ptr, precision);
+               ptr += sprintf(ptr, "</coordinates></LinearRing></innerBoundaryIs>");
+       }
+       ptr += sprintf(ptr, "</Polygon>");
+
+       return (ptr-output);
+}
+
+static char *
+askml2_poly(LWPOLY *poly, int precision)
+{
+       char *output;
+       int size;
+
+       size = askml2_poly_size(poly, precision);
+       output = lwalloc(size);
+       askml2_poly_buf(poly, output, precision);
+       return output;
+}
+
+/*
+ * Compute max size required for KML version of this
+ * inspected geometry. Will recurse when needed.
+ * Don't call this with single-geoms inspected.
+ */
+static size_t
+askml2_inspected_size(LWGEOM_INSPECTED *insp, int precision)
+{
+       int i;
+       size_t size;
+
+       /* the longest possible multi version */
+       size = sizeof("<MultiGeometry></MultiGeometry>");
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+               LWGEOM_INSPECTED *subinsp;
+               uchar *subgeom;
+
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       size += askml2_point_size(point, precision);
+                       lwpoint_free(point);
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       size += askml2_line_size(line, precision);
+                       lwline_free(line);
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       size += askml2_poly_size(poly, precision);
+                       lwpoly_free(poly);
+               }
+               else
+               {
+                       subgeom = lwgeom_getsubgeometry_inspected(insp, i);
+                       subinsp = lwgeom_inspect(subgeom);
+                       size += askml2_inspected_size(subinsp, precision);
+                       lwinspected_release(subinsp);
+               }
+       }
+
+       return size;
+}
+
+/*
+ * Don't call this with single-geoms inspected!
+ */
+static size_t
+askml2_inspected_buf(LWGEOM_INSPECTED *insp, char *output, int precision)
+{
+       char *ptr, *kmltype;
+       int i;
+
+       ptr = output;
+       kmltype = "MultiGeometry";
+
+       /* Open outmost tag */
+       ptr += sprintf(ptr, "<%s>", kmltype);
+
+       for (i=0; i<insp->ngeometries; i++)
+       {
+               LWPOINT *point;
+               LWLINE *line;
+               LWPOLY *poly;
+               LWGEOM_INSPECTED *subinsp;
+               uchar *subgeom;
+
+               if ((point=lwgeom_getpoint_inspected(insp, i)))
+               {
+                       ptr += askml2_point_buf(point, ptr, precision);
+                       lwpoint_free(point);
+               }
+               else if ((line=lwgeom_getline_inspected(insp, i)))
+               {
+                       ptr += askml2_line_buf(line, ptr, precision);
+                       lwline_free(line);
+               }
+               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
+               {
+                       ptr += askml2_poly_buf(poly, ptr, precision);
+                       lwpoly_free(poly);
+               }
+               else
+               {
+                       subgeom = lwgeom_getsubgeometry_inspected(insp, i);
+                       subinsp = lwgeom_inspect(subgeom);
+                       ptr += askml2_inspected_buf(subinsp, ptr, precision);
+                       lwinspected_release(subinsp);
+               }
+       }
+
+       /* Close outmost tag */
+       ptr += sprintf(ptr, "</%s>", kmltype);
+
+       return (ptr-output);
+}
+
+/*
+ * Don't call this with single-geoms inspected!
+ */
+static char *
+askml2_inspected(LWGEOM_INSPECTED *insp, int precision)
+{
+       char *kml;
+       size_t size;
+
+       size = askml2_inspected_size(insp, precision);
+       kml = lwalloc(size);
+       askml2_inspected_buf(insp, kml, precision);
+       return kml;
+}
+
+static size_t
+pointArray_toKML2(POINTARRAY *pa, char *output, int precision)
+{
+       int i;
+       char *ptr;
+       char x[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+       char y[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+       char z[OUT_MAX_DIGS_DOUBLE+OUT_MAX_DOUBLE_PRECISION+1];
+
+       ptr = output;
+
+       if ( ! TYPE_HASZ(pa->dims) )
+       {
+               for (i=0; i<pa->npoints; i++)
+               {
+                       POINT2D pt;
+                       getPoint2d_p(pa, i, &pt);
+
+                       if (fabs(pt.x) < OUT_MAX_DOUBLE)
+                               sprintf(x, "%.*f", precision, pt.x);
+                       else
+                               sprintf(x, "%g", pt.x);
+                       trim_trailing_zeros(x);
+
+                       if (fabs(pt.y) < OUT_MAX_DOUBLE)
+                               sprintf(y, "%.*f", precision, pt.y);
+                       else
+                               sprintf(y, "%g", pt.y);
+                       trim_trailing_zeros(y);
+
+                       if ( i ) ptr += sprintf(ptr, " ");
+                       ptr += sprintf(ptr, "%s,%s", x, y);
+               }
+       }
+       else
+       {
+               for (i=0; i<pa->npoints; i++)
+               {
+                       POINT4D pt;
+                       getPoint4d_p(pa, i, &pt);
+
+                       if (fabs(pt.x) < OUT_MAX_DOUBLE)
+                               sprintf(x, "%.*f", precision, pt.x);
+                       else
+                               sprintf(x, "%g", pt.x);
+                       trim_trailing_zeros(x);
+
+                       if (fabs(pt.y) < OUT_MAX_DOUBLE)
+                               sprintf(y, "%.*f", precision, pt.y);
+                       else
+                               sprintf(y, "%g", pt.y);
+                       trim_trailing_zeros(y);
+
+                       if (fabs(pt.z) < OUT_MAX_DOUBLE)
+                               sprintf(z, "%.*f", precision, pt.z);
+                       else
+                               sprintf(z, "%g", pt.z);
+                       trim_trailing_zeros(z);
+
+                       if ( i ) ptr += sprintf(ptr, " ");
+                       ptr += sprintf(ptr, "%s,%s,%s", x, y, z);
+               }
+       }
+
+       return ptr-output;
+}
+
+
+
+/*
+ * Common KML routines
+ */
+
+/*
+ * Returns maximum size of rendered pointarray in bytes.
+ */
+static size_t
+pointArray_KMLsize(POINTARRAY *pa, int precision)
+{
+       if (TYPE_NDIMS(pa->dims) == 2)
+               return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", "))
+                      * 2 * pa->npoints;
+
+       return (OUT_MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints;
+}
+
index 1e10065c45701643fb669d632c174edcedc82c2e..f4064482bec8e5e0ca17d7fe2070f9ad34b75501 100644 (file)
@@ -507,7 +507,7 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
        int version;
        char *srs;
        int SRID = SRID_DEFAULT;
-       int precision = MAX_DOUBLE_PRECISION;
+       int precision = OUT_MAX_DOUBLE_PRECISION;
        int option=0;
 
        /* Get the version */
@@ -529,8 +529,8 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
        if (PG_NARGS() >2 && !PG_ARGISNULL(2))
        {
                precision = PG_GETARG_INT32(2);
-               if ( precision > MAX_DOUBLE_PRECISION )
-                       precision = MAX_DOUBLE_PRECISION;
+               if ( precision > OUT_MAX_DOUBLE_PRECISION )
+                       precision = OUT_MAX_DOUBLE_PRECISION;
                else if ( precision < 0 ) precision = 0;
        }
 
@@ -560,7 +560,7 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
 
        memcpy(VARDATA(result), gml, len-VARHDRSZ);
 
-       pfree(gml);
+       lwfree(gml);
 
        PG_RETURN_POINTER(result);
 }
@@ -578,7 +578,7 @@ Datum geography_as_kml(PG_FUNCTION_ARGS)
        text *result;
        int len;
        int version;
-       int precision = MAX_DOUBLE_PRECISION;
+       int precision = OUT_MAX_DOUBLE_PRECISION;
 
 
        /* Get the version */
@@ -600,12 +600,12 @@ Datum geography_as_kml(PG_FUNCTION_ARGS)
        if (PG_NARGS() >2 && !PG_ARGISNULL(2))
        {
                precision = PG_GETARG_INT32(2);
-               if ( precision > MAX_DOUBLE_PRECISION )
-                       precision = MAX_DOUBLE_PRECISION;
+               if ( precision > OUT_MAX_DOUBLE_PRECISION )
+                       precision = OUT_MAX_DOUBLE_PRECISION;
                else if ( precision < 0 ) precision = 0;
        }
 
-       kml = geometry_to_kml2(lwgeom_serialize(lwgeom), precision);
+       kml = lwgeom_to_kml2(lwgeom_serialize(lwgeom), precision);
 
        PG_FREE_IF_COPY(lwgeom, 1);
 
@@ -616,7 +616,7 @@ Datum geography_as_kml(PG_FUNCTION_ARGS)
 
        memcpy(VARDATA(result), kml, len-VARHDRSZ);
 
-       pfree(kml);
+       lwfree(kml);
 
        PG_RETURN_POINTER(result);
 }
index 6d813688013a3601d485a31ec6c58f6fcefdc8f4..774b1bb0d26b10c3a8458ffea26f4628a2264368 100644 (file)
 
 Datum LWGEOM_asKML(PG_FUNCTION_ARGS);
 
-char *geometry_to_kml2(uchar *srl, int precision);
-
-static size_t askml2_point_size(LWPOINT *point, int precision);
-static char *askml2_point(LWPOINT *point, int precision);
-static size_t askml2_line_size(LWLINE *line, int precision);
-static char *askml2_line(LWLINE *line, int precision);
-static size_t askml2_poly_size(LWPOLY *poly, int precision);
-static char *askml2_poly(LWPOLY *poly, int precision);
-static size_t askml2_inspected_size(LWGEOM_INSPECTED *geom, int precision);
-static char *askml2_inspected(LWGEOM_INSPECTED *geom, int precision);
-static size_t pointArray_toKML2(POINTARRAY *pa, char *buf, int precision);
-
-static size_t pointArray_KMLsize(POINTARRAY *pa, int precision);
-
-
 /**
  * Encode feature in KML
  */
@@ -54,7 +39,7 @@ Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
        text *result;
        int len;
        int version;
-       int precision = MAX_DOUBLE_PRECISION;
+       int precision = OUT_MAX_DOUBLE_PRECISION;
 
 
        /* Get the version */
@@ -73,12 +58,12 @@ Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
        if (PG_NARGS() >2 && !PG_ARGISNULL(2))
        {
                precision = PG_GETARG_INT32(2);
-               if ( precision > MAX_DOUBLE_PRECISION )
-                       precision = MAX_DOUBLE_PRECISION;
+               if ( precision > OUT_MAX_DOUBLE_PRECISION )
+                       precision = OUT_MAX_DOUBLE_PRECISION;
                else if ( precision < 0 ) precision = 0;
        }
 
-       kml = geometry_to_kml2(SERIALIZED_FORM(geom), precision);
+       kml = lwgeom_to_kml2(SERIALIZED_FORM(geom), precision);
 
        PG_FREE_IF_COPY(geom, 1);
 
@@ -89,374 +74,7 @@ Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
 
        memcpy(VARDATA(result), kml, len-VARHDRSZ);
 
-       pfree(kml);
+       lwfree(kml);
 
        PG_RETURN_POINTER(result);
 }
-
-
-
-/*
- * VERSION KML 2
- */
-
-/* takes a GEOMETRY and returns a KML representation */
-char *
-geometry_to_kml2(uchar *geom, int precision)
-{
-       int type;
-       LWPOINT *point;
-       LWLINE *line;
-       LWPOLY *poly;
-       LWGEOM_INSPECTED *inspected;
-
-       type = lwgeom_getType(geom[0]);
-
-       switch (type)
-       {
-
-       case POINTTYPE:
-               point = lwpoint_deserialize(geom);
-               return askml2_point(point, precision);
-
-       case LINETYPE:
-               line = lwline_deserialize(geom);
-               return askml2_line(line, precision);
-
-       case POLYGONTYPE:
-               poly = lwpoly_deserialize(geom);
-               return askml2_poly(poly, precision);
-
-       case MULTIPOINTTYPE:
-       case MULTILINETYPE:
-       case MULTIPOLYGONTYPE:
-               inspected = lwgeom_inspect(geom);
-               return askml2_inspected(inspected, precision);
-
-       default:
-               lwerror("geometry_to_kml: '%s' geometry type not supported by Google Earth", lwgeom_typename(type));
-               return NULL;
-       }
-}
-
-static size_t
-askml2_point_size(LWPOINT *point, int precision)
-{
-       int size;
-       size = pointArray_KMLsize(point->point, precision);
-       size += sizeof("<point><coordinates>/") * 2;
-       return size;
-}
-
-static size_t
-askml2_point_buf(LWPOINT *point, char *output, int precision)
-{
-       char *ptr = output;
-
-       ptr += sprintf(ptr, "<Point>");
-       ptr += sprintf(ptr, "<coordinates>");
-       ptr += pointArray_toKML2(point->point, ptr, precision);
-       ptr += sprintf(ptr, "</coordinates></Point>");
-
-       return (ptr-output);
-}
-
-static char *
-askml2_point(LWPOINT *point, int precision)
-{
-       char *output;
-       int size;
-
-       size = askml2_point_size(point, precision);
-       output = palloc(size);
-       askml2_point_buf(point, output, precision);
-       return output;
-}
-
-static size_t
-askml2_line_size(LWLINE *line, int precision)
-{
-       int size;
-       size = pointArray_KMLsize(line->points, precision);
-       size += sizeof("<linestring><coordinates>/") * 2;
-       return size;
-}
-
-static size_t
-askml2_line_buf(LWLINE *line, char *output, int precision)
-{
-       char *ptr=output;
-
-       ptr += sprintf(ptr, "<LineString>");
-       ptr += sprintf(ptr, "<coordinates>");
-       ptr += pointArray_toKML2(line->points, ptr, precision);
-       ptr += sprintf(ptr, "</coordinates></LineString>");
-
-       return (ptr-output);
-}
-
-static char *
-askml2_line(LWLINE *line, int precision)
-{
-       char *output;
-       int size;
-
-       size = askml2_line_size(line, precision);
-       output = palloc(size);
-       askml2_line_buf(line, output, precision);
-       return output;
-}
-
-static size_t
-askml2_poly_size(LWPOLY *poly, int precision)
-{
-       size_t size;
-       int i;
-
-       size = sizeof("<polygon></polygon>");
-       size += sizeof("<outerboundaryis><linearring><coordinates>/") * 2;
-       size += sizeof("<innerboundaryis><linearring><coordinates>/") * 2 *
-               poly->nrings;
-
-       for (i=0; i<poly->nrings; i++)
-               size += pointArray_KMLsize(poly->rings[i], precision);
-
-       return size;
-}
-
-static size_t
-askml2_poly_buf(LWPOLY *poly, char *output, int precision)
-{
-       int i;
-       char *ptr=output;
-
-       ptr += sprintf(ptr, "<Polygon>");
-       ptr += sprintf(ptr, "<outerBoundaryIs><LinearRing><coordinates>");
-       ptr += pointArray_toKML2(poly->rings[0], ptr, precision);
-       ptr += sprintf(ptr, "</coordinates></LinearRing></outerBoundaryIs>");
-       for (i=1; i<poly->nrings; i++)
-       {
-               ptr += sprintf(ptr, "<innerBoundaryIs><LinearRing><coordinates>");
-               ptr += pointArray_toKML2(poly->rings[i], ptr, precision);
-               ptr += sprintf(ptr, "</coordinates></LinearRing></innerBoundaryIs>");
-       }
-       ptr += sprintf(ptr, "</Polygon>");
-
-       return (ptr-output);
-}
-
-static char *
-askml2_poly(LWPOLY *poly, int precision)
-{
-       char *output;
-       int size;
-
-       size = askml2_poly_size(poly, precision);
-       output = palloc(size);
-       askml2_poly_buf(poly, output, precision);
-       return output;
-}
-
-/*
- * Compute max size required for KML version of this
- * inspected geometry. Will recurse when needed.
- * Don't call this with single-geoms inspected.
- */
-static size_t
-askml2_inspected_size(LWGEOM_INSPECTED *insp, int precision)
-{
-       int i;
-       size_t size;
-
-       /* the longest possible multi version */
-       size = sizeof("<MultiGeometry></MultiGeometry>");
-
-       for (i=0; i<insp->ngeometries; i++)
-       {
-               LWPOINT *point;
-               LWLINE *line;
-               LWPOLY *poly;
-               LWGEOM_INSPECTED *subinsp;
-               uchar *subgeom;
-
-               if ((point=lwgeom_getpoint_inspected(insp, i)))
-               {
-                       size += askml2_point_size(point, precision);
-                       lwpoint_free(point);
-               }
-               else if ((line=lwgeom_getline_inspected(insp, i)))
-               {
-                       size += askml2_line_size(line, precision);
-                       lwline_free(line);
-               }
-               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-               {
-                       size += askml2_poly_size(poly, precision);
-                       lwpoly_free(poly);
-               }
-               else
-               {
-                       subgeom = lwgeom_getsubgeometry_inspected(insp, i);
-                       subinsp = lwgeom_inspect(subgeom);
-                       size += askml2_inspected_size(subinsp, precision);
-                       lwinspected_release(subinsp);
-               }
-       }
-
-       return size;
-}
-
-/*
- * Don't call this with single-geoms inspected!
- */
-static size_t
-askml2_inspected_buf(LWGEOM_INSPECTED *insp, char *output, int precision)
-{
-       char *ptr, *kmltype;
-       int i;
-
-       ptr = output;
-       kmltype = "MultiGeometry";
-
-       /* Open outmost tag */
-       ptr += sprintf(ptr, "<%s>", kmltype);
-
-       for (i=0; i<insp->ngeometries; i++)
-       {
-               LWPOINT *point;
-               LWLINE *line;
-               LWPOLY *poly;
-               LWGEOM_INSPECTED *subinsp;
-               uchar *subgeom;
-
-               if ((point=lwgeom_getpoint_inspected(insp, i)))
-               {
-                       ptr += askml2_point_buf(point, ptr, precision);
-                       lwpoint_free(point);
-               }
-               else if ((line=lwgeom_getline_inspected(insp, i)))
-               {
-                       ptr += askml2_line_buf(line, ptr, precision);
-                       lwline_free(line);
-               }
-               else if ((poly=lwgeom_getpoly_inspected(insp, i)))
-               {
-                       ptr += askml2_poly_buf(poly, ptr, precision);
-                       lwpoly_free(poly);
-               }
-               else
-               {
-                       subgeom = lwgeom_getsubgeometry_inspected(insp, i);
-                       subinsp = lwgeom_inspect(subgeom);
-                       ptr += askml2_inspected_buf(subinsp, ptr, precision);
-                       lwinspected_release(subinsp);
-               }
-       }
-
-       /* Close outmost tag */
-       ptr += sprintf(ptr, "</%s>", kmltype);
-
-       return (ptr-output);
-}
-
-/*
- * Don't call this with single-geoms inspected!
- */
-static char *
-askml2_inspected(LWGEOM_INSPECTED *insp, int precision)
-{
-       char *kml;
-       size_t size;
-
-       size = askml2_inspected_size(insp, precision);
-       kml = palloc(size);
-       askml2_inspected_buf(insp, kml, precision);
-       return kml;
-}
-
-static size_t
-pointArray_toKML2(POINTARRAY *pa, char *output, int precision)
-{
-       int i;
-       char *ptr;
-       char x[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
-       char y[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
-       char z[MAX_DIGS_DOUBLE+MAX_DOUBLE_PRECISION+1];
-
-       ptr = output;
-
-       if ( ! TYPE_HASZ(pa->dims) )
-       {
-               for (i=0; i<pa->npoints; i++)
-               {
-                       POINT2D pt;
-                       getPoint2d_p(pa, i, &pt);
-
-                       if (fabs(pt.x) < MAX_DOUBLE)
-                               sprintf(x, "%.*f", precision, pt.x);
-                       else
-                               sprintf(x, "%g", pt.x);
-                       trim_trailing_zeros(x);
-
-                       if (fabs(pt.y) < MAX_DOUBLE)
-                               sprintf(y, "%.*f", precision, pt.y);
-                       else
-                               sprintf(y, "%g", pt.y);
-                       trim_trailing_zeros(y);
-
-                       if ( i ) ptr += sprintf(ptr, " ");
-                       ptr += sprintf(ptr, "%s,%s", x, y);
-               }
-       }
-       else
-       {
-               for (i=0; i<pa->npoints; i++)
-               {
-                       POINT4D pt;
-                       getPoint4d_p(pa, i, &pt);
-
-                       if (fabs(pt.x) < MAX_DOUBLE)
-                               sprintf(x, "%.*f", precision, pt.x);
-                       else
-                               sprintf(x, "%g", pt.x);
-                       trim_trailing_zeros(x);
-
-                       if (fabs(pt.y) < MAX_DOUBLE)
-                               sprintf(y, "%.*f", precision, pt.y);
-                       else
-                               sprintf(y, "%g", pt.y);
-                       trim_trailing_zeros(y);
-
-                       if (fabs(pt.z) < MAX_DOUBLE)
-                               sprintf(z, "%.*f", precision, pt.z);
-                       else
-                               sprintf(z, "%g", pt.z);
-                       trim_trailing_zeros(z);
-
-                       if ( i ) ptr += sprintf(ptr, " ");
-                       ptr += sprintf(ptr, "%s,%s,%s", x, y, z);
-               }
-       }
-
-       return ptr-output;
-}
-
-
-
-/*
- * Common KML routines
- */
-
-/*
- * Returns maximum size of rendered pointarray in bytes.
- */
-static size_t
-pointArray_KMLsize(POINTARRAY *pa, int precision)
-{
-       if (TYPE_NDIMS(pa->dims) == 2)
-               return (MAX_DIGS_DOUBLE + precision + sizeof(", "))
-                      * 2 * pa->npoints;
-
-       return (MAX_DIGS_DOUBLE + precision + sizeof(", ")) * 3 * pa->npoints;
-}
-
index 1fb031c015d3adc036dc82135351bf894f416b32..5a93ab38d2adddb648b4aa07e19784eda761b9ce 100644 (file)
@@ -1,94 +1,31 @@
--- Regression tests for KML producer
--- Written by: Eduin Carrillo <yecarrillo@cas.gov.co>
---             © 2006 Corporacion Autonoma Regional de Santander - CAS
--- http://postgis.refractions.net/pipermail/postgis-devel/2006-December/002376.html
-
--- SPATIAL INFO NO AVAILABLE
-SELECT 'no_srid_01', AsKML(GeomFromEWKT('SRID=1021892;POINT(1000000 1000000)'));
+-- Regress test for ST_AsKML 
 
 --- EPSG 4326 : WGS 84
-INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ');
+INSERT INTO "spatial_ref_sys" ("srid", "proj4text") VALUES (4326, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ');
+
 --- EPSG 1021892 : Bogota 1975 / Colombia Bogota zone (deprecated)
-INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (1021892,'EPSG',1021892,'PROJCS["Bogota 1975 / Colombia Bogota zone (deprecated)",GEOGCS["Bogota 1975",DATUM["Bogota_1975",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],TOWGS84[307,304,-318,0,0,0,0],AUTHORITY["EPSG","6218"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4218"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",4.599047222222222],PARAMETER["central_meridian",-74.08091666666667],PARAMETER["scale_factor",1],PARAMETER["false_easting",1000000],PARAMETER["false_northing",1000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","21892"]]','+proj=tmerc +lat_0=4.599047222222222 +lon_0=-74.08091666666667 +k=1.000000 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m +no_defs ');
+INSERT INTO "spatial_ref_sys" ("srid", "proj4text") VALUES (1021892, '+proj=tmerc +lat_0=4.599047222222222 +lon_0=-74.08091666666667 +k=1.000000 +x_0=1000000 +y_0=1000000 +ellps=intl +towgs84=307,304,-318,0,0,0,0 +units=m +no_defs ');
 
--- NO SRID PROVIDED
-SELECT 'no_srid_02', AsKML(GeomFromEWKT('POINT(1 1)'));
 
--- UNSUPPORTED GEOMETRY TYPES
-SELECT 'invalid_01', AsKML(GeomFromEWKT('SRID=4326;CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)'));
-SELECT 'invalid_02', AsKML(GeomFromEWKT('SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))'));
-SELECT 'invalid_03', AsKML(GeomFromEWKT('SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))'));
-SELECT 'invalid_04', AsKML(GeomFromEWKT('SRID=4326;MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))'));
-SELECT 'invalid_05', AsKML(GeomFromEWKT('SRID=4326;MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))'));
+-- SRID
+SELECT 'srid_01', ST_AsKML(GeomFromEWKT('SRID=10;POINT(0 1)'));
+SELECT 'srid_02', ST_AsKML(GeomFromEWKT('POINT(0 1)'));
 
--- PARAMETERS
-SELECT 'parameter_01', AsKML(GeomFromEWKT('SRID=4326;POINT(1.1111111111111111 1.1111111111111111)'), 0);
-SELECT 'parameter_02', AsKML(GeomFromEWKT('SRID=4326;POINT(1.1111111111111111 1.1111111111111111)'), 16);
-SELECT 'parameter_03', AsKML(3,GeomFromEWKT('SRID=4326;POINT(1.1111111111111111 1.1111111111111111)'), 15);
+-- Empty Geometry
+SELECT 'empty_geom', ST_AsKML(GeomFromEWKT(NULL));
 
--- SIMPLE FEATURES
--- San Felipe de Barajas Fortresses - Cartagena, Colombia (Placemark) http://en.wikipedia.org/wiki/Cartagena%2C_Bol%C3%ADvar
-SELECT 'point_01', AsKML(GeomFromEWKT('SRID=4326;POINT(-75.55217297757488 10.42033663453054)'), 3);
-SELECT 'point_02', AsKML(GeomFromEWKT('SRID=4326;POINT(-75.55217297757488 10.42033663453054)'), 8);
--- Olaya Herrera Airport - Medellin, Colombia (Path) http://en.wikipedia.org/wiki/Olaya_Herrera_Airport
-SELECT 'linestring_01', AsKML(GeomFromEWKT('SRID=4326;LINESTRING(-75.58845168747847 6.230811711917435, -75.59257646818483 6.209034252575331)'), 3);
-SELECT 'linestring_02', AsKML(GeomFromEWKT('SRID=4326;LINESTRING(-75.58845168747847 6.230811711917435, -75.59257646818483 6.209034252575331)'), 8);
--- Unicentro Shopping Centre - Bogota, Colombia (Polygon) http://www.unicentrobogota.com/
-SELECT 'polygon_01', AsKML(SnapToGrid(GeomFromEWKT('SRID=4326;POLYGON((-74.0423991077642 4.70128819450968, -74.04209925973704 4.700950993650923, -74.0420182951016 4.701011516462908, -74.04183483125468 4.700831448835688, -74.0414862905795 4.70114015046422, -74.04132847200927 4.70097698051241, -74.04101990886149 4.701244756502166, -74.0411777421693 4.701425554204853, -74.04087244656924 4.701697127180076, -74.040940643764 4.701773680406961, -74.04089952744008 4.702605660205299, -74.04082413388542 4.702677666010084, -74.04106565350325 4.702949831221687, -74.04087265096442 4.703121094787139, -74.04118884713594 4.7034683330851, -74.04138264686453 4.703308983914091, -74.04173931195382 4.703688847671272, -74.04192370456995 4.703528238994438, -74.0419535628069 4.70355486096117, -74.04230657961881 4.703239478084376, -74.04207492135191 4.702978242710751, -74.0421546959669 4.702907817351857, -74.04195032608129 4.70267512672329, -74.04209558069562 4.702533577124568, -74.04203505048247 4.702466795922, -74.04205318281811 4.702038077671765, -74.04212335562635 4.701974337580458, -74.04198589330784 4.701816901909086, -74.04222167646385 4.70160442413543, -74.04214901975594 4.701519995786457, -74.0423991077642 4.70128819450968))'), 0.000001), 3);
-SELECT 'polygon_02', AsKML(GeomFromEWKT('SRID=4326;POLYGON((-74.0423991077642 4.70128819450968, -74.04209925973704 4.700950993650923, -74.0420182951016 4.701011516462908, -74.04183483125468 4.700831448835688, -74.0414862905795 4.70114015046422, -74.04132847200927 4.70097698051241, -74.04101990886149 4.701244756502166, -74.0411777421693 4.701425554204853, -74.04087244656924 4.701697127180076, -74.040940643764 4.701773680406961, -74.04089952744008 4.702605660205299, -74.04082413388542 4.702677666010084, -74.04106565350325 4.702949831221687, -74.04087265096442 4.703121094787139, -74.04118884713594 4.7034683330851, -74.04138264686453 4.703308983914091, -74.04173931195382 4.703688847671272, -74.04192370456995 4.703528238994438, -74.0419535628069 4.70355486096117, -74.04230657961881 4.703239478084376, -74.04207492135191 4.702978242710751, -74.0421546959669 4.702907817351857, -74.04195032608129 4.70267512672329, -74.04209558069562 4.702533577124568, -74.04203505048247 4.702466795922, -74.04205318281811 4.702038077671765, -74.04212335562635 4.701974337580458, -74.04198589330784 4.701816901909086, -74.04222167646385 4.70160442413543, -74.04214901975594 4.701519995786457, -74.0423991077642 4.70128819450968))'), 8);
+-- Precision
+SELECT 'precision_01', ST_AsKML(ST_GeomFromEWKT('SRID=4326;POINT(1.1111111 1.1111111)'), -2);
+SELECT 'precision_02', ST_AsKML(ST_GeomFromEWKT('SRID=4326;POINT(1.1111111 1.1111111)'), 19);
 
--- MULTI FEATURES
--- Transmilenio mass-transit system Portal Stations - Bogota, Colombia (Placemarks) http://en.wikipedia.org/wiki/List_of_TransMilenio_Stations
-SELECT 'multipoint_01', AsKML(GeomFromEWKT('SRID=4326;MULTIPOINT((-74.04603457594773 4.754687006656519),(-74.095833 4.746435),(-74.11037547492613 4.7098754227297),(-74.120148 4.533696))'), 3);
-SELECT 'multipoint_02', AsKML(GeomFromEWKT('SRID=4326;MULTIPOINT((-74.04603457594773 4.754687006656519),(-74.095833 4.746435),(-74.11037547492613 4.7098754227297),(-74.120148 4.533696))'), 8);
+-- Version
+SELECT 'version_01', ST_AsKML(2, GeomFromEWKT('SRID=4326;POINT(1 1)'));
+SELECT 'version_02', ST_AsKML(3, GeomFromEWKT('SRID=4326;POINT(1 1)'));
+SELECT 'version_03', ST_AsKML(-4, GeomFromEWKT('SRID=4326;POINT(1 1)'));
 
--- REPROJECTED DATA
--- Sun Door Interchange - Bucaramanga, Colombia (Placemark)
-SELECT 'projection_01', AsKML(GeomFromEWKT('SRID=1021892;POINT(1106465.31495947 1277689.13470039)'), 0);
--- Chicamocha, Suarez and Fonce rivers confluence - Santander, Colombia (Placemark)
-SELECT 'projection_02', AsKML(GeomFromEWKT('SRID=1021892;POINT(1097247.52170185 1240255.74263751)'), 0);
+-- Projected 
 -- National Astronomical Observatory of Colombia - Bogota, Colombia (Placemark)
-SELECT 'projection_03', AsKML(GeomFromEWKT('SRID=1021892;POINT(1000000 1000000)'), 0);
-
--- Repeat all tests with the new function names.
--- NO SRID PROVIDED
-SELECT 'no_srid_03', ST_AsKML(ST_GeomFromEWKT('POINT(1 1)'));
-
--- UNSUPPORTED GEOMETRY TYPES
-SELECT 'invalid_06', ST_AsKML(ST_GeomFromEWKT('SRID=4326;CIRCULARSTRING(-2 0,0 2,2 0,0 2,2 4)'));
-SELECT 'invalid_07', ST_AsKML(ST_GeomFromEWKT('SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))'));
-SELECT 'invalid_08', ST_AsKML(ST_GeomFromEWKT('SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))'));
-SELECT 'invalid_09', ST_AsKML(ST_GeomFromEWKT('SRID=4326;MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))'));
-SELECT 'invalid_10', ST_AsKML(ST_GeomFromEWKT('SRID=4326;MULTISURFACE(CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)),((7 8,10 10,6 14,4 11,7 8)))'));
+SELECT 'projection_01', ST_AsKML(ST_GeomFromEWKT('SRID=1021892;POINT(1000000 1000000)'), 3);
 
--- PARAMETERS
-SELECT 'parameter_04', ST_AsKML(ST_GeomFromEWKT('SRID=4326;POINT(1.1111111111111111 1.1111111111111111)'), 0);
-SELECT 'parameter_05', ST_AsKML(ST_GeomFromEWKT('SRID=4326;POINT(1.1111111111111111 1.1111111111111111)'), 16);
-SELECT 'parameter_06', ST_AsKML(3,ST_GeomFromEWKT('SRID=4326;POINT(1.1111111111111111 1.1111111111111111)'), 15);
-
--- SIMPLE FEATURES
--- San Felipe de Barajas Fortresses - Cartagena, Colombia (Placemark) http://en.wikipedia.org/wiki/Cartagena%2C_Bol%C3%ADvar
-SELECT 'point_03', ST_AsKML(ST_GeomFromEWKT('SRID=4326;POINT(-75.55217297757488 10.42033663453054)'));
-SELECT 'point_04', ST_AsKML(ST_GeomFromEWKT('SRID=4326;POINT(-75.55217297757488 10.42033663453054)'), 8);
--- Olaya Herrera Airport - Medellin, Colombia (Path) http://en.wikipedia.org/wiki/Olaya_Herrera_Airport
-SELECT 'linestring_03', ST_AsKML(ST_GeomFromEWKT('SRID=4326;LINESTRING(-75.58845168747847 6.230811711917435, -75.59257646818483 6.209034252575331)'), 3);
-SELECT 'linestring_04', ST_AsKML(ST_GeomFromEWKT('SRID=4326;LINESTRING(-75.58845168747847 6.230811711917435, -75.59257646818483 6.209034252575331)'), 8);
--- Unicentro Shopping Centre - Bogota, Colombia (Polygon) http://www.unicentrobogota.com/
-SELECT 'polygon_03', ST_AsKML(ST_SnapToGrid(GeomFromEWKT('SRID=4326;POLYGON((-74.0423991077642 4.70128819450968, -74.04209925973704 4.700950993650923, -74.0420182951016 4.701011516462908, -74.04183483125468 4.700831448835688, -74.0414862905795 4.70114015046422, -74.04132847200927 4.70097698051241, -74.04101990886149 4.701244756502166, -74.0411777421693 4.701425554204853, -74.04087244656924 4.701697127180076, -74.040940643764 4.701773680406961, -74.04089952744008 4.702605660205299, -74.04082413388542 4.702677666010084, -74.04106565350325 4.702949831221687, -74.04087265096442 4.703121094787139, -74.04118884713594 4.7034683330851, -74.04138264686453 4.703308983914091, -74.04173931195382 4.703688847671272, -74.04192370456995 4.703528238994438, -74.0419535628069 4.70355486096117, -74.04230657961881 4.703239478084376, -74.04207492135191 4.702978242710751, -74.0421546959669 4.702907817351857, -74.04195032608129 4.70267512672329, -74.04209558069562 4.702533577124568, -74.04203505048247 4.702466795922, -74.04205318281811 4.702038077671765, -74.04212335562635 4.701974337580458, -74.04198589330784 4.701816901909086, -74.04222167646385 4.70160442413543, -74.04214901975594 4.701519995786457, -74.0423991077642 4.70128819450968))'), 0.000001), 3);
-SELECT 'polygon_04', ST_AsKML(ST_GeomFromEWKT('SRID=4326;POLYGON((-74.0423991077642 4.70128819450968, -74.04209925973704 4.700950993650923, -74.0420182951016 4.701011516462908, -74.04183483125468 4.700831448835688, -74.0414862905795 4.70114015046422, -74.04132847200927 4.70097698051241, -74.04101990886149 4.701244756502166, -74.0411777421693 4.701425554204853, -74.04087244656924 4.701697127180076, -74.040940643764 4.701773680406961, -74.04089952744008 4.702605660205299, -74.04082413388542 4.702677666010084, -74.04106565350325 4.702949831221687, -74.04087265096442 4.703121094787139, -74.04118884713594 4.7034683330851, -74.04138264686453 4.703308983914091, -74.04173931195382 4.703688847671272, -74.04192370456995 4.703528238994438, -74.0419535628069 4.70355486096117, -74.04230657961881 4.703239478084376, -74.04207492135191 4.702978242710751, -74.0421546959669 4.702907817351857, -74.04195032608129 4.70267512672329, -74.04209558069562 4.702533577124568, -74.04203505048247 4.702466795922, -74.04205318281811 4.702038077671765, -74.04212335562635 4.701974337580458, -74.04198589330784 4.701816901909086, -74.04222167646385 4.70160442413543, -74.04214901975594 4.701519995786457, -74.0423991077642 4.70128819450968))'), 8);
-
--- MULTI FEATURES
--- Transmilenio mass-transit system Portal Stations - Bogota, Colombia (Placemarks) http://en.wikipedia.org/wiki/List_of_TransMilenio_Stations
-SELECT 'multipoint_03', ST_AsKML(ST_GeomFromEWKT('SRID=4326;MULTIPOINT((-74.04603457594773 4.754687006656519),(-74.095833 4.746435),(-74.11037547492613 4.7098754227297),(-74.120148 4.533696))'), 3);
-SELECT 'multipoint_04', ST_AsKML(ST_GeomFromEWKT('SRID=4326;MULTIPOINT((-74.04603457594773 4.754687006656519),(-74.095833 4.746435),(-74.11037547492613 4.7098754227297),(-74.120148 4.533696))'), 8);
-
--- REPROJECTED DATA
--- Sun Door Interchange - Bucaramanga, Colombia (Placemark)
-SELECT 'projection_04', ST_AsKML(ST_GeomFromEWKT('SRID=1021892;POINT(1106465.31495947 1277689.13470039)'), 3);
--- Chicamocha, Suarez and Fonce rivers confluence - Santander, Colombia (Placemark)
-SELECT 'projection_05', ST_AsKML(ST_GeomFromEWKT('SRID=1021892;POINT(1097247.52170185 1240255.74263751)'), 8);
--- National Astronomical Observatory of Colombia - Bogota, Colombia (Placemark)
-SELECT 'projection_06', ST_AsKML(ST_GeomFromEWKT('SRID=1021892;POINT(1000000 1000000)'), 3);
 
-DELETE FROM spatial_ref_sys WHERE srid = 4326;
-DELETE FROM spatial_ref_sys WHERE srid >= 1000000;
+DELETE FROM spatial_ref_sys;
index 3f290f3b3da014bce028a94bae177e5971de8b25..f223c152f853da44d80477d36e4e86e5f643ccd3 100644 (file)
@@ -1,41 +1,9 @@
-ERROR:  GetProj4StringSPI: Cannot find SRID (4326) in spatial_ref_sys
+ERROR:  GetProj4StringSPI: Cannot find SRID (10) in spatial_ref_sys
 ERROR:  Input geometry has unknown (-1) SRID
-ERROR:  geometry_to_kml: 'CircularString' geometry type not supported by Google Earth
-ERROR:  geometry_to_kml: 'CompoundString' geometry type not supported by Google Earth
-ERROR:  geometry_to_kml: 'CurvePolygon' geometry type not supported by Google Earth
-ERROR:  geometry_to_kml: 'MultiCurve' geometry type not supported by Google Earth
-ERROR:  geometry_to_kml: 'MultiSurface' geometry type not supported by Google Earth
-parameter_01|<Point><coordinates>1,1</coordinates></Point>
-parameter_02|<Point><coordinates>1.111111111111111,1.111111111111111</coordinates></Point>
+empty_geom|
+precision_01|<Point><coordinates>1,1</coordinates></Point>
+precision_02|<Point><coordinates>1.1111111,1.1111111</coordinates></Point>
+version_01|<Point><coordinates>1,1</coordinates></Point>
 ERROR:  Only KML 2 is supported
-point_01|<Point><coordinates>-75.552,10.42</coordinates></Point>
-point_02|<Point><coordinates>-75.55217298,10.42033663</coordinates></Point>
-linestring_01|<LineString><coordinates>-75.588,6.231 -75.593,6.209</coordinates></LineString>
-linestring_02|<LineString><coordinates>-75.58845169,6.23081171 -75.59257647,6.20903425</coordinates></LineString>
-polygon_01|<Polygon><outerBoundaryIs><LinearRing><coordinates>-74.042,4.701 -74.042,4.701 -74.042,4.701 -74.042,4.701 -74.041,4.701 -74.041,4.701 -74.041,4.701 -74.041,4.701 -74.041,4.702 -74.041,4.702 -74.041,4.703 -74.041,4.703 -74.041,4.703 -74.041,4.703 -74.041,4.703 -74.041,4.703 -74.042,4.704 -74.042,4.704 -74.042,4.704 -74.042,4.703 -74.042,4.703 -74.042,4.703 -74.042,4.703 -74.042,4.703 -74.042,4.702 -74.042,4.702 -74.042,4.702 -74.042,4.702 -74.042,4.702 -74.042,4.702 -74.042,4.701</coordinates></LinearRing></outerBoundaryIs></Polygon>
-polygon_02|<Polygon><outerBoundaryIs><LinearRing><coordinates>-74.04239911,4.70128819 -74.04209926,4.70095099 -74.0420183,4.70101152 -74.04183483,4.70083145 -74.04148629,4.70114015 -74.04132847,4.70097698 -74.04101991,4.70124476 -74.04117774,4.70142555 -74.04087245,4.70169713 -74.04094064,4.70177368 -74.04089953,4.70260566 -74.04082413,4.70267767 -74.04106565,4.70294983 -74.04087265,4.70312109 -74.04118885,4.70346833 -74.04138265,4.70330898 -74.04173931,4.70368885 -74.0419237,4.70352824 -74.04195356,4.70355486 -74.04230658,4.70323948 -74.04207492,4.70297824 -74.0421547,4.70290782 -74.04195033,4.70267513 -74.04209558,4.70253358 -74.04203505,4.7024668 -74.04205318,4.70203808 -74.04212336,4.70197434 -74.04198589,4.7018169 -74.04222168,4.70160442 -74.04214902,4.70152 -74.04239911,4.70128819</coordinates></LinearRing></outerBoundaryIs></Polygon>
-multipoint_01|<MultiGeometry><Point><coordinates>-74.046,4.755</coordinates></Point><Point><coordinates>-74.096,4.746</coordinates></Point><Point><coordinates>-74.11,4.71</coordinates></Point><Point><coordinates>-74.12,4.534</coordinates></Point></MultiGeometry>
-multipoint_02|<MultiGeometry><Point><coordinates>-74.04603458,4.75468701</coordinates></Point><Point><coordinates>-74.095833,4.746435</coordinates></Point><Point><coordinates>-74.11037547,4.70987542</coordinates></Point><Point><coordinates>-74.120148,4.533696</coordinates></Point></MultiGeometry>
-projection_01|<Point><coordinates>-73,7</coordinates></Point>
-projection_02|<Point><coordinates>-73,7</coordinates></Point>
-projection_03|<Point><coordinates>-74,5</coordinates></Point>
-ERROR:  Input geometry has unknown (-1) SRID
-ERROR:  geometry_to_kml: 'CircularString' geometry type not supported by Google Earth
-ERROR:  geometry_to_kml: 'CompoundString' geometry type not supported by Google Earth
-ERROR:  geometry_to_kml: 'CurvePolygon' geometry type not supported by Google Earth
-ERROR:  geometry_to_kml: 'MultiCurve' geometry type not supported by Google Earth
-ERROR:  geometry_to_kml: 'MultiSurface' geometry type not supported by Google Earth
-parameter_04|<Point><coordinates>1,1</coordinates></Point>
-parameter_05|<Point><coordinates>1.111111111111111,1.111111111111111</coordinates></Point>
 ERROR:  Only KML 2 is supported
-point_03|<Point><coordinates>-75.552172977574884,10.420336634530541</coordinates></Point>
-point_04|<Point><coordinates>-75.55217298,10.42033663</coordinates></Point>
-linestring_03|<LineString><coordinates>-75.588,6.231 -75.593,6.209</coordinates></LineString>
-linestring_04|<LineString><coordinates>-75.58845169,6.23081171 -75.59257647,6.20903425</coordinates></LineString>
-polygon_03|<Polygon><outerBoundaryIs><LinearRing><coordinates>-74.042,4.701 -74.042,4.701 -74.042,4.701 -74.042,4.701 -74.041,4.701 -74.041,4.701 -74.041,4.701 -74.041,4.701 -74.041,4.702 -74.041,4.702 -74.041,4.703 -74.041,4.703 -74.041,4.703 -74.041,4.703 -74.041,4.703 -74.041,4.703 -74.042,4.704 -74.042,4.704 -74.042,4.704 -74.042,4.703 -74.042,4.703 -74.042,4.703 -74.042,4.703 -74.042,4.703 -74.042,4.702 -74.042,4.702 -74.042,4.702 -74.042,4.702 -74.042,4.702 -74.042,4.702 -74.042,4.701</coordinates></LinearRing></outerBoundaryIs></Polygon>
-polygon_04|<Polygon><outerBoundaryIs><LinearRing><coordinates>-74.04239911,4.70128819 -74.04209926,4.70095099 -74.0420183,4.70101152 -74.04183483,4.70083145 -74.04148629,4.70114015 -74.04132847,4.70097698 -74.04101991,4.70124476 -74.04117774,4.70142555 -74.04087245,4.70169713 -74.04094064,4.70177368 -74.04089953,4.70260566 -74.04082413,4.70267767 -74.04106565,4.70294983 -74.04087265,4.70312109 -74.04118885,4.70346833 -74.04138265,4.70330898 -74.04173931,4.70368885 -74.0419237,4.70352824 -74.04195356,4.70355486 -74.04230658,4.70323948 -74.04207492,4.70297824 -74.0421547,4.70290782 -74.04195033,4.70267513 -74.04209558,4.70253358 -74.04203505,4.7024668 -74.04205318,4.70203808 -74.04212336,4.70197434 -74.04198589,4.7018169 -74.04222168,4.70160442 -74.04214902,4.70152 -74.04239911,4.70128819</coordinates></LinearRing></outerBoundaryIs></Polygon>
-multipoint_03|<MultiGeometry><Point><coordinates>-74.046,4.755</coordinates></Point><Point><coordinates>-74.096,4.746</coordinates></Point><Point><coordinates>-74.11,4.71</coordinates></Point><Point><coordinates>-74.12,4.534</coordinates></Point></MultiGeometry>
-multipoint_04|<MultiGeometry><Point><coordinates>-74.04603458,4.75468701</coordinates></Point><Point><coordinates>-74.095833,4.746435</coordinates></Point><Point><coordinates>-74.11037547,4.70987542</coordinates></Point><Point><coordinates>-74.120148,4.533696</coordinates></Point></MultiGeometry>
-projection_04|<Point><coordinates>-73.114,7.106</coordinates></Point>
-projection_05|<Point><coordinates>-73.1978481,6.76797716</coordinates></Point>
-projection_06|<Point><coordinates>-74.078,4.596</coordinates></Point>
+projection_01|<Point><coordinates>-74.078,4.596</coordinates></Point>