PostGIS  2.1.10dev-r@@SVN_REVISION@@
static LWGEOM* parse_gml_curve ( xmlNodePtr  xnode,
bool *  hasz,
int *  root_srid 
)
static

Parse GML Curve (3.1.1)

Definition at line 985 of file lwgeom_in_gml.c.

References get_xlink_node(), getPoint_internal(), gml_lwerror(), gml_reproject_pa(), gmlGetProp(), is_gml_namespace(), is_xlink(), lwalloc(), lwfree(), lwline_construct(), lwrealloc(), POINTARRAY::npoints, parse_gml_data(), parse_gml_srs(), ptarray_construct(), ptarray_flip_coordinates(), ptarray_point_size(), struct_gmlSrs::reverse_axis, struct_gmlSrs::srid, and SRID_UNKNOWN.

Referenced by parse_gml().

986 {
987  xmlNodePtr xa;
988  int lss, last, i;
989  bool found=false;
990  gmlSrs srs;
991  LWGEOM *geom=NULL;
992  POINTARRAY *pa=NULL;
993  POINTARRAY **ppa=NULL;
994  uint32 npoints=0;
995  xmlChar *interpolation=NULL;
996 
997  if (is_xlink(xnode)) xnode = get_xlink_node(xnode);
998 
999  /* Looking for gml:segments */
1000  for (xa = xnode->children ; xa != NULL ; xa = xa->next)
1001  {
1002  if (xa->type != XML_ELEMENT_NODE) continue;
1003  if (!is_gml_namespace(xa, false)) continue;
1004  if (!strcmp((char *) xa->name, "segments"))
1005  {
1006  found = true;
1007  break;
1008  }
1009  }
1010  if (!found) gml_lwerror("invalid GML representation", 37);
1011 
1012  ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*));
1013 
1014  /* Processing each gml:LineStringSegment */
1015  for (xa = xa->children, lss=0; xa != NULL ; xa = xa->next)
1016  {
1017  if (xa->type != XML_ELEMENT_NODE) continue;
1018  if (!is_gml_namespace(xa, false)) continue;
1019  if (strcmp((char *) xa->name, "LineStringSegment")) continue;
1020 
1021  /* GML SF is resticted to linear interpolation */
1022  interpolation = gmlGetProp(xa, (xmlChar *) "interpolation");
1023  if (interpolation != NULL)
1024  {
1025  if (strcmp((char *) interpolation, "linear"))
1026  gml_lwerror("invalid GML representation", 38);
1027  xmlFree(interpolation);
1028  }
1029 
1030  if (lss > 0) ppa = (POINTARRAY**) lwrealloc((POINTARRAY *) ppa,
1031  sizeof(POINTARRAY*) * (lss + 1));
1032 
1033  ppa[lss] = parse_gml_data(xa->children, hasz, root_srid);
1034  npoints += ppa[lss]->npoints;
1035  if (ppa[lss]->npoints < 2)
1036  gml_lwerror("invalid GML representation", 39);
1037  lss++;
1038  }
1039  if (lss == 0) gml_lwerror("invalid GML representation", 40);
1040 
1041  /* Most common case, a single segment */
1042  if (lss == 1) pa = ppa[0];
1043 
1044  /*
1045  * "The curve segments are connected to one another, with the end point
1046  * of each segment except the last being the start point of the next
1047  * segment" from ISO 19107:2003 -> 6.3.16.1 (p43)
1048  *
1049  * So we must aggregate all the segments into a single one and avoid
1050  * to copy the redundants points
1051  */
1052  if (lss > 1)
1053  {
1054  pa = ptarray_construct(1, 0, npoints - (lss - 1));
1055  for (last = npoints = i = 0; i < lss ; i++)
1056  {
1057  if (i + 1 == lss) last = 1;
1058  /* Check if segments are not disjoints */
1059  if (i > 0 && memcmp( getPoint_internal(pa, npoints),
1060  getPoint_internal(ppa[i], 0),
1061  *hasz?sizeof(POINT3D):sizeof(POINT2D)))
1062  gml_lwerror("invalid GML representation", 41);
1063 
1064  /* Aggregate stuff */
1065  memcpy( getPoint_internal(pa, npoints),
1066  getPoint_internal(ppa[i], 0),
1067  ptarray_point_size(ppa[i]) * (ppa[i]->npoints + last));
1068 
1069  npoints += ppa[i]->npoints - 1;
1070  lwfree(ppa[i]);
1071  }
1072  lwfree(ppa);
1073  }
1074 
1075  parse_gml_srs(xnode, &srs);
1076  if (srs.reverse_axis) pa = ptarray_flip_coordinates(pa);
1077  if (srs.srid != *root_srid && *root_srid != SRID_UNKNOWN)
1078  gml_reproject_pa(pa, srs.srid, *root_srid);
1079  geom = (LWGEOM *) lwline_construct(*root_srid, NULL, pa);
1080 
1081  return geom;
1082 }
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...
Definition: ptarray.c:49
void lwfree(void *mem)
Definition: lwutil.c:190
int npoints
Definition: liblwgeom.h:327
static void parse_gml_srs(xmlNodePtr xnode, gmlSrs *srs)
Parse gml srsName attribute.
static xmlChar * gmlGetProp(xmlNodePtr xnode, xmlChar *prop)
Retrieve a GML propertie from a node or NULL otherwise Respect namespaces if presents in the node ele...
static POINTARRAY * gml_reproject_pa(POINTARRAY *pa, int srid_in, int srid_out)
Use Proj4 to reproject a given POINTARRAY.
POINTARRAY * ptarray_flip_coordinates(POINTARRAY *pa)
Reverse X and Y axis on a given POINTARRAY.
Definition: ptarray.c:354
static xmlNodePtr get_xlink_node(xmlNodePtr xnode)
Return a xmlNodePtr on a node referenced by a XLink or NULL otherwise.
unsigned int uint32
Definition: shpopen.c:274
LWGEOM * geom
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:29
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:154
uint8_t * getPoint_internal(const POINTARRAY *pa, int n)
Definition: ptarray.c:1645
int ptarray_point_size(const POINTARRAY *pa)
Definition: ptarray.c:41
static bool is_xlink(xmlNodePtr node)
Return true if current node contains a simple XLink Return false otherwise.
static POINTARRAY * parse_gml_data(xmlNodePtr xnode, bool *hasz, int *root_srid)
Parse data coordinates.
static bool is_gml_namespace(xmlNodePtr xnode, bool is_strict)
Return false if current element namespace is not a GML one Return true otherwise. ...
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:183
static void gml_lwerror(char *msg, int error_code)
Definition: lwgeom_in_gml.c:68
void * lwalloc(size_t size)
Definition: lwutil.c:175

Here is the call graph for this function:

Here is the caller graph for this function: