]> granicus.if.org Git - postgis/commitdiff
Add multi data coordinates support. Add unit test case data_1
authorOlivier Courtin <olivier.courtin@camptocamp.com>
Sat, 24 Oct 2009 16:37:12 +0000 (16:37 +0000)
committerOlivier Courtin <olivier.courtin@camptocamp.com>
Sat, 24 Oct 2009 16:37:12 +0000 (16:37 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@4680 b70326c6-7e19-0410-871a-916f4a2858ee

postgis/lwgeom_in_gml.c
regress/in_gml.sql
regress/in_gml_expected

index b7201d055b5b9c4ebd44cfc9bbb90784437999a7..1c2de0a5256316135eca06f716a40a50ec9fcf67 100644 (file)
@@ -264,9 +264,10 @@ static POINTARRAY* parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
                        if (gml_dims < 2 || gml_dims > 3)
                                lwerror("invalid GML representation");
 
-                       if (gml_dims == 3) pt.z = parse_gml_double(q, 0, 1);
+                       if (gml_dims == 3)
+                               pt.z = parse_gml_double(q, 0, 1);
                        else {
-                               pt.y = atof(q);
+                               pt.y = parse_gml_double(q, 0, 1);
                                *hasz = false;
                        }
 
@@ -293,7 +294,7 @@ static POINTARRAY* parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
  */
 static POINTARRAY* parse_gml_coord(xmlNodePtr xnode, bool *hasz)
 {
-       xmlNodePtr coord, xyz;
+       xmlNodePtr xyz;
        DYNPTARRAY *dpa;
        POINTARRAY *pa;
        bool x,y,z;
@@ -304,45 +305,37 @@ static POINTARRAY* parse_gml_coord(xmlNodePtr xnode, bool *hasz)
        TYPE_SETZM(dims, 1, 0);
        dpa = dynptarray_create(1, dims);
 
-       for (coord = xnode ; coord != NULL ; coord = coord->next) {
-
-               /* Looking for gml:coord element */
-               if (coord->type != XML_ELEMENT_NODE) continue;
-               if (strcmp((char *) coord->name, "coord")) continue;
-
-               x = y = z = false;
-               for (xyz = coord->children ; xyz != NULL ; xyz = xyz->next) {
-
-                       if (xyz->type != XML_ELEMENT_NODE) continue;
-
-                       if (!strcmp((char *) xyz->name, "X")) {
-                               if (x) lwerror("invalid GML representation");
-                               c = xmlNodeGetContent(xyz);
-                               p.x = parse_gml_double((char *) c, 1, 1);
-                               x = true;
-                               xmlFree(c);
-                       } else  if (!strcmp((char *) xyz->name, "Y")) {
-                               if (y) lwerror("invalid GML representation");
-                               c = xmlNodeGetContent(xyz);
-                               p.y = parse_gml_double((char *) c, 1, 1);
-                               y = true;
-                               xmlFree(c);
-                       } else if (!strcmp((char *) xyz->name, "Z")) {
-                               if (z) lwerror("invalid GML representation");
-                               c = xmlNodeGetContent(xyz);
-                               p.z = parse_gml_double((char *) c, 1, 1);
-                               z = true;
-                               xmlFree(c);
-                       }
+       x = y = z = false;
+       for (xyz = xnode->children ; xyz != NULL ; xyz = xyz->next) {
+
+               if (xyz->type != XML_ELEMENT_NODE) continue;
+
+               if (!strcmp((char *) xyz->name, "X")) {
+                       if (x) lwerror("invalid GML representation");
+                       c = xmlNodeGetContent(xyz);
+                       p.x = parse_gml_double((char *) c, 1, 1);
+                       x = true;
+                       xmlFree(c);
+               } else  if (!strcmp((char *) xyz->name, "Y")) {
+                       if (y) lwerror("invalid GML representation");
+                       c = xmlNodeGetContent(xyz);
+                       p.y = parse_gml_double((char *) c, 1, 1);
+                       y = true;
+                       xmlFree(c);
+               } else if (!strcmp((char *) xyz->name, "Z")) {
+                       if (z) lwerror("invalid GML representation");
+                       c = xmlNodeGetContent(xyz);
+                       p.z = parse_gml_double((char *) c, 1, 1);
+                       z = true;
+                       xmlFree(c);
                }
-
-               /* Check dimension consistancy */
-               if (!x || !y) lwerror("invalid GML representation");
-               if (!z) *hasz = false;
-
-               dynptarray_addPoint4d(dpa, &p, 0);
-               x = y = z = false;
        }
+       /* Check dimension consistancy */
+       if (!x || !y) lwerror("invalid GML representation");
+       if (!z) *hasz = false;
+
+       dynptarray_addPoint4d(dpa, &p, 0);
+       x = y = z = false;
 
        pa = ptarray_clone(dpa->pa);
        lwfree(dpa);
@@ -496,7 +489,8 @@ static POINTARRAY* parse_gml_poslist(xmlNodePtr xnode, bool *hasz)
 /**
  * Parse data coordinates
  *
- * There's four ways to encode coordinates:
+ * There's four ways to encode coordinates, who could be mixed inside a 
+ * single geometrie:
  *  - gml:pos element
  *  - gml:posList element 
  *  - gml:coord elements with X,Y(,Z) nested elements (deprecated in 3.0.0)
@@ -507,39 +501,41 @@ static POINTARRAY* parse_gml_poslist(xmlNodePtr xnode, bool *hasz)
  *
  *  NOTA: we don't support pointRep references !
  */
-static POINTARRAY * parse_gml_data(xmlNodePtr xnode, bool *hasz)
+static POINTARRAY* parse_gml_data(xmlNodePtr xnode, bool *hasz)
 {
-       bool coordinates, coord, pos, poslist;
        xmlNodePtr node;
+       POINTARRAY *pa, *tmp_pa;
 
-       coordinates = coord = pos = poslist = false;
+       pa = NULL;
 
        for (node = xnode ; node != NULL ; node = node->next) {
 
                if (node->type != XML_ELEMENT_NODE) continue;
                if (!strcmp((char *) node->name, "pos")) {
-                       pos=true;
-                       break;
+                       tmp_pa = parse_gml_pos(node, hasz);
+                       if (pa == NULL) pa = tmp_pa;
+                       else pa = ptarray_merge(pa, tmp_pa);
+
                } else if (!strcmp((char *) node->name, "posList")) {
-                       poslist=true;
-                       break;
+                       tmp_pa = parse_gml_poslist(node, hasz);
+                       if (pa == NULL) pa = tmp_pa;
+                       else pa = ptarray_merge(pa, tmp_pa);
+
                } else if (!strcmp((char *) node->name, "coordinates")) {
-                       coordinates=true;
-                       break;
+                       tmp_pa = parse_gml_coordinates(node, hasz);
+                       if (pa == NULL) pa = tmp_pa;
+                       else pa = ptarray_merge(pa, tmp_pa);
+
                } else if (!strcmp((char *) node->name, "coord")) {
-                       coord=true;
-                       break;
+                       tmp_pa = parse_gml_coord(node, hasz);
+                       if (pa == NULL) pa = tmp_pa;
+                       else pa = ptarray_merge(pa, tmp_pa);
                }
        }
 
-       if (pos)         return parse_gml_pos(node, hasz);
-       if (poslist)     return parse_gml_poslist(node, hasz);
-       if (coordinates) return parse_gml_coordinates(node, hasz);
-       if (coord)       return parse_gml_coord(node, hasz);
+       if (pa == NULL) lwerror("invalid GML representation");
 
-       lwerror("invalid GML representation");
-
-       return NULL;
+       return pa;
 }
 
 
@@ -672,7 +668,7 @@ static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz)
                        xmlFree(interpolation);
                }
 
-               if (lss > 0) ppa = (POINTARRAY**) lwrealloc((LWLINE *) ppa, 
+               if (lss > 0) ppa = (POINTARRAY**) lwrealloc((POINTARRAY *) ppa,
                                sizeof(POINTARRAY*) * (lss + 1));
 
                ppa[lss] = parse_gml_data(xa->children, hasz);
index d1e06271653c84c7bdceeddbcc5d010dc4d89983..e9d905a4b287df94f3673eca74cb2fa694270a3b 100644 (file)
@@ -17,13 +17,13 @@ SELECT 'empty_geom', ST_AsEWKT(ST_GeomFromGML(NULL));
 -- XML
 --
 
--- Empty String
+-- ERROR: Empty String
 SELECT 'xml_1', ST_AsEWKT(ST_GeomFromGML(''));
 
--- Not well formed XML
+-- ERROR: Not well formed XML
 SELECT 'xml_2', ST_AsEWKT(ST_GeomFromGML('<foo>'));
 
--- Not a GML Geometry
+-- ERROR: Not a GML Geometry
 SELECT 'xml_3', ST_AsEWKT(ST_GeomFromGML('<foo/>'));
 
 
@@ -512,7 +512,6 @@ SELECT 'coordinates_17', ST_AsEWKT(ST_GeomFromGML('<gml:LineString><gml:coordina
 
 
 
-
 --
 -- Coordinates (cs,ts,decimal)
 --
@@ -669,6 +668,13 @@ SELECT 'poslist_18', ST_AsEWKT(ST_GeomFromGML('<gml:LineString><gml:posList>!@#$
 
 
 
+--
+-- Generic data
+--
+
+-- Mixed Pos, PosList, Coordinates, coord
+SELECT 'data_1', ST_AsEWKT(ST_GeomFromGML('<gml:LineString><gml:pos>1 2</gml:pos><gml:posList>3 4 5 6</gml:posList><gml:coordinates>7,8 9,10</gml:coordinates><gml:coord><gml:X>11</gml:X><gml:Y>12</gml:Y></gml:coord></gml:LineString>'));
+
 
 
 --
index 843d43dd53ceee036e37d5268f426988b78ed497..e1fcef1d0ebdc34ee6497b5e34af80f41787cbd4 100644 (file)
@@ -207,6 +207,7 @@ ERROR:  invalid GML representation
 ERROR:  invalid GML representation
 ERROR:  invalid GML representation
 ERROR:  invalid GML representation
+data_1|LINESTRING(1 2,3 4,5 6,7 8,9 10,11 12)
 coord_1|POINT(1 2)
 coord_2|POINT(1 2 3)
 ERROR:  invalid GML representation