#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#if defined(_WIN32) && !defined(__MINGW32__)
#include "config-msvc.h"
#else
#include "config.h"
#endif
#include <spatialite/sqlite.h>
#include <spatialite/debug.h>
#include <spatialite/gaiageo.h>
#ifdef _WIN32
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define atoll _atoi64
#endif
#if defined(_WIN32) || defined(WIN32)
#include <io.h>
#ifndef isatty
#define isatty _isatty
#endif
#ifndef fileno
#define fileno _fileno
#endif
#endif
#define EWKT_DYN_NONE 0
#define EWKT_DYN_POINT 1
#define EWKT_DYN_LINESTRING 2
#define EWKT_DYN_POLYGON 3
#define EWKT_DYN_RING 4
#define EWKT_DYN_GEOMETRY 5
#define EWKT_DYN_BLOCK 1024
#define YYMINORTYPE EWKT_MINORTYPE
#define YY_CHAR EWKT_YY_CHAR
#define input ewkt_input
#define ParseAlloc ewktParseAlloc
#define ParseFree ewktParseFree
#define ParseStackPeak ewktParseStackPeak
#define Parse ewktParse
#define yyStackEntry ewkt_yyStackEntry
#define yyzerominor ewkt_yyzerominor
#define yy_accept ewkt_yy_accept
#define yy_action ewkt_yy_action
#define yy_base ewkt_yy_base
#define yy_buffer_stack ewkt_yy_buffer_stack
#define yy_buffer_stack_max ewkt_yy_buffer_stack_max
#define yy_buffer_stack_top ewkt_yy_buffer_stack_top
#define yy_c_buf_p ewkt_yy_c_buf_p
#define yy_chk ewkt_yy_chk
#define yy_def ewkt_yy_def
#define yy_default ewkt_yy_default
#define yy_destructor ewkt_yy_destructor
#define yy_ec ewkt_yy_ec
#define yy_fatal_error ewkt_yy_fatal_error
#define yy_find_reduce_action ewkt_yy_find_reduce_action
#define yy_find_shift_action ewkt_yy_find_shift_action
#define yy_get_next_buffer ewkt_yy_get_next_buffer
#define yy_get_previous_state ewkt_yy_get_previous_state
#define yy_init ewkt_yy_init
#define yy_init_globals ewkt_yy_init_globals
#define yy_lookahead ewkt_yy_lookahead
#define yy_meta ewkt_yy_meta
#define yy_nxt ewkt_yy_nxt
#define yy_parse_failed ewkt_yy_parse_failed
#define yy_pop_parser_stack ewkt_yy_pop_parser_stack
#define yy_reduce ewkt_yy_reduce
#define yy_reduce_ofst ewkt_yy_reduce_ofst
#define yy_shift ewkt_yy_shift
#define yy_shift_ofst ewkt_yy_shift_ofst
#define yy_start ewkt_yy_start
#define yy_state_type ewkt_yy_state_type
#define yy_syntax_error ewkt_yy_syntax_error
#define yy_trans_info ewkt_yy_trans_info
#define yy_try_NUL_trans ewkt_yy_try_NUL_trans
#define yyParser ewkt_yyParser
#define yyStackEntry ewkt_yyStackEntry
#define yyStackOverflow ewkt_yyStackOverflow
#define yyRuleInfo ewkt_yyRuleInfo
#define yyunput ewkt_yyunput
#define yyzerominor ewkt_yyzerominor
#define yyTraceFILE ewkt_yyTraceFILE
#define yyTracePrompt ewkt_yyTracePrompt
#define yyTokenName ewkt_yyTokenName
#define yyRuleName ewkt_yyRuleName
#define ParseTrace ewkt_ParseTrace
#define yylex ewky_yylex
#define YY_DECL int yylex (yyscan_t yyscanner)
#include "Ewkt.h"
typedef union
{
double dval;
struct symtab *symp;
} ewkt_yystype;
#define YYSTYPE ewkt_yystype
struct ewkt_dyn_block
{
int type[EWKT_DYN_BLOCK];
void *ptr[EWKT_DYN_BLOCK];
int index;
struct ewkt_dyn_block *next;
};
struct ewkt_data
{
int ewkt_parse_error;
int ewkt_line;
int ewkt_col;
struct ewkt_dyn_block *ewkt_first_dyn_block;
struct ewkt_dyn_block *ewkt_last_dyn_block;
gaiaGeomCollPtr result;
YYSTYPE EwktLval;
};
static struct ewkt_dyn_block *
ewktCreateDynBlock (void)
{
int i;
struct ewkt_dyn_block *p = malloc (sizeof (struct ewkt_dyn_block));
for (i = 0; i < EWKT_DYN_BLOCK; i++)
{
p->type[i] = EWKT_DYN_NONE;
p->ptr[i] = NULL;
}
p->index = 0;
p->next = NULL;
return p;
}
static void
ewktMapDynAlloc (struct ewkt_data *p_data, int type, void *ptr)
{
struct ewkt_dyn_block *p;
if (p_data->ewkt_first_dyn_block == NULL)
{
p = ewktCreateDynBlock ();
p_data->ewkt_first_dyn_block = p;
p_data->ewkt_last_dyn_block = p;
}
if (p_data->ewkt_last_dyn_block->index >= EWKT_DYN_BLOCK)
{
p = ewktCreateDynBlock ();
p_data->ewkt_last_dyn_block->next = p;
p_data->ewkt_last_dyn_block = p;
}
p_data->ewkt_last_dyn_block->type[p_data->ewkt_last_dyn_block->index] =
type;
p_data->ewkt_last_dyn_block->ptr[p_data->ewkt_last_dyn_block->index] = ptr;
p_data->ewkt_last_dyn_block->index++;
}
static void
ewktMapDynClean (struct ewkt_data *p_data, void *ptr)
{
int i;
struct ewkt_dyn_block *p = p_data->ewkt_first_dyn_block;
while (p)
{
for (i = 0; i < EWKT_DYN_BLOCK; i++)
{
switch (p->type[i])
{
case EWKT_DYN_POINT:
case EWKT_DYN_LINESTRING:
case EWKT_DYN_POLYGON:
case EWKT_DYN_RING:
case EWKT_DYN_GEOMETRY:
if (p->ptr[i] == ptr)
{
p->type[i] = EWKT_DYN_NONE;
return;
}
break;
};
}
p = p->next;
}
}
static void
ewktCleanMapDynAlloc (struct ewkt_data *p_data, int clean_all)
{
int i;
struct ewkt_dyn_block *pn;
struct ewkt_dyn_block *p = p_data->ewkt_first_dyn_block;
while (p)
{
if (clean_all)
{
for (i = 0; i < EWKT_DYN_BLOCK; i++)
{
switch (p->type[i])
{
case EWKT_DYN_POINT:
gaiaFreePoint ((gaiaPointPtr) (p->ptr[i]));
break;
case EWKT_DYN_LINESTRING:
gaiaFreeLinestring ((gaiaLinestringPtr)
(p->ptr[i]));
break;
case EWKT_DYN_POLYGON:
gaiaFreePolygon ((gaiaPolygonPtr) (p->ptr[i]));
break;
case EWKT_DYN_RING:
gaiaFreeRing ((gaiaRingPtr) (p->ptr[i]));
break;
case EWKT_DYN_GEOMETRY:
gaiaFreeGeomColl ((gaiaGeomCollPtr) (p->ptr[i]));
break;
};
}
}
pn = p->next;
free (p);
p = pn;
}
}
static int
ewktCheckValidity (gaiaGeomCollPtr geom)
{
gaiaPointPtr pt;
gaiaLinestringPtr ln;
gaiaPolygonPtr pg;
gaiaRingPtr rng;
int ib;
int entities = 0;
pt = geom->FirstPoint;
while (pt)
{
entities++;
pt = pt->Next;
}
ln = geom->FirstLinestring;
while (ln)
{
if (ln->Points < 2)
return 0;
entities++;
ln = ln->Next;
}
pg = geom->FirstPolygon;
while (pg)
{
rng = pg->Exterior;
if (rng->Points < 4)
return 0;
for (ib = 0; ib < pg->NumInteriors; ib++)
{
rng = pg->Interiors + ib;
if (rng->Points < 4)
return 0;
}
entities++;
pg = pg->Next;
}
if (!entities)
return 0;
return 1;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromPoint (struct ewkt_data *p_data, gaiaPointPtr point)
{
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomColl ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINT;
gaiaAddPointToGeomColl (geom, point->X, point->Y);
ewktMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromPointZ (struct ewkt_data *p_data, gaiaPointPtr point)
{
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYZ ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTZ;
gaiaAddPointToGeomCollXYZ (geom, point->X, point->Y, point->Z);
ewktMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromPointM (struct ewkt_data *p_data, gaiaPointPtr point)
{
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTM;
gaiaAddPointToGeomCollXYM (geom, point->X, point->Y, point->M);
ewktMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromPointZM (struct ewkt_data *p_data, gaiaPointPtr point)
{
gaiaGeomCollPtr geom = NULL;
geom = gaiaAllocGeomCollXYZM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POINTZM;
gaiaAddPointToGeomCollXYZM (geom, point->X, point->Y, point->Z, point->M);
ewktMapDynClean (p_data, point);
gaiaFreePoint (point);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromLinestring (struct ewkt_data *p_data,
gaiaLinestringPtr line)
{
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
geom = gaiaAllocGeomColl ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
gaiaGetPoint (line->Coords, iv, &x, &y);
gaiaSetPoint (line2->Coords, iv, x, y);
}
ewktMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromLinestringZ (struct ewkt_data *p_data,
gaiaLinestringPtr line)
{
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double z;
geom = gaiaAllocGeomCollXYZ ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z);
gaiaSetPointXYZ (line2->Coords, iv, x, y, z);
}
ewktMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromLinestringM (struct ewkt_data *p_data,
gaiaLinestringPtr line)
{
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double m;
geom = gaiaAllocGeomCollXYM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
gaiaGetPointXYM (line->Coords, iv, &x, &y, &m);
gaiaSetPointXYM (line2->Coords, iv, x, y, m);
}
ewktMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaGeomCollPtr
gaiaEwktGeometryFromLinestringZM (struct ewkt_data *p_data,
gaiaLinestringPtr line)
{
gaiaGeomCollPtr geom = NULL;
gaiaLinestringPtr line2;
int iv;
double x;
double y;
double z;
double m;
geom = gaiaAllocGeomCollXYZM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_LINESTRING;
line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
for (iv = 0; iv < line2->Points; iv++)
{
gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m);
gaiaSetPointXYZM (line2->Coords, iv, x, y, z, m);
}
ewktMapDynClean (p_data, line);
gaiaFreeLinestring (line);
return geom;
}
static gaiaPointPtr
ewkt_point_xy (struct ewkt_data *p_data, double *x, double *y)
{
gaiaPointPtr pt = gaiaAllocPoint (*x, *y);
ewktMapDynAlloc (p_data, EWKT_DYN_POINT, pt);
return pt;
}
static gaiaPointPtr
ewkt_point_xyz (struct ewkt_data *p_data, double *x, double *y, double *z)
{
gaiaPointPtr pt = gaiaAllocPointXYZ (*x, *y, *z);
ewktMapDynAlloc (p_data, EWKT_DYN_POINT, pt);
return pt;
}
static gaiaPointPtr
ewkt_point_xym (struct ewkt_data *p_data, double *x, double *y, double *m)
{
gaiaPointPtr pt = gaiaAllocPointXYM (*x, *y, *m);
ewktMapDynAlloc (p_data, EWKT_DYN_POINT, pt);
return pt;
}
gaiaPointPtr
ewkt_point_xyzm (struct ewkt_data * p_data, double *x, double *y, double *z,
double *m)
{
gaiaPointPtr pt = gaiaAllocPointXYZM (*x, *y, *z, *m);
ewktMapDynAlloc (p_data, EWKT_DYN_POINT, pt);
return pt;
}
static gaiaGeomCollPtr
ewkt_buildGeomFromPoint (struct ewkt_data *p_data, gaiaPointPtr point)
{
switch (point->DimensionModel)
{
case GAIA_XY:
return gaiaEwktGeometryFromPoint (p_data, point);
case GAIA_XY_Z:
return gaiaEwktGeometryFromPointZ (p_data, point);
case GAIA_XY_M:
return gaiaEwktGeometryFromPointM (p_data, point);
case GAIA_XY_Z_M:
return gaiaEwktGeometryFromPointZM (p_data, point);
}
return NULL;
}
static gaiaLinestringPtr
ewkt_linestring_xy (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestring (points);
ewktMapDynAlloc (p_data, EWKT_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPoint (linestring->Coords, i, p->X, p->Y);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
static gaiaLinestringPtr
ewkt_linestring_xyz (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYZ (points);
ewktMapDynAlloc (p_data, EWKT_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYZ (linestring->Coords, i, p->X, p->Y, p->Z);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
static gaiaLinestringPtr
ewkt_linestring_xym (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYM (points);
ewktMapDynAlloc (p_data, EWKT_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYM (linestring->Coords, i, p->X, p->Y, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
static gaiaLinestringPtr
ewkt_linestring_xyzm (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
int points = 0;
int i = 0;
gaiaLinestringPtr linestring;
while (p != NULL)
{
p = p->Next;
points++;
}
linestring = gaiaAllocLinestringXYZM (points);
ewktMapDynAlloc (p_data, EWKT_DYN_LINESTRING, linestring);
p = first;
while (p != NULL)
{
gaiaSetPointXYZM (linestring->Coords, i, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
i++;
}
return linestring;
}
static gaiaGeomCollPtr
ewkt_buildGeomFromLinestring (struct ewkt_data *p_data, gaiaLinestringPtr line)
{
switch (line->DimensionModel)
{
case GAIA_XY:
return gaiaEwktGeometryFromLinestring (p_data, line);
case GAIA_XY_Z:
return gaiaEwktGeometryFromLinestringZ (p_data, line);
case GAIA_XY_M:
return gaiaEwktGeometryFromLinestringM (p_data, line);
case GAIA_XY_Z_M:
return gaiaEwktGeometryFromLinestringZM (p_data, line);
}
return NULL;
}
static int
ewkt_count_points (gaiaPointPtr first)
{
gaiaPointPtr p = first;
int numpoints = 0;
while (p != NULL)
{
numpoints++;
p = p->Next;
}
return numpoints;
}
static gaiaRingPtr
ewkt_ring_xy (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
if (first == NULL)
return NULL;
numpoints = ewkt_count_points (first);
if (numpoints < 4)
return NULL;
ring = gaiaAllocRing (numpoints);
if (ring == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_RING, ring);
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPoint (ring->Coords, index, p->X, p->Y);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
static gaiaRingPtr
ewkt_ring_xyz (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
if (first == NULL)
return NULL;
numpoints = ewkt_count_points (first);
if (numpoints < 4)
return NULL;
ring = gaiaAllocRingXYZ (numpoints);
if (ring == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_RING, ring);
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYZ (ring->Coords, index, p->X, p->Y, p->Z);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
static gaiaRingPtr
ewkt_ring_xym (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
if (first == NULL)
return NULL;
numpoints = ewkt_count_points (first);
if (numpoints < 4)
return NULL;
ring = gaiaAllocRingXYM (numpoints);
if (ring == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_RING, ring);
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYM (ring->Coords, index, p->X, p->Y, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
static gaiaRingPtr
ewkt_ring_xyzm (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaRingPtr ring = NULL;
int numpoints;
int index;
if (first == NULL)
return NULL;
numpoints = ewkt_count_points (first);
if (numpoints < 4)
return NULL;
ring = gaiaAllocRingXYZM (numpoints);
if (ring == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_RING, ring);
p = first;
for (index = 0; index < numpoints; index++)
{
gaiaSetPointXYZM (ring->Coords, index, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return ring;
}
static gaiaPolygonPtr
ewkt_polygon_any_type (struct ewkt_data *p_data, gaiaRingPtr first)
{
gaiaRingPtr p;
gaiaRingPtr p_n;
gaiaPolygonPtr polygon;
if (first == NULL)
return NULL;
polygon = gaiaCreatePolygon (first);
if (polygon == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_POLYGON, polygon);
p = first;
while (p != NULL)
{
p_n = p->Next;
ewktMapDynClean (p_data, p);
if (p == first)
gaiaFreeRing (p);
else
gaiaAddRingToPolyg (polygon, p);
p = p_n;
}
return polygon;
}
static gaiaPolygonPtr
ewkt_polygon_xy (struct ewkt_data *p_data, gaiaRingPtr first)
{
return ewkt_polygon_any_type (p_data, first);
}
static gaiaPolygonPtr
ewkt_polygon_xyz (struct ewkt_data *p_data, gaiaRingPtr first)
{
return ewkt_polygon_any_type (p_data, first);
}
static gaiaPolygonPtr
ewkt_polygon_xym (struct ewkt_data *p_data, gaiaRingPtr first)
{
return ewkt_polygon_any_type (p_data, first);
}
static gaiaPolygonPtr
ewkt_polygon_xyzm (struct ewkt_data *p_data, gaiaRingPtr first)
{
return ewkt_polygon_any_type (p_data, first);
}
static gaiaGeomCollPtr
ewkt_buildGeomFromPolygon (struct ewkt_data *p_data, gaiaPolygonPtr polygon)
{
gaiaGeomCollPtr geom = NULL;
if (polygon == NULL)
{
return NULL;
}
switch (polygon->DimensionModel)
{
case GAIA_XY:
geom = gaiaAllocGeomColl ();
break;
case GAIA_XY_Z:
geom = gaiaAllocGeomCollXYZ ();
break;
case GAIA_XY_M:
geom = gaiaAllocGeomCollXYM ();
break;
case GAIA_XY_Z_M:
geom = gaiaAllocGeomCollXYZM ();
break;
}
if (geom == NULL)
{
return NULL;
}
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_POLYGON;
geom->FirstPolygon = polygon;
while (polygon != NULL)
{
ewktMapDynClean (p_data, polygon);
geom->LastPolygon = polygon;
polygon = polygon->Next;
}
return geom;
}
static gaiaGeomCollPtr
ewkt_multipoint_xy (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
if (first == NULL)
return NULL;
geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
while (p != NULL)
{
gaiaAddPointToGeomColl (geom, p->X, p->Y);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
static gaiaGeomCollPtr
ewkt_multipoint_xyz (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
if (first == NULL)
return NULL;
geom = gaiaAllocGeomCollXYZ ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
while (p != NULL)
{
gaiaAddPointToGeomCollXYZ (geom, p->X, p->Y, p->Z);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
static gaiaGeomCollPtr
ewkt_multipoint_xym (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
if (first == NULL)
return NULL;
geom = gaiaAllocGeomCollXYM ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
while (p != NULL)
{
gaiaAddPointToGeomCollXYM (geom, p->X, p->Y, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
static gaiaGeomCollPtr
ewkt_multipoint_xyzm (struct ewkt_data *p_data, gaiaPointPtr first)
{
gaiaPointPtr p = first;
gaiaPointPtr p_n;
gaiaGeomCollPtr geom = NULL;
if (first == NULL)
return NULL;
geom = gaiaAllocGeomCollXYZM ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOINT;
while (p != NULL)
{
gaiaAddPointToGeomCollXYZM (geom, p->X, p->Y, p->Z, p->M);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePoint (p);
p = p_n;
}
return geom;
}
static gaiaGeomCollPtr
ewkt_multilinestring_xy (struct ewkt_data *p_data, gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomColl ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
static gaiaGeomCollPtr
ewkt_multilinestring_xyz (struct ewkt_data *p_data, gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYZ ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_Z;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
static gaiaGeomCollPtr
ewkt_multilinestring_xym (struct ewkt_data *p_data, gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_M;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
static gaiaGeomCollPtr
ewkt_multilinestring_xyzm (struct ewkt_data *p_data, gaiaLinestringPtr first)
{
gaiaLinestringPtr p = first;
gaiaLinestringPtr p_n;
gaiaLinestringPtr new_line;
gaiaGeomCollPtr a = gaiaAllocGeomCollXYZM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, a);
a->DeclaredType = GAIA_MULTILINESTRING;
a->DimensionModel = GAIA_XY_Z_M;
while (p)
{
new_line = gaiaAddLinestringToGeomColl (a, p->Points);
gaiaCopyLinestringCoords (new_line, p);
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreeLinestring (p);
p = p_n;
}
return a;
}
static gaiaGeomCollPtr
ewkt_multipolygon_xy (struct ewkt_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
static gaiaGeomCollPtr
ewkt_multipolygon_xyz (struct ewkt_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYZ ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
static gaiaGeomCollPtr
ewkt_multipolygon_xym (struct ewkt_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
static gaiaGeomCollPtr
ewkt_multipolygon_xyzm (struct ewkt_data *p_data, gaiaPolygonPtr first)
{
gaiaPolygonPtr p = first;
gaiaPolygonPtr p_n;
int i = 0;
gaiaPolygonPtr new_polyg;
gaiaRingPtr i_ring;
gaiaRingPtr o_ring;
gaiaGeomCollPtr geom = gaiaAllocGeomCollXYZM ();
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_MULTIPOLYGON;
while (p)
{
i_ring = p->Exterior;
new_polyg =
gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
o_ring = new_polyg->Exterior;
gaiaCopyRingCoords (o_ring, i_ring);
for (i = 0; i < new_polyg->NumInteriors; i++)
{
i_ring = p->Interiors + i;
o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
gaiaCopyRingCoords (o_ring, i_ring);
}
p_n = p->Next;
ewktMapDynClean (p_data, p);
gaiaFreePolygon (p);
p = p_n;
}
return geom;
}
static void
ewkt_geomColl_common (struct ewkt_data *p_data, gaiaGeomCollPtr org,
gaiaGeomCollPtr dst)
{
gaiaGeomCollPtr p = org;
gaiaGeomCollPtr p_n;
gaiaPointPtr pt;
gaiaPointPtr pt_n;
gaiaLinestringPtr ln;
gaiaLinestringPtr ln_n;
gaiaPolygonPtr pg;
gaiaPolygonPtr pg_n;
while (p)
{
pt = p->FirstPoint;
while (pt)
{
pt_n = pt->Next;
pt->Next = NULL;
if (dst->FirstPoint == NULL)
dst->FirstPoint = pt;
if (dst->LastPoint != NULL)
dst->LastPoint->Next = pt;
dst->LastPoint = pt;
pt = pt_n;
}
ln = p->FirstLinestring;
while (ln)
{
ln_n = ln->Next;
ln->Next = NULL;
if (dst->FirstLinestring == NULL)
dst->FirstLinestring = ln;
if (dst->LastLinestring != NULL)
dst->LastLinestring->Next = ln;
dst->LastLinestring = ln;
ln = ln_n;
}
pg = p->FirstPolygon;
while (pg)
{
pg_n = pg->Next;
pg->Next = NULL;
if (dst->FirstPolygon == NULL)
dst->FirstPolygon = pg;
if (dst->LastPolygon != NULL)
dst->LastPolygon->Next = pg;
dst->LastPolygon = pg;
pg = pg_n;
}
p_n = p->Next;
p->FirstPoint = NULL;
p->LastPoint = NULL;
p->FirstLinestring = NULL;
p->LastLinestring = NULL;
p->FirstPolygon = NULL;
p->LastPolygon = NULL;
ewktMapDynClean (p_data, p);
gaiaFreeGeomColl (p);
p = p_n;
}
}
static gaiaGeomCollPtr
ewkt_geomColl_xy (struct ewkt_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY;
ewkt_geomColl_common (p_data, first, geom);
return geom;
}
static gaiaGeomCollPtr
ewkt_geomColl_xyz (struct ewkt_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_Z;
ewkt_geomColl_common (p_data, first, geom);
return geom;
}
static gaiaGeomCollPtr
ewkt_geomColl_xym (struct ewkt_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_M;
ewkt_geomColl_common (p_data, first, geom);
return geom;
}
static gaiaGeomCollPtr
ewkt_geomColl_xyzm (struct ewkt_data *p_data, gaiaGeomCollPtr first)
{
gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
if (geom == NULL)
return NULL;
ewktMapDynAlloc (p_data, EWKT_DYN_GEOMETRY, geom);
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
geom->DimensionModel = GAIA_XY_Z_M;
ewkt_geomColl_common (p_data, first, geom);
return geom;
}
#include "Ewkt.c"
#undef yy_accept
#define yy_accept yy_ewkt_flex_accept
#include "lex.Ewkt.c"
#line 3 "lex.Ewkt.c"
#define YY_INT_ALIGNED short int
typedef struct ewktFlexTokenStruct
{
double value;
struct ewktFlexTokenStruct *Next;
} ewktFlexToken;
static int
ewkt_cleanup (ewktFlexToken * token)
{
ewktFlexToken *ptok;
ewktFlexToken *ptok_n;
if (token == NULL)
return 0;
ptok = token;
while (ptok)
{
ptok_n = ptok->Next;
free (ptok);
ptok = ptok_n;
}
return 0;
}
static int
findEwktSrid (const char *buffer, int *base_offset)
{
char dummy[1024];
char *out;
const char *in = buffer;
int end = -1;
int i;
*base_offset = 0;
while (*in != '\0')
{
if (*in == ';')
{
end = in - buffer;
break;
}
in++;
}
if (end < 0)
return -1;
in = buffer;
out = dummy;
for (i = 0; i < end; i++)
{
char c = *in;
if (c == ' ' || c == '\t' || c == '\n')
{
in++;
continue;
}
*out++ = *in++;
}
*out = '\0';
if (strncasecmp (dummy, "SRID=", 5) != 0)
return -1;
for (i = 5; i < (int) strlen (dummy); i++)
{
if (i == 5)
{
if (dummy[i] == '-' || dummy[i] == '+')
continue;
}
if (dummy[i] >= '0' && dummy[i] <= '9')
continue;
return -1;
}
*base_offset = end + 1;
return atoi (dummy + 5);
}
gaiaGeomCollPtr
gaiaParseEWKT (const unsigned char *dirty_buffer)
{
void *pParser = ParseAlloc (malloc);
ewktFlexToken *tokens = malloc (sizeof (ewktFlexToken));
ewktFlexToken *head = tokens;
int yv;
int srid;
int base_offset;
yyscan_t scanner;
struct ewkt_data str_data;
str_data.ewkt_line = 1;
str_data.ewkt_col = 1;
str_data.ewkt_parse_error = 0;
str_data.ewkt_first_dyn_block = NULL;
str_data.ewkt_last_dyn_block = NULL;
str_data.result = NULL;
Ewktlex_init_extra (&str_data, &scanner);
tokens->Next = NULL;
srid = findEwktSrid ((char *) dirty_buffer, &base_offset);
Ewkt_scan_string ((char *) dirty_buffer + base_offset, scanner);
while ((yv = yylex (scanner)) != 0)
{
if (yv == -1)
{
str_data.ewkt_parse_error = 1;
break;
}
tokens->Next = malloc (sizeof (ewktFlexToken));
tokens->Next->Next = NULL;
tokens->Next->value = str_data.EwktLval.dval;
Parse (pParser, yv, &(tokens->Next->value), &str_data);
tokens = tokens->Next;
}
Parse (pParser, EWKT_NEWLINE, 0, &str_data);
ParseFree (pParser, free);
Ewktlex_destroy (scanner);
tokens->Next = NULL;
ewkt_cleanup (head);
if (str_data.ewkt_parse_error)
{
if (str_data.result)
{
gaiaFreeGeomColl (str_data.result);
ewktCleanMapDynAlloc (&str_data, 0);
}
else
{
ewktCleanMapDynAlloc (&str_data, 1);
}
return NULL;
}
ewktCleanMapDynAlloc (&str_data, 0);
if (str_data.result == NULL)
return NULL;
if (!ewktCheckValidity (str_data.result))
{
gaiaFreeGeomColl (str_data.result);
return NULL;
}
gaiaMbrGeometry (str_data.result);
str_data.result->Srid = srid;
return str_data.result;
}
#undef YYNOCODE
#undef YYNSTATE
#undef YYNRULE
#undef YY_SHIFT_MAX
#undef YY_SHIFT_USE_DFLT
#undef YY_REDUCE_USE_DFLT
#undef YY_REDUCE_MAX
#undef YY_FLUSH_BUFFER
#undef YY_DO_BEFORE_ACTION
#undef YY_NUM_RULES
#undef YY_END_OF_BUFFER
#undef YY_END_FILE
#undef YYACTIONTYPE
#undef YY_SZ_ACTTAB
#undef YY_NEW_FILE
#undef BEGIN
#undef YY_START
#undef YY_CURRENT_BUFFER
#undef YY_CURRENT_BUFFER_LVALUE
#undef YY_STATE_BUF_SIZE
#undef YY_DECL
#undef YY_FATAL_ERROR
#undef YYMINORTYPE
#undef YY_CHAR
#undef YYSTYPE
#undef input
#undef ParseAlloc
#undef ParseFree
#undef ParseStackPeak
#undef Parse
#undef yyalloc
#undef yyfree
#undef yyin
#undef yyleng
#undef yyless
#undef yylex
#undef yylineno
#undef yyout
#undef yyrealloc
#undef yyrestart
#undef yyStackEntry
#undef yytext
#undef yywrap
#undef yyzerominor
#undef yy_accept
#undef yy_action
#undef yy_base
#undef yy_buffer_stack
#undef yy_buffer_stack_max
#undef yy_buffer_stack_top
#undef yy_c_buf_p
#undef yy_chk
#undef yy_create_buffer
#undef yy_def
#undef yy_default
#undef yy_delete_buffer
#undef yy_destructor
#undef yy_ec
#undef yy_fatal_error
#undef yy_find_reduce_action
#undef yy_find_shift_action
#undef yy_flex_debug
#undef yy_flush_buffer
#undef yy_get_next_buffer
#undef yy_get_previous_state
#undef yy_init
#undef yy_init_buffer
#undef yy_init_globals
#undef yy_load_buffer
#undef yy_load_buffer_state
#undef yy_lookahead
#undef yy_meta
#undef yy_new_buffer
#undef yy_nxt
#undef yy_parse_failed
#undef yy_pop_parser_stack
#undef yy_reduce
#undef yy_reduce_ofst
#undef yy_set_bol
#undef yy_set_interactive
#undef yy_shift
#undef yy_shift_ofst
#undef yy_start
#undef yy_state_type
#undef yy_switch_to_buffer
#undef yy_syntax_error
#undef yy_trans_info
#undef yy_try_NUL_trans
#undef yyParser
#undef yyStackEntry
#undef yyStackOverflow
#undef yyRuleInfo
#undef yytext_ptr
#undef yyunput
#undef yyzerominor
#undef ParseARG_SDECL
#undef ParseARG_PDECL
#undef ParseARG_FETCH
#undef ParseARG_STORE
#undef REJECT
#undef yymore
#undef YY_MORE_ADJ
#undef YY_RESTORE_YY_MORE_OFFSET
#undef YY_LESS_LINENO
#undef yyTracePrompt
#undef yyTraceFILE
#undef yyTokenName
#undef yyRuleName
#undef ParseTrace
#undef yylex
#undef YY_DECL