#include <libxml/tree.h>
#include <libxml/parser.h>
+#include <errno.h>
+#include <string.h>
#include "postgres.h"
#endif
+#if 0 /* unused */
/**
* Parse a string supposed to be a double
*/
for (st = INIT, p = d ; *p ; p++)
{
+lwnotice("State: %d, *p=%c", st, *p);
+
if (isdigit(*p))
{
if (st == INIT || st == NEED_DIG) st = DIG;
return atof(d);
}
+#endif /* unused */
/**
static POINTARRAY* parse_kml_coordinates(xmlNodePtr xnode, bool *hasz)
{
xmlChar *kml_coord;
- bool digit, found;
+ bool found;
POINTARRAY *dpa;
int kml_dims;
char *p, *q;
POINT4D pt;
+ double d;
if (xnode == NULL) lwerror("invalid KML representation");
/* HasZ, !HasM, 1pt */
dpa = ptarray_construct_empty(1, 0, 1);
- for (q = p, kml_dims=0, digit = false ; *p ; p++)
+ while (*p && isspace(*p)) ++p;
+ for (kml_dims=0; *p ; p++)
{
+//lwnotice("*p:%c, kml_dims:%d", *p, kml_dims);
+ if ( isdigit(*p) || *p == '+' || *p == '-' || *p == '.' ) {
+ kml_dims++;
+ errno = 0; d = strtod(p, &q);
+ if ( errno != 0 ) {
+ // TODO: destroy dpa, return NULL
+ lwerror("invalid KML representation"); /*: %s", strerror(errno));*/
+ }
+ if (kml_dims == 1) pt.x = d;
+ else if (kml_dims == 2) pt.y = d;
+ else if (kml_dims == 3) pt.z = d;
+ else {
+ lwerror("invalid KML representation"); /* (more than 3 dimensions)"); */
+ // TODO: destroy dpa, return NULL
+ }
- if (isdigit(*p)) digit = true; /* One state parser */
-
- /* Coordinate Separator */
- if (*p == ',')
- {
- *p = '\0';
- kml_dims++;
-
- if (*(p+1) == '\0') lwerror("invalid KML representation");
-
- if (kml_dims == 1) pt.x = parse_kml_double(q, true, true);
- else if (kml_dims == 2) pt.y = parse_kml_double(q, true, true);
- q = p+1;
-
- /* Tuple Separator (or end string) */
- }
- else if (digit && (isspace(*p) || *(p+1) == '\0'))
- {
- if (isspace(*p)) *p = '\0';
- kml_dims++;
-
- if (kml_dims < 2 || kml_dims > 3)
- lwerror("invalid KML representation");
-
- if (kml_dims == 3)
- pt.z = parse_kml_double(q, true, true);
- else
- {
- pt.y = parse_kml_double(q, true, true);
- *hasz = false;
- }
+//lwnotice("after strtod d:%f, *q:%c, kml_dims:%d", d, *q, kml_dims);
- ptarray_append_point(dpa, &pt, LW_FALSE);
- digit = false;
- q = p+1;
- kml_dims = 0;
+ if ( *q && ! isspace(*q) && *q != ',' ) {
+ lwerror("invalid KML representation"); /* (invalid character %c follows ordinate value)", *q); */
+ }
- }
+ /* Look-ahead to see if we're done reading */
+ while (*q && isspace(*q)) ++q;
+ if ( isdigit(*q) || *q == '+' || *q == '-' || *q == '.' || ! *q ) {
+ if ( kml_dims < 2 ) lwerror("invalid KML representation"); /* (not enough ordinates)"); */
+ if ( kml_dims < 3 ) *hasz = false;
+ ptarray_append_point(dpa, &pt, LW_FALSE);
+ kml_dims = 0;
+ }
+ p = q-1; /* will be incrementedon next iteration */
+//lwnotice("after look-ahead *p:%c, kml_dims:%d", *p, kml_dims);
+ } else if ( *p != ',' && ! isspace(*p) ) {
+ lwerror("invalid KML representation"); /* (unexpected character %c)", *p); */
+ }
}
xmlFree(kml_coord);
-- 1 Point
SELECT 'point_1', ST_AsEWKT(ST_GeomFromKML('<kml:Point><kml:coordinates>1,2</kml:coordinates></kml:Point>'));
+-- See http://trac.osgeo.org/postgis/ticket/2372
+SELECT 'point_1a', ST_AsEWKT(ST_GeomFromKML('<kml:Point><kml:coordinates>1 ,2</kml:coordinates></kml:Point>'));
+SELECT 'point_1b', ST_AsEWKT(ST_GeomFromKML('<kml:Point><kml:coordinates>1, 2</kml:coordinates></kml:Point>'));
+SELECT 'point_1c', ST_AsEWKT(ST_GeomFromKML('<kml:Point><kml:coordinates> 1,2</kml:coordinates></kml:Point>'));
+SELECT 'point_1d', ST_AsEWKT(ST_GeomFromKML('<kml:Point><kml:coordinates> 1,2 </kml:coordinates></kml:Point>'));
+
-- ERROR: 2 points
-SELECT 'point_2', ST_AsEWKT(ST_GeomFromKML('<kml:Point><kml:coordinates>1,2 3,4</kml:coordinates></kml:Point>'));
+SELECT 'point_error_1', ST_AsEWKT(ST_GeomFromKML('<kml:Point><kml:coordinates>1,2 3,4</kml:coordinates></kml:Point>'));
-- ERROR: empty point
-SELECT 'point_3', ST_AsEWKT(ST_GeomFromKML('<kml:Point></kml:Point>'));
+SELECT 'point_error_2', ST_AsEWKT(ST_GeomFromKML('<kml:Point></kml:Point>'));
ERROR: invalid KML representation
ERROR: invalid KML representation
point_1|SRID=4326;POINT(1 2)
+point_1a|SRID=4326;POINT(1 2)
+point_1b|SRID=4326;POINT(1 2)
+point_1c|SRID=4326;POINT(1 2)
+point_1d|SRID=4326;POINT(1 2)
ERROR: invalid KML representation
ERROR: invalid KML representation
linestring_1|SRID=4326;LINESTRING(1 2,3 4)
ERROR: invalid KML representation
coordinates_12|SRID=4326;LINESTRING(1 2,3 4)
coordinates_13|SRID=4326;LINESTRING(1 2,3 4)
-ERROR: invalid KML representation
+coordinates_14|SRID=4326;LINESTRING(1 2,3 4)
coordinates_15|SRID=4326;LINESTRING(1 2,3 4)
coordinates_16|SRID=4326;LINESTRING(1 2,3 4)
ERROR: invalid KML representation
double_7|SRID=4326;POINT(1 1.23)
double_8|SRID=4326;POINT(1 1)
ERROR: invalid KML representation
-ERROR: invalid KML representation
-ERROR: invalid KML representation
+double_10|SRID=4326;POINT(1 0.1)
+double_11|SRID=4326;POINT(1 -0.1)
ERROR: invalid KML representation
ERROR: invalid KML representation
ERROR: invalid KML representation