From 1cf437e6afa093016645c2901981239c75a55959 Mon Sep 17 00:00:00 2001 From: Paul Ramsey Date: Wed, 22 Jul 2015 17:54:09 +0000 Subject: [PATCH] #2395, force un-closed KML polygons closed, and issue NOTICE git-svn-id: http://svn.osgeo.org/postgis/trunk@13834 b70326c6-7e19-0410-871a-916f4a2858ee --- postgis/lwgeom_in_kml.c | 26 ++++++++++++++++++++------ regress/in_kml.sql | 8 ++++---- regress/in_kml_expected | 12 ++++++++---- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/postgis/lwgeom_in_kml.c b/postgis/lwgeom_in_kml.c index caa38b955..82b0f855e 100644 --- a/postgis/lwgeom_in_kml.c +++ b/postgis/lwgeom_in_kml.c @@ -407,10 +407,17 @@ static LWGEOM* parse_kml_polygon(xmlNodePtr xnode, bool *hasz) ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*)); ppa[0] = parse_kml_coordinates(xb->children, hasz); - if (ppa[0]->npoints < 4 - || (!*hasz && !ptarray_is_closed_2d(ppa[0])) - || (*hasz && !ptarray_is_closed_3d(ppa[0]))) + if (ppa[0]->npoints < 4) lwpgerror("invalid KML representation"); + + if ((!*hasz && !ptarray_is_closed_2d(ppa[0])) || + ( *hasz && !ptarray_is_closed_3d(ppa[0]))) + { + POINT4D pt; + getPoint4d_p(ppa[0], 0, &pt); + ptarray_append_point(ppa[0], &pt, LW_TRUE); + lwpgnotice("forced closure on an un-closed KML polygon"); + } } } @@ -433,11 +440,18 @@ static LWGEOM* parse_kml_polygon(xmlNodePtr xnode, bool *hasz) sizeof(POINTARRAY*) * (ring + 1)); ppa[ring] = parse_kml_coordinates(xb->children, hasz); - if (ppa[ring]->npoints < 4 - || (!*hasz && !ptarray_is_closed_2d(ppa[ring])) - || (*hasz && !ptarray_is_closed_3d(ppa[ring]))) + if (ppa[ring]->npoints < 4) lwpgerror("invalid KML representation"); + if ((!*hasz && !ptarray_is_closed_2d(ppa[ring])) || + ( *hasz && !ptarray_is_closed_3d(ppa[ring]))) + { + POINT4D pt; + getPoint4d_p(ppa[ring], 0, &pt); + ptarray_append_point(ppa[ring], &pt, LW_TRUE); + lwpgnotice("forced closure on an un-closed KML polygon"); + } + ring++; } } diff --git a/regress/in_kml.sql b/regress/in_kml.sql index 3ac14e0c3..2af1f1c2a 100644 --- a/regress/in_kml.sql +++ b/regress/in_kml.sql @@ -81,10 +81,10 @@ SELECT 'polygon_1', ST_AsEWKT(ST_GeomFromKML(' -- ERROR: In exterior ring: Last point is not the same as the first one SELECT 'polygon_2', ST_AsEWKT(ST_GeomFromKML('1,2 3,4 5,6 1,3')); --- ERROR: In exterior 3D ring: Last point is not the same as the first one in Z +-- FORCE CLOSE: In exterior 3D ring: Last point is not the same as the first one in Z SELECT 'polygon_3', ST_AsEWKT(ST_GeomFromKML('1,2,3 4,5,6 7,8,9 1,2,0')); --- ERROR: Only 3 points in exterior ring +-- FORCE CLOSE: Only 3 points in exterior ring SELECT 'polygon_4', ST_AsEWKT(ST_GeomFromKML('1,2 3,4 1,2')); -- ERROR: Empty exterior ring coordinates @@ -105,10 +105,10 @@ SELECT 'polygon_11', ST_AsEWKT(ST_GeomFromKML('1,2 3,4 5,6 1,27,8 9,10 7,8')); --- ERROR: In interior ring: Last point is not the same as the first one +-- FORCE CLOSE: In interior ring: Last point is not the same as the first one SELECT 'polygon_13', ST_AsEWKT(ST_GeomFromKML('1,2 3,4 5,6 1,27,8 9,10 11,12 7,9')); --- ERROR: In interior 3D ring: Last point is not the same as the first one in Z +-- FORCE CLOSE: In interior 3D ring: Last point is not the same as the first one in Z SELECT 'polygon_14', ST_AsEWKT(ST_GeomFromKML('1,2,3 4,5,6 7,8,9 1,2,310,11,12 13,14,15 16,17,18 10,11,0')); -- 3 rings diff --git a/regress/in_kml_expected b/regress/in_kml_expected index 0203db685..d34514689 100644 --- a/regress/in_kml_expected +++ b/regress/in_kml_expected @@ -15,8 +15,10 @@ ERROR: invalid KML representation ERROR: invalid KML representation linestring_5|SRID=4326;LINESTRING(1 2,3 4) polygon_1|SRID=4326;POLYGON((1 2,3 4,5 6,1 2)) -ERROR: invalid KML representation -ERROR: invalid KML representation +NOTICE: forced closure on an un-closed KML polygon +polygon_2|SRID=4326;POLYGON((1 2,3 4,5 6,1 3,1 2)) +NOTICE: forced closure on an un-closed KML polygon +polygon_3|SRID=4326;POLYGON((1 2 3,4 5 6,7 8 9,1 2 0,1 2 3)) ERROR: invalid KML representation ERROR: invalid KML representation ERROR: invalid KML representation @@ -26,8 +28,10 @@ polygon_9|SRID=4326;POLYGON((1 2,3 4,5 6,1 2),(7 8,9 10,11 12,7 8)) polygon_10|SRID=4326;POLYGON((1 2,3 4,5 6,1 2),(7 8,9 10,11 12,7 8)) polygon_11|SRID=4326;POLYGON((1 2,3 4,5 6,1 2)) ERROR: invalid KML representation -ERROR: invalid KML representation -ERROR: invalid KML representation +NOTICE: forced closure on an un-closed KML polygon +polygon_13|SRID=4326;POLYGON((1 2,3 4,5 6,1 2),(7 8,9 10,11 12,7 9,7 8)) +NOTICE: forced closure on an un-closed KML polygon +polygon_14|SRID=4326;POLYGON((1 2 3,4 5 6,7 8 9,1 2 3),(10 11 12,13 14 15,16 17 18,10 11 0,10 11 12)) polygon_15|SRID=4326;POLYGON((1 2,3 4,5 6,1 2),(7 8,9 10,11 12,7 8),(13 14,15 16,17 18,13 14)) multi_7|SRID=4326;GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(3 4,5 6),POLYGON((7 8,9 10,11 12,7 8))) multi_8|SRID=4326;GEOMETRYCOLLECTION EMPTY -- 2.40.0