[svn-commits] r181 - branches/geospatial/wkt-wkb
thich01 at ingres.com
thich01 at ingres.com
Thu Aug 7 13:29:06 PDT 2008
Author: thich01
Date: 2008-08-07 13:29:06 -0700 (Thu, 07 Aug 2008)
New Revision: 181
Modified:
branches/geospatial/wkt-wkb/main.c
branches/geospatial/wkt-wkb/makefile
branches/geospatial/wkt-wkb/testgrammar
branches/geospatial/wkt-wkb/wkbOps.c
branches/geospatial/wkt-wkb/wkbOps.h
branches/geospatial/wkt-wkb/wktToWkb.y
Log:
#107 - Clean up the binary stream and parse a stream to text.
Modified: branches/geospatial/wkt-wkb/main.c
===================================================================
--- branches/geospatial/wkt-wkb/main.c 2008-08-07 17:55:29 UTC (rev 180)
+++ branches/geospatial/wkt-wkb/main.c 2008-08-07 20:29:06 UTC (rev 181)
@@ -1,29 +1,45 @@
-//TODO: Make the input stream an argument in what's to become the library.
-//TODO: Allow parser to read only a string as well. Currently only a whole
-// file is parsed.
-
#include <stdio.h>
#include <stdlib.h>
#include "wkbOps.h"
int main(int argc,char *argv[])
{
+ FILE *fp;
char *wkbStream;
size_t streamSize = 0;
+ int parsed = 5;
- if(argc<2)
+ if( argc == 2 )
{
- printf("Please specify the input file\n");
- exit(0);
+ fp = fopen( argv[1],"r" );
+ if( !fp )
+ {
+ parsed = wkbParseString( argv[1], &wkbStream, &streamSize );
+ }
+ else
+ {
+ parsed = wkbParseFile( fp, &wkbStream, &streamSize );
+ fclose( fp );
+ }
+ if( parsed == 0 )
+ {
+ wkbParseBinary( wkbStream, NULL );
+ }
+ else
+ {
+ printf( "Error while parsing %d.\n", parsed );
+ }
+
+ if( wkbStream != NULL )
+ {
+ free( wkbStream );
+ }
}
- FILE *fp=fopen(argv[1],"r");
- if(!fp)
+ else
{
- printf("couldn't open file for reading\n");
- exit(0);
+ printf( "Incorrect arguments.\n" );
+ return 0;
}
- wkbParseFile( fp, wkbStream, &streamSize );
- fclose(fp);
return 1;
}
Modified: branches/geospatial/wkt-wkb/makefile
===================================================================
--- branches/geospatial/wkt-wkb/makefile 2008-08-07 17:55:29 UTC (rev 180)
+++ branches/geospatial/wkt-wkb/makefile 2008-08-07 20:29:06 UTC (rev 181)
@@ -1,8 +1,12 @@
-wktToWkb.o : wktToWkb.l wktToWkb.y
+all : wktToWkb testMain
+
+wktToWkb : wktToWkb.l wktToWkb.y
bison -d -o wktToWkb.tab.c wktToWkb.y
flex -o wktToWkb.Flex.c --header-file=wktToWkb.Flex.h wktToWkb.l
- gcc -Wall -g main.c wktToWkb.Flex.c wktToWkb.tab.c wkbOps.c -ll -o wktToWkb
+ gcc -shared -Wall -g wktToWkb.Flex.c wktToWkb.tab.c wkbOps.c -ll -o libWktToWkb.so.1.0.1
+testMain : wktToWkb
+ gcc -Wall -g -Wl,-rpath,. main.c -l:libWktToWkb.so.1.0.1 -o testMain
clean:
- rm wktToWkb.tab.c wktToWkb.tab.h wktToWkb.Flex.c wktToWkb.Flex.h wktToWkb
+ rm wktToWkb.tab.c wktToWkb.tab.h wktToWkb.Flex.c wktToWkb.Flex.h libWktToWkb.so.1.0.1 testMain
Modified: branches/geospatial/wkt-wkb/testgrammar
===================================================================
--- branches/geospatial/wkt-wkb/testgrammar 2008-08-07 17:55:29 UTC (rev 180)
+++ branches/geospatial/wkt-wkb/testgrammar 2008-08-07 20:29:06 UTC (rev 181)
@@ -1,24 +1,26 @@
- GEOMETRYCOLLECTION(
- POINT(6 10),
- LINESTRING(3 4,10 50,20 25),
- LINESTRING(100 200),
- POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2, 3 2, 3 3, 2 3,2 2)),
- MULTIPOINT(3.5 5.6,4.8 10.5),
- MULTILINESTRING((3 4,10 50,20 25),(-5 -8,-10 -8,-15 -4)),
- MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2, 3 2, 3 3, 2 3,2 2)),((3 3,6 2,6 4,3 3)),((78 45,65 34,100 54,78 45),(4 65, 54 23, 544 346, 2 1, 4 65))),
- GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10),
- GEOMETRYCOLLECTION(
- POINT EMPTY,
- LINESTRING EMPTY,
- POLYGON EMPTY,
- POLYGON(EMPTY),
- POLYGON(EMPTY,(4 5, 7 6, 4 5)),
- MULTIPOINT EMPTY,
- MULTILINESTRING EMPTY,
- MULTILINESTRING(EMPTY),
- MULTILINESTRING(EMPTY, (10 20, 45 67, 10 20)),
- MULTIPOLYGON EMPTY,
- MULTIPOLYGON(EMPTY),
- MULTIPOLYGON(EMPTY,((2.4 5.6, 2.0 4.5))),
- MULTIPOLYGON((EMPTY),(EMPTY,(9 0, 5 6, 0 1))),
- GEOMETRYCOLLECTION EMPTY)))
+GEOMETRYCOLLECTION(
+POINT(6 10),
+LINESTRING(3 4,10 50,20 25),
+LINESTRING(100 200),
+POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2, 3 2, 3 3, 2 3,2 2)),
+MULTIPOINT(3.5 5.6,4.8 10.5),
+MULTILINESTRING((3 4,10 50,20 25),(-5 -8,-10 -8,-15 -4)),
+MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2, 3 2, 3 3, 2 3,2 2)),((3 3,6 2,6 4,3 3)),((78 45,65 34,100 54,78 45),(4 65, 54 23, 544 346, 2 1, 4 65))),
+GEOMETRYCOLLECTION(
+POINT(4 6),
+LINESTRING(4 6,7 10),
+GEOMETRYCOLLECTION(
+POINT EMPTY,
+LINESTRING EMPTY,
+POLYGON EMPTY,
+POLYGON(EMPTY),
+POLYGON(EMPTY,(4 5, 7 6, 4 5)),
+MULTIPOINT EMPTY,
+MULTILINESTRING EMPTY,
+MULTILINESTRING(EMPTY),
+MULTILINESTRING(EMPTY, (10 20, 45 67, 10 20)),
+MULTIPOLYGON EMPTY,
+MULTIPOLYGON(EMPTY),
+MULTIPOLYGON(EMPTY,((2.4 5.6, 2.0 4.5))),
+MULTIPOLYGON((EMPTY),(EMPTY,(9 0, 5 6, 0 1))),
+GEOMETRYCOLLECTION EMPTY)))
Modified: branches/geospatial/wkt-wkb/wkbOps.c
===================================================================
--- branches/geospatial/wkt-wkb/wkbOps.c 2008-08-07 17:55:29 UTC (rev 180)
+++ branches/geospatial/wkt-wkb/wkbOps.c 2008-08-07 20:29:06 UTC (rev 181)
@@ -30,7 +30,7 @@
* allocate and create a well known binary stream.
****************************************************************************/
static int createBinaryStream( wkbGeometryCollectionT *geometryCollection,
- size_t *streamSize, char *stream )
+ size_t *streamSize, char **stream )
{
wkbGeometryCollectionT *current;
wkbGeometryT *geometry;
@@ -41,18 +41,19 @@
wkbByteOrderT byteOrder;
char *streamPtr;
wkbGeometryTypeT tempType;
- uint32_t tempNum, x, y;
+ uint32_t tempNum;
+ double x, y;
printf( "Stream size %d.\n", *streamSize );
// Allocate the binary stream size.
- stream = malloc( *streamSize );
+ *stream = malloc( *streamSize );
if( stream == NULL )
{
printf( "Error allocating stream.\n" );
return 1;
}
// Start the 'mobile' pointer at the beginning of the stream.
- streamPtr = stream;
+ streamPtr = *stream;
// wkb streams start with the byte order that the values were encoded in.
byteOrder = getByteOrder();
@@ -90,10 +91,10 @@
streamPtr += sizeof( uint8_t );
x = geometry->point.x;
y = geometry->point.y;
- memcpy( streamPtr, &x, sizeof( uint32_t ));
- streamPtr += sizeof( uint32_t );
- memcpy( streamPtr, &y, sizeof( uint32_t ));
- streamPtr += sizeof( uint32_t );
+ memcpy( streamPtr, &x, sizeof( double ));
+ streamPtr += sizeof( double );
+ memcpy( streamPtr, &y, sizeof( double ));
+ streamPtr += sizeof( double );
}
else
{
@@ -119,10 +120,10 @@
{
x = line->point.x;
y = line->point.y;
- memcpy( streamPtr, &x, sizeof( uint32_t ));
- streamPtr += sizeof( uint32_t );
- memcpy( streamPtr, &y, sizeof( uint32_t ));
- streamPtr += sizeof( uint32_t );
+ memcpy( streamPtr, &x, sizeof( double ));
+ streamPtr += sizeof( double );
+ memcpy( streamPtr, &y, sizeof( double ));
+ streamPtr += sizeof( double );
line = line->next;
}
break;
@@ -150,10 +151,10 @@
{
x = line->point.x;
y = line->point.y;
- memcpy( streamPtr, &x, sizeof( uint32_t ));
- streamPtr += sizeof( uint32_t );
- memcpy( streamPtr, &y, sizeof( uint32_t ));
- streamPtr += sizeof( uint32_t );
+ memcpy( streamPtr, &x, sizeof( double ));
+ streamPtr += sizeof( double );
+ memcpy( streamPtr, &y, sizeof( double ));
+ streamPtr += sizeof( double );
line = line->next;
}
linearRing = linearRing->next;
@@ -187,10 +188,10 @@
{
x = line->point.x;
y = line->point.y;
- memcpy( streamPtr, &x, sizeof( uint32_t ));
- streamPtr += sizeof( uint32_t );
- memcpy( streamPtr, &y, sizeof( uint32_t ));
- streamPtr += sizeof( uint32_t );
+ memcpy( streamPtr, &x, sizeof( double ));
+ streamPtr += sizeof( double );
+ memcpy( streamPtr, &y, sizeof( double ));
+ streamPtr += sizeof( double );
line = line->next;
}
linearRing = linearRing->next;
@@ -580,10 +581,80 @@
}
/*****************************************************************************
+ * Given a string, attempt to convert the contents from well known text
+ * to a well known binary stream.
+ ****************************************************************************/
+int wkbParseString( char* input, char **wkbStream, size_t *streamSize )
+{
+ extern int yyparse( void*, void*, size_t* );
+ yyscan_t scanner;
+ wkbGeometryCollectionT *geoCollection;
+ YY_BUFFER_STATE buffState;
+
+ // Allocate the start of the geometry collection.
+ geoCollection = malloc( sizeof( wkbGeometryCollectionT ));
+ if( geoCollection == NULL )
+ {
+ printf( "Could not allocate geometry collection.\n" );
+ *wkbStream = NULL;
+ return 1;
+ }
+
+ geoCollection->numGeometries = 0;
+ geoCollection->geoType = wkbTypeInvalid;
+
+ if( yylex_init( &scanner ) != 0 )
+ {
+ printf( "Could not initialize scanner.\n" );
+ *wkbStream = NULL;
+ return 10;
+ }
+
+ buffState = yy_scan_string( (yyconst char*) input, scanner );
+
+ yy_switch_to_buffer( buffState, scanner );
+
+ // Parse the well known text into a linked list containing all the
+ // geometry collection data.
+ if( yyparse( scanner, (void *)geoCollection, streamSize ) != 0 )
+ {
+ printf( "Error parsing grammar.\n" );
+ *wkbStream = NULL;
+ return 20;
+ }
+
+ yy_delete_buffer( buffState, scanner );
+
+ if( yylex_destroy( scanner ) != 0 )
+ {
+ printf( "Could not destroy scanner.\n" );
+ }
+
+ // Add a byte to the stream size to hold the byte order data.
+ *streamSize = *streamSize + ( sizeof( uint8_t ));
+
+ // Traverse the linked list and convert to a wkb stream.
+ if( createBinaryStream( geoCollection, streamSize, wkbStream ) != 0 )
+ {
+ printf( "Error creating binary stream.\n" );
+ return 2;
+ }
+
+ printf( "Geocollection size for wkb is %d.\n", *streamSize );
+ // Display the linked list for debugging.
+ wkbTraverseGeoDisplay( geoCollection );
+
+ // Clean up the memory allocated for the linked lists.
+ traverseGeoFree( geoCollection );
+
+ return 0;
+}
+
+/*****************************************************************************
* Given a file pointer, attempt to convert the contents from well known text
* to a well known binary stream.
****************************************************************************/
-int wkbParseFile( FILE* fp, char *wkbStream, size_t *streamSize )
+int wkbParseFile( FILE* fp, char **wkbStream, size_t *streamSize )
{
extern int yyparse( void*, void*, size_t* );
yyscan_t scanner;
@@ -594,6 +665,7 @@
if( geoCollection == NULL )
{
printf( "Could not allocate geometry collection.\n" );
+ *wkbStream = NULL;
return 1;
}
@@ -603,6 +675,7 @@
if( yylex_init( &scanner ) != 0 )
{
printf( "Could not initialize scanner.\n" );
+ *wkbStream = NULL;
return 10;
}
@@ -615,6 +688,7 @@
if( yyparse( scanner, (void *)geoCollection, streamSize ) != 0 )
{
printf( "Error parsing grammar.\n" );
+ *wkbStream = NULL;
return 20;
}
@@ -644,6 +718,229 @@
}
/*****************************************************************************
+ * Print the point data. Returns the new location in the wkb stream that the
+ * pointer is at.
+ ****************************************************************************/
+char *printWktPoint( char *streamPtr )
+{
+ printf( "%f ", *(double*)streamPtr);
+ streamPtr += sizeof( double );
+ printf( "%f", *(double*)streamPtr);
+ streamPtr += sizeof( double );
+
+ return streamPtr;
+};
+
+/*****************************************************************************
+ * Extract the number of points and process them. Returns the
+ * new location in the wkb stream that the pointer is at.
+ ****************************************************************************/
+char *printWktLineString( char *streamPtr )
+{
+ uint32_t numPoints;
+ uint32_t counter;
+
+ numPoints = *(uint32_t*)streamPtr;
+ streamPtr += sizeof( uint32_t );
+
+ if( numPoints == 0 )
+ {
+ printf( " EMPTY" );
+ return streamPtr;
+ }
+
+ printf( "(" );
+ for( counter = 0; counter < numPoints - 1; ++counter )
+ {
+ streamPtr = printWktPoint( streamPtr );
+ printf( "," );
+ }
+ streamPtr = printWktPoint( streamPtr );
+ printf( ")" );
+
+ return streamPtr;
+}
+
+/*****************************************************************************
+ * Extract the number of lines and process them. Returns the
+ * new location in the wkb stream that the pointer is at.
+ ****************************************************************************/
+char *printWktPolygon( char *streamPtr )
+{
+ uint32_t numLines;
+ uint32_t counter;
+
+ numLines = *(uint32_t*)streamPtr;
+ streamPtr += sizeof( uint32_t );
+
+ if( numLines == 0 )
+ {
+ printf( " EMPTY" );
+ return streamPtr;
+ }
+
+ printf( "(" );
+ for( counter = 0; counter < numLines - 1; ++counter )
+ {
+ streamPtr = printWktLineString( streamPtr );
+ printf( "," );
+ }
+ streamPtr = printWktLineString( streamPtr );
+ printf( ")" );
+
+ return streamPtr;
+}
+
+/*****************************************************************************
+ * Extract the number of polygons and process them. Returns the
+ * new location in the wkb stream that the pointer is at.
+ ****************************************************************************/
+char *printWktMultiPolygon( char *streamPtr )
+{
+ uint32_t numPolygons;
+ uint32_t counter;
+
+ numPolygons = *(uint32_t*)streamPtr;
+ streamPtr += sizeof( uint32_t );
+
+ if( numPolygons == 0 )
+ {
+ printf( " EMPTY" );
+ return streamPtr;
+ }
+
+ printf( "(" );
+ for( counter = 0; counter < numPolygons - 1; ++counter )
+ {
+ streamPtr = printWktPolygon( streamPtr );
+ printf( "," );
+ }
+ streamPtr = printWktPolygon( streamPtr );
+ printf( ")" );
+
+ return streamPtr;
+}
+
+/*****************************************************************************
+ * Extract the number of geometries and process the next type. Returns the
+ * new location in the wkb stream that the pointer is at.
+ ****************************************************************************/
+char *printWktGeoCollection( char *streamPtr )
+{
+ uint32_t numGeometries;
+ uint32_t counter;
+
+ numGeometries = *(uint32_t*)streamPtr;
+ streamPtr += sizeof( uint32_t );
+
+ if( numGeometries == 0 )
+ {
+ printf( " EMPTY" );
+ return streamPtr;
+ }
+
+ printf( "(" );
+ for( counter = 0; counter < numGeometries - 1; ++counter )
+ {
+ printf( "\n" );
+ streamPtr = processType( streamPtr );
+ printf( "," );
+ }
+ printf( "\n" );
+ streamPtr = processType( streamPtr );
+ printf( ")" );
+
+ return streamPtr;
+}
+
+/*****************************************************************************
+ * Process the geometry type from a wkb stream. Returns the new location in
+ * the wkb stream that the pointer is at.
+ ****************************************************************************/
+char *processType( char *streamPtr )
+{
+ uint8_t geoType;
+
+ geoType = *(uint8_t*)streamPtr;
+ streamPtr += sizeof( uint8_t );
+
+ switch( geoType )
+ {
+ case wkbPoint:
+ printf( "POINT(" );
+ streamPtr = printWktPoint( streamPtr );
+ printf( ")" );
+ break;
+
+ case wkbLineString:
+ printf( "LINESTRING" );
+ streamPtr = printWktLineString( streamPtr );
+ break;
+
+ case wkbPolygon:
+ printf( "POLYGON" );
+ streamPtr = printWktPolygon( streamPtr );
+ break;
+
+ case wkbMultiPoint:
+ printf( "MULTIPOINT" );
+ streamPtr = printWktLineString( streamPtr );
+ break;
+
+ case wkbMultiLineString:
+ printf( "MULTILINESTRING" );
+ streamPtr = printWktPolygon( streamPtr );
+ break;
+
+ case wkbMultiPolygon:
+ printf( "MULTIPOLYGON" );
+ streamPtr = printWktMultiPolygon( streamPtr );
+ break;
+
+ case wkbGeometryCollection:
+ printf( "GEOMETRYCOLLECTION" );
+ streamPtr = printWktGeoCollection( streamPtr );
+ break;
+
+ case wkbEmptyPoint:
+ printf( "POINT EMPTY" );
+ break;
+
+ default:
+ printf( "Unrecognized geometry type %d.\n", geoType );
+ return NULL;
+ }
+ return streamPtr;
+}
+
+/*****************************************************************************
+ * Parse a well known binary stream by moving a pointer through the stream.
+ ****************************************************************************/
+int wkbParseBinary( char *wkbStream, FILE *output )
+{
+ //TODO: Output to a file.
+ //TODO: Output to a string.
+
+ char *streamPtr;
+ uint8_t byteOrder;
+
+ streamPtr = wkbStream;
+
+ //TODO: How to convert endian-ness.
+ byteOrder = *(uint8_t*)streamPtr;
+
+ printf( "Byte order is %d\n", byteOrder );
+ streamPtr += sizeof( uint8_t );
+
+ if( processType( streamPtr ) == NULL )
+ {
+ return 1;
+ }
+ printf( "\n" );
+ return 0;
+}
+
+/*****************************************************************************
* Insert a new geometry into the geometry collection. Add to the stream
* size as required.
****************************************************************************/
@@ -734,6 +1031,9 @@
// The new geometry is a geometry collection.
// Add a byte to the stream size for geo type.
*streamSize = *streamSize + ( sizeof( uint8_t ));
+ // Add four bytes to the stream size for the number of geometries
+ // contained in this geometry collection.
+ *streamSize = *streamSize + ( sizeof( uint32_t ));
if( currentChild != NULL )
{
// If there is a child geometry collection already in progress
@@ -1137,8 +1437,8 @@
newPoint->x = point->x;
newPoint->y = point->y;
- // Add 8 bytes to the stream size, for both x and y data.
- *streamSize = *streamSize + ( sizeof( uint32_t ) * 2 );
+ // Add 16 bytes to the stream size, for both x and y data.
+ *streamSize = *streamSize + ( sizeof( double ) * 2 );
currGeo->geometry = geometry;
}
}
@@ -1223,8 +1523,8 @@
}
// Add one to the number of points in the line.
currRing->numPoints++;
- // Add 8 bytes to the stream size, for both x and y data.
- *streamSize = *streamSize + ( sizeof( uint32_t ) * 2 );
+ // Add 16 bytes to the stream size, for both x and y data.
+ *streamSize = *streamSize + ( sizeof( double ) * 2 );
}
return 0;
}
Modified: branches/geospatial/wkt-wkb/wkbOps.h
===================================================================
--- branches/geospatial/wkt-wkb/wkbOps.h 2008-08-07 17:55:29 UTC (rev 180)
+++ branches/geospatial/wkt-wkb/wkbOps.h 2008-08-07 20:29:06 UTC (rev 181)
@@ -4,12 +4,35 @@
#include "wkbTypes.h"
/*****************************************************************************
+ Private Functions
+ ***************************************************************************/
+/*****************************************************************************
+ * Process the geometry type from a wkb stream. Returns the new location in
+ * the wkb stream that the pointer is at.
+ ***************************************************************************/
+char *processType( char *streamPtr );
+
+/*****************************************************************************
+ Public Functions
+ ***************************************************************************/
+/*****************************************************************************
+ * Given a string, attempt to convert the contents from well known text
+ * to a well known binary stream.
+ * ***************************************************************************/
+int wkbParseString( char* input, char **wkbStream, size_t *streamSize );
+
+/*****************************************************************************
* Given a file pointer, attempt to convert the contents from well known text
* to a well known binary stream.
****************************************************************************/
-int wkbParseFile( FILE* fp, char *wkbStream, size_t *streamSize );
+int wkbParseFile( FILE* fp, char **wkbStream, size_t *streamSize );
/*****************************************************************************
+ * Parse a well known binary stream by moving a pointer through the stream.
+ ****************************************************************************/
+int wkbParseBinary( char *wkbStream, FILE *output );
+
+/*****************************************************************************
* Insert a new geometry into the geometry collection. Add to the stream
* size as required.
****************************************************************************/
Modified: branches/geospatial/wkt-wkb/wktToWkb.y
===================================================================
--- branches/geospatial/wkt-wkb/wktToWkb.y 2008-08-07 17:55:29 UTC (rev 180)
+++ branches/geospatial/wkt-wkb/wktToWkb.y 2008-08-07 20:29:06 UTC (rev 181)
@@ -1,3 +1,4 @@
+/* TODO: Add OGC 1.2 types. */
/* TODO: Error checking on insert calls. */
%pure_parser
More information about the svn-commits
mailing list