From: Olivier Courtin Date: Fri, 29 Apr 2011 17:44:00 +0000 (+0000) Subject: Add an srid default value as second optional parameter for ST_GeomFromGML. Related... X-Git-Tag: 2.0.0alpha1~1735 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c21dad8b299dbdc639232f245c403c3cd839ef7c;p=postgis Add an srid default value as second optional parameter for ST_GeomFromGML. Related to #906. Remove a wrong srsName definition. Update doc and unit test git-svn-id: http://svn.osgeo.org/postgis/trunk@7071 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/doc/reference_constructor.xml b/doc/reference_constructor.xml index a79479200..9fdc3a36e 100644 --- a/doc/reference_constructor.xml +++ b/doc/reference_constructor.xml @@ -452,6 +452,11 @@ SELECT ST_GeomFromEWKT('POLYHEDRALSURFACE( geometry ST_GeomFromGML text geomgml + + geometry ST_GeomFromGML + text geomgml + integer srid + @@ -477,6 +482,7 @@ SELECT ST_GeomFromEWKT('POLYHEDRALSURFACE( Availability: 1.5 Enhanced: 2.0.0 support for Polyhedral surfaces and TIN was introduced. + Enhanced: 2.0.0 default srid optional parameter added. &Z_support; &P_support; &T_support; @@ -639,12 +645,19 @@ SELECT ST_GeomFromEWKT('POLYHEDRALSURFACE( geometry ST_GMLToSQL text geomgml + + geometry ST_GMLToSQL + text geomgml + integer srid + Description &sqlmm_compliant; SQL-MM 3: 5.1.50 (except for curves support). Availability: 1.5 + Enhanced: 2.0.0 support for Polyhedral surfaces and TIN was introduced. + Enhanced: 2.0.0 default srid optional parameter added. See Also diff --git a/postgis/lwgeom_in_gml.c b/postgis/lwgeom_in_gml.c index 91e995b3e..2924974a0 100644 --- a/postgis/lwgeom_in_gml.c +++ b/postgis/lwgeom_in_gml.c @@ -81,8 +81,8 @@ Datum geom_from_gml(PG_FUNCTION_ARGS) LWGEOM *lwgeom; int xml_size; char *xml; + int root_srid; bool hasz=true; - int root_srid=0; xmlNodePtr xmlroot=NULL; @@ -92,6 +92,8 @@ Datum geom_from_gml(PG_FUNCTION_ARGS) xml = text2cstring(xml_input); xml_size = VARSIZE(xml_input) - VARHDRSZ; + root_srid = PG_GETARG_INT32(1); + /* Begin to Parse XML doc */ xmlInitParser(); xmldoc = xmlParseMemory(xml, xml_size); @@ -102,8 +104,10 @@ Datum geom_from_gml(PG_FUNCTION_ARGS) lwerror("invalid GML representation"); } + lwgeom = parse_gml(xmlroot, &hasz, &root_srid); lwgeom_add_bbox(lwgeom); + if (root_srid && lwgeom->srid == -1) lwgeom->srid = root_srid; xmlFreeDoc(xmldoc); xmlCleanupParser(); @@ -303,8 +307,8 @@ static POINTARRAY* gml_reproject_pa(POINTARRAY *pa, int srid_in, int srid_out) projPJ in_pj, out_pj; char *text_in, *text_out; - if (srid_in == -1 || srid_out == -1) - lwerror("invalid GML representation"); + if (srid_in == 0 || srid_in == -1) return pa; /* nothing to do */ + if (srid_out == 0 || srid_out == -1) lwerror("invalid GML representation"); text_in = GetProj4StringSPI(srid_in); text_out = GetProj4StringSPI(srid_out); @@ -428,11 +432,6 @@ static gmlSrs* parse_gml_srs(xmlNodePtr xnode) sep = '#'; latlon = false; } - else if (!strncmp((char *) srsname, "http://www.epsg.org/", 20)) - { - sep = '/'; - latlon = false; - } else lwerror("unknown spatial reference system"); /* retrieve the last ':' or '#' char */ @@ -1123,6 +1122,45 @@ static LWGEOM* parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid) } +/** + * Parse GML LinearRing (3.1.1) + */ +static LWGEOM* parse_gml_linearring(xmlNodePtr xnode, bool *hasz, int *root_srid) +{ + gmlSrs *srs; + LWGEOM *geom; + POINTARRAY **ppa = NULL; + + if (is_xlink(xnode)) xnode = get_xlink_node(xnode); + srs = parse_gml_srs(xnode); + + ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*)); + ppa[0] = parse_gml_data(xnode->children, hasz, root_srid); + + if (ppa[0]->npoints < 4 + || (!*hasz && !ptarray_isclosed2d(ppa[0])) + || (*hasz && !ptarray_isclosed3d(ppa[0]))) + lwerror("invalid GML representation"); + + if (srs->reverse_axis) ppa[0] = ptarray_flip_coordinates(ppa[0]); + + + if (!*root_srid) + { + *root_srid = srs->srid; + geom = (LWGEOM *) lwpoly_construct(*root_srid, NULL, 1, ppa); + } + else + { + if (srs->srid != *root_srid) gml_reproject_pa(ppa[0], srs->srid, *root_srid); + geom = (LWGEOM *) lwpoly_construct(-1, NULL, 1, ppa); + } + lwfree(srs); + + return geom; +} + + /** * Parse GML Polygon (2.1.2, 3.1.1) */ @@ -1812,6 +1850,9 @@ static LWGEOM* parse_gml(xmlNodePtr xnode, bool *hasz, int *root_srid) if (!strcmp((char *) xa->name, "Curve")) return parse_gml_curve(xa, hasz, root_srid); + if (!strcmp((char *) xa->name, "LinearRing")) + return parse_gml_linearring(xa, hasz, root_srid); + if (!strcmp((char *) xa->name, "Polygon")) return parse_gml_polygon(xa, hasz, root_srid); diff --git a/postgis/postgis.sql.in.c b/postgis/postgis.sql.in.c index bddaa24ca..20c4663ff 100644 --- a/postgis/postgis.sql.in.c +++ b/postgis/postgis.sql.in.c @@ -3741,18 +3741,37 @@ CREATE OR REPLACE FUNCTION ST_Equals(geometry,geometry) ----------------------------------------------------------------------- -- GML & KML INPUT --- Availability: 1.5.0 ----------------------------------------------------------------------- +CREATE OR REPLACE FUNCTION _ST_GeomFromGML(text, int4) + RETURNS geometry + AS 'MODULE_PATHNAME','geom_from_gml' + LANGUAGE 'C' IMMUTABLE; + +-- Availability: 2.0.0 +CREATE OR REPLACE FUNCTION ST_GeomFromGML(text, int4) + RETURNS geometry + AS 'MODULE_PATHNAME','geom_from_gml' + LANGUAGE 'C' IMMUTABLE STRICT; + +-- Availability: 1.5.0 CREATE OR REPLACE FUNCTION ST_GeomFromGML(text) - RETURNS geometry - AS 'MODULE_PATHNAME','geom_from_gml' - LANGUAGE 'C' IMMUTABLE STRICT; + RETURNS geometry + AS 'SELECT _ST_GeomFromGML($1, 0)' + LANGUAGE 'SQL' IMMUTABLE STRICT; +-- Availability: 1.5.0 CREATE OR REPLACE FUNCTION ST_GMLToSQL(text) - RETURNS geometry - AS 'MODULE_PATHNAME','geom_from_gml' - LANGUAGE 'C' IMMUTABLE STRICT; + RETURNS geometry + AS 'SELECT _ST_GeomFromGML($1, 0)' + LANGUAGE 'SQL' IMMUTABLE STRICT; +-- Availability: 2.0.0 +CREATE OR REPLACE FUNCTION ST_GMLToSQL(text, int4) + RETURNS geometry + AS 'MODULE_PATHNAME','geom_from_gml' + LANGUAGE 'C' IMMUTABLE STRICT; + +-- Availability: 1.5.0 CREATE OR REPLACE FUNCTION ST_GeomFromKML(text) RETURNS geometry AS 'MODULE_PATHNAME','geom_from_kml' diff --git a/regress/in_gml.sql b/regress/in_gml.sql index e7db24df0..7f22bb1ce 100644 --- a/regress/in_gml.sql +++ b/regress/in_gml.sql @@ -603,7 +603,9 @@ SELECT 'srs_4', ST_AsEWKT(ST_GeomFromGML('1 2')); SELECT 'srs_6', ST_AsEWKT(ST_GeomFromGML('1 2')); SELECT 'srs_7', ST_AsEWKT(ST_GeomFromGML('1 2')); -SELECT 'srs_8', ST_AsEWKT(ST_GeomFromGML('1 2')); + +-- Use default srsName +SELECT 'srs_8', ST_AsEWKT(ST_GeomFromGML('1 2', 4326)); -- ERROR not a valid pattern SELECT 'srs_9', ST_AsEWKT(ST_GeomFromGML('1 2'));