50 #include "executor/spi.h"
51 #include "utils/builtins.h"
53 #include <libxml/tree.h>
54 #include <libxml/parser.h>
55 #include <libxml/xpath.h>
56 #include <libxml/xpathInternals.h>
58 #include "../postgis_config.h"
59 #include "lwgeom_pg.h"
61 #include "lwgeom_transform.h"
75 #define XLINK_NS ((char *) "http://www.w3.org/1999/xlink")
76 #define GML_NS ((char *) "http://www.opengis.net/gml")
77 #define GML32_NS ((char *) "http://www.opengis.net/gml/3.2")
83 POSTGIS_DEBUGF(3,
"ST_GeomFromGML ERROR %i", error_code);
107 if (PG_ARGISNULL(0)) PG_RETURN_NULL();
108 xml_input = PG_GETARG_TEXT_P(0);
109 xml = text_to_cstring(xml_input);
110 xml_size = VARSIZE_ANY_EXHDR(xml_input);
113 root_srid = PG_GETARG_INT32(1);
117 lwgeom->
srid = root_srid;
119 geom = geometry_serialize(lwgeom);
122 PG_RETURN_POINTER(geom);
134 ns = xmlGetNsList(xnode->doc, xnode);
140 if (ns == NULL) {
return !is_strict; }
147 for (p=ns ; *p ; p++)
149 if ((*p)->href == NULL || (*p)->prefix == NULL ||
150 xnode->ns == NULL || xnode->ns->prefix == NULL)
continue;
152 if (!xmlStrcmp(xnode->ns->prefix, (*p)->prefix))
154 if ( !strcmp((
char *) (*p)->href,
GML_NS)
155 || !strcmp((
char *) (*p)->href,
GML32_NS))
180 return xmlGetProp(xnode, prop);
186 value = xmlGetNsProp(xnode, prop, (xmlChar *)
GML_NS);
190 if (
value == NULL)
value = xmlGetNoNsProp(xnode, prop);
204 prop = xmlGetNsProp(node, (xmlChar *)
"type", (xmlChar *)
XLINK_NS);
205 if (prop == NULL)
return false;
206 if (strcmp((
char *) prop,
"simple"))
212 prop = xmlGetNsProp(node, (xmlChar *)
"href", (xmlChar *)
XLINK_NS);
213 if (prop == NULL)
return false;
232 xmlXPathContext *ctx;
233 xmlXPathObject *xpath;
234 xmlNodePtr node, ret_node;
235 xmlChar *href, *p, *node_id;
237 href = xmlGetNsProp(xnode, (xmlChar *)
"href", (xmlChar *)
XLINK_NS);
238 id =
lwalloc((xmlStrlen(xnode->ns->prefix) * 2 + xmlStrlen(xnode->name)
239 + xmlStrlen(href) +
sizeof(
"//:[@:id='']") + 1));
244 sprintf(
id,
"//%s:%s[@%s:id='%s']", (
char *) xnode->ns->prefix,
245 (
char *) xnode->name,
246 (
char *) xnode->ns->prefix,
249 ctx = xmlXPathNewContext(xnode->doc);
258 ns = xmlGetNsList(xnode->doc, xnode);
259 for (n=ns ; *n; n++) xmlXPathRegisterNs(ctx, (*n)->prefix, (*n)->href);
263 xpath = xmlXPathEvalExpression((xmlChar *)
id, ctx);
265 if (xpath == NULL || xpath->nodesetval == NULL || xpath->nodesetval->nodeNr != 1)
268 xmlXPathFreeObject(xpath);
269 xmlXPathFreeContext(ctx);
272 ret_node = xpath->nodesetval->nodeTab[0];
273 xmlXPathFreeObject(xpath);
274 xmlXPathFreeContext(ctx);
277 for (node = xnode ; node != NULL ; node = node->parent)
279 if (node->type != XML_ELEMENT_NODE)
continue;
283 if (!xmlStrcmp(node_id, p))
315 snprintf(text_in, 16,
"EPSG:%d", epsg_in);
316 snprintf(text_out, 16,
"EPSG:%d", epsg_out);
328 elog(ERROR,
"gml_reproject_pa: reprojection failed");
331 proj_destroy(lwp->
pj);
347 int is_axis_order_gis_friendly, err;
349 if (SPI_OK_CONNECT != SPI_connect ())
350 lwpgerror(
"gml_is_srs_axis_order_gis_friendly: could not connect to SPI manager");
352 sprintf(query,
"SELECT srtext \
353 FROM spatial_ref_sys WHERE srid='%d'", srid);
355 err = SPI_exec(query, 1);
356 if (err < 0) lwpgerror(
"gml_is_srs_axis_order_gis_friendly: error executing query %d", err);
359 if (SPI_processed <= 0)
365 srtext = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
367 is_axis_order_gis_friendly = 1;
368 if (srtext && srtext[0] !=
'\0')
371 char* srtext_horizontal = (
char*)
malloc(strlen(srtext) + 1);
372 strcpy(srtext_horizontal, srtext);
375 ptr = strstr(srtext_horizontal,
",VERT_CS[");
379 if( strstr(srtext_horizontal,
"AXIS[") == NULL &&
380 strstr(srtext_horizontal,
"GEOCCS[") == NULL )
385 is_axis_order_gis_friendly = 0;
387 else if( strstr(srtext_horizontal,
388 "AXIS[\"Latitude\",NORTH],AXIS[\"Longitude\",EAST]") != NULL )
390 is_axis_order_gis_friendly = 0;
392 else if( strstr(srtext_horizontal,
393 "AXIS[\"Northing\",NORTH],AXIS[\"Easting\",EAST]") != NULL )
395 is_axis_order_gis_friendly = 0;
397 else if( strstr(srtext_horizontal,
398 "AXIS[\"geodetic latitude (Lat)\",north,ORDER[1]") != NULL )
400 is_axis_order_gis_friendly = 0;
403 free(srtext_horizontal);
407 return is_axis_order_gis_friendly;
417 int is_axis_order_gis_friendly;
420 bool honours_authority_axis_order =
false;
424 srsname =
gmlGetProp(node, (xmlChar *)
"srsName");
428 if (node->parent == NULL)
455 if (!strncmp((
char *) srsname,
"EPSG:", 5))
458 honours_authority_axis_order =
false;
460 else if (!strncmp((
char *) srsname,
"urn:ogc:def:crs:EPSG:", 21)
461 || !strncmp((
char *) srsname,
"urn:x-ogc:def:crs:EPSG:", 23)
462 || !strncmp((
char *) srsname,
"urn:EPSG:geographicCRS:", 23))
465 honours_authority_axis_order =
true;
467 else if (!strncmp((
char *) srsname,
468 "http://www.opengis.net/gml/srs/epsg.xml#", 40))
471 honours_authority_axis_order =
false;
476 for (p = (
char *) srsname ; *p ; p++);
477 for (--p ; *p != sep ; p--)
478 if (!isdigit(*p))
gml_lwpgerror(
"unknown spatial reference system", 5);
480 srs->
srid = atoi(++p);
490 srs->
reverse_axis = !is_axis_order_gis_friendly && honours_authority_axis_order;
525 if (space_before)
while (isspace(*d)) d++;
526 for (st = INIT, p = d ; *p ; p++)
531 if (st == INIT || st == NEED_DIG) st = DIG;
532 else if (st == NEED_DIG_DEC) st = DIG_DEC;
533 else if (st == NEED_DIG_EXP || st == EXP) st = DIG_EXP;
534 else if (st == DIG || st == DIG_DEC || st == DIG_EXP);
539 if (st == DIG) st = NEED_DIG_DEC;
542 else if (*p ==
'-' || *p ==
'+')
544 if (st == INIT) st = NEED_DIG;
545 else if (st == EXP) st = NEED_DIG_EXP;
548 else if (*p ==
'e' || *p ==
'E')
550 if (st == DIG || st == DIG_DEC) st = EXP;
553 else if (isspace(*p))
555 if (!space_after)
gml_lwpgerror(
"invalid GML representation", 11);
556 if (st == DIG || st == DIG_DEC || st == DIG_EXP)st = END;
557 else if (st == NEED_DIG_DEC) st = END;
564 if (st != DIG && st != NEED_DIG_DEC && st != DIG_DEC && st != DIG_EXP && st != END)
576 xmlChar *gml_coord, *gml_ts, *gml_cs, *gml_dec;
585 gml_coord = xmlNodeGetContent(xnode);
586 p = (
char *) gml_coord;
596 if (gml_ts == NULL) ts =
' ';
599 if (xmlStrlen(gml_ts) > 1 || isdigit(gml_ts[0]))
607 if (gml_cs == NULL) cs =
',';
610 if (xmlStrlen(gml_cs) > 1 || isdigit(gml_cs[0]))
617 gml_dec =
gmlGetProp(xnode, (xmlChar *)
"decimal");
618 if (gml_dec == NULL) dec =
'.';
621 if (xmlStrlen(gml_dec) > 1 || isdigit(gml_dec[0]))
627 if (cs == ts || cs == dec || ts == dec)
633 while (isspace(*p)) p++;
634 for (q = p, gml_dims=0, digit =
false ; *p ; p++)
637 if (isdigit(*p)) digit =
true;
645 if (*(p+1) ==
'\0')
gml_lwpgerror(
"invalid GML representation", 19);
654 else if (digit && (*p == ts || *(p+1) ==
'\0'))
656 if (*p == ts) *p =
'\0';
659 if (gml_dims < 2 || gml_dims > 3)
678 else if (*p == dec && dec !=
'.') *p =
'.';
702 for (xyz = xnode->children ; xyz != NULL ; xyz = xyz->next)
704 if (xyz->type != XML_ELEMENT_NODE)
continue;
707 if (!strcmp((
char *) xyz->name,
"X"))
710 c = xmlNodeGetContent(xyz);
715 else if (!strcmp((
char *) xyz->name,
"Y"))
718 c = xmlNodeGetContent(xyz);
723 else if (!strcmp((
char *) xyz->name,
"Z"))
726 c = xmlNodeGetContent(xyz);
734 if (!z) *hasz =
false;
747 xmlChar *dimension, *gmlpos;
757 dimension =
gmlGetProp(xnode, (xmlChar *)
"srsDimension");
758 if (dimension == NULL)
759 dimension =
gmlGetProp(xnode, (xmlChar *)
"dimension");
760 if (dimension == NULL) dim = 2;
763 dim = atoi((
char *) dimension);
765 if (dim < 2 || dim > 3)
768 if (dim == 2) *hasz =
false;
771 gmlpos = xmlNodeGetContent(xnode);
772 pos = (
char *) gmlpos;
773 while (isspace(*pos)) pos++;
778 for (p=pos, gml_dim=0, digit=
false ; *pos ; pos++)
780 if (isdigit(*pos)) digit =
true;
781 if (digit && (*pos ==
' ' || *(pos+1) ==
'\0'))
783 if (*pos ==
' ') *pos =
'\0';
787 else if (gml_dim == 2)
789 else if (gml_dim == 3)
799 if (gml_dim == 2) *hasz =
false;
800 if (gml_dim < 2 || gml_dim > 3 || gml_dim != dim)
814 xmlChar *dimension, *gmlposlist;
822 dimension =
gmlGetProp(xnode, (xmlChar *)
"srsDimension");
823 if (dimension == NULL)
824 dimension =
gmlGetProp(xnode, (xmlChar *)
"dimension");
825 if (dimension == NULL) dim = 2;
828 dim = atoi((
char *) dimension);
830 if (dim < 2 || dim > 3)
gml_lwpgerror(
"invalid GML representation", 27);
832 if (dim == 2) *hasz =
false;
835 gmlposlist = xmlNodeGetContent(xnode);
836 poslist = (
char *) gmlposlist;
844 while (isspace(*poslist)) poslist++;
845 for (p=poslist, gml_dim=0, digit=
false ; *poslist ; poslist++)
847 if (isdigit(*poslist)) digit =
true;
848 if (digit && (*poslist ==
' ' || *(poslist+1) ==
'\0'))
850 if (*poslist ==
' ') *poslist =
'\0';
861 pt.
x = pt.
y = pt.
z = pt.
m = 0.0;
864 else if (*(poslist+1) ==
'\0')
899 for (xa = xnode ; xa != NULL ; xa = xa->next)
901 if (xa->type != XML_ELEMENT_NODE)
continue;
903 if (xa->name == NULL)
continue;
905 if (!strcmp((
char *) xa->name,
"pos"))
908 if (pa == NULL) pa = tmp_pa;
912 else if (!strcmp((
char *) xa->name,
"posList"))
915 if (pa == NULL) pa = tmp_pa;
919 else if (!strcmp((
char *) xa->name,
"coordinates"))
922 if (pa == NULL) pa = tmp_pa;
926 else if (!strcmp((
char *) xa->name,
"coord"))
929 if (pa == NULL) pa = tmp_pa;
933 else if (!strcmp((
char *) xa->name,
"pointRep") ||
934 !strcmp((
char *) xa->name,
"pointProperty"))
938 for (xb = xa->children ; xb != NULL ; xb = xb->next)
940 if (xb->type != XML_ELEMENT_NODE)
continue;
942 if (!strcmp((
char *) xb->name,
"Point"))
948 if (!found || xb == NULL)
952 if (xb == NULL || xb->children == NULL)
956 if (tmp_pa->npoints != 1)
962 else if (srs.
srid != *root_srid)
964 if (pa == NULL) pa = tmp_pa;
969 if (pa == NULL)
gml_lwpgerror(
"invalid GML representation", 32);
986 if (xnode->children == NULL)
996 *root_srid = srs.
srid;
1001 if (srs.
srid != *root_srid)
1021 if (xnode->children == NULL)
1031 *root_srid = srs.
srid;
1036 if (srs.
srid != *root_srid)
1058 xmlChar *interpolation=NULL;
1063 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1065 if (xa->type != XML_ELEMENT_NODE)
continue;
1067 if (!strcmp((
char *) xa->name,
"segments"))
1073 if (!found)
gml_lwpgerror(
"invalid GML representation", 37);
1078 for (xa = xa->children, lss=0; xa != NULL ; xa = xa->next)
1080 if (xa->type != XML_ELEMENT_NODE)
continue;
1082 if (strcmp((
char *) xa->name,
"LineStringSegment"))
continue;
1085 interpolation =
gmlGetProp(xa, (xmlChar *)
"interpolation");
1086 if (interpolation != NULL)
1088 if (strcmp((
char *) interpolation,
"linear"))
1090 xmlFree(interpolation);
1098 if (ppa[lss]->npoints < 2)
1102 if (lss == 0)
gml_lwpgerror(
"invalid GML representation", 40);
1105 if (lss == 1) pa = ppa[0];
1117 size_t cp_point_size =
sizeof(
POINT3D);
1118 size_t final_point_size = *hasz ?
sizeof(
POINT3D) :
sizeof(
POINT2D);
1130 for (
size_t i = 1; i < lss; i++)
1137 cp_point_size * (ppa[i]->npoints - 1));
1139 npoints += ppa[i]->
npoints - 1;
1171 if (ppa[0]->npoints < 4
1201 if (xnode->children == NULL)
1206 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1210 if (xa->type != XML_ELEMENT_NODE)
continue;
1212 if (strcmp((
char *) xa->name,
"outerBoundaryIs") &&
1213 strcmp((
char *) xa->name,
"exterior"))
continue;
1215 for (xb = xa->children ; xb != NULL ; xb = xb->next)
1217 if (xb->type != XML_ELEMENT_NODE)
continue;
1219 if (strcmp((
char *) xb->name,
"LinearRing"))
continue;
1224 if (ppa[0]->npoints < 4
1237 for (ring=1, xa = xnode->children ; xa != NULL ; xa = xa->next)
1241 if (xa->type != XML_ELEMENT_NODE)
continue;
1243 if (strcmp((
char *) xa->name,
"innerBoundaryIs") &&
1244 strcmp((
char *) xa->name,
"interior"))
continue;
1246 for (xb = xa->children ; xb != NULL ; xb = xb->next)
1248 if (xb->type != XML_ELEMENT_NODE)
continue;
1250 if (strcmp((
char *) xb->name,
"LinearRing"))
continue;
1256 if (ppa[ring]->npoints < 4
1267 if (ppa == NULL || ppa[0] == NULL)
gml_lwpgerror(
"invalid GML representation", 44);
1271 for (i=0 ; i < ring ; i++)
1289 xmlChar *interpolation=NULL;
1293 if (xnode->children == NULL)
1299 interpolation =
gmlGetProp(xnode, (xmlChar *)
"interpolation");
1300 if (interpolation != NULL)
1302 if (strcmp((
char *) interpolation,
"planar"))
1304 xmlFree(interpolation);
1309 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1312 if (xa->type != XML_ELEMENT_NODE)
continue;
1314 if (strcmp((
char *) xa->name,
"exterior"))
continue;
1316 for (xb = xa->children ; xb != NULL ; xb = xb->next)
1319 if (xb->type != XML_ELEMENT_NODE)
continue;
1321 if (strcmp((
char *) xb->name,
"LinearRing"))
continue;
1336 if (pa == NULL)
gml_lwpgerror(
"invalid GML representation", 47);
1352 xmlChar *interpolation=NULL;
1360 if (strcmp((
char *) xnode->name,
"PolygonPatch"))
1364 interpolation =
gmlGetProp(xnode, (xmlChar *)
"interpolation");
1365 if (interpolation != NULL)
1367 if (strcmp((
char *) interpolation,
"planar"))
1369 xmlFree(interpolation);
1375 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1378 if (strcmp((
char *) xa->name,
"exterior"))
continue;
1381 for (xb = xa->children ; xb != NULL ; xb = xb->next)
1383 if (xb->type != XML_ELEMENT_NODE)
continue;
1385 if (strcmp((
char *) xb->name,
"LinearRing"))
continue;
1390 if (ppa[0]->npoints < 4
1405 for (ring=1, xa = xnode->children ; xa != NULL ; xa = xa->next)
1407 if (xa->type != XML_ELEMENT_NODE)
continue;
1409 if (strcmp((
char *) xa->name,
"interior"))
continue;
1412 for (xb = xa->children ; xb != NULL ; xb = xb->next)
1414 if (xb->type != XML_ELEMENT_NODE)
continue;
1415 if (strcmp((
char *) xb->name,
"LinearRing"))
continue;
1421 if (ppa[ring]->npoints < 4
1434 if (ppa == NULL || ppa[0] == NULL)
gml_lwpgerror(
"invalid GML representation", 50);
1438 for (i=0 ; i < ring ; i++)
1460 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1462 if (xa->type != XML_ELEMENT_NODE)
continue;
1464 if (!strcmp((
char *) xa->name,
"patches"))
1470 if (!found)
gml_lwpgerror(
"invalid GML representation", 51);
1473 for (patch=0, xa = xa->children ; xa != NULL ; xa = xa->next)
1475 if (xa->type != XML_ELEMENT_NODE)
continue;
1477 if (strcmp((
char *) xa->name,
"PolygonPatch"))
continue;
1482 if (patch > 1)
gml_lwpgerror(
"invalid GML representation", 52);
1487 if (!patch)
gml_lwpgerror(
"invalid GML representation", 53);
1513 *root_srid = srs.
srid;
1517 if (xnode->children == NULL)
1521 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1523 if (xa->type != XML_ELEMENT_NODE)
continue;
1525 if (!strcmp((
char *) xa->name,
"patches") ||
1526 !strcmp((
char *) xa->name,
"trianglePatches"))
1532 if (!found)
return geom;
1535 for (xa = xa->children ; xa != NULL ; xa = xa->next)
1537 if (xa->type != XML_ELEMENT_NODE)
continue;
1539 if (strcmp((
char *) xa->name,
"Triangle"))
continue;
1541 if (xa->children != NULL)
1563 *root_srid = srs.
srid;
1567 if (xnode->children == NULL)
1570 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1573 if (xa->type != XML_ELEMENT_NODE)
continue;
1575 if (!strcmp((
char *) xa->name,
"pointMembers"))
1577 for (xb = xa->children ; xb != NULL ; xb = xb->next)
1584 else if (!strcmp((
char *) xa->name,
"pointMember"))
1586 if (xa->children != NULL)
1609 *root_srid = srs.
srid;
1613 if (xnode->children == NULL)
1616 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1619 if (xa->type != XML_ELEMENT_NODE)
continue;
1621 if (strcmp((
char *) xa->name,
"lineStringMember"))
continue;
1622 if (xa->children != NULL)
1644 *root_srid = srs.
srid;
1648 if (xnode->children == NULL)
1651 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1655 if (xa->type != XML_ELEMENT_NODE)
continue;
1657 if (!strcmp((
char *) xa->name,
"curveMembers"))
1659 for (xb = xa->children ; xb != NULL ; xb = xb->next)
1666 else if (!strcmp((
char *) xa->name,
"curveMember"))
1668 if (xa->children != NULL)
1691 *root_srid = srs.
srid;
1695 if (xnode->children == NULL)
1698 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1701 if (xa->type != XML_ELEMENT_NODE)
continue;
1703 if (strcmp((
char *) xa->name,
"polygonMember"))
continue;
1704 if (xa->children != NULL)
1726 *root_srid = srs.
srid;
1730 if (xnode->children == NULL)
1733 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1736 if (xa->type != XML_ELEMENT_NODE)
continue;
1738 if (!strcmp((
char *) xa->name,
"surfaceMembers"))
1740 for (xb = xa->children ; xb != NULL ; xb = xb->next)
1747 else if (!strcmp((
char *) xa->name,
"surfaceMember"))
1749 if (xa->children != NULL)
1774 *root_srid = srs.
srid;
1778 if (xnode->children == NULL)
1782 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1784 if (xa->type != XML_ELEMENT_NODE)
continue;
1786 if (!strcmp((
char *) xa->name,
"polygonPatches"))
1792 if (!found)
return geom;
1794 for (xa = xa->children ; xa != NULL ; xa = xa->next)
1797 if (xa->type != XML_ELEMENT_NODE)
continue;
1799 if (strcmp((
char *) xa->name,
"PolygonPatch"))
continue;
1822 *root_srid = srs.
srid;
1826 if (xnode->children == NULL)
1829 for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1831 if (xa->type != XML_ELEMENT_NODE)
continue;
1839 if ( !strcmp((
char *) xa->name,
"pointMember")
1840 || !strcmp((
char *) xa->name,
"lineStringMember")
1841 || !strcmp((
char *) xa->name,
"polygonMember")
1842 || !strcmp((
char *) xa->name,
"geometryMember"))
1844 if (xa->children == NULL)
break;
1846 parse_gml(xa->children, hasz, root_srid));
1860 xmlNodePtr xmlroot=NULL;
1868 xmldoc = xmlReadMemory(xml, xml_size, NULL, NULL, XML_PARSE_SAX1);
1876 xmlroot = xmlDocGetRootElement(xmldoc);
1885 lwgeom =
parse_gml(xmlroot, &hasz, &root_srid);
1892 lwgeom->
srid = root_srid;
1917 xmlNodePtr xa = xnode;
1920 while (xa != NULL && (xa->type != XML_ELEMENT_NODE
1923 if (xa == NULL)
gml_lwpgerror(
"invalid GML representation", 55);
1928 *root_srid = srs.
srid;
1931 if (!strcmp((
char *) xa->name,
"Point"))
1934 if (!strcmp((
char *) xa->name,
"LineString"))
1937 if (!strcmp((
char *) xa->name,
"Curve"))
1940 if (!strcmp((
char *) xa->name,
"LinearRing"))
1943 if (!strcmp((
char *) xa->name,
"Polygon"))
1946 if (!strcmp((
char *) xa->name,
"Triangle"))
1949 if (!strcmp((
char *) xa->name,
"Surface"))
1952 if (!strcmp((
char *) xa->name,
"MultiPoint"))
1955 if (!strcmp((
char *) xa->name,
"MultiLineString"))
1958 if (!strcmp((
char *) xa->name,
"MultiCurve"))
1961 if (!strcmp((
char *) xa->name,
"MultiPolygon"))
1964 if (!strcmp((
char *) xa->name,
"MultiSurface"))
1967 if (!strcmp((
char *) xa->name,
"PolyhedralSurface"))
1970 if ((!strcmp((
char *) xa->name,
"Tin")) ||
1971 !strcmp((
char *) xa->name,
"TriangulatedSurface" ))
1974 if (!strcmp((
char *) xa->name,
"MultiGeometry"))
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
int ptarray_transform(POINTARRAY *pa, LWPROJ *pj)
void lwgeom_free(LWGEOM *geom)
int ptarray_is_closed_3d(const POINTARRAY *pa)
LWTIN * lwtin_add_lwtriangle(LWTIN *mobj, const LWTRIANGLE *obj)
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
LWMLINE * lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj)
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
LWTRIANGLE * lwtriangle_construct_empty(int32_t srid, char hasz, char hasm)
LWMPOINT * lwmpoint_add_lwpoint(LWMPOINT *mobj, const LWPOINT *obj)
LWMPOLY * lwmpoly_add_lwpoly(LWMPOLY *mobj, const LWPOLY *obj)
LWPSURFACE * lwpsurface_add_lwpoly(LWPSURFACE *mobj, const LWPOLY *obj)
LWPROJ * lwproj_from_str(const char *str_in, const char *str_out)
Allocate a new LWPROJ containing the reference to the PROJ's PJ If extra_geography_data is true,...
void * lwrealloc(void *mem, size_t size)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
#define POLYHEDRALSURFACETYPE
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE,...
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
void * lwalloc(size_t size)
int ptarray_is_closed_2d(const POINTARRAY *pa)
LWGEOM * lwtriangle_as_lwgeom(const LWTRIANGLE *obj)
#define LW_TRUE
Return types for functions with status returns.
#define SRID_UNKNOWN
Unknown SRID value.
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
POINTARRAY * ptarray_merge(POINTARRAY *pa1, POINTARRAY *pa2)
Merge two given POINTARRAY and returns a pointer on the new aggregate one.
POINTARRAY * ptarray_flip_coordinates(POINTARRAY *pa)
Reverse X and Y axis on a given POINTARRAY.
LWLINE * lwline_construct_empty(int32_t srid, char hasz, char hasm)
LWTRIANGLE * lwtriangle_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
LWGEOM * lwgeom_force_2d(const LWGEOM *geom)
Strip out the Z/M components of an LWGEOM.
This library is the generic geometry handling section of PostGIS.
static LWGEOM * parse_gml_surface(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML Surface (3.1.1)
struct struct_gmlSrs gmlSrs
static xmlNodePtr get_xlink_node(xmlNodePtr xnode)
Return a xmlNodePtr on a node referenced by a XLink or NULL otherwise.
static POINTARRAY * parse_gml_pos(xmlNodePtr xnode, bool *hasz)
Parse gml:pos.
PG_FUNCTION_INFO_V1(geom_from_gml)
Ability to parse GML geometry fragment and to return an LWGEOM or an error message.
static bool is_xlink(xmlNodePtr node)
Return true if current node contains a simple XLink Return false otherwise.
static LWGEOM * parse_gml_patch(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML PolygonPatch (3.1.1)
static LWGEOM * parse_gml_msurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML MultiSurface (3.1.1)
static LWGEOM * parse_gml(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML.
static LWGEOM * parse_gml_psurface(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML PolyhedralSurface (3.1.1) Nota: It's not part of SF-2.
static LWGEOM * parse_gml_coll(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML MultiGeometry (2.1.2, 3.1.1)
static POINTARRAY * gml_reproject_pa(POINTARRAY *pa, int32_t epsg_in, int32_t epsg_out)
Use Proj to reproject a given POINTARRAY.
static double parse_gml_double(char *d, bool space_before, bool space_after)
Parse a string supposed to be a double.
static int gml_is_srs_axis_order_gis_friendly(int32_t srid)
Return 1 if the SRS definition from the authority has a GIS friendly order, that is easting,...
static LWGEOM * parse_gml_mcurve(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML MultiCurve (3.1.1)
static xmlChar * gmlGetProp(xmlNodePtr xnode, xmlChar *prop)
Retrieve a GML property from a node or NULL otherwise Respect namespaces if presents in the node elem...
Datum geom_from_gml(PG_FUNCTION_ARGS)
static LWGEOM * lwgeom_from_gml(const char *wkt, int xml_size)
Read GML.
static bool is_gml_namespace(xmlNodePtr xnode, bool is_strict)
Return false if current element namespace is not a GML one Return true otherwise.
static void parse_gml_srs(xmlNodePtr xnode, gmlSrs *srs)
Parse gml srsName attribute.
static LWGEOM * parse_gml_polygon(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML Polygon (2.1.2, 3.1.1)
static POINTARRAY * parse_gml_coordinates(xmlNodePtr xnode, bool *hasz)
Parse gml:coordinates.
static LWGEOM * parse_gml_line(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML lineString (2.1.2, 3.1.1)
static POINTARRAY * parse_gml_data(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse data coordinates.
static LWGEOM * parse_gml_mpoly(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML MultiPolygon (2.1.2, 3.1.1)
static POINTARRAY * parse_gml_coord(xmlNodePtr xnode, bool *hasz)
Parse gml:coord.
static LWGEOM * parse_gml_curve(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML Curve (3.1.1)
static void gml_lwpgerror(char *msg, __attribute__((__unused__)) int error_code)
static LWGEOM * parse_gml_mpoint(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse gml:MultiPoint (2.1.2, 3.1.1)
static LWGEOM * parse_gml_point(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML point (2.1.2, 3.1.1)
static LWGEOM * parse_gml_tin(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML Tin (and TriangulatedSurface) (3.1.1)
static LWGEOM * parse_gml_triangle(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML Triangle (3.1.1)
static LWGEOM * parse_gml_mline(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse gml:MultiLineString (2.1.2, 3.1.1)
static POINTARRAY * parse_gml_poslist(xmlNodePtr xnode, bool *hasz)
Parse gml:posList.
static LWGEOM * parse_gml_linearring(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse GML LinearRing (3.1.1)
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)