/**********************************************************************
+ * $Id:$
+ *
* PostGIS - Spatial Types for PostgreSQL
* http://postgis.refractions.net
* Copyright 2009 Oslandia
*
* This is free software; you can redistribute and/or modify it under
- * the terms of hte GNU General Public Licence. See the COPYING file.
+ * the terms of the GNU General Public Licence. See the COPYING file.
*
**********************************************************************/
* - Support only GML SF profile geometries (i.e no PostGIS curves support)
* - Don't care about GML namespace
* - Don't handle Xlink or PointRef construction
-* - Don't reproject if mixed srsName in multi/aggregate geoms
*
* Written by Olivier Courtin - Oslandia
*
#include "postgres.h"
#include "lwgeom_pg.h"
#include "liblwgeom.h"
+#include "lwgeom_transform.h"
+#include "executor/spi.h"
+
#if HAVE_LIBXML2
#include <libxml/tree.h>
#include <libxml/parser.h>
-#include "lwgeom_export.h" /* getSRSbySRID */
-
Datum geom_from_gml(PG_FUNCTION_ARGS);
-static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz);
+static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz, int *root_srid);
+
+typedef struct struct_gmlSrs
+{
+ int srid;
+ bool reverse_axis;
+}
+gmlSrs;
/**
char *xml;
size_t size=0;
bool hasz=true;
+ int root_srid=0;
xmlNodePtr xmlroot=NULL;
lwerror("invalid GML representation");
}
- lwgeom = parse_gml(xmlroot, &hasz);
+ lwgeom = parse_gml(xmlroot, &hasz, &root_srid);
+ lwgeom->bbox = lwgeom_compute_box2d(lwgeom);
geom = pglwgeom_serialize(lwgeom);
lwgeom_release(lwgeom);
}
+/**
+ * Reverse X and Y axis on a given POINTARRAY
+ */
+static POINTARRAY* gml_reverse_axis_pa(POINTARRAY *pa)
+{
+ int i;
+ double d;
+ POINT4D p;
+
+ for (i=0 ; i < pa->npoints ; i++) {
+ getPoint4d_p(pa, i, &p);
+ d = p.y;
+ p.y = p.x;
+ p.x = d;
+ setPoint4d(pa, i, &p);
+ }
+
+ return pa;
+}
+
+
+/**
+ * Use Proj4 to reproject a given POINTARRAY
+ */
+static POINTARRAY* gml_reproject_pa(POINTARRAY *pa, int srid_in, int srid_out)
+{
+ int i;
+ POINT4D p;
+ projPJ in_pj, out_pj;
+ char *text_in, *text_out;
+
+ if (srid_in == -1 || srid_out == -1)
+ lwerror("invalid GML representation");
+
+ text_in = GetProj4StringSPI(srid_in);
+ text_out = GetProj4StringSPI(srid_out);
+
+ in_pj = make_project(text_in);
+ out_pj = make_project(text_out);
+
+ lwfree(text_in);
+ lwfree(text_out);
+
+ for (i=0 ; i < pa->npoints ; i++) {
+ getPoint4d_p(pa, i, &p);
+ transform_point(&p, in_pj, out_pj);
+ setPoint4d(pa, i, &p);
+ }
+
+ pj_free(in_pj);
+ pj_free(out_pj);
+
+ return pa;
+}
+
+
+/**
+ * TODO
+ * Return -1 if srid is not in spatial_ref_sys
+ */
+static int gml_is_srid_planar(int srid)
+{
+ char *result;
+ char query[256];
+ int is_planar, err;
+
+ if (SPI_OK_CONNECT != SPI_connect ())
+ lwerror("gml_is_srid_lat_lon: could not connect to SPI manager");
+
+ /* A way to find if this projection is planar or geocentric */
+ sprintf(query, "SELECT position('+units=m ' in proj4text) \
+ FROM spatial_ref_sys WHERE srid='%d'", srid);
+
+ err = SPI_exec(query, 1);
+ if (err < 0) lwerror("gml_is_srid_lat_lon: error executing query %d", err);
+
+ /* No entry in spatial_ref_sys */
+ if (SPI_processed <= 0) {
+ SPI_finish();
+ return -1;
+ }
+
+ result = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
+ is_planar = atoi(result);
+ SPI_finish();
+
+ return is_planar;
+}
+
+
/**
* Parse gml srsName attribute
*/
-static int parse_gml_srs(xmlNodePtr xnode)
+static gmlSrs* parse_gml_srs(xmlNodePtr xnode)
{
- xmlChar *srs;
char *p;
- int srid=-1;
+ gmlSrs *srs;
+ int is_planar;
+ xmlNodePtr node;
+ xmlChar *srsname;
+ bool latlon = false;
+ char sep = ':';
+
+ node = xnode;
+ srsname = xmlGetProp(node, (xmlChar *) "srsName");
+ if (!srsname) {
+ if (node->parent == NULL) {
+ srs = (gmlSrs*) lwalloc(sizeof(gmlSrs));
+ srs->srid = -1;
+ srs->reverse_axis = false;
+ return srs;
+ }
+ return parse_gml_srs(node->parent);
+ }
- srs = xmlGetProp(xnode, (xmlChar *) "srsName");
- if (!srs) return -1; /* Default srid if no srsName attribute */
+ srs = (gmlSrs*) lwalloc(sizeof(gmlSrs));
/* Severals srsName formats are available...
* cf WFS 1.1.0 -> 9.2 (p36)
urn:ogc:def:crs:EPSG:4326
urn:ogc:def:crs:EPSG::4326
urn:ogc:def:crs:EPSG:6.6:4326
- urn:x-ogc:def:crs:EPSG:6.6:4326 */
-
- if ( !strncmp((char *) srs, "EPSG:", 5)
- || !strncmp((char *) srs, "urn:ogc:def:crs:EPSG:", 21)
- || !strncmp((char *) srs, "urn:x-ogc:def:crs:EPSG:", 23)
- || !strncmp((char *) srs, "urn:EPSG:geographicCRS:", 23)) {
-
- /* retrieve the last ':' char */
- for (p = (char *) srs ; *p ; p++);
- for (--p ; *p != ':' ; p--)
- if (!isdigit(*p)) lwerror("unknown spatial reference system");
-
- srid = atoi(++p);
-
- /* SRS pattern like: http://www.opengis.net/gml/srs/epsg.xml#4326 */
- } else if (!strncmp((char *) srs, "http://www.opengis.net/gml/srs/epsg.xml#", 40)) {
- p = strchr((char *) srs, '#');
- srid = atoi(++p);
- }
+ urn:x-ogc:def:crs:EPSG:6.6:4326
+ http://www.opengis.net/gml/srs/epsg.xml#4326
+ */
+
+ if (!strncmp((char *) srsname, "EPSG:", 5)) {
+ sep = ':';
+ latlon = false;
+ } else if (!strncmp((char *) srsname, "urn:ogc:def:crs:EPSG:", 21)
+ || !strncmp((char *) srsname, "urn:x-ogc:def:crs:EPSG:", 23)
+ || !strncmp((char *) srsname, "urn:EPSG:geographicCRS:", 23)) {
+ sep = ':';
+ latlon = true;
+ } else if (!strncmp((char *) srsname, "http://www.opengis.net/gml/srs/epsg.xml#", 40)) {
+ sep = '#';
+ latlon = false;
+ } else lwerror("unknown spatial reference system");
+
+ /* retrieve the last ':' or '#' char */
+ for (p = (char *) srsname ; *p ; p++);
+ for (--p ; *p != sep ; p--)
+ if (!isdigit(*p)) lwerror("unknown spatial reference system");
+
+ srs->srid = atoi(++p);
/* Check into spatial_ref_sys that this SRID really exist */
- if (srid == -1 || getSRSbySRID(srid, true) == NULL)
+ is_planar = gml_is_srid_planar(srs->srid);
+ if (srs->srid == -1 || is_planar == -1)
lwerror("unknown spatial reference system");
- xmlFree(srs);
- return srid;
+ /* About lat/lon issue, Cf: http://tinyurl.com/yjpr55z */
+ srs->reverse_axis = !is_planar && latlon;
+
+ xmlFree(srsname);
+ return srs;
}
/**
* Parse GML point (2.1.2, 3.x.x)
*/
-static LWGEOM* parse_gml_point(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_point(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid;
+ gmlSrs *srs;
+ LWGEOM* geom;
POINTARRAY *pa;
- srid = parse_gml_srs(xnode);
-
pa = parse_gml_data(xnode->children, hasz);
if (pa->npoints != 1)
lwerror("invalid GML representation");
- return (LWGEOM *) lwpoint_construct(srid, NULL, pa);
+ srs = parse_gml_srs(xnode);
+ if (srs->reverse_axis) pa = gml_reverse_axis_pa(pa);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *) lwpoint_construct(*root_srid, NULL, pa);
+ } else {
+ if (srs->srid != *root_srid)
+ gml_reproject_pa(pa, srs->srid, *root_srid);
+ geom = (LWGEOM *) lwpoint_construct(-1, NULL, pa);
+ }
+ lwfree(srs);
+
+ return geom;
}
/**
* Parse GML lineString (2.1.2, 3.x.x)
*/
-static LWGEOM* parse_gml_line(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_line(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid;
+ gmlSrs *srs;
+ LWGEOM *geom;
POINTARRAY *pa;
- srid = parse_gml_srs(xnode);
pa = parse_gml_data(xnode->children, hasz);
if (pa->npoints < 2)
lwerror("invalid GML representation");
- return (LWGEOM *) lwline_construct(srid, NULL, pa);
+ srs = parse_gml_srs(xnode);
+ if (srs->reverse_axis) pa = gml_reverse_axis_pa(pa);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *) lwline_construct(*root_srid, NULL, pa);
+ } else {
+ if (srs->srid != *root_srid)
+ gml_reproject_pa(pa, srs->srid, *root_srid);
+ geom = (LWGEOM *) lwline_construct(-1, NULL, pa);
+ }
+ lwfree(srs);
+
+ return geom;
}
/**
* Parse GML Curve (3.x.x)
*/
-static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid, lss, last, i;
xmlChar *interpolation;
+ int lss, last, i;
POINTARRAY **ppa;
POINTARRAY *pa;
xmlNodePtr xa;
+ LWGEOM *geom;
+ gmlSrs *srs;
bool found=false;
unsigned int npoints=0;
- srid = parse_gml_srs(xnode);
-
/* Looking for gml:segments */
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
if (lss == 0) lwerror("invalid GML representation");
/* Most common case, a single segment */
- if (lss == 1) return (LWGEOM *) lwline_construct(srid, NULL, ppa[0]);
+ if (lss == 1) pa = ppa[0];
/*
* So we must aggregate all the segments into a single one and avoid
* to copy the redundants points
*/
- pa = ptarray_construct(1, 0, npoints - (lss - 1));
- for (last = npoints = i = 0; i < lss ; i++) {
-
- if (i + 1 == lss) last = 1;
- /* Check if segments are not disjoints */
- if (i > 0 && memcmp( getPoint_internal(pa, npoints),
- getPoint_internal(ppa[i], 0),
- *hasz?sizeof(POINT3D):sizeof(POINT2D)))
- lwerror("invalid GML representation");
+ if (lss > 1) {
+ pa = ptarray_construct(1, 0, npoints - (lss - 1));
+ for (last = npoints = i = 0; i < lss ; i++) {
+
+ if (i + 1 == lss) last = 1;
+ /* Check if segments are not disjoints */
+ if (i > 0 && memcmp( getPoint_internal(pa, npoints),
+ getPoint_internal(ppa[i], 0),
+ *hasz?sizeof(POINT3D):sizeof(POINT2D)))
+ lwerror("invalid GML representation");
+
+ /* Aggregate stuff */
+ memcpy( getPoint_internal(pa, npoints),
+ getPoint_internal(ppa[i], 0),
+ pointArray_ptsize(ppa[i]) * (ppa[i]->npoints + last));
- /* Aggregate stuff */
- memcpy( getPoint_internal(pa, npoints),
- getPoint_internal(ppa[i], 0),
- pointArray_ptsize(ppa[i]) * (ppa[i]->npoints + last));
+ npoints += ppa[i]->npoints - 1;
+ lwfree(ppa[i]);
+ }
+ lwfree(ppa);
+ }
- npoints += ppa[i]->npoints - 1;
- lwfree(ppa[i]);
- }
- lwfree(ppa);
+ srs = parse_gml_srs(xnode);
+ if (srs->reverse_axis) pa = gml_reverse_axis_pa(pa);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *) lwline_construct(*root_srid, NULL, pa);
+ } else {
+ if (srs->srid != *root_srid)
+ gml_reproject_pa(pa, srs->srid, *root_srid);
+ geom = (LWGEOM *) lwline_construct(-1, NULL, pa);
+ }
+ lwfree(srs);
- return (LWGEOM *) lwline_construct(srid, NULL, pa);
+ return geom;
}
/**
* Parse GML Polygon (2.1.2, 3.x.x)
*/
-static LWGEOM* parse_gml_polygon(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_polygon(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid, ring;
+ gmlSrs *srs;
+ int i, ring;
+ LWGEOM *geom;
xmlNodePtr xa, xb;
POINTARRAY **ppa = NULL;
+ srs = parse_gml_srs(xnode);
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
/* Polygon/outerBoundaryIs -> GML 2.1.2 */
|| (!*hasz && !ptarray_isclosed2d(ppa[0]))
|| (*hasz && !ptarray_isclosed3d(ppa[0])))
lwerror("invalid GML representation");
+
+ if (srs->reverse_axis) ppa[0] = gml_reverse_axis_pa(ppa[0]);
}
}
|| (!*hasz && !ptarray_isclosed2d(ppa[ring]))
|| (*hasz && !ptarray_isclosed3d(ppa[ring])))
lwerror("invalid GML representation");
+
+ if (srs->reverse_axis) ppa[ring] = gml_reverse_axis_pa(ppa[ring]);
ring++;
}
}
/* Exterior Ring is mandatory */
if (ppa == NULL || ppa[0] == NULL) lwerror("invalid GML representation");
- srid = parse_gml_srs(xnode);
- return (LWGEOM*) lwpoly_construct(srid, NULL, ring, ppa);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *) lwpoly_construct(*root_srid, NULL, ring, ppa);
+ } else {
+ if (srs->srid != *root_srid) {
+ for (i=0 ; i < ring ; i++)
+ gml_reproject_pa(ppa[i], srs->srid, *root_srid);
+ }
+ geom = (LWGEOM *) lwpoly_construct(-1, NULL, ring, ppa);
+ }
+ lwfree(srs);
+
+ return geom;
}
/**
* Parse GML Surface (3.x.x)
*/
-static LWGEOM* parse_gml_surface(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_surface(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
xmlChar *interpolation;
xmlNodePtr xa, xb, xc;
- int patch, ring, srid;
+ int i, patch, ring;
POINTARRAY **ppa;
+ LWGEOM *geom;
+ gmlSrs *srs;
bool found=false;
+ srs = parse_gml_srs(xnode);
/* Looking for gml:patches */
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
|| (!*hasz && !ptarray_isclosed2d(ppa[0]))
|| (*hasz && !ptarray_isclosed3d(ppa[0])))
lwerror("invalid GML representation");
+
+ if (srs->reverse_axis) ppa[0] = gml_reverse_axis_pa(ppa[0]);
}
}
|| (!*hasz && !ptarray_isclosed2d(ppa[ring]))
|| ( *hasz && !ptarray_isclosed3d(ppa[ring])))
lwerror("invalid GML representation");
+
+ if (srs->reverse_axis) ppa[ring] = gml_reverse_axis_pa(ppa[ring]);
}
ring++;
}
/* Exterior Ring is mandatory */
if (ppa == NULL || ppa[0] == NULL) lwerror("invalid GML representation");
- srid = parse_gml_srs(xnode);
- return (LWGEOM*) lwpoly_construct(srid, NULL, ring, ppa);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *) lwpoly_construct(*root_srid, NULL, ring, ppa);
+ } else {
+ if (srs->srid != *root_srid) {
+ for (i=0 ; i < ring ; i++)
+ gml_reproject_pa(ppa[i], srs->srid, *root_srid);
+ }
+ geom = (LWGEOM *) lwpoly_construct(-1, NULL, ring, ppa);
+ }
+ lwfree(srs);
+
+ return geom;
}
/**
* Parse gml:MultiPoint (2.1.2, 3.x.x)
*/
-static LWGEOM* parse_gml_mpoint(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_mpoint(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid;
+ gmlSrs *srs;
xmlNodePtr xa;
LWGEOM *geom = NULL;
- srid = parse_gml_srs(xnode);
-
- geom = (LWGEOM *)lwcollection_construct_empty(srid, 1, 0);
- geom->type = lwgeom_makeType(1, 0, srid != -1, MULTIPOINTTYPE);
+ srs = parse_gml_srs(xnode);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *)lwcollection_construct_empty(*root_srid, 1, 0);
+ geom->type = lwgeom_makeType(1, 1, 0, MULTIPOINTTYPE);
+ } else {
+ geom = (LWGEOM *)lwcollection_construct_empty(-1, 1, 0);
+ geom->type = lwgeom_makeType(1, 0, 0, MULTIPOINTTYPE);
+ }
+ lwfree(srs);
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
if (strcmp((char *) xa->name, "pointMember")) continue;
if (xa->children != NULL)
geom = lwmpoint_add((LWMPOINT *)geom, -1,
- parse_gml(xa->children, hasz));
+ parse_gml(xa->children, hasz, root_srid));
}
return geom;
/**
* Parse gml:MultiLineString (2.1.2, 3.x.x)
*/
-static LWGEOM* parse_gml_mline(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_mline(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid;
+ gmlSrs *srs;
xmlNodePtr xa;
LWGEOM *geom = NULL;
- srid = parse_gml_srs(xnode);
-
- geom = (LWGEOM *)lwcollection_construct_empty(srid, 1, 0);
- geom->type = lwgeom_makeType(1, 0, srid != -1, MULTILINETYPE);
+ srs = parse_gml_srs(xnode);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *)lwcollection_construct_empty(*root_srid, 1, 0);
+ geom->type = lwgeom_makeType(1, 1, 0, MULTILINETYPE);
+ } else {
+ geom = (LWGEOM *)lwcollection_construct_empty(-1, 1, 0);
+ geom->type = lwgeom_makeType(1, 0, 0, MULTILINETYPE);
+ }
+ lwfree(srs);
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
- /* MultiLineString/lineMember */
+ /* MultiLineString/lineStringMember */
if (xa->type != XML_ELEMENT_NODE) continue;
if (strcmp((char *) xa->name, "lineStringMember")) continue;
if (xa->children != NULL)
geom = lwmline_add((LWMLINE *)geom, -1,
- parse_gml(xa->children, hasz));
+ parse_gml(xa->children, hasz, root_srid));
}
return geom;
/**
* Parse GML MultiCurve (3.x.x)
*/
-static LWGEOM* parse_gml_mcurve(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_mcurve(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid;
+ gmlSrs *srs;
xmlNodePtr xa;
LWGEOM *geom = NULL;
- srid = parse_gml_srs(xnode);
-
- geom = (LWGEOM *)lwcollection_construct_empty(srid, 1, 0);
- geom->type = lwgeom_makeType(1, 0, srid != -1, MULTILINETYPE);
+ srs = parse_gml_srs(xnode);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *)lwcollection_construct_empty(*root_srid, 1, 0);
+ geom->type = lwgeom_makeType(1, 1, 0, MULTILINETYPE);
+ } else {
+ geom = (LWGEOM *)lwcollection_construct_empty(-1, 1, 0);
+ geom->type = lwgeom_makeType(1, 0, 0, MULTILINETYPE);
+ }
+ lwfree(srs);
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
if (strcmp((char *) xa->name, "curveMember")) continue;
if (xa->children != NULL)
geom = lwmline_add((LWMLINE *)geom, -1,
- parse_gml(xa->children, hasz));
+ parse_gml(xa->children, hasz, root_srid));
}
return geom;
/**
* Parse GML MultiPolygon (2.1.2, 3.x.x)
*/
-static LWGEOM* parse_gml_mpoly(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_mpoly(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid;
+ gmlSrs *srs;
xmlNodePtr xa;
LWGEOM *geom = NULL;
- srid = parse_gml_srs(xnode);
-
- geom = (LWGEOM *)lwcollection_construct_empty(srid, 1, 0);
- geom->type = lwgeom_makeType(1, 0, srid != -1, MULTIPOLYGONTYPE);
+ srs = parse_gml_srs(xnode);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *)lwcollection_construct_empty(*root_srid, 1, 0);
+ geom->type = lwgeom_makeType(1, 1, 0, MULTIPOLYGONTYPE);
+ } else {
+ geom = (LWGEOM *)lwcollection_construct_empty(-1, 1, 0);
+ geom->type = lwgeom_makeType(1, 0, 0, MULTIPOLYGONTYPE);
+ }
+ lwfree(srs);
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
if (strcmp((char *) xa->name, "polygonMember")) continue;
if (xa->children != NULL)
geom = lwmpoly_add((LWMPOLY *)geom, -1,
- parse_gml(xa->children, hasz));
+ parse_gml(xa->children, hasz, root_srid));
}
return geom;
/**
* Parse GML MultiSurface (3.x.x)
*/
-static LWGEOM* parse_gml_msurface(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_msurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid;
+ gmlSrs *srs;
xmlNodePtr xa;
LWGEOM *geom = NULL;
- srid = parse_gml_srs(xnode);
-
- geom = (LWGEOM *)lwcollection_construct_empty(srid, 1, 0);
- geom->type = lwgeom_makeType(1, 0, srid != -1, MULTIPOLYGONTYPE);
+ srs = parse_gml_srs(xnode);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *)lwcollection_construct_empty(*root_srid, 1, 0);
+ geom->type = lwgeom_makeType(1, 1, 0, MULTIPOLYGONTYPE);
+ } else {
+ geom = (LWGEOM *)lwcollection_construct_empty(-1, 1, 0);
+ geom->type = lwgeom_makeType(1, 0, 0, MULTIPOLYGONTYPE);
+ }
+ lwfree(srs);
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
if (strcmp((char *) xa->name, "surfaceMember")) continue;
if (xa->children != NULL)
geom = lwmpoly_add((LWMPOLY *)geom, -1,
- parse_gml(xa->children, hasz));
+ parse_gml(xa->children, hasz, root_srid));
}
return geom;
/**
* Parse GML MultiGeometry (2.1.2, 3.x.x)
*/
-static LWGEOM* parse_gml_coll(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml_coll(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
- int srid;
+ gmlSrs *srs;
xmlNodePtr xa;
LWGEOM *geom = NULL;
- srid = parse_gml_srs(xnode);
-
- geom = (LWGEOM *)lwcollection_construct_empty(srid, 1, 0);
- geom->type = lwgeom_makeType(1, 0, srid != -1, COLLECTIONTYPE);
+ srs = parse_gml_srs(xnode);
+ if (!*root_srid) {
+ *root_srid = srs->srid;
+ geom = (LWGEOM *)lwcollection_construct_empty(*root_srid, 1, 0);
+ geom->type = lwgeom_makeType(1, 1, 0, COLLECTIONTYPE);
+ } else {
+ geom = (LWGEOM *)lwcollection_construct_empty(-1, 1, 0);
+ geom->type = lwgeom_makeType(1, 0, 0, COLLECTIONTYPE);
+ }
+ lwfree(srs);
for (xa = xnode->children ; xa != NULL ; xa = xa->next) {
if (xa->type != XML_ELEMENT_NODE) continue;
if ( !strcmp((char *) xa->name, "pointMember")
- || !strcmp((char *) xa->name, "lineMember")
- || !strcmp((char *) xa->name, "curveMember")
- || !strcmp((char *) xa->name, "polygonMember")
- || !strcmp((char *) xa->name, "surfaceMember")
+ || !strcmp((char *) xa->name, "lineStringMember")
+ || !strcmp((char *) xa->name, "polygonMember")
|| !strcmp((char *) xa->name, "geometryMember")) {
if (xa->children == NULL) break;
geom = lwcollection_add((LWCOLLECTION *)geom, -1,
- parse_gml(xa->children, hasz));
-
- } else if ( !strcmp((char *) xa->name, "MultiPoint")
- || !strcmp((char *) xa->name, "MultiLineString")
- || !strcmp((char *) xa->name, "MultiCurve")
- || !strcmp((char *) xa->name, "MultiPolygon")
- || !strcmp((char *) xa->name, "MultiSurface")
- || !strcmp((char *) xa->name, "MultiGeometry")) {
-
- if (xa->children == NULL) break;
- geom = lwcollection_add((LWCOLLECTION *)geom, -1,
- parse_gml(xa, hasz));
+ parse_gml(xa->children, hasz, root_srid));
}
}
/**
* Parse GML
*/
-static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz)
+static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz, int *root_srid)
{
xmlNodePtr xa = xnode;
while (xa != NULL && xa->type != XML_ELEMENT_NODE) xa = xa->next;
if (!strcmp((char *) xa->name, "Point"))
- return parse_gml_point(xa, hasz);
+ return parse_gml_point(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "LineString"))
- return parse_gml_line(xa, hasz);
+ return parse_gml_line(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "Curve"))
- return parse_gml_curve(xa, hasz);
+ return parse_gml_curve(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "Polygon"))
- return parse_gml_polygon(xa, hasz);
+ return parse_gml_polygon(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "Surface"))
- return parse_gml_surface(xa, hasz);
+ return parse_gml_surface(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "MultiPoint"))
- return parse_gml_mpoint(xa, hasz);
+ return parse_gml_mpoint(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "MultiLineString"))
- return parse_gml_mline(xa, hasz);
+ return parse_gml_mline(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "MultiCurve"))
- return parse_gml_mcurve(xa, hasz);
+ return parse_gml_mcurve(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "MultiPolygon"))
- return parse_gml_mpoly(xa, hasz);
+ return parse_gml_mpoly(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "MultiSurface"))
- return parse_gml_msurface(xa, hasz);
+ return parse_gml_msurface(xa, hasz, root_srid);
if (!strcmp((char *) xa->name, "MultiGeometry"))
- return parse_gml_coll(xa, hasz);
+ return parse_gml_coll(xa, hasz, root_srid);
lwerror("invalid GML representation");
return NULL; /* Never reach */
--
--- spatial_ref_sys data
+-- spatial_ref_sys datas
--
+
+-- EPSG 4326 : WGS 84
INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ');
+--- EPSG 27562 : NTF (Paris) / Lambert Centre France
+INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (27562,'EPSG',27562,'PROJCS["NTF (Paris) / Lambert Centre France",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936265,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",52],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99987742],PARAMETER["false_easting",600000],PARAMETER["false_northing",200000],AUTHORITY["EPSG","27562"],AXIS["X",EAST],AXIS["Y",NORTH]]','+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ');
+
+--- EPSG 27582 : NTF (Paris) / France II (deprecated)
+INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (27582,'EPSG',27582,'PROJCS["NTF (Paris) / France II (deprecated)",GEOGCS["NTF (Paris)",DATUM["Nouvelle_Triangulation_Francaise_Paris",SPHEROID["Clarke 1880 (IGN)",6378249.2,293.4660212936265,AUTHORITY["EPSG","7011"]],TOWGS84[-168,-60,320,0,0,0,0],AUTHORITY["EPSG","6807"]],PRIMEM["Paris",2.33722917,AUTHORITY["EPSG","8903"]],UNIT["grad",0.01570796326794897,AUTHORITY["EPSG","9105"]],AUTHORITY["EPSG","4807"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_1SP"],PARAMETER["latitude_of_origin",52],PARAMETER["central_meridian",0],PARAMETER["scale_factor",0.99987742],PARAMETER["false_easting",600000],PARAMETER["false_northing",2200000],AUTHORITY["EPSG","27582"],AXIS["X",EAST],AXIS["Y",NORTH]]','+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ');
+
+
+
-- Empty Geometry
SELECT 'empty_geom', ST_AsEWKT(ST_GeomFromGML(NULL));
-- XML not elements handle
SELECT 'mpoint_6', ST_AsEWKT(ST_GeomFromGML(' <!-- --> <gml:MultiPoint> <!-- --> <gml:pointMember> <!-- --> <gml:Point> <!-- --> <gml:coordinates>1,2</gml:coordinates></gml:Point></gml:pointMember> <!-- --> <gml:pointMember> <!-- --> <gml:Point> <!-- --> <gml:coordinates>3,4</gml:coordinates></gml:Point></gml:pointMember></gml:MultiPoint>'));
--- TODO Mixed srsName
+-- Mixed srsName
+SELECT 'mpoint_7', ST_AsEWKT(ST_GeomFromGML('<gml:MultiPoint srsName="EPSG:27582"><gml:pointMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point srsName="EPSG:27562"><gml:coordinates>400000,5000000</gml:coordinates></gml:Point></gml:pointMember></gml:MultiPoint>'));
SELECT 'mline_7', ST_AsEWKT(ST_GeomFromGML('<gml:MultiLineString><gml:lineStringMember><gml:LineString><gml:posList dimension="3">1 2 3 4 5 6</gml:posList></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:posList dimension="2">7 8 9 10</gml:posList></gml:LineString></gml:lineStringMember></gml:MultiLineString>'));
SELECT 'mline_8', ST_AsEWKT(ST_GeomFromGML('<gml:MultiLineString><gml:lineStringMember><gml:LineString><gml:posList dimension="2">1 2 3 4</gml:posList></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:posList dimension="3">5 6 7 8 9 10</gml:posList></gml:LineString></gml:lineStringMember></gml:MultiLineString>'));
--- TODO Mixed srsName
+-- Mixed srsName
+SELECT 'mline_9', ST_AsEWKT(ST_GeomFromGML('<gml:MultiLineString srsName="EPSG:27582"><gml:lineStringMember><gml:LineString><gml:coordinates>1,2 3,4</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString srsName="EPSG:27562"><gml:coordinates>400000,5000000 400010,5000010</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString>'));
SELECT 'mcurve_7', ST_AsEWKT(ST_GeomFromGML('<gml:MultiCurve><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList dimension="3">1 2 3 4 5 6</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList dimension="2">7 8 9 10</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve>'));
SELECT 'mcurve_8', ST_AsEWKT(ST_GeomFromGML('<gml:MultiCurve><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList dimension="2">1 2 3 4</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList dimension="3">5 6 7 8 9 10</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve>'));
--- TODO Mixed srsName
+-- Mixed srsName
+SELECT 'mcurve_9', ST_AsEWKT(ST_GeomFromGML('<gml:MultiCurve srsName="EPSG:27582"><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:coordinates>1,2 3,4</gml:coordinates></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve srsName="EPSG:27562"><gml:segments><gml:LineStringSegment><gml:coordinates>400000,5000000 400010,5000010</gml:coordinates></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve>'));
SELECT 'mpoly_7', ST_AsEWKT(ST_GeomFromGML('<gml:MultiPolygon><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList dimension="3">1 2 3 4 5 6 7 8 9 1 2 3</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList dimension="2">10 11 12 13 14 15 10 11</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon>'));
SELECT 'mpoly_8', ST_AsEWKT(ST_GeomFromGML('<gml:MultiPolygon><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList dimension="2">1 2 3 4 5 6 1 2</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:posList dimension="3">7 8 9 10 11 12 13 14 15 7 8 9</gml:posList></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon>'));
--- TODO Mixed srsName
+-- Mixed srsName
+SELECT 'mpoly_9', ST_AsEWKT(ST_GeomFromGML('<gml:MultiPolygon srsName="EPSG:27582"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,2 3,4 5,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember><gml:polygonMember><gml:Polygon srsName="EPSG:27562"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>400000,5000000 400010,5000010 400020,5000020 400000,5000000</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>400100,5000100 400110,5000110 400120,5000120 400100,5000100</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon>'));
SELECT 'msurface_7', ST_AsEWKT(ST_GeomFromGML('<gml:MultiSurface><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList dimension="3">1 2 3 4 5 6 7 8 9 1 2 3</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList dimension="2">10 11 12 13 14 15 10 11</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface>'));
SELECT 'msurface_8', ST_AsEWKT(ST_GeomFromGML('<gml:MultiSurface><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList dimension="2">1 2 3 4 5 6 1 2</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList dimension="3">7 8 9 10 11 12 13 14 15 7 8 9</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface>'));
--- TODO Mixed srsName
+-- Mixed srsName
+SELECT 'msurface_9', ST_AsEWKT(ST_GeomFromGML('<gml:MultiSurface srsName="EPSG:27582"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:coordinates>1,2 3,4 5,6 1,2</gml:coordinates></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon srsName="EPSG:27562"><gml:exterior><gml:LinearRing><gml:coordinates>400000,5000000 400010,5000010 400020,5000020 400000,5000000</gml:coordinates></gml:LinearRing></gml:exterior><gml:interior><gml:LinearRing><gml:coordinates>400100,5000100 400110,5000110 400120,5000120 400100,5000100</gml:coordinates></gml:LinearRing></gml:interior></gml:Polygon></gml:surfaceMember></gml:MultiSurface>'));
--
-- 1 simple geom
-SELECT 'collection_1', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:pointMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:pointMember></gml:MultiGeometry>'));
+SELECT 'collection_1', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:geometryMember></gml:MultiGeometry>'));
-- 2 simples geom
-SELECT 'collection_2', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:pointMember><gml:Point><gml:pos>1 2</gml:pos></gml:Point></gml:pointMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>3 4 5 6</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiGeometry>'));
+SELECT 'collection_2', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:pos>1 2</gml:pos></gml:Point></gml:geometryMember><gml:geometryMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>3 4 5 6</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:geometryMember></gml:MultiGeometry>'));
-- 1 multi geom
-SELECT 'collection_3', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:MultiPoint><gml:pointMember><gml:Point><gml:pos>1 2</gml:pos></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:pos>3 4</gml:pos></gml:Point></gml:pointMember></gml:MultiPoint></gml:MultiGeometry>'));
+SELECT 'collection_3', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember><gml:MultiPoint><gml:pointMember><gml:Point><gml:pos>1 2</gml:pos></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:pos>3 4</gml:pos></gml:Point></gml:pointMember></gml:MultiPoint></gml:geometryMember></gml:MultiGeometry>'));
-- 2 multi geom
-SELECT 'collection_4', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:MultiPoint><gml:pointMember><gml:Point><gml:pos>1 2</gml:pos></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:pos>3 4</gml:pos></gml:Point></gml:pointMember></gml:MultiPoint><gml:MultiCurve><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>5 6 7 8</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>9 10 11 12</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve></gml:MultiGeometry>'));
+SELECT 'collection_4', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember><gml:MultiPoint><gml:pointMember><gml:Point><gml:pos>1 2</gml:pos></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:pos>3 4</gml:pos></gml:Point></gml:pointMember></gml:MultiPoint></gml:geometryMember><gml:geometryMember><gml:MultiCurve><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>5 6 7 8</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>9 10 11 12</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve></gml:geometryMember></gml:MultiGeometry>'));
-- 2 multi geom and 2 simples
-SELECT 'collection_5', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:MultiPoint><gml:pointMember><gml:Point><gml:pos>1 2</gml:pos></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:pos>3 4</gml:pos></gml:Point></gml:pointMember></gml:MultiPoint><gml:pointMember><gml:Point><gml:pos>5 6</gml:pos></gml:Point></gml:pointMember><gml:MultiCurve><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>7 8 9 10</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>11 12 13 14</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>15 16 17 18 19 20 15 16</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiGeometry>'));
+SELECT 'collection_5', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember><gml:MultiPoint><gml:pointMember><gml:Point><gml:pos>1 2</gml:pos></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:pos>3 4</gml:pos></gml:Point></gml:pointMember></gml:MultiPoint></gml:geometryMember><gml:geometryMember><gml:Point><gml:pos>5 6</gml:pos></gml:Point></gml:geometryMember><gml:geometryMember><gml:MultiCurve><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>7 8 9 10</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember><gml:curveMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList>11 12 13 14</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:curveMember></gml:MultiCurve></gml:geometryMember><gml:geometryMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>15 16 17 18 19 20 15 16</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:geometryMember></gml:MultiGeometry>'));
-- Empty collection
-SELECT 'collection_6', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:pointMember></gml:pointMember></gml:MultiGeometry>'));
+SELECT 'collection_6', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember></gml:geometryMember></gml:MultiGeometry>'));
SELECT 'collection_7', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry></gml:MultiGeometry>'));
-- Collection of collection
-SELECT 'collection_8', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:pointMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:pointMember><gml:MultiGeometry><gml:pointMember><gml:Point><gml:coordinates>3,4</gml:coordinates></gml:Point></gml:pointMember></gml:MultiGeometry></gml:MultiGeometry>'));
+SELECT 'collection_8', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:pointMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:pointMember><gml:geometryMember><gml:MultiGeometry><gml:pointMember><gml:Point><gml:coordinates>3,4</gml:coordinates></gml:Point></gml:pointMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry>'));
-- Collection of collection of collection
-SELECT 'collection_9', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:pointMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:pointMember><gml:MultiGeometry><gml:MultiGeometry><gml:pointMember><gml:Point><gml:coordinates>3,4</gml:coordinates></gml:Point></gml:pointMember></gml:MultiGeometry></gml:MultiGeometry></gml:MultiGeometry>'));
+SELECT 'collection_9', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:geometryMember><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:Point><gml:coordinates>3,4</gml:coordinates></gml:Point></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry>'));
-- srsName handle
-SELECT 'collection_10', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry srsName="EPSG:4326"><gml:pointMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:pointMember></gml:MultiGeometry>'));
+SELECT 'collection_10', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry srsName="EPSG:4326"><gml:geometryMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:geometryMember></gml:MultiGeometry>'));
-- XML not elements handle
-SELECT 'collection_11', ST_AsEWKT(ST_GeomFromGML(' <!-- --> <gml:MultiGeometry> <!-- --> <gml:pointMember> <!-- --> <gml:Point> <!-- --> <gml:coordinates>1,2</gml:coordinates></gml:Point></gml:pointMember> <!-- --> <gml:MultiGeometry> <!-- --> <gml:MultiGeometry> <!-- --> <gml:pointMember> <!-- --> <gml:Point> <!-- --> <gml:coordinates>3,4</gml:coordinates></gml:Point></gml:pointMember></gml:MultiGeometry></gml:MultiGeometry></gml:MultiGeometry>'));
+SELECT 'collection_11', ST_AsEWKT(ST_GeomFromGML(' <!-- --> <gml:MultiGeometry> <!-- --> <gml:geometryMember> <!-- --> <gml:Point> <!-- --> <gml:pos dimension="2">1 2</gml:pos></gml:Point></gml:geometryMember> <!-- --> <gml:geometryMember> <!-- --> <gml:MultiGeometry> <!-- --> <gml:geometryMember> <!-- --> <gml:MultiGeometry> <!-- --> <gml:geometryMember><gml:Point><gml:pos dimension="3">3 4 5</gml:pos></gml:Point></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry>'));
-- Mixed dimension
-SELECT 'collection_12', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:pointMember><gml:Point><gml:pos dimension="3">1 2 3</gml:pos></gml:Point></gml:pointMember><gml:MultiGeometry><gml:MultiGeometry><gml:pointMember><gml:Point><gml:pos dimension="2">4 5</gml:pos></gml:Point></gml:pointMember></gml:MultiGeometry></gml:MultiGeometry></gml:MultiGeometry>'));
-SELECT 'collection_13', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:pointMember><gml:Point><gml:pos dimension="2">1 2</gml:pos></gml:Point></gml:pointMember><gml:MultiGeometry><gml:MultiGeometry><gml:pointMember><gml:Point><gml:pos dimension="3">3 4 5</gml:pos></gml:Point></gml:pointMember></gml:MultiGeometry></gml:MultiGeometry></gml:MultiGeometry>'));
-
--- TODO Mixed srsName
+SELECT 'collection_12', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:pos dimension="3">1 2 3</gml:pos></gml:Point></gml:geometryMember><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:Point><gml:pos dimension="2">4 5</gml:pos></gml:Point></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry>'));
+SELECT 'collection_13', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry><gml:geometryMember><gml:Point><gml:pos dimension="2">1 2</gml:pos></gml:Point></gml:geometryMember><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:Point><gml:pos dimension="3">3 4 5</gml:pos></gml:Point></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry>'));
+-- Mixed srsName
+SELECT 'collection_14', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry srsName="EPSG:27582"><gml:geometryMember><gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point></gml:geometryMember><gml:geometryMember><gml:MultiGeometry><gml:geometryMember><gml:MultiGeometry srsName="EPSG:27562"><gml:geometryMember><gml:Point><gml:coordinates>400000,5000000</gml:coordinates></gml:Point></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry></gml:geometryMember></gml:MultiGeometry>'));
SELECT 'srs_1', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
SELECT 'srs_2', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:EPSG:geographicCRS:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
SELECT 'srs_3', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:ogc:def:crs:EPSG:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
-SELECT 'srs_4', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:ogc:def:crs:EPSG:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
-SELECT 'srs_5', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>1 2</gml:pos></gml:Point>'));
-SELECT 'srs_6', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:ogc:def:crs:EPSG:6.6:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
-SELECT 'srs_7', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:x-ogc:def:crs:EPSG:6.6:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
-SELECT 'srs_8', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_4', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_5', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:ogc:def:crs:EPSG:6.6:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_6', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="urn:x-ogc:def:crs:EPSG:6.6:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_7', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:pos>1 2</gml:pos></gml:Point>'));
-- ERROR not a valid pattern
-SELECT 'srs_9', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="a:wrong:pattern:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_8', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="a:wrong:pattern:4326"><gml:pos>1 2</gml:pos></gml:Point>'));
-- ERROR: not a defined SRID
-SELECT 'srs_10', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:01"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_9', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:01"><gml:pos>1 2</gml:pos></gml:Point>'));
-- ERROR: SRID is not an int
-SELECT 'srs_11', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:abc"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_10', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:abc"><gml:pos>1 2</gml:pos></gml:Point>'));
-- ERROR: SRID is not only int
-SELECT 'srs_12', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:4326abc"><gml:pos>1 2</gml:pos></gml:Point>'));
-SELECT 'srs_13', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:abc4326"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_11', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:4326abc"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_12', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:abc4326"><gml:pos>1 2</gml:pos></gml:Point>'));
-- ERROR: srsName empty
-SELECT 'srs_14', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:"><gml:pos>1 2</gml:pos></gml:Point>'));
-SELECT 'srs_15', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName=""><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_13', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_14', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName=""><gml:pos>1 2</gml:pos></gml:Point>'));
-- ERROR: srsName is defined as -1
-SELECT 'srs_16', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:-1"><gml:pos>1 2</gml:pos></gml:Point>'));
+SELECT 'srs_15', ST_AsEWKT(ST_GeomFromGML('<gml:Point srsName="EPSG:-1"><gml:pos>1 2</gml:pos></gml:Point>'));
+
+-- Reverse axis with all kind of simples geometry types
+SELECT 'srs_16', ST_AsEWKT(ST_GeomFromGML('<gml:MultiGeometry srsName="urn:ogc:def:crs:EPSG::4326"><gml:geometryMember><gml:Point><gml:pos dimension="2">1 2</gml:pos></gml:Point></gml:geometryMember><gml:geometryMember><gml:LineString><gml:posList dimension="2">3 4 5 6</gml:posList></gml:LineString></gml:geometryMember><gml:geometryMember><gml:Curve><gml:segments><gml:LineStringSegment><gml:posList dimension="2">7 8 9 10</gml:posList></gml:LineStringSegment></gml:segments></gml:Curve></gml:geometryMember><gml:geometryMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList dimension="2">11 12 13 14 15 16 11 12</gml:posList></gml:LinearRing></gml:exterior><gml:interior><gml:LinearRing><gml:posList dimension="2">17 18 19 20 21 22 17 18</gml:posList></gml:LinearRing></gml:interior></gml:Polygon></gml:geometryMember><gml:geometryMember><gml:Surface><gml:patches><gml:PolygonPatch><gml:exterior><gml:LinearRing><gml:posList dimension="2">23 24 25 26 27 28 23 24</gml:posList></gml:LinearRing></gml:exterior><gml:interior><gml:LinearRing><gml:posList dimension="2">25 26 27 28 29 30 25 26</gml:posList></gml:LinearRing></gml:interior></gml:PolygonPatch></gml:patches></gml:Surface></gml:geometryMember></gml:MultiGeometry>'));
+
+
+
+-- Reverse axis with severals multi geometry types
--
-- TODO GML Namespace
-- Delete inserted spatial data
--
DELETE FROM spatial_ref_sys WHERE srid = 4326;
+DELETE FROM spatial_ref_sys WHERE srid = 27562;
+DELETE FROM spatial_ref_sys WHERE srid = 27582;
mpoint_4|MULTIPOINT EMPTY
mpoint_5|MULTIPOINT EMPTY
mpoint_6|MULTIPOINT(1 2,3 4)
+mpoint_7|SRID=27582;MULTIPOINT(1 2,400000 7000000)
mline_1|MULTILINESTRING((1 2,3 4))
mline_2|MULTILINESTRING((1 2,3 4),(5 6,7 8))
mline_3|SRID=4326;MULTILINESTRING((1 2,3 4))
mline_6|MULTILINESTRING((1 2,3 4),(5 6,7 8))
mline_7|MULTILINESTRING((1 2,4 5),(7 8,9 10))
mline_8|MULTILINESTRING((1 2,3 4),(5 6,8 9))
+mline_9|SRID=27582;MULTILINESTRING((1 2,3 4),(400000 7000000,400010 7000010))
mcurve_1|MULTILINESTRING((1 2,3 4))
mcurve_2|MULTILINESTRING((1 2,3 4),(5 6,7 8))
mcurve_3|SRID=4326;MULTILINESTRING((1 2,3 4))
mcurve_6|MULTILINESTRING((1 2,3 4),(5 6,7 8))
mcurve_7|MULTILINESTRING((1 2,4 5),(7 8,9 10))
mcurve_8|MULTILINESTRING((1 2,3 4),(5 6,8 9))
+mcurve_9|SRID=27582;MULTILINESTRING((1 2,3 4),(400000 7000000,400010 7000010))
mpoly_1|MULTIPOLYGON(((1 2,3 4,5 6,1 2)))
mpoly_2|MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((7 8,9 10,11 12,7 8)))
mpoly_3|SRID=4326;MULTIPOLYGON(((1 2,3 4,5 6,1 2)))
mpoly_6|MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((7 8,9 10,11 12,7 8)))
mpoly_7|MULTIPOLYGON(((1 2,4 5,7 8,1 2)),((10 11,12 13,14 15,10 11)))
mpoly_8|MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((7 8,10 11,13 14,7 8)))
+mpoly_9|SRID=27582;MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((400000 7000000,400010 7000010,400020 7000020,400000 7000000),(400100 7000100,400110 7000110,400120 7000120,400100 7000100)))
msurface_1|MULTIPOLYGON(((1 2,3 4,5 6,1 2)))
msurface_2|MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((7 8,9 10,11 12,7 8)))
msurface_3|SRID=4326;MULTIPOLYGON(((1 2,3 4,5 6,1 2)))
msurface_6|MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((7 8,9 10,11 12,7 8)))
msurface_7|MULTIPOLYGON(((1 2,4 5,7 8,1 2)),((10 11,12 13,14 15,10 11)))
msurface_8|MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((7 8,10 11,13 14,7 8)))
+msurface_9|SRID=27582;MULTIPOLYGON(((1 2,3 4,5 6,1 2)),((400000 7000000,400010 7000010,400020 7000020,400000 7000000),(400100 7000100,400110 7000110,400120 7000120,400100 7000100)))
collection_1|GEOMETRYCOLLECTION(POINT(1 2))
collection_2|GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(3 4,5 6))
collection_3|GEOMETRYCOLLECTION(MULTIPOINT(1 2,3 4))
collection_11|GEOMETRYCOLLECTION(POINT(1 2),GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(3 4))))
collection_12|GEOMETRYCOLLECTION(POINT(1 2),GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(4 5))))
collection_13|GEOMETRYCOLLECTION(POINT(1 2),GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(3 4))))
+collection_14|SRID=27582;GEOMETRYCOLLECTION(POINT(1 2),GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(400000 7000000))))
srs_1|SRID=4326;POINT(1 2)
-srs_2|SRID=4326;POINT(1 2)
-srs_3|SRID=4326;POINT(1 2)
-srs_4|SRID=4326;POINT(1 2)
-srs_5|SRID=4326;POINT(1 2)
-srs_6|SRID=4326;POINT(1 2)
+srs_2|SRID=4326;POINT(2 1)
+srs_3|SRID=4326;POINT(2 1)
+srs_4|SRID=4326;POINT(2 1)
+srs_5|SRID=4326;POINT(2 1)
+srs_6|SRID=4326;POINT(2 1)
srs_7|SRID=4326;POINT(1 2)
-srs_8|SRID=4326;POINT(1 2)
ERROR: unknown spatial reference system
ERROR: unknown spatial reference system
ERROR: unknown spatial reference system
ERROR: unknown spatial reference system
ERROR: unknown spatial reference system
ERROR: unknown spatial reference system
+srs_16|SRID=4326;GEOMETRYCOLLECTION(POINT(2 1),LINESTRING(4 3,6 5),LINESTRING(8 7,10 9),POLYGON((12 11,14 13,16 15,12 11),(18 17,20 19,22 21,18 17)),POLYGON((24 23,26 25,28 27,24 23),(26 25,28 27,30 29,26 25)))
coordinates_1|POINT(1 2)
ERROR: invalid GML representation
coordinates_3|POINT(1 2 3)