Skip to content

Commit

Permalink
Continue with new WKB parser. Change signature of RHR "right hand rul…
Browse files Browse the repository at this point in the history
…e" functions to "clockwise" to avoid misinterpretations of orientation rules.

git-svn-id: http://svn.osgeo.org/postgis/trunk@6036 b70326c6-7e19-0410-871a-916f4a2858ee
  • Loading branch information
pramsey committed Oct 3, 2010
1 parent b3c1790 commit 2d07d7e
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 76 deletions.
1 change: 1 addition & 0 deletions liblwgeom/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ SA_OBJS = \
lwtin.o \
lwout_wkt.o \
lwout_wkb.o \
lwin_wkb.o \
lwutil.o \
lwhomogenize.o \
lwalgorithm.o \
Expand Down
4 changes: 2 additions & 2 deletions liblwgeom/cunit/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ CUNIT_CPPFLAGS=@CUNIT_CPPFLAGS@ -I..
OBJS= \
cu_algorithm.o \
cu_print.o \
cu_wkt.o \
cu_wkb.o \
cu_geodetic.o \
cu_measures.o \
cu_libgeom.o \
cu_surface.o \
cu_homogenize.o \
cu_out_wkt.o \
cu_out_wkb.o \
cu_out_gml.o \
cu_out_kml.o \
cu_out_geojson.o \
Expand Down
File renamed without changes.
File renamed without changes.
70 changes: 41 additions & 29 deletions liblwgeom/liblwgeom.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,14 +312,14 @@ POINT4D;
*/
typedef struct
{
/* array of POINT 2D, 3D or 4D. probably missaligned. */
/* array of POINT 2D, 3D or 4D. possibly missaligned. */
uchar *serialized_pointlist;

/* use TYPE_* macros to handle */
uchar dims;

int npoints;
int maxpoints;
int npoints; /* how many points we are currently storing */
int maxpoints; /* how many points we have space for in serialized_pointlist */
}
POINTARRAY;

Expand Down Expand Up @@ -396,8 +396,8 @@ typedef struct
uchar type; /* POLYGONTYPE */
BOX2DFLOAT4 *bbox;
uint32 SRID;
int nrings;
int maxrings;
int nrings; /* how many rings we are currently storing */
int maxrings; /* how many rings we have space for in **rings */
POINTARRAY **rings; /* list of rings (list of points) */
}
LWPOLY; /* "light-weight polygon" */
Expand All @@ -408,8 +408,8 @@ typedef struct
uchar type;
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWPOINT **geoms;
}
LWMPOINT;
Expand All @@ -420,8 +420,8 @@ typedef struct
uchar type;
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWLINE **geoms;
}
LWMLINE;
Expand All @@ -432,8 +432,8 @@ typedef struct
uchar type;
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWPOLY **geoms;
}
LWMPOLY;
Expand All @@ -444,8 +444,8 @@ typedef struct
uchar type;
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWGEOM **geoms;
}
LWCOLLECTION;
Expand All @@ -466,8 +466,8 @@ typedef struct
uchar type; /* COMPOUNDTYPE */
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWGEOM **geoms;
}
LWCOMPOUND; /* "light-weight compound line" */
Expand All @@ -478,8 +478,8 @@ typedef struct
uchar type; /* CURVEPOLYTYPE */
BOX2DFLOAT4 *bbox;
uint32 SRID;
int nrings;
int maxrings;
int nrings; /* how many rings we are currently storing */
int maxrings; /* how many rings we have space for in **rings */
LWGEOM **rings; /* list of rings (list of points) */
}
LWCURVEPOLY; /* "light-weight polygon" */
Expand All @@ -490,8 +490,8 @@ typedef struct
uchar type;
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWGEOM **geoms;
}
LWMCURVE;
Expand All @@ -502,8 +502,8 @@ typedef struct
uchar type;
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWGEOM **geoms;
}
LWMSURFACE;
Expand All @@ -514,8 +514,8 @@ typedef struct
uchar type;
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWPOLY **geoms;
}
LWPSURFACE;
Expand All @@ -536,8 +536,8 @@ typedef struct
uchar type;
BOX2DFLOAT4 *bbox;
uint32 SRID;
int ngeoms;
int maxgeoms;
int ngeoms; /* how many geometries we are currently storing */
int maxgeoms; /* how many geometries we have space for in **geoms */
LWTRIANGLE **geoms;
}
LWTIN;
Expand Down Expand Up @@ -908,6 +908,13 @@ extern void lwpoly_serialize_buf(LWPOLY *poly, uchar *buf, size_t *size);
*/
extern BOX3D *lwpoly_compute_box3d(LWPOLY *poly);

/**
* Add a ring, allocating extra space if necessary. The polygon takes
* ownership of the passed point array.
*/
extern int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa);


/******************************************************************
* LWTRIANGLE functions
******************************************************************/
Expand Down Expand Up @@ -1347,9 +1354,6 @@ extern void lwgeom_reverse(LWGEOM *lwgeom);
extern void lwline_reverse(LWLINE *line);
extern void lwpoly_reverse(LWPOLY *poly);
extern void lwtriangle_reverse(LWTRIANGLE *triangle);
extern void lwpoly_forceRHR(LWPOLY *poly);
extern void lwtriangle_forceRHR(LWTRIANGLE *triangle);
extern void lwgeom_force_rhr(LWGEOM *lwgeom);
extern char* lwgeom_summary(const LWGEOM *lwgeom, int offset);
extern const char *lwtype_name(int type);
extern int ptarray_compute_box2d_p(const POINTARRAY *pa, BOX2DFLOAT4 *result);
Expand All @@ -1368,6 +1372,14 @@ extern int lwcompound_is_closed(LWCOMPOUND *curve);
extern int lwpsurface_is_closed(LWPSURFACE *psurface);
extern int lwtin_is_closed(LWTIN *tin);

/**
* Ensure the outer ring is clockwise oriented and all inner rings
* are counter-clockwise.
*/
extern void lwgeom_force_clockwise(LWGEOM *lwgeom);
extern void lwpoly_force_clockwise(LWPOLY *poly);
extern void lwtriangle_force_clockwise(LWTRIANGLE *triangle);


extern void interpolate_point4d(POINT4D *A, POINT4D *B, POINT4D *I, double F);

Expand Down Expand Up @@ -1484,7 +1496,7 @@ extern const char *lwgeom_typeflags(uchar type);
extern POINTARRAY* ptarray_construct(char hasz, char hasm, uint32 npoints);

/* Construct a pointarray, *copying* in the data from ptlist */
extern POINTARRAY* ptarray_construct_copy_data(char hasz, char hasm, uint32 npoints, uchar *ptlist);
extern POINTARRAY* ptarray_construct_copy_data(char hasz, char hasm, uint32 npoints, const uchar *ptlist);

/*
* extern POINTARRAY *ptarray_construct2d(uint32 npoints, const POINT2D *pts);
Expand Down
8 changes: 4 additions & 4 deletions liblwgeom/lwgeom.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,19 +173,19 @@ lwgeom_serialize(LWGEOM *lwgeom)

/** Force Right-hand-rule on LWGEOM polygons **/
void
lwgeom_force_rhr(LWGEOM *lwgeom)
lwgeom_force_clockwise(LWGEOM *lwgeom)
{
LWCOLLECTION *coll;
int i;

switch (TYPE_GETTYPE(lwgeom->type))
{
case POLYGONTYPE:
lwpoly_forceRHR((LWPOLY *)lwgeom);
lwpoly_force_clockwise((LWPOLY *)lwgeom);
return;

case TRIANGLETYPE:
lwtriangle_forceRHR((LWTRIANGLE *)lwgeom);
lwtriangle_force_clockwise((LWTRIANGLE *)lwgeom);
return;

/* Not handle POLYHEDRALSURFACE and TIN
Expand All @@ -194,7 +194,7 @@ lwgeom_force_rhr(LWGEOM *lwgeom)
case COLLECTIONTYPE:
coll = (LWCOLLECTION *)lwgeom;
for (i=0; i<coll->ngeoms; i++)
lwgeom_force_rhr(coll->geoms[i]);
lwgeom_force_clockwise(coll->geoms[i]);
return;
}
}
Expand Down
58 changes: 30 additions & 28 deletions liblwgeom/lwin_wkb.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@

#include "libgeom.h"


/**
* Used for passing the parse state between the parsing functions.
*/
typedef struct
{
const char *wkb; /* Points to start of WKB */
size_t wkb_size; /* Expected size of WKB */
int swap_bytes; /* Do an endian flip? */
int check; /* Simple validity checks on geometries */
uint32 lwtype; /* Current type we are handling */
uint32 srid; /* Current SRID we are handling */
int has_z; /* Z? */
int has_m; /* M? */
int has_srid; /* SRID? */
const char *pos; /* Current parse position */
} wkb_parse_state;

/**********************************************************************/

static char hex2char[256] = {
Expand Down Expand Up @@ -55,8 +73,8 @@ static char* bytes_from_hexbytes(const char *hexbuf, size_t hexsize)

for( i = 0; i < hexsize/2; i++ )
{
h1 = hex2char[hexbuf[2*i]];
h2 = hex2char[hexbuf[2*i+1]];
h1 = hex2char[(int)hexbuf[2*i]];
h2 = hex2char[(int)hexbuf[2*i+1]];
if( h1 < 0 )
lwerror("Invalid hex character (%c) encountered", hexbuf[i]);
if( h2 < 0 )
Expand All @@ -71,22 +89,7 @@ static char* bytes_from_hexbytes(const char *hexbuf, size_t hexsize)



/**
* Used for passing the parse state between the parsing functions.
*/
typedef struct
{
const char *wkb; /* Points to start of WKB */
const size_t wkb_size; /* Expected size of WKB */
int swap_bytes; /* Do an endian flip? */
int check; /* Simple validity checks on geometries */
uint32 lwtype; /* Current type we are handling */
uint32 srid; /* Current SRID we are handling */
int has_z; /* Z? */
int has_m; /* M? */
int has_srid; /* SRID? */
const char *pos; /* Current parse position */
} wkb_parse_state;


/**
* Check that we are not about to read off the end of the WKB
Expand Down Expand Up @@ -208,7 +211,7 @@ static uint32 integer_from_wkb_state(wkb_parse_state *s)

wkb_parse_state_check(s, WKB_INT_SIZE);

i = *((uint32*)(s->pos));
memcpy(&i, s->pos, WKB_INT_SIZE);

/* Swap? Copy into a stack-allocated integer. */
if( s->swap_bytes )
Expand Down Expand Up @@ -237,7 +240,7 @@ static double double_from_wkb_state(wkb_parse_state *s)

wkb_parse_state_check(s, WKB_DOUBLE_SIZE);

d = *((double*)(s->pos));
memcpy(&d, s->pos, WKB_DOUBLE_SIZE);

/* Swap? Copy into a stack-allocated integer. */
if( s->swap_bytes )
Expand Down Expand Up @@ -277,16 +280,15 @@ static POINTARRAY* ptarray_from_wkb_state(wkb_parse_state *s)
wkb_parse_state_check(s, npoints * ndims * WKB_DOUBLE_SIZE);

/* If we're in a native endianness, we can just copy the data directly! */
if( ! s->flip_bytes )
if( ! s->swap_bytes )
{
pa = ptarray_construct_copy_data(s->has_z, s->has_m, npoints, s->pos);
s->pos += pa->npoints * TYPE_NDIMS(pa->dims);
s->pos += npoints * ndims * WKB_DOUBLE_SIZE;
}
/* Otherwise we have to read each double, separately */
else
{
int i = 0;
double d;
double *dlist;
pa = ptarray_construct(s->has_z, s->has_m, npoints);
dlist = (double*)(pa->serialized_pointlist);
Expand All @@ -304,7 +306,7 @@ static POINTARRAY* ptarray_from_wkb_state(wkb_parse_state *s)
*/
static LWLINE* lwline_from_wkb_state(wkb_parse_state *s)
{
POINTARRAY pa = ptarray_from_wkb_state(s);
POINTARRAY *pa = ptarray_from_wkb_state(s);

if( pa == NULL )
return lwline_construct_empty(s->has_z, s->has_m, s->srid);
Expand All @@ -323,7 +325,7 @@ static LWLINE* lwline_from_wkb_state(wkb_parse_state *s)
*/
static LWCIRCSTRING* lwcircstring_from_wkb_state(wkb_parse_state *s)
{
POINTARRAY pa = ptarray_from_wkb_state(s);
POINTARRAY *pa = ptarray_from_wkb_state(s);

if( pa == NULL )
return lwcircstring_construct_empty(s->has_z, s->has_m, s->srid);
Expand Down Expand Up @@ -357,10 +359,11 @@ static LWPOLY* lwpoly_from_wkb_state(wkb_parse_state *s)

for( i = 0; i < nrings; i++ )
{
POINTARRAY pa = ptarray_from_wkb_state(s);
POINTARRAY *pa = ptarray_from_wkb_state(s);
if( pa == NULL )
continue;
lwpoly_add_ring(poly, pa);
if ( lwpoly_add_ring(poly, pa) == LW_FALSE )
lwerror("Unable to add ring to polygon");
}
return poly;
}
Expand Down Expand Up @@ -417,7 +420,6 @@ static LWGEOM* lwgeom_from_wkb_state(wkb_parse_state *s)
/** TODO TODO
* lw*_construct_empty() for all types
* add maxrings, maxpoints, maxgeoms to all lwtypes
* lwpoly_add_ring()
* lwcollection_add_geom()
* ptarray_add_point()
* reorganize header file for clarity
Expand Down
Loading

0 comments on commit 2d07d7e

Please sign in to comment.