]> granicus.if.org Git - postgis/commitdiff
Add optional namespace to ST_AsKML function. related in a way to #460
authorOlivier Courtin <olivier.courtin@camptocamp.com>
Mon, 12 Apr 2010 08:48:02 +0000 (08:48 +0000)
committerOlivier Courtin <olivier.courtin@camptocamp.com>
Mon, 12 Apr 2010 08:48:02 +0000 (08:48 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@5532 b70326c6-7e19-0410-871a-916f4a2858ee

12 files changed:
doc/reference_output.xml
liblwgeom/cunit/cu_out_kml.c
liblwgeom/liblwgeom.h
liblwgeom/lwout_kml.c
postgis/geography.sql.in.c
postgis/geography_inout.c
postgis/lwgeom_export.c
postgis/postgis.sql.in.c
regress/out_geography.sql
regress/out_geography_expected
regress/out_geometry.sql
regress/out_geometry_expected

index 7ba0225abcf9f89215dda6720d45e9f5795265e4..7a098020610a05a8cd4b2ba84760cea857cad97b 100644 (file)
@@ -616,6 +616,13 @@ namespace prefix or no prefix (if empty). If null or omitted 'gml' prefix is use
                                <paramdef><type>geography </type> <parameter>geom1</parameter></paramdef>
                                <paramdef><type>integer </type> <parameter>precision</parameter></paramdef>
                        </funcprototype>
+                       <funcprototype>
+                               <funcdef>text <function>ST_AsKML</function></funcdef>
+                               <paramdef><type>integer </type> <parameter>version</parameter></paramdef>
+                               <paramdef><type>geography </type> <parameter>geom1</parameter></paramdef>
+                               <paramdef><type>integer </type> <parameter>precision</parameter></paramdef>
+                               <paramdef><type>text </type> <parameter>namespace prefix</parameter></paramdef>
+                       </funcprototype>
                </funcsynopsis>
          </refsynopsisdiv>
 
@@ -624,12 +631,13 @@ namespace prefix or no prefix (if empty). If null or omitted 'gml' prefix is use
 
                <para>Return the geometry as a Keyhole Markup Language (KML) element. There are several variants of this function.
                        maximum number of decimal places used in
-                       output (defaults to 15) and version default to 2.</para>
+                       output (defaults to 15), version default to 2 and default namespace is no prefix.</para>
 
                <para>Version 1: ST_AsKML(geom) / version=2 precision=15</para>
                <para>Version 2: ST_AsKML(geom, max_sig_digits) / version=2 </para>
                <para>Version 3: ST_AsKML(version, geom) / precision=15 </para>
                <para>Version 4: ST_AsKML(version, geom, precision) </para>
+               <para>Version 5: ST_AsKML(version, geom, precision, namespace_prefix) </para>
 
                <note>
                  <para>Requires PostGIS be compiled with Proj support.  Use <xref linkend="PostGIS_Full_Version" /> to confirm you have proj support compiled in.</para>
@@ -638,6 +646,9 @@ namespace prefix or no prefix (if empty). If null or omitted 'gml' prefix is use
                <note>
                  <para>Availability: 1.2.2 - later variants that include version param came in 1.3.2</para>
                </note>
+               <note>
+                 <para>Availability: 2.0.0 - Add prefix namespace. Default is no prefix</para>
+               </note>
 
                <note>
                        <para>AsKML output will not work with geometries that do not have an SRID</para>
index 48246571e441d97799b2a49af96de369319944cd..72280ec753b6ec328828e12b4a3557edc8532c34 100644 (file)
@@ -24,7 +24,7 @@ static void do_kml_test(char * in, char * out, int precision)
        char * h;
 
        g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
-       h = lwgeom_to_kml2(lwgeom_serialize(g), precision);
+       h = lwgeom_to_kml2(lwgeom_serialize(g), precision, "");
 
        if (strcmp(h, out))
                fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n", in, h, out);
@@ -42,7 +42,7 @@ static void do_kml_unsupported(char * in, char * out)
        char *h;
 
        g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
-       h = lwgeom_to_kml2(lwgeom_serialize(g), 0);
+       h = lwgeom_to_kml2(lwgeom_serialize(g), 0, "");
 
        if (strcmp(cu_error_msg, out))
                fprintf(stderr, "\nIn:   %s\nOut:  %s\nTheo: %s\n",
@@ -56,6 +56,25 @@ static void do_kml_unsupported(char * in, char * out)
 }
 
 
+static void do_kml_test_prefix(char * in, char * out, int precision, const char *prefix)
+{
+       LWGEOM *g;
+       char * h;
+
+       g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE);
+       h = lwgeom_to_kml2(lwgeom_serialize(g), precision, prefix);
+
+       if (strcmp(h, out))
+               fprintf(stderr, "\nPrefix: %s\nIn:   %s\nOut:  %s\nTheo: %s\n",
+                       prefix, in, h, out);
+
+       CU_ASSERT_STRING_EQUAL(h, out);
+
+       lwgeom_free(g);
+       lwfree(h);
+}
+
+
 static void out_kml_test_precision(void)
 {
        /* 0 precision, i.e a round */
@@ -175,6 +194,45 @@ static void out_kml_test_geoms(void)
            "lwgeom_to_kml2: 'MultiSurface' geometry type not supported");
 }
 
+static void out_kml_test_prefix(void)
+{
+       /* Linestring */
+       do_kml_test_prefix(
+           "LINESTRING(0 1,2 3,4 5)",
+           "<kml:LineString><kml:coordinates>0,1 2,3 4,5</kml:coordinates></kml:LineString>",
+           0, "kml:");
+
+       /* Polygon */
+       do_kml_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1))",
+           "<kml:Polygon><kml:outerBoundaryIs><kml:LinearRing><kml:coordinates>0,1 2,3 4,5 0,1</kml:coordinates></kml:LinearRing></kml:outerBoundaryIs></kml:Polygon>",
+           0, "kml:");
+
+       /* Polygon - with internal ring */
+       do_kml_test_prefix(
+           "POLYGON((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7))",
+           "<kml:Polygon><kml:outerBoundaryIs><kml:LinearRing><kml:coordinates>0,1 2,3 4,5 0,1</kml:coordinates></kml:LinearRing></kml:outerBoundaryIs><kml:innerBoundaryIs><kml:LinearRing><kml:coordinates>6,7 8,9 10,11 6,7</kml:coordinates></kml:LinearRing></kml:innerBoundaryIs></kml:Polygon>",
+           0, "kml:");
+
+       /* MultiPoint */
+       do_kml_test_prefix(
+           "MULTIPOINT(0 1,2 3)",
+           "<kml:MultiGeometry><kml:Point><kml:coordinates>0,1</kml:coordinates></kml:Point><kml:Point><kml:coordinates>2,3</kml:coordinates></kml:Point></kml:MultiGeometry>",
+           0, "kml:");
+
+       /* MultiLine */
+       do_kml_test_prefix(
+           "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))",
+           "<kml:MultiGeometry><kml:LineString><kml:coordinates>0,1 2,3 4,5</kml:coordinates></kml:LineString><kml:LineString><kml:coordinates>6,7 8,9 10,11</kml:coordinates></kml:LineString></kml:MultiGeometry>",
+           0, "kml:");
+
+       /* MultiPolygon */
+       do_kml_test_prefix(
+           "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))",
+           "<kml:MultiGeometry><kml:Polygon><kml:outerBoundaryIs><kml:LinearRing><kml:coordinates>0,1 2,3 4,5 0,1</kml:coordinates></kml:LinearRing></kml:outerBoundaryIs></kml:Polygon><kml:Polygon><kml:outerBoundaryIs><kml:LinearRing><kml:coordinates>6,7 8,9 10,11 6,7</kml:coordinates></kml:LinearRing></kml:outerBoundaryIs></kml:Polygon></kml:MultiGeometry>",
+           0, "kml:");
+
+}
 /*
 ** Used by test harness to register the tests in this file.
 */
@@ -182,6 +240,7 @@ CU_TestInfo out_kml_tests[] = {
        PG_TEST(out_kml_test_precision),
        PG_TEST(out_kml_test_dims),
        PG_TEST(out_kml_test_geoms),
+       PG_TEST(out_kml_test_prefix),
        CU_TEST_INFO_NULL
 };
 CU_SuiteInfo out_kml_suite = {"KML Out Suite",  NULL,  NULL, out_kml_tests};
index 6f4c41b3276dd66029a7d624dc1c562c3dd6c334..89c67bd4a04d902b4e037c74e340b717f2cb8c47 100644 (file)
@@ -1420,7 +1420,7 @@ extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
 
 extern char* lwgeom_to_gml2(uchar *geom, char *srs, int precision, const char *prefix);
 extern char* lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, const char *prefix);
-extern char* lwgeom_to_kml2(uchar *geom, int precision);
+extern char* lwgeom_to_kml2(uchar *geom, int precision, const char *prefix);
 extern char* lwgeom_to_geojson(uchar *geom, char *srs, int precision, int has_bbox);
 extern char* lwgeom_to_svg(uchar *geom, int precision, int relative);
 
index c5e841e8e398913581728ccbcb3f16006e831d60..702269f738cd4aca3a43b8f2b1d0a5324644c359 100644 (file)
 #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);
+char *lwgeom_to_kml2(uchar *srl, int precision, const char *prefix);
+
+static size_t askml2_point_size(LWPOINT *point, int precision, const char *prefix);
+static char *askml2_point(LWPOINT *point, int precision, const char *prefix);
+static size_t askml2_line_size(LWLINE *line, int precision, const char *prefix);
+static char *askml2_line(LWLINE *line, int precision, const char *prefix);
+static size_t askml2_poly_size(LWPOLY *poly, int precision, const char *prefix);
+static char *askml2_poly(LWPOLY *poly, int precision, const char *prefix);
+static size_t askml2_inspected_size(LWGEOM_INSPECTED *geom, int precision, const char *prefix);
+static char *askml2_inspected(LWGEOM_INSPECTED *geom, int precision, const char *prefix);
 static size_t pointArray_toKML2(POINTARRAY *pa, char *buf, int precision);
 
 static size_t pointArray_KMLsize(POINTARRAY *pa, int precision);
@@ -42,7 +42,7 @@ static size_t pointArray_KMLsize(POINTARRAY *pa, int precision);
 
 /* takes a GEOMETRY and returns a KML representation */
 char *
-lwgeom_to_kml2(uchar *geom, int precision)
+lwgeom_to_kml2(uchar *geom, int precision, const char *prefix)
 {
        int type;
        LWPOINT *point;
@@ -57,21 +57,21 @@ lwgeom_to_kml2(uchar *geom, int precision)
 
        case POINTTYPE:
                point = lwpoint_deserialize(geom);
-               return askml2_point(point, precision);
+               return askml2_point(point, precision, prefix);
 
        case LINETYPE:
                line = lwline_deserialize(geom);
-               return askml2_line(line, precision);
+               return askml2_line(line, precision, prefix);
 
        case POLYGONTYPE:
                poly = lwpoly_deserialize(geom);
-               return askml2_poly(poly, precision);
+               return askml2_poly(poly, precision, prefix);
 
        case MULTIPOINTTYPE:
        case MULTILINETYPE:
        case MULTIPOLYGONTYPE:
                inspected = lwgeom_inspect(geom);
-               return askml2_inspected(inspected, precision);
+               return askml2_inspected(inspected, precision, prefix);
 
        default:
                lwerror("lwgeom_to_kml2: '%s' geometry type not supported",
@@ -81,83 +81,92 @@ lwgeom_to_kml2(uchar *geom, int precision)
 }
 
 static size_t
-askml2_point_size(LWPOINT *point, int precision)
+askml2_point_size(LWPOINT *point, int precision, const char *prefix)
 {
        int size;
+       size_t prefixlen = strlen(prefix);
+
        size = pointArray_KMLsize(point->point, precision);
        size += sizeof("<point><coordinates>/") * 2;
+       size += prefixlen * 2 * 2;
        return size;
 }
 
 static size_t
-askml2_point_buf(LWPOINT *point, char *output, int precision)
+askml2_point_buf(LWPOINT *point, char *output, int precision, const char *prefix)
 {
        char *ptr = output;
 
-       ptr += sprintf(ptr, "<Point>");
-       ptr += sprintf(ptr, "<coordinates>");
+       ptr += sprintf(ptr, "<%sPoint>", prefix);
+       ptr += sprintf(ptr, "<%scoordinates>", prefix);
        ptr += pointArray_toKML2(point->point, ptr, precision);
-       ptr += sprintf(ptr, "</coordinates></Point>");
+       ptr += sprintf(ptr, "</%scoordinates></%sPoint>", prefix, prefix);
 
        return (ptr-output);
 }
 
 static char *
-askml2_point(LWPOINT *point, int precision)
+askml2_point(LWPOINT *point, int precision, const char *prefix)
 {
        char *output;
        int size;
 
-       size = askml2_point_size(point, precision);
+       size = askml2_point_size(point, precision, prefix);
        output = lwalloc(size);
-       askml2_point_buf(point, output, precision);
+       askml2_point_buf(point, output, precision, prefix);
        return output;
 }
 
 static size_t
-askml2_line_size(LWLINE *line, int precision)
+askml2_line_size(LWLINE *line, int precision, const char * prefix)
 {
        int size;
+       size_t prefixlen = strlen(prefix);
+
        size = pointArray_KMLsize(line->points, precision);
        size += sizeof("<linestring><coordinates>/") * 2;
+       size += prefixlen * 2 * 2;
        return size;
 }
 
 static size_t
-askml2_line_buf(LWLINE *line, char *output, int precision)
+askml2_line_buf(LWLINE *line, char *output, int precision, const char *prefix)
 {
        char *ptr=output;
 
-       ptr += sprintf(ptr, "<LineString>");
-       ptr += sprintf(ptr, "<coordinates>");
+       ptr += sprintf(ptr, "<%sLineString>", prefix);
+       ptr += sprintf(ptr, "<%scoordinates>", prefix);
        ptr += pointArray_toKML2(line->points, ptr, precision);
-       ptr += sprintf(ptr, "</coordinates></LineString>");
+       ptr += sprintf(ptr, "</%scoordinates></%sLineString>", prefix, prefix);
 
        return (ptr-output);
 }
 
 static char *
-askml2_line(LWLINE *line, int precision)
+askml2_line(LWLINE *line, int precision, const char *prefix)
 {
        char *output;
        int size;
 
-       size = askml2_line_size(line, precision);
+       size = askml2_line_size(line, precision, prefix);
        output = lwalloc(size);
-       askml2_line_buf(line, output, precision);
+       askml2_line_buf(line, output, precision, prefix);
        return output;
 }
 
 static size_t
-askml2_poly_size(LWPOLY *poly, int precision)
+askml2_poly_size(LWPOLY *poly, int precision, const char *prefix)
 {
        size_t size;
        int i;
+       size_t prefixlen = strlen(prefix);
 
        size = sizeof("<polygon></polygon>");
        size += sizeof("<outerboundaryis><linearring><coordinates>/") * 2;
        size += sizeof("<innerboundaryis><linearring><coordinates>/") * 2 *
                poly->nrings;
+       
+       size += prefixlen * (1 + 3 + (3 * poly->nrings)) * 2;
 
        for (i=0; i<poly->nrings; i++)
                size += pointArray_KMLsize(poly->rings[i], precision);
@@ -166,35 +175,44 @@ askml2_poly_size(LWPOLY *poly, int precision)
 }
 
 static size_t
-askml2_poly_buf(LWPOLY *poly, char *output, int precision)
+askml2_poly_buf(LWPOLY *poly, char *output, int precision, const char *prefix)
 {
        int i;
        char *ptr=output;
 
-       ptr += sprintf(ptr, "<Polygon>");
-       ptr += sprintf(ptr, "<outerBoundaryIs><LinearRing><coordinates>");
+       ptr += sprintf(ptr, "<%sPolygon>", prefix);
+       ptr += sprintf(ptr, "<%souterBoundaryIs><%sLinearRing><%scoordinates>",
+               prefix, prefix, prefix);
        ptr += pointArray_toKML2(poly->rings[0], ptr, precision);
-       ptr += sprintf(ptr, "</coordinates></LinearRing></outerBoundaryIs>");
+       ptr += sprintf(ptr, "</%scoordinates></%sLinearRing></%souterBoundaryIs>",
+               prefix, prefix, prefix);
+
        for (i=1; i<poly->nrings; i++)
        {
-               ptr += sprintf(ptr, "<innerBoundaryIs><LinearRing><coordinates>");
+               ptr += sprintf(ptr,
+                       "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>",
+                       prefix, prefix, prefix);
+
                ptr += pointArray_toKML2(poly->rings[i], ptr, precision);
-               ptr += sprintf(ptr, "</coordinates></LinearRing></innerBoundaryIs>");
+
+               ptr += sprintf(ptr,
+                       "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>",
+                       prefix, prefix, prefix);
        }
-       ptr += sprintf(ptr, "</Polygon>");
+       ptr += sprintf(ptr, "</%sPolygon>", prefix);
 
        return (ptr-output);
 }
 
 static char *
-askml2_poly(LWPOLY *poly, int precision)
+askml2_poly(LWPOLY *poly, int precision, const char *prefix)
 {
        char *output;
        int size;
 
-       size = askml2_poly_size(poly, precision);
+       size = askml2_poly_size(poly, precision, prefix);
        output = lwalloc(size);
-       askml2_poly_buf(poly, output, precision);
+       askml2_poly_buf(poly, output, precision, prefix);
        return output;
 }
 
@@ -204,13 +222,14 @@ askml2_poly(LWPOLY *poly, int precision)
  * Don't call this with single-geoms inspected.
  */
 static size_t
-askml2_inspected_size(LWGEOM_INSPECTED *insp, int precision)
+askml2_inspected_size(LWGEOM_INSPECTED *insp, int precision, const char *prefix)
 {
        int i;
        size_t size;
+       size_t prefixlen = strlen(prefix);
 
        /* the longest possible multi version */
-       size = sizeof("<MultiGeometry></MultiGeometry>");
+       size = sizeof("<MultiGeometry></MultiGeometry>") + prefixlen * 2;
 
        for (i=0; i<insp->ngeometries; i++)
        {
@@ -222,24 +241,24 @@ askml2_inspected_size(LWGEOM_INSPECTED *insp, int precision)
 
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       size += askml2_point_size(point, precision);
+                       size += askml2_point_size(point, precision, prefix);
                        lwpoint_free(point);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       size += askml2_line_size(line, precision);
+                       size += askml2_line_size(line, precision, prefix);
                        lwline_free(line);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       size += askml2_poly_size(poly, precision);
+                       size += askml2_poly_size(poly, precision, prefix);
                        lwpoly_free(poly);
                }
                else
                {
                        subgeom = lwgeom_getsubgeometry_inspected(insp, i);
                        subinsp = lwgeom_inspect(subgeom);
-                       size += askml2_inspected_size(subinsp, precision);
+                       size += askml2_inspected_size(subinsp, precision, prefix);
                        lwinspected_release(subinsp);
                }
        }
@@ -251,7 +270,7 @@ askml2_inspected_size(LWGEOM_INSPECTED *insp, int precision)
  * Don't call this with single-geoms inspected!
  */
 static size_t
-askml2_inspected_buf(LWGEOM_INSPECTED *insp, char *output, int precision)
+askml2_inspected_buf(LWGEOM_INSPECTED *insp, char *output, int precision, const char *prefix)
 {
        char *ptr, *kmltype;
        int i;
@@ -260,7 +279,7 @@ askml2_inspected_buf(LWGEOM_INSPECTED *insp, char *output, int precision)
        kmltype = "MultiGeometry";
 
        /* Open outmost tag */
-       ptr += sprintf(ptr, "<%s>", kmltype);
+       ptr += sprintf(ptr, "<%s%s>", prefix, kmltype);
 
        for (i=0; i<insp->ngeometries; i++)
        {
@@ -272,30 +291,30 @@ askml2_inspected_buf(LWGEOM_INSPECTED *insp, char *output, int precision)
 
                if ((point=lwgeom_getpoint_inspected(insp, i)))
                {
-                       ptr += askml2_point_buf(point, ptr, precision);
+                       ptr += askml2_point_buf(point, ptr, precision, prefix);
                        lwpoint_free(point);
                }
                else if ((line=lwgeom_getline_inspected(insp, i)))
                {
-                       ptr += askml2_line_buf(line, ptr, precision);
+                       ptr += askml2_line_buf(line, ptr, precision, prefix);
                        lwline_free(line);
                }
                else if ((poly=lwgeom_getpoly_inspected(insp, i)))
                {
-                       ptr += askml2_poly_buf(poly, ptr, precision);
+                       ptr += askml2_poly_buf(poly, ptr, precision, prefix);
                        lwpoly_free(poly);
                }
                else
                {
                        subgeom = lwgeom_getsubgeometry_inspected(insp, i);
                        subinsp = lwgeom_inspect(subgeom);
-                       ptr += askml2_inspected_buf(subinsp, ptr, precision);
+                       ptr += askml2_inspected_buf(subinsp, ptr, precision, prefix);
                        lwinspected_release(subinsp);
                }
        }
 
        /* Close outmost tag */
-       ptr += sprintf(ptr, "</%s>", kmltype);
+       ptr += sprintf(ptr, "</%s%s>",prefix,  kmltype);
 
        return (ptr-output);
 }
@@ -304,14 +323,14 @@ askml2_inspected_buf(LWGEOM_INSPECTED *insp, char *output, int precision)
  * Don't call this with single-geoms inspected!
  */
 static char *
-askml2_inspected(LWGEOM_INSPECTED *insp, int precision)
+askml2_inspected(LWGEOM_INSPECTED *insp, int precision, const char *prefix)
 {
        char *kml;
        size_t size;
 
-       size = askml2_inspected_size(insp, precision);
+       size = askml2_inspected_size(insp, precision, prefix);
        kml = lwalloc(size);
-       askml2_inspected_buf(insp, kml, precision);
+       askml2_inspected_buf(insp, kml, precision, prefix);
        return kml;
 }
 
index 7e15f4f6514406f13d48bf1fb1c5524f589efcf8..4d158744747c654a03bd1b694198131f59d6e93b 100644 (file)
@@ -458,21 +458,21 @@ CREATE OR REPLACE FUNCTION ST_AsGML(int4, geography, int4, int4, text)
 --
 
 -- _ST_AsKML(version, geography, precision)
-CREATE OR REPLACE FUNCTION _ST_AsKML(int4, geography, int4)
+CREATE OR REPLACE FUNCTION _ST_AsKML(int4, geography, int4, text)
        RETURNS text
        AS 'MODULE_PATHNAME','geography_as_kml'
-       LANGUAGE 'C' IMMUTABLE STRICT;
+       LANGUAGE 'C' IMMUTABLE;
 
 -- AsKML(geography,precision) / version=2
 CREATE OR REPLACE FUNCTION ST_AsKML(geography, int4)
        RETURNS text
-       AS 'SELECT _ST_AsKML(2, $1, $2)'
+       AS 'SELECT _ST_AsKML(2, $1, $2, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- AsKML(geography) / precision=15 version=2
 CREATE OR REPLACE FUNCTION ST_AsKML(geography)
        RETURNS text
-       AS 'SELECT _ST_AsKML(2, $1, 15)'
+       AS 'SELECT _ST_AsKML(2, $1, 15, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
@@ -485,13 +485,20 @@ CREATE OR REPLACE FUNCTION ST_AsKML(text)
 -- ST_AsKML(version, geography) / precision=15 
 CREATE OR REPLACE FUNCTION ST_AsKML(int4, geography)
        RETURNS text
-       AS 'SELECT _ST_AsKML($1, $2, 15)'
+       AS 'SELECT _ST_AsKML($1, $2, 15, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- ST_AsKML(version, geography, precision)
 CREATE OR REPLACE FUNCTION ST_AsKML(int4, geography, int4)
        RETURNS text
-       AS 'SELECT _ST_AsKML($1, $2, $3)'
+       AS 'SELECT _ST_AsKML($1, $2, $3, null)'
+       LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+-- ST_AsKML(version, geography, precision, prefix)
+-- Availability: 2.0.0
+CREATE OR REPLACE FUNCTION ST_AsKML(int4, geography, int4, text)
+       RETURNS text
+       AS 'SELECT _ST_AsKML($1, $2, $3, $4)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 
index fd51b575821189a0056f5f295ad2c859996c70da..b7a18cb9b1c8713c6e79575f5badaee36967a9cc 100644 (file)
@@ -610,6 +610,10 @@ Datum geography_as_kml(PG_FUNCTION_ARGS)
        int len;
        int version;
        int precision = OUT_MAX_DOUBLE_PRECISION;
+       static const char *default_prefix = "";
+       char *prefixbuf;
+        const char* prefix = default_prefix;
+        text *prefix_text;
 
 
        /* Get the version */
@@ -636,7 +640,28 @@ Datum geography_as_kml(PG_FUNCTION_ARGS)
                else if ( precision < 0 ) precision = 0;
        }
 
-       kml = lwgeom_to_kml2(lwgeom_serialize(lwgeom), precision);
+       /* retrieve prefix */
+       if (PG_NARGS() >3 && !PG_ARGISNULL(3))
+        {
+                prefix_text = PG_GETARG_TEXT_P(3);
+                if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
+                {
+                        prefix = "";
+                }
+                else
+                {
+                        /* +2 is one for the ':' and one for term null */
+                        prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
+                        memcpy(prefixbuf, VARDATA(prefix_text),
+                               VARSIZE(prefix_text)-VARHDRSZ);
+                        /* add colon and null terminate */
+                        prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] = ':';
+                        prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0';
+                        prefix = prefixbuf;
+                }
+        }
+
+       kml = lwgeom_to_kml2(lwgeom_serialize(lwgeom), precision, prefix);
 
        PG_FREE_IF_COPY(lwgeom, 1);
 
index a2a9de4576389ad60ae78673843a335e2ba6af5f..b0becf8e9377e020f38f9c0c883171e8161edeb0 100644 (file)
@@ -2,7 +2,7 @@
  * $Id:$
  *
  * PostGIS - Export functions for PostgreSQL/PostGIS
- * Copyright 2009 Olivier Courtin <olivier.courtin@oslandia.com>
+ * Copyright 2009-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.
@@ -197,6 +197,10 @@ Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
        int len;
        int version;
        int precision = OUT_MAX_DOUBLE_PRECISION;
+       static const char* default_prefix = ""; /* default prefix */
+       char *prefixbuf;
+       const char* prefix = default_prefix;
+       text *prefix_text;
 
 
        /* Get the version */
@@ -220,7 +224,28 @@ Datum LWGEOM_asKML(PG_FUNCTION_ARGS)
                else if ( precision < 0 ) precision = 0;
        }
 
-       kml = lwgeom_to_kml2(SERIALIZED_FORM(geom), precision);
+       /* retrieve prefix */
+       if (PG_NARGS() >3 && !PG_ARGISNULL(3))
+       {
+               prefix_text = PG_GETARG_TEXT_P(3);
+               if ( VARSIZE(prefix_text)-VARHDRSZ == 0 )
+               {
+                       prefix = "";
+               }
+               else
+               {
+                       /* +2 is one for the ':' and one for term null */
+                       prefixbuf = palloc(VARSIZE(prefix_text)-VARHDRSZ+2);
+                       memcpy(prefixbuf, VARDATA(prefix_text),
+                              VARSIZE(prefix_text)-VARHDRSZ);
+                       /* add colon and null terminate */
+                       prefixbuf[VARSIZE(prefix_text)-VARHDRSZ] = ':';
+                       prefixbuf[VARSIZE(prefix_text)-VARHDRSZ+1] = '\0';
+                       prefix = prefixbuf;
+               }
+       }
+
+       kml = lwgeom_to_kml2(SERIALIZED_FORM(geom), precision, prefix);
 
        PG_FREE_IF_COPY(geom, 1);
 
index cdd646ff979cb2ad5aceedcc8132ff7eaeb94a9e..4c455e7cd35cc7a0404419151dcedb8b1266dbbb 100644 (file)
@@ -4733,58 +4733,66 @@ CREATE OR REPLACE FUNCTION ST_AsGML(int4, geometry, int4, int4, text)
 -- KML OUTPUT
 -----------------------------------------------------------------------
 -- _ST_AsKML(version, geom, precision)
-CREATE OR REPLACE FUNCTION _ST_AsKML(int4, geometry, int4)
+CREATE OR REPLACE FUNCTION _ST_AsKML(int4, geometry, int4, text)
        RETURNS TEXT
        AS 'MODULE_PATHNAME','LWGEOM_asKML'
-       LANGUAGE 'C' IMMUTABLE STRICT;
+       LANGUAGE 'C' IMMUTABLE;
 
 -- AsKML(geom, precision) / version=2
 -- Deprecation in 1.2.3
 CREATE OR REPLACE FUNCTION AsKML(geometry, int4)
        RETURNS TEXT
-       AS 'SELECT _ST_AsKML(2, transform($1,4326), $2)'
+       AS 'SELECT _ST_AsKML(2, transform($1,4326), $2, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- Availability: 1.2.2
 CREATE OR REPLACE FUNCTION ST_AsKML(geometry, int4)
        RETURNS TEXT
-       AS 'SELECT _ST_AsKML(2, ST_Transform($1,4326), $2)'
+       AS 'SELECT _ST_AsKML(2, ST_Transform($1,4326), $2, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- AsKML(geom) / precision=15 version=2
 -- Deprecation in 1.2.3
 CREATE OR REPLACE FUNCTION AsKML(geometry)
        RETURNS TEXT
-       AS 'SELECT _ST_AsKML(2, transform($1,4326), 15)'
+       AS 'SELECT _ST_AsKML(2, transform($1,4326), 15, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- AsKML(version, geom, precision)
 -- Deprecation in 1.2.3
 CREATE OR REPLACE FUNCTION AsKML(int4, geometry, int4)
        RETURNS TEXT
-       AS 'SELECT _ST_AsKML($1, transform($2,4326), $3)'
+       AS 'SELECT _ST_AsKML($1, transform($2,4326), $3, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- Availability: 1.2.2
 CREATE OR REPLACE FUNCTION ST_AsKML(geometry)
        RETURNS TEXT
-       AS 'SELECT _ST_AsKML(2, ST_Transform($1,4326), 15)'
+       AS 'SELECT _ST_AsKML(2, ST_Transform($1,4326), 15, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- ST_AsKML(version, geom) / precision=15 version=2
 -- Availability: 1.3.2
 CREATE OR REPLACE FUNCTION ST_AsKML(int4, geometry)
        RETURNS TEXT
-       AS 'SELECT _ST_AsKML($1, ST_Transform($2,4326), 15)'
+       AS 'SELECT _ST_AsKML($1, ST_Transform($2,4326), 15, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
 -- ST_AsKML(version, geom, precision)
 -- Availability: 1.3.2
 CREATE OR REPLACE FUNCTION ST_AsKML(int4, geometry, int4)
        RETURNS TEXT
-       AS 'SELECT _ST_AsKML($1, ST_Transform($2,4326), $3)'
+       AS 'SELECT _ST_AsKML($1, ST_Transform($2,4326), $3, null)'
        LANGUAGE 'SQL' IMMUTABLE STRICT;
 
+-- ST_AsKML(version, geom, precision, text)
+-- Availability: 2.0.0
+CREATE OR REPLACE FUNCTION ST_AsKML(int4, geometry, int4, text)
+       RETURNS TEXT
+       AS 'SELECT _ST_AsKML($1, ST_Transform($2,4326), $3, $4)'
+       LANGUAGE 'SQL' IMMUTABLE STRICT;
+
+
 -----------------------------------------------------------------------
 -- GEOJSON OUTPUT
 -- Availability: 1.3.4
index 9e055fc85cd1678a85e2b79ff502714923cbc718..e33cb39c1a9c0c54ef2022037dfd4aac7e680fb4 100644 (file)
@@ -61,6 +61,10 @@ SELECT 'kml_version_01', ST_AsKML(2, geography(GeomFromEWKT('SRID=4326;POINT(1 1
 SELECT 'kml_version_02', ST_AsKML(3, geography(GeomFromEWKT('SRID=4326;POINT(1 1)')));
 SELECT 'kml_version_03', ST_AsKML(-4, geography(GeomFromEWKT('SRID=4326;POINT(1 1)')));
 
+-- Prefix
+SELECT 'kml_prefix_01', ST_AsKML(2, geography(GeomFromEWKT('SRID=4326;POINT(1 2)')), 0, '');
+SELECT 'kml_prefix_02', ST_AsKML(2, geography(GeomFromEWKT('SRID=4326;POINT(1 2)')), 0, 'kml');
+
 -- Projected 
 -- National Astronomical Observatory of Colombia - Bogota, Colombia (Placemark)
 SELECT 'kml_projection_01', ST_AsKML(geography(GeomFromEWKT('SRID=1021892;POINT(1000000 1000000)')), 3);
index f7287c480f4772fb3df1e56f893cbb03557721b3..b8cfe38d4af1af3a45b3689390fd9bf94f1ba173 100644 (file)
@@ -23,6 +23,8 @@ kml_precision_02|<Point><coordinates>1.1111111,1.1111111</coordinates></Point>
 kml_version_01|<Point><coordinates>1,1</coordinates></Point>
 ERROR:  Only KML 2 is supported
 ERROR:  Only KML 2 is supported
+kml_prefix_01|<Point><coordinates>1,2</coordinates></Point>
+kml_prefix_02|<kml:Point><kml:coordinates>1,2</kml:coordinates></kml:Point>
 ERROR:  Only SRID SRID_DEFAULT is currently supported in geography.
 svg_empty_geom|
 svg_option_01|M 1 -1 L 4 -4 5 -7
index 909347e37bd5fa42d3ffd7c2cb25785cee136239..920e286bdfbe6c259731041b65b32bc9fead867e 100644 (file)
@@ -62,6 +62,10 @@ SELECT 'kml_version_01', ST_AsKML(2, GeomFromEWKT('SRID=4326;POINT(1 1)'));
 SELECT 'kml_version_02', ST_AsKML(3, GeomFromEWKT('SRID=4326;POINT(1 1)'));
 SELECT 'kml_version_03', ST_AsKML(-4, GeomFromEWKT('SRID=4326;POINT(1 1)'));
 
+-- Prefix
+SELECT 'kml_prefix_01', ST_AsKML(2, GeomFromEWKT('SRID=4326;POINT(1 2)'), 0, '');
+SELECT 'kml_prefix_02', ST_AsKML(2, GeomFromEWKT('SRID=4326;POINT(1 2)'), 0, 'kml');
+
 -- Projected 
 -- National Astronomical Observatory of Colombia - Bogota, Colombia (Placemark)
 SELECT 'kml_projection_01', ST_AsKML(ST_GeomFromEWKT('SRID=1021892;POINT(1000000 1000000)'), 3);
index 1b04e2a7134d19be8a208c4a108f9bd1c8452251..c9be1c42e96c84e4f9d6d6b111fe7e483a65917c 100644 (file)
@@ -25,6 +25,8 @@ kml_precision_02|<Point><coordinates>1.1111111,1.1111111</coordinates></Point>
 kml_version_01|<Point><coordinates>1,1</coordinates></Point>
 ERROR:  Only KML 2 is supported
 ERROR:  Only KML 2 is supported
+kml_prefix_01|<Point><coordinates>1,2</coordinates></Point>
+kml_prefix_02|<kml:Point><kml:coordinates>1,2</kml:coordinates></kml:Point>
 kml_projection_01|<Point><coordinates>-74.078,4.596</coordinates></Point>
 svg_empty_geom|
 svg_option_01|M 1 -1 L 4 -4 5 -7