From 23d4eb80c3ccadea6157758e1ef7efa60f38aaf0 Mon Sep 17 00:00:00 2001 From: Olivier Courtin Date: Tue, 27 Apr 2010 15:26:08 +0000 Subject: [PATCH] Add new option to ST_AsGML: ability to remove srsDimension attribute in GML 3. cf #508 git-svn-id: http://svn.osgeo.org/postgis/trunk@5575 b70326c6-7e19-0410-871a-916f4a2858ee --- doc/reference_output.xml | 4 + liblwgeom/cunit/cu_out_gml.c | 84 +++++++++++++++++- liblwgeom/liblwgeom.h | 2 +- liblwgeom/lwout_gml.c | 152 ++++++++++++++++----------------- postgis/geography_inout.c | 4 +- postgis/lwgeom_export.c | 4 +- regress/out_geography.sql | 1 + regress/out_geography_expected | 1 + regress/out_geometry.sql | 1 + regress/out_geometry_expected | 1 + 10 files changed, 172 insertions(+), 82 deletions(-) diff --git a/doc/reference_output.xml b/doc/reference_output.xml index 429791a1e..349225da3 100644 --- a/doc/reference_output.xml +++ b/doc/reference_output.xml @@ -474,6 +474,10 @@ st_asgeojson 1: GML Long CRS (e.g urn:ogc:def:crs:EPSG::4326) + + 2: For GML 3 only, remove srsDimension attribute from output. + + 16: Declare that datas are lat/lon (e.g srid=4326). Default is to assume that data are planars. This option is usefull for GML 3.1.1 output only, related to axis order. diff --git a/liblwgeom/cunit/cu_out_gml.c b/liblwgeom/cunit/cu_out_gml.c index 671405268..af02e516f 100644 --- a/liblwgeom/cunit/cu_out_gml.c +++ b/liblwgeom/cunit/cu_out_gml.c @@ -59,7 +59,7 @@ static void do_gml3_test(char * in, char * out, char * srs, int precision, int i char *h; g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE); - h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic, "gml:"); + h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic, 1, "gml:"); if (strcmp(h, out)) fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); @@ -76,7 +76,24 @@ static void do_gml3_test_prefix(char * in, char * out, char * srs, int precision char *h; g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE); - h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic, prefix); + h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic, 1, prefix); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); + + lwgeom_free(g); + lwfree(h); +} + +static void do_gml3_test_nodims(char * in, char * out, char * srs, int precision, int is_geodetic, int is_dims, const char *prefix) +{ + LWGEOM *g; + char *h; + + g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE); + h = lwgeom_to_gml3(lwgeom_serialize(g), srs, precision, is_geodetic, is_dims, prefix); if (strcmp(h, out)) fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); @@ -111,7 +128,7 @@ static void do_gml3_unsupported(char * in, char * out) char *h; g = lwgeom_from_ewkt(in, PARSER_CHECK_NONE); - h = lwgeom_to_gml3(lwgeom_serialize(g), NULL, 0, 0, ""); + h = lwgeom_to_gml3(lwgeom_serialize(g), NULL, 0, 0, 1, ""); if (strcmp(cu_error_msg, out)) fprintf(stderr, "\nGML 3 - In: %s\nOut: %s\nTheo: %s\n", @@ -738,6 +755,66 @@ static void out_gml_test_geoms_prefix(void) } + +static void out_gml_test_geoms_nodims(void) +{ + /* GML3 - Linestring */ + do_gml3_test_nodims( + "LINESTRING(0 1,2 3,4 5)", + "0 1 2 3 4 5", + NULL, 0, 0, 0, ""); + + + /* GML3 Polygon */ + do_gml3_test_nodims( + "POLYGON((0 1,2 3,4 5,0 1))", + "0 1 2 3 4 5 0 1", + NULL, 0, 0, 0, ""); + + + /* GML3 Polygon - with internal ring */ + do_gml3_test_nodims( + "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", + NULL, 0, 0, 0, ""); + + + /* GML3 MultiPoint */ + do_gml3_test_nodims( + "MULTIPOINT(0 1,2 3)", + "0 12 3", + NULL, 0, 0, 0, ""); + + + /* GML3 Multiline */ + do_gml3_test_nodims( + "MULTILINESTRING((0 1,2 3,4 5),(6 7,8 9,10 11))", + "0 1 2 3 4 56 7 8 9 10 11", + NULL, 0, 0, 0, ""); + + + /* GML3 MultiPolygon */ + do_gml3_test_nodims( + "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", + NULL, 0, 0, 0, ""); + + + /* GML3 - GeometryCollection */ + do_gml3_test_nodims( + "GEOMETRYCOLLECTION(POINT(0 1),LINESTRING(2 3,4 5))", + "0 12 3 4 5", + NULL, 0, 0, 0, ""); + + /* GML3 - Nested GeometryCollection */ + do_gml3_test_nodims( + "GEOMETRYCOLLECTION(POINT(0 1),GEOMETRYCOLLECTION(LINESTRING(2 3,4 5)))", + "0 12 3 4 5", + NULL, 0, 0, 0, ""); +} + + + /* ** Used by test harness to register the tests in this file. */ @@ -748,6 +825,7 @@ CU_TestInfo out_gml_tests[] = { PG_TEST(out_gml_test_geodetic), PG_TEST(out_gml_test_geoms), PG_TEST(out_gml_test_geoms_prefix), + PG_TEST(out_gml_test_geoms_nodims), CU_TEST_INFO_NULL }; CU_SuiteInfo out_gml_suite = {"GML Out Suite", NULL, NULL, out_gml_tests}; diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index 89c67bd4a..1eac65739 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -1419,7 +1419,7 @@ extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist); #define OUT_MAX_DIGS_DOUBLE (OUT_SHOW_DIGS_DOUBLE + 2) /* +2 mean add dot and sign */ extern char* lwgeom_to_gml2(uchar *geom, char *srs, int precision, const char *prefix); -extern char* lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, const char *prefix); +extern char* lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, int is_dims, const char *prefix); 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_gml.c b/liblwgeom/lwout_gml.c index b65c7c472..d313be462 100644 --- a/liblwgeom/lwout_gml.c +++ b/liblwgeom/lwout_gml.c @@ -34,16 +34,16 @@ static size_t asgml2_collection_size(LWGEOM_INSPECTED *geom, char *srs, int prec static char *asgml2_collection(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix); static size_t pointArray_toGML2(POINTARRAY *pa, char *buf, int precision); -static size_t asgml3_point_size(LWPOINT *point, char *srs, int precision, const char *prefix); -static char *asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree, const char *prefix); -static size_t asgml3_line_size(LWLINE *line, char *srs, int precision, const char *prefix); -static char *asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree, const char *prefix); -static size_t asgml3_poly_size(LWPOLY *poly, char *srs, int precision, const char *prefix); -static char *asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree, const char *prefix); -static size_t asgml3_multi_size(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix); -static char *asgml3_multi(LWGEOM_INSPECTED *geom, char *srs, int precision, int is_deegree, const char *prefix); -static size_t asgml3_collection_size(LWGEOM_INSPECTED *geom, char *srs, int precision, const char *prefix); -static char *asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, const char *prefix); +static size_t asgml3_point_size(LWPOINT *point, char *srs, int precision, int is_dims, const char *prefix); +static char *asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree, int is_dims, const char *prefix); +static size_t asgml3_line_size(LWLINE *line, char *srs, int precision, int is_dims, const char *prefix); +static char *asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree, int is_dims, const char *prefix); +static size_t asgml3_poly_size(LWPOLY *poly, char *srs, int precision, int is_dims, const char *prefix); +static char *asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree, int is_dims, const char *prefix); +static size_t asgml3_multi_size(LWGEOM_INSPECTED *geom, char *srs, int precision, int is_dims, const char *prefix); +static char *asgml3_multi(LWGEOM_INSPECTED *geom, char *srs, int precision, int is_deegree, int is_dims, const char *prefix); +static size_t asgml3_collection_size(LWGEOM_INSPECTED *geom, char *srs, int precision, int is_dims, const char *prefix); +static char *asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, int is_dims, const char *prefix); static size_t pointArray_toGML3(POINTARRAY *pa, char *buf, int precision, int is_deegree); static size_t pointArray_GMLsize(POINTARRAY *pa, int precision); @@ -578,8 +578,7 @@ pointArray_toGML2(POINTARRAY *pa, char *output, int precision) /* takes a GEOMETRY and returns a GML representation */ extern char * -lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, - const char *prefix) +lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, int is_dims, const char *prefix) { int type; LWPOINT *point; @@ -593,25 +592,25 @@ lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, { case POINTTYPE: point = lwpoint_deserialize(geom); - return asgml3_point(point, srs, precision, is_deegree, prefix); + return asgml3_point(point, srs, precision, is_deegree, is_dims, prefix); case LINETYPE: line = lwline_deserialize(geom); - return asgml3_line(line, srs, precision, is_deegree, prefix); + return asgml3_line(line, srs, precision, is_deegree, is_dims, prefix); case POLYGONTYPE: poly = lwpoly_deserialize(geom); - return asgml3_poly(poly, srs, precision, is_deegree, prefix); + return asgml3_poly(poly, srs, precision, is_deegree, is_dims, prefix); case MULTIPOINTTYPE: case MULTILINETYPE: case MULTIPOLYGONTYPE: inspected = lwgeom_inspect(geom); - return asgml3_multi(inspected, srs, precision, is_deegree, prefix); + return asgml3_multi(inspected, srs, precision, is_deegree, is_dims, prefix); case COLLECTIONTYPE: inspected = lwgeom_inspect(geom); - return asgml3_collection(inspected, srs, precision, is_deegree, prefix); + return asgml3_collection(inspected, srs, precision, is_deegree, is_dims, prefix); default: lwerror("lwgeom_to_gml3: '%s' geometry type not supported", lwtype_name(type)); @@ -620,20 +619,20 @@ lwgeom_to_gml3(uchar *geom, char *srs, int precision, int is_deegree, } static size_t -asgml3_point_size(LWPOINT *point, char *srs, int precision, - const char *prefix) +asgml3_point_size(LWPOINT *point, char *srs, int precision, int is_dims, const char *prefix) { int size; size_t prefixlen = strlen(prefix); size = pointArray_GMLsize(point->point, precision); - size += ( sizeof("/") + (prefixlen*2) ) * 2; - if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); + size += ( sizeof("/") + (prefixlen*2) ) * 2; + if (srs) size += strlen(srs) + sizeof(" srsName=.."); + if (is_dims) size += sizeof(" srsDimension='x'"); return size; } static size_t -asgml3_point_buf(LWPOINT *point, char *srs, char *output, int precision, int is_deegree, const char *prefix) +asgml3_point_buf(LWPOINT *point, char *srs, char *output, int precision, int is_deegree, int is_dims, const char *prefix) { char *ptr = output; int dimension=2; @@ -647,7 +646,8 @@ asgml3_point_buf(LWPOINT *point, char *srs, char *output, int precision, int is_ { ptr += sprintf(ptr, "<%sPoint>", prefix); } - ptr += sprintf(ptr, "<%spos srsDimension=\"%d\">", prefix, dimension); + if (is_dims) ptr += sprintf(ptr, "<%spos srsDimension=\"%d\">", prefix, dimension); + else ptr += sprintf(ptr, "<%spos>", prefix); ptr += pointArray_toGML3(point->point, ptr, precision, is_deegree); ptr += sprintf(ptr, "", prefix, prefix); @@ -655,33 +655,33 @@ asgml3_point_buf(LWPOINT *point, char *srs, char *output, int precision, int is_ } static char * -asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree, const char *prefix) +asgml3_point(LWPOINT *point, char *srs, int precision, int is_deegree, int is_dims, const char *prefix) { char *output; int size; - size = asgml3_point_size(point, srs, precision, prefix); + size = asgml3_point_size(point, srs, precision, is_dims, prefix); output = lwalloc(size); - asgml3_point_buf(point, srs, output, precision, is_deegree, prefix); + asgml3_point_buf(point, srs, output, precision, is_deegree, is_dims, prefix); return output; } static size_t -asgml3_line_size(LWLINE *line, char *srs, int precision, const char *prefix) +asgml3_line_size(LWLINE *line, char *srs, int precision, int is_dims, const char *prefix) { int size; size_t prefixlen = strlen(prefix); size = pointArray_GMLsize(line->points, precision); size += ( sizeof("/") + ( prefixlen * 4 ) ) * 2; - size += sizeof(" srsDimension='x'"); - if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); + if (srs) size += strlen(srs) + sizeof(" srsName=.."); + if (is_dims) size += sizeof(" srsDimension='x'"); return size; } static size_t -asgml3_line_buf(LWLINE *line, char *srs, char *output, int precision, int is_deegree, const char *prefix) +asgml3_line_buf(LWLINE *line, char *srs, char *output, int precision, int is_deegree, int is_dims, const char *prefix) { char *ptr=output; int dimension=2; @@ -697,7 +697,8 @@ asgml3_line_buf(LWLINE *line, char *srs, char *output, int precision, int is_dee } ptr += sprintf(ptr, "<%ssegments>", prefix); ptr += sprintf(ptr, "<%sLineStringSegment>", prefix); - ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension); + if (is_dims) ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension); + else ptr += sprintf(ptr, "<%sposList>", prefix); ptr += pointArray_toGML3(line->points, ptr, precision, is_deegree); ptr += sprintf(ptr, "", prefix, prefix); ptr += sprintf(ptr, "", prefix); @@ -707,20 +708,20 @@ asgml3_line_buf(LWLINE *line, char *srs, char *output, int precision, int is_dee } static char * -asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree, const char *prefix) +asgml3_line(LWLINE *line, char *srs, int precision, int is_deegree, int is_dims, const char *prefix) { char *output; int size; - size = asgml3_line_size(line, srs, precision, prefix); + size = asgml3_line_size(line, srs, precision, is_dims, prefix); output = lwalloc(size); - asgml3_line_buf(line, srs, output, precision, is_deegree, prefix); + asgml3_line_buf(line, srs, output, precision, is_deegree, is_dims, prefix); return output; } static size_t -asgml3_poly_size(LWPOLY *poly, char *srs, int precision, const char *prefix) +asgml3_poly_size(LWPOLY *poly, char *srs, int precision, int is_dims, const char *prefix) { size_t size; size_t prefixlen = strlen(prefix); @@ -728,8 +729,9 @@ asgml3_poly_size(LWPOLY *poly, char *srs, int precision, const char *prefix) size = ( sizeof("///") + (prefixlen*3) ) * 2; size += ( sizeof("//") + (prefixlen*2) ) * 2 * (poly->nrings - 1); - size += ( sizeof("") + (prefixlen*2) ) * poly->nrings; - if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); + size += ( sizeof("") + (prefixlen*2) ) * poly->nrings; + if (srs) size += strlen(srs) + sizeof(" srsName=.."); + if (is_dims) size += sizeof(" srsDimension='x'") * poly->nrings; for (i=0; inrings; i++) size += pointArray_GMLsize(poly->rings[i], precision); @@ -738,30 +740,28 @@ asgml3_poly_size(LWPOLY *poly, char *srs, int precision, const char *prefix) } static size_t -asgml3_poly_buf(LWPOLY *poly, char *srs, char *output, int precision, int is_deegree, const char *prefix) +asgml3_poly_buf(LWPOLY *poly, char *srs, char *output, int precision, int is_deegree, int is_dims, const char *prefix) { int i; char *ptr=output; int dimension=2; if (TYPE_HASZ(poly->type)) dimension = 3; - if ( srs ) - { - ptr += sprintf(ptr, "<%sPolygon srsName=\"%s\">", prefix, srs); - } - else - { - ptr += sprintf(ptr, "<%sPolygon>", prefix); - } + if (srs) ptr += sprintf(ptr, "<%sPolygon srsName=\"%s\">", prefix, srs); + else ptr += sprintf(ptr, "<%sPolygon>", prefix); + ptr += sprintf(ptr, "<%sexterior><%sLinearRing>", prefix, prefix); - ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension); + if (is_dims) ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension); + else ptr += sprintf(ptr, "<%sposList>", prefix); + ptr += pointArray_toGML3(poly->rings[0], ptr, precision, is_deegree); ptr += sprintf(ptr, "", prefix, prefix, prefix); for (i=1; inrings; i++) { ptr += sprintf(ptr, "<%sinterior><%sLinearRing>", prefix, prefix); - ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension); + if (is_dims) ptr += sprintf(ptr, "<%sposList srsDimension=\"%d\">", prefix, dimension); + else ptr += sprintf(ptr, "<%sposList>", prefix); ptr += pointArray_toGML3(poly->rings[i], ptr, precision, is_deegree); ptr += sprintf(ptr, "", prefix, prefix, prefix); @@ -772,14 +772,14 @@ asgml3_poly_buf(LWPOLY *poly, char *srs, char *output, int precision, int is_dee } static char * -asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree, const char *prefix) +asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree, int is_dims, const char *prefix) { char *output; int size; - size = asgml3_poly_size(poly, srs, precision, prefix); + size = asgml3_poly_size(poly, srs, precision, is_dims, prefix); output = lwalloc(size); - asgml3_poly_buf(poly, srs, output, precision, is_deegree, prefix); + asgml3_poly_buf(poly, srs, output, precision, is_deegree, is_dims, prefix); return output; } @@ -790,7 +790,7 @@ asgml3_poly(LWPOLY *poly, char *srs, int precision, int is_deegree, const char * * Don't call this with single-geoms inspected. */ static size_t -asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision, const char *prefix) +asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_dims, const char *prefix) { int i; size_t size; @@ -810,19 +810,19 @@ asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision, const char * if ((point=lwgeom_getpoint_inspected(insp, i))) { size += ( sizeof("/") + prefixlen ) * 2; - size += asgml3_point_size(point, 0, precision, prefix); + size += asgml3_point_size(point, 0, precision, is_dims, prefix); lwpoint_release(point); } else if ((line=lwgeom_getline_inspected(insp, i))) { size += ( sizeof("/") + prefixlen ) * 2; - size += asgml3_line_size(line, 0, precision, prefix); + size += asgml3_line_size(line, 0, precision, is_dims, prefix); lwline_release(line); } else if ((poly=lwgeom_getpoly_inspected(insp, i))) { size += ( sizeof("/") + prefixlen ) * 2; - size += asgml3_poly_size(poly, 0, precision, prefix); + size += asgml3_poly_size(poly, 0, precision, is_dims, prefix); lwpoly_release(poly); } } @@ -834,7 +834,7 @@ asgml3_multi_size(LWGEOM_INSPECTED *insp, char *srs, int precision, const char * * Don't call this with single-geoms inspected! */ static size_t -asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree, const char *prefix) +asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree, int is_dims, const char *prefix) { int type = lwgeom_getType(insp->serialized_form[0]); char *ptr, *gmltype; @@ -866,21 +866,21 @@ asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, if ((point=lwgeom_getpoint_inspected(insp, i))) { ptr += sprintf(ptr, "<%spointMember>", prefix); - ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree, prefix); + ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree, is_dims, prefix); lwpoint_release(point); ptr += sprintf(ptr, "", prefix); } else if ((line=lwgeom_getline_inspected(insp, i))) { ptr += sprintf(ptr, "<%scurveMember>", prefix); - ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree, prefix); + ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree, is_dims, prefix); lwline_release(line); ptr += sprintf(ptr, "", prefix); } else if ((poly=lwgeom_getpoly_inspected(insp, i))) { ptr += sprintf(ptr, "<%ssurfaceMember>", prefix); - ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree, prefix); + ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree, is_dims, prefix); lwpoly_release(poly); ptr += sprintf(ptr, "", prefix); } @@ -896,20 +896,20 @@ asgml3_multi_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, * Don't call this with single-geoms inspected! */ static char * -asgml3_multi(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, const char *prefix) +asgml3_multi(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, int is_dims, const char *prefix) { char *gml; size_t size; - size = asgml3_multi_size(insp, srs, precision, prefix); + size = asgml3_multi_size(insp, srs, precision, is_dims, prefix); gml = lwalloc(size); - asgml3_multi_buf(insp, srs, gml, precision, is_deegree, prefix); + asgml3_multi_buf(insp, srs, gml, precision, is_deegree, is_dims, prefix); return gml; } static size_t -asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision, const char *prefix) +asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_dims, const char *prefix) { int i; size_t size; @@ -930,24 +930,24 @@ asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision, const c size += ( sizeof("/") + prefixlen ) * 2; if ((point=lwgeom_getpoint_inspected(insp, i))) { - size += asgml3_point_size(point, 0, precision, prefix); + size += asgml3_point_size(point, 0, precision, is_dims, prefix); lwpoint_release(point); } else if ((line=lwgeom_getline_inspected(insp, i))) { - size += asgml3_line_size(line, 0, precision, prefix); + size += asgml3_line_size(line, 0, precision, is_dims, prefix); lwline_release(line); } else if ((poly=lwgeom_getpoly_inspected(insp, i))) { - size += asgml3_poly_size(poly, 0, precision, prefix); + size += asgml3_poly_size(poly, 0, precision, is_dims, prefix); lwpoly_release(poly); } else { subgeom = lwgeom_getsubgeometry_inspected(insp, i); subinsp = lwgeom_inspect(subgeom); - size += asgml3_multi_size(subinsp, 0, precision, prefix); + size += asgml3_multi_size(subinsp, 0, precision, is_dims, prefix); lwinspected_release(subinsp); } } @@ -956,7 +956,7 @@ asgml3_collection_size(LWGEOM_INSPECTED *insp, char *srs, int precision, const c } static size_t -asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree, const char *prefix) +asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int precision, int is_deegree, int is_dims, const char *prefix) { char *ptr; int i; @@ -984,17 +984,17 @@ asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci ptr += sprintf(ptr, "<%sgeometryMember>", prefix); if ((point=lwgeom_getpoint_inspected(insp, i))) { - ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree, prefix); + ptr += asgml3_point_buf(point, 0, ptr, precision, is_deegree, is_dims, prefix); lwpoint_release(point); } else if ((line=lwgeom_getline_inspected(insp, i))) { - ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree, prefix); + ptr += asgml3_line_buf(line, 0, ptr, precision, is_deegree, is_dims, prefix); lwline_release(line); } else if ((poly=lwgeom_getpoly_inspected(insp, i))) { - ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree, prefix); + ptr += asgml3_poly_buf(poly, 0, ptr, precision, is_deegree, is_dims, prefix); lwpoly_release(poly); } else @@ -1002,9 +1002,9 @@ asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci subgeom = lwgeom_getsubgeometry_inspected(insp, i); subinsp = lwgeom_inspect(subgeom); if (lwgeom_getType(subgeom[0]) == COLLECTIONTYPE) - ptr += asgml3_collection_buf(subinsp, 0, ptr, precision, is_deegree, prefix); + ptr += asgml3_collection_buf(subinsp, 0, ptr, precision, is_deegree, is_dims, prefix); else - ptr += asgml3_multi_buf(subinsp, 0, ptr, precision, is_deegree, prefix); + ptr += asgml3_multi_buf(subinsp, 0, ptr, precision, is_deegree, is_dims, prefix); lwinspected_release(subinsp); } ptr += sprintf(ptr, "", prefix); @@ -1020,14 +1020,14 @@ asgml3_collection_buf(LWGEOM_INSPECTED *insp, char *srs, char *output, int preci * Don't call this with single-geoms inspected! */ static char * -asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, const char *prefix) +asgml3_collection(LWGEOM_INSPECTED *insp, char *srs, int precision, int is_deegree, int is_dims, const char *prefix) { char *gml; size_t size; - size = asgml3_collection_size(insp, srs, precision, prefix); + size = asgml3_collection_size(insp, srs, precision, is_dims, prefix); gml = lwalloc(size); - asgml3_collection_buf(insp, srs, gml, precision, is_deegree, prefix); + asgml3_collection_buf(insp, srs, gml, precision, is_deegree, is_dims, prefix); return gml; } diff --git a/postgis/geography_inout.c b/postgis/geography_inout.c index b7a18cb9b..6f4cc5c7e 100644 --- a/postgis/geography_inout.c +++ b/postgis/geography_inout.c @@ -510,6 +510,7 @@ Datum geography_as_gml(PG_FUNCTION_ARGS) int precision = OUT_MAX_DOUBLE_PRECISION; int option=0; int is_deegree=0; + int is_dims=1; static const char *default_prefix = "gml:"; char *prefixbuf; const char* prefix = default_prefix; @@ -576,11 +577,12 @@ Datum geography_as_gml(PG_FUNCTION_ARGS) /* Revert lat/lon only with long SRS */ if (option & 1) is_deegree = 1; + if (option & 2) is_dims = 0; if (version == 2) gml = lwgeom_to_gml2(lwgeom_serialize(lwgeom), srs, precision, prefix); else - gml = lwgeom_to_gml3(lwgeom_serialize(lwgeom), srs, precision, is_deegree, prefix); + gml = lwgeom_to_gml3(lwgeom_serialize(lwgeom), srs, precision, is_deegree, is_dims, prefix); PG_FREE_IF_COPY(lwgeom, 1); diff --git a/postgis/lwgeom_export.c b/postgis/lwgeom_export.c index ccaca578a..93e4db3f5 100644 --- a/postgis/lwgeom_export.c +++ b/postgis/lwgeom_export.c @@ -106,6 +106,7 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS) int SRID; int option = 0; int is_deegree = 0; + int is_dims = 1; int precision = OUT_MAX_DOUBLE_PRECISION; static const char* default_prefix = "gml:"; /* default prefix */ char *prefixbuf; @@ -163,12 +164,13 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS) else if (option & 1) srs = getSRSbySRID(SRID, false); else srs = getSRSbySRID(SRID, true); + if (option & 2) is_dims = 0; if (option & 16) is_deegree = 1; if (version == 2) gml = lwgeom_to_gml2(SERIALIZED_FORM(geom), srs, precision, prefix); else - gml = lwgeom_to_gml3(SERIALIZED_FORM(geom), srs, precision, is_deegree, prefix); + gml = lwgeom_to_gml3(SERIALIZED_FORM(geom), srs, precision, is_deegree, is_dims, prefix); PG_FREE_IF_COPY(geom, 1); diff --git a/regress/out_geography.sql b/regress/out_geography.sql index e33cb39c1..1eb2b9aa1 100644 --- a/regress/out_geography.sql +++ b/regress/out_geography.sql @@ -27,6 +27,7 @@ SELECT 'gml_version_04', ST_AsGML(-4, geography(GeomFromEWKT('SRID=4326;POINT(1 -- Option SELECT 'gml_option_01', ST_AsGML(2, geography(GeomFromEWKT('SRID=4326;POINT(1 1)')), 0, 0); SELECT 'gml_option_02', ST_AsGML(3, geography(GeomFromEWKT('SRID=4326;POINT(1 1)')), 0, 1); +SELECT 'gml_option_03', ST_AsGML(3, geography(GeomFromEWKT('SRID=4326;POINT(1 1)')), 0, 2); -- Deegree data SELECT 'gml_deegree_01', ST_AsGML(2, geography(GeomFromEWKT('SRID=4326;POINT(1 2)')), 0, 0); diff --git a/regress/out_geography_expected b/regress/out_geography_expected index 0b8fa9a8f..448d7260c 100644 --- a/regress/out_geography_expected +++ b/regress/out_geography_expected @@ -7,6 +7,7 @@ ERROR: Only GML 2 and GML 3 are supported ERROR: Only GML 2 and GML 3 are supported gml_option_01|1,1 gml_option_02|1 1 +gml_option_03|1 1 gml_deegree_01|1,2 gml_deegree_02|1,2 gml_deegree_03|1 2 diff --git a/regress/out_geometry.sql b/regress/out_geometry.sql index 920e286bd..169fd7112 100644 --- a/regress/out_geometry.sql +++ b/regress/out_geometry.sql @@ -27,6 +27,7 @@ SELECT 'gml_version_04', ST_AsGML(-4, GeomFromEWKT('SRID=4326;POINT(1 1)')); -- Option SELECT 'gml_option_01', ST_AsGML(2, GeomFromEWKT('SRID=4326;POINT(1 1)'), 0, 0); SELECT 'gml_option_02', ST_AsGML(3, GeomFromEWKT('SRID=4326;POINT(1 1)'), 0, 1); +SELECT 'gml_option_03', ST_AsGML(3, GeomFromEWKT('SRID=4326;POINT(1 1)'), 0, 2); -- Deegree data SELECT 'gml_deegree_01', ST_AsGML(3, GeomFromEWKT('SRID=4326;POINT(1 2)'), 0, 0); diff --git a/regress/out_geometry_expected b/regress/out_geometry_expected index 917afa696..0948d4b8d 100644 --- a/regress/out_geometry_expected +++ b/regress/out_geometry_expected @@ -7,6 +7,7 @@ ERROR: Only GML 2 and GML 3 are supported ERROR: Only GML 2 and GML 3 are supported gml_option_01|1,1 gml_option_02|1 1 +gml_option_03|1 1 gml_deegree_01|1 2 gml_deegree_02|1,2 gml_deegree_03|2 1 -- 2.40.0