[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