From: Olivier Courtin Date: Mon, 12 Apr 2010 08:48:02 +0000 (+0000) Subject: Add optional namespace to ST_AsKML function. related in a way to #460 X-Git-Tag: 2.0.0alpha1~3043 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fa69a731495be16e215c6f1c56ef05c93341959a;p=postgis Add optional namespace to ST_AsKML function. related in a way to #460 git-svn-id: http://svn.osgeo.org/postgis/trunk@5532 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/doc/reference_output.xml b/doc/reference_output.xml index 7ba0225ab..7a0980206 100644 --- a/doc/reference_output.xml +++ b/doc/reference_output.xml @@ -616,6 +616,13 @@ namespace prefix or no prefix (if empty). If null or omitted 'gml' prefix is use geography geom1 integer precision + + text ST_AsKML + integer version + geography geom1 + integer precision + text namespace prefix + @@ -624,12 +631,13 @@ namespace prefix or no prefix (if empty). If null or omitted 'gml' prefix is use 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. + output (defaults to 15), version default to 2 and default namespace is no prefix. Version 1: ST_AsKML(geom) / version=2 precision=15 Version 2: ST_AsKML(geom, max_sig_digits) / version=2 Version 3: ST_AsKML(version, geom) / precision=15 Version 4: ST_AsKML(version, geom, precision) + Version 5: ST_AsKML(version, geom, precision, namespace_prefix) Requires PostGIS be compiled with Proj support. Use to confirm you have proj support compiled in. @@ -638,6 +646,9 @@ namespace prefix or no prefix (if empty). If null or omitted 'gml' prefix is use Availability: 1.2.2 - later variants that include version param came in 1.3.2 + + Availability: 2.0.0 - Add prefix namespace. Default is no prefix + AsKML output will not work with geometries that do not have an SRID diff --git a/liblwgeom/cunit/cu_out_kml.c b/liblwgeom/cunit/cu_out_kml.c index 48246571e..72280ec75 100644 --- a/liblwgeom/cunit/cu_out_kml.c +++ b/liblwgeom/cunit/cu_out_kml.c @@ -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)", + "0,1 2,3 4,5", + 0, "kml:"); + + /* Polygon */ + do_kml_test_prefix( + "POLYGON((0 1,2 3,4 5,0 1))", + "0,1 2,3 4,5 0,1", + 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))", + "0,1 2,3 4,5 0,16,7 8,9 10,11 6,7", + 0, "kml:"); + + /* MultiPoint */ + do_kml_test_prefix( + "MULTIPOINT(0 1,2 3)", + "0,12,3", + 0, "kml:"); + + /* MultiLine */ + do_kml_test_prefix( + "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))", + "0,1 2,3 4,56,7 8,9 10,11", + 0, "kml:"); + + /* MultiPolygon */ + do_kml_test_prefix( + "MULTIPOLYGON(((0 1,2 3,4 5,0 1)),((6 7,8 9,10 11,6 7)))", + "0,1 2,3 4,5 0,16,7 8,9 10,11 6,7", + 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}; diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index 6f4c41b32..89c67bd4a 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -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); diff --git a/liblwgeom/lwout_kml.c b/liblwgeom/lwout_kml.c index c5e841e8e..702269f73 100644 --- a/liblwgeom/lwout_kml.c +++ b/liblwgeom/lwout_kml.c @@ -21,16 +21,16 @@ #include "liblwgeom.h" #include /* 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("/") * 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, ""); - ptr += sprintf(ptr, ""); + ptr += sprintf(ptr, "<%sPoint>", prefix); + ptr += sprintf(ptr, "<%scoordinates>", prefix); ptr += pointArray_toKML2(point->point, ptr, precision); - ptr += sprintf(ptr, ""); + ptr += sprintf(ptr, "", 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("/") * 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, ""); - ptr += sprintf(ptr, ""); + ptr += sprintf(ptr, "<%sLineString>", prefix); + ptr += sprintf(ptr, "<%scoordinates>", prefix); ptr += pointArray_toKML2(line->points, ptr, precision); - ptr += sprintf(ptr, ""); + ptr += sprintf(ptr, "", 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(""); size += sizeof("/") * 2; size += sizeof("/") * 2 * poly->nrings; + + size += prefixlen * (1 + 3 + (3 * poly->nrings)) * 2; for (i=0; inrings; 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, ""); - ptr += sprintf(ptr, ""); + 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, ""); + ptr += sprintf(ptr, "", + prefix, prefix, prefix); + for (i=1; inrings; i++) { - ptr += sprintf(ptr, ""); + ptr += sprintf(ptr, + "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", + prefix, prefix, prefix); + ptr += pointArray_toKML2(poly->rings[i], ptr, precision); - ptr += sprintf(ptr, ""); + + ptr += sprintf(ptr, + "", + prefix, prefix, prefix); } - ptr += sprintf(ptr, ""); + ptr += sprintf(ptr, "", 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(""); + size = sizeof("") + prefixlen * 2; for (i=0; ingeometries; 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; ingeometries; 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, "", kmltype); + ptr += sprintf(ptr, "",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; } diff --git a/postgis/geography.sql.in.c b/postgis/geography.sql.in.c index 7e15f4f65..4d1587447 100644 --- a/postgis/geography.sql.in.c +++ b/postgis/geography.sql.in.c @@ -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; diff --git a/postgis/geography_inout.c b/postgis/geography_inout.c index fd51b5758..b7a18cb9b 100644 --- a/postgis/geography_inout.c +++ b/postgis/geography_inout.c @@ -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); diff --git a/postgis/lwgeom_export.c b/postgis/lwgeom_export.c index a2a9de457..b0becf8e9 100644 --- a/postgis/lwgeom_export.c +++ b/postgis/lwgeom_export.c @@ -2,7 +2,7 @@ * $Id:$ * * PostGIS - Export functions for PostgreSQL/PostGIS - * Copyright 2009 Olivier Courtin + * Copyright 2009-2010 Olivier Courtin * * 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); diff --git a/postgis/postgis.sql.in.c b/postgis/postgis.sql.in.c index cdd646ff9..4c455e7cd 100644 --- a/postgis/postgis.sql.in.c +++ b/postgis/postgis.sql.in.c @@ -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 diff --git a/regress/out_geography.sql b/regress/out_geography.sql index 9e055fc85..e33cb39c1 100644 --- a/regress/out_geography.sql +++ b/regress/out_geography.sql @@ -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); diff --git a/regress/out_geography_expected b/regress/out_geography_expected index f7287c480..b8cfe38d4 100644 --- a/regress/out_geography_expected +++ b/regress/out_geography_expected @@ -23,6 +23,8 @@ kml_precision_02|1.1111111,1.1111111 kml_version_01|1,1 ERROR: Only KML 2 is supported ERROR: Only KML 2 is supported +kml_prefix_01|1,2 +kml_prefix_02|1,2 ERROR: Only SRID SRID_DEFAULT is currently supported in geography. svg_empty_geom| svg_option_01|M 1 -1 L 4 -4 5 -7 diff --git a/regress/out_geometry.sql b/regress/out_geometry.sql index 909347e37..920e286bd 100644 --- a/regress/out_geometry.sql +++ b/regress/out_geometry.sql @@ -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); diff --git a/regress/out_geometry_expected b/regress/out_geometry_expected index 1b04e2a71..c9be1c42e 100644 --- a/regress/out_geometry_expected +++ b/regress/out_geometry_expected @@ -25,6 +25,8 @@ kml_precision_02|1.1111111,1.1111111 kml_version_01|1,1 ERROR: Only KML 2 is supported ERROR: Only KML 2 is supported +kml_prefix_01|1,2 +kml_prefix_02|1,2 kml_projection_01|-74.078,4.596 svg_empty_geom| svg_option_01|M 1 -1 L 4 -4 5 -7