PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ parse_kml_coordinates()

static POINTARRAY * parse_kml_coordinates ( xmlNodePtr  xnode,
bool *  hasz 
)
static

Parse kml:coordinates.

Definition at line 301 of file lwgeom_in_kml.c.

302{
303 xmlChar *kml_coord;
304 bool found;
305 POINTARRAY *dpa;
306 int seen_kml_dims = 0;
307 int kml_dims;
308 char *p, *q;
309 POINT4D pt;
310 double d;
311
312 if (xnode == NULL) lwpgerror("invalid KML representation");
313
314 for (found = false ; xnode != NULL ; xnode = xnode->next)
315 {
316 if (xnode->type != XML_ELEMENT_NODE) continue;
317 if (!is_kml_namespace(xnode, false)) continue;
318 if (!is_kml_element(xnode, "coordinates")) continue;
319
320 found = true;
321 break;
322 }
323 if (!found) lwpgerror("invalid KML representation");
324
325 /* We begin to retrieve coordinates string */
326 kml_coord = xmlNodeGetContent(xnode);
327 p = (char *) kml_coord;
328
329 /* KML coordinates pattern: x1,y1 x2,y2
330 * x1,y1,z1 x2,y2,z2
331 */
332
333 /* Now we create PointArray from coordinates values */
334 /* HasZ, !HasM, 1pt */
335 dpa = ptarray_construct_empty(1, 0, 1);
336
337 while (*p && isspace(*p)) ++p;
338 for (kml_dims=0; *p ; p++)
339 {
340//lwpgnotice("*p:%c, kml_dims:%d", *p, kml_dims);
341 if ( isdigit(*p) || *p == '+' || *p == '-' || *p == '.' ) {
342 kml_dims++;
343 errno = 0; d = strtod(p, &q);
344 if ( errno != 0 ) {
345 // TODO: destroy dpa, return NULL
346 lwpgerror("invalid KML representation"); /*: %s", strerror(errno));*/
347 }
348 if (kml_dims == 1) pt.x = d;
349 else if (kml_dims == 2) pt.y = d;
350 else if (kml_dims == 3) pt.z = d;
351 else {
352 lwpgerror("invalid KML representation"); /* (more than 3 dimensions)"); */
353 // TODO: destroy dpa, return NULL
354 }
355
356//lwpgnotice("after strtod d:%f, *q:%c, kml_dims:%d", d, *q, kml_dims);
357
358 if ( *q && ! isspace(*q) && *q != ',' ) {
359 lwpgerror("invalid KML representation"); /* (invalid character %c follows ordinate value)", *q); */
360 }
361
362 /* Look-ahead to see if we're done reading */
363 while (*q && isspace(*q)) ++q;
364 if ( isdigit(*q) || *q == '+' || *q == '-' || *q == '.' || ! *q ) {
365 if ( kml_dims < 2 ) lwpgerror("invalid KML representation"); /* (not enough ordinates)"); */
366 else if ( kml_dims < 3 ) *hasz = false;
367 if ( ! seen_kml_dims ) seen_kml_dims = kml_dims;
368 else if ( seen_kml_dims != kml_dims ) {
369 lwpgerror("invalid KML representation: mixed coordinates dimension");
370 }
371 ptarray_append_point(dpa, &pt, LW_TRUE);
372 kml_dims = 0;
373 }
374 p = q-1; /* will be incremented on next iteration */
375//lwpgnotice("after look-ahead *p:%c, kml_dims:%d", *p, kml_dims);
376 } else if ( *p != ',' && ! isspace(*p) ) {
377 lwpgerror("invalid KML representation"); /* (unexpected character %c)", *p); */
378 }
379 }
380
381 xmlFree(kml_coord);
382
383 /* TODO: we shouldn't need to clone here */
384 return ptarray_clone_deep(dpa);
385}
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition ptarray.c:59
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,...
Definition ptarray.c:147
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition ptarray.c:634
static bool is_kml_namespace(xmlNodePtr xnode, bool is_strict)
Return false if current element namespace is not a KML one Return true otherwise.
static bool is_kml_element(xmlNodePtr xn, const char *kml_name)
double x
Definition liblwgeom.h:400
double z
Definition liblwgeom.h:400
double y
Definition liblwgeom.h:400

References is_kml_element(), 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().

Here is the call graph for this function:
Here is the caller graph for this function: