PostGIS  2.5.0dev-r@@SVN_REVISION@@
static POINTARRAY* parse_kml_coordinates ( xmlNodePtr  xnode,
bool *  hasz 
)
static

Parse kml:coordinates.

Definition at line 279 of file lwgeom_in_kml.c.

References is_kml_namespace(), LW_TRUE, ptarray_append_point(), ptarray_clone_deep(), ptarray_construct_empty(), POINT4D::x, POINT4D::y, and POINT4D::z.

Referenced by parse_kml_line(), parse_kml_point(), and parse_kml_polygon().

280 {
281  xmlChar *kml_coord;
282  bool found;
283  POINTARRAY *dpa;
284  int seen_kml_dims = 0;
285  int kml_dims;
286  char *p, *q;
287  POINT4D pt;
288  double d;
289 
290  if (xnode == NULL) lwpgerror("invalid KML representation");
291 
292  for (found = false ; xnode != NULL ; xnode = xnode->next)
293  {
294  if (xnode->type != XML_ELEMENT_NODE) continue;
295  if (!is_kml_namespace(xnode, false)) continue;
296  if (strcmp((char *) xnode->name, "coordinates")) continue;
297 
298  found = true;
299  break;
300  }
301  if (!found) lwpgerror("invalid KML representation");
302 
303  /* We begin to retrieve coordinates string */
304  kml_coord = xmlNodeGetContent(xnode);
305  p = (char *) kml_coord;
306 
307  /* KML coordinates pattern: x1,y1 x2,y2
308  * x1,y1,z1 x2,y2,z2
309  */
310 
311  /* Now we create PointArray from coordinates values */
312  /* HasZ, !HasM, 1pt */
313  dpa = ptarray_construct_empty(1, 0, 1);
314 
315  while (*p && isspace(*p)) ++p;
316  for (kml_dims=0; *p ; p++)
317  {
318 //lwpgnotice("*p:%c, kml_dims:%d", *p, kml_dims);
319  if ( isdigit(*p) || *p == '+' || *p == '-' || *p == '.' ) {
320  kml_dims++;
321  errno = 0; d = strtod(p, &q);
322  if ( errno != 0 ) {
323  // TODO: destroy dpa, return NULL
324  lwpgerror("invalid KML representation"); /*: %s", strerror(errno));*/
325  }
326  if (kml_dims == 1) pt.x = d;
327  else if (kml_dims == 2) pt.y = d;
328  else if (kml_dims == 3) pt.z = d;
329  else {
330  lwpgerror("invalid KML representation"); /* (more than 3 dimensions)"); */
331  // TODO: destroy dpa, return NULL
332  }
333 
334 //lwpgnotice("after strtod d:%f, *q:%c, kml_dims:%d", d, *q, kml_dims);
335 
336  if ( *q && ! isspace(*q) && *q != ',' ) {
337  lwpgerror("invalid KML representation"); /* (invalid character %c follows ordinate value)", *q); */
338  }
339 
340  /* Look-ahead to see if we're done reading */
341  while (*q && isspace(*q)) ++q;
342  if ( isdigit(*q) || *q == '+' || *q == '-' || *q == '.' || ! *q ) {
343  if ( kml_dims < 2 ) lwpgerror("invalid KML representation"); /* (not enough ordinates)"); */
344  else if ( kml_dims < 3 ) *hasz = false;
345  if ( ! seen_kml_dims ) seen_kml_dims = kml_dims;
346  else if ( seen_kml_dims != kml_dims ) {
347  lwpgerror("invalid KML representation: mixed coordinates dimension");
348  }
349  ptarray_append_point(dpa, &pt, LW_TRUE);
350  kml_dims = 0;
351  }
352  p = q-1; /* will be incrementedon next iteration */
353 //lwpgnotice("after look-ahead *p:%c, kml_dims:%d", *p, kml_dims);
354  } else if ( *p != ',' && ! isspace(*p) ) {
355  lwpgerror("invalid KML representation"); /* (unexpected character %c)", *p); */
356  }
357  }
358 
359  xmlFree(kml_coord);
360 
361  /* TODO: we shouldn't need to clone here */
362  return ptarray_clone_deep(dpa);
363 }
double x
Definition: liblwgeom.h:351
static bool is_kml_namespace(xmlNodePtr xnode, bool is_strict)
Return false if current element namespace is not a KML one Return true otherwise. ...
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:70
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, then a duplicate point will not be added.
Definition: ptarray.c:156
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:628
double z
Definition: liblwgeom.h:351
double y
Definition: liblwgeom.h:351

Here is the call graph for this function:

Here is the caller graph for this function: