]> granicus.if.org Git - postgis/commitdiff
Adjusted to work with new bytea WKB encoding, only supports 2d/3dz.
authorSandro Santilli <strk@keybit.net>
Thu, 9 Dec 2004 09:42:25 +0000 (09:42 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 9 Dec 2004 09:42:25 +0000 (09:42 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@1128 b70326c6-7e19-0410-871a-916f4a2858ee

examples/wkb_reader/.cvsignore [new file with mode: 0644]
examples/wkb_reader/Makefile
examples/wkb_reader/printwkb.c [moved from examples/wkb_reader/printwkb.inc with 95% similarity]
examples/wkb_reader/readwkb.c
examples/wkb_reader/wkbtest.h [new file with mode: 0644]

diff --git a/examples/wkb_reader/.cvsignore b/examples/wkb_reader/.cvsignore
new file mode 100644 (file)
index 0000000..c0abf3b
--- /dev/null
@@ -0,0 +1 @@
+readwkb
index 717386db922b8b3b47ac3e245ba26a45a626ff6e..ca6c9eae5781007b42e966fc6ddd1794e36cfcf8 100644 (file)
@@ -1,18 +1,15 @@
 #
-# Edit the following variables to point to your PostgreSQL
-# client libraries and include files
+# Have pg_config in your PATH
 #
-PG_INC=/usr/include/pgsql
-PG_LIB=/usr/lib
 
 #
 # Below should be fine
 #
-CFLAGS=-I$(PG_INC) -L$(PG_LIB) -lpq
+CFLAGS=-I`pg_config --includedir` -L`pg_config --libdir` -lpq
 
 all: readwkb
 
-readwkb: readwkb.c
+readwkb: readwkb.c printwkb.c
 
 clean:
        @rm -f readwkb
similarity index 95%
rename from examples/wkb_reader/printwkb.inc
rename to examples/wkb_reader/printwkb.c
index e1385d9643b894d4888856fd10a0f290c918f441..8dc1e67763a6f94c8c29ce109b1ffa718b499ed4 100644 (file)
@@ -1,3 +1,9 @@
+#include <math.h>
+#include <float.h>
+#include "wkbtest.h"
+
+#define WKBZOFFSET 0x80000000
+#define WKBMOFFSET 0x40000000
 
 
 //  DO NOT USE THESE decoding function (except for debugging purposes)
@@ -13,6 +19,7 @@
 // you shouldnt call this function; just call decode_wkb() and it will
 // call this function
 
+//#define DEBUG 1
 
 
 
@@ -51,7 +58,6 @@ void decode_wkb_collection(char *wkb,int      *size)
        int     total_size=0,sub_size;
        int     numb_sub,t;
        bool    first_one = TRUE;
-       
                
        if (wkb[0] ==0 )  //big endian
        {
@@ -104,7 +110,7 @@ void decode_wkb(char *wkb, int *size)
        uint32  type;
        uint32  n1,n2,n3,t,u,v;
        bool    is3d;
-       bool first_one,first_one2,first_one3;
+       bool    first_one,first_one2,first_one3;
 
        int     offset,offset1;
        double  x,y,z;
@@ -112,7 +118,9 @@ void decode_wkb(char *wkb, int *size)
 
 
 
-       //printf("decoding wkb\n");
+#if DEBUG
+       printf("decoding wkb\n");
+#endif
        
 
        if (wkb[0] ==0 )  //big endian
@@ -130,21 +138,27 @@ void decode_wkb(char *wkb, int *size)
                        flipbytes= 1;
        }
        
-       //printf("      + flipbytes = %i\n", flipbytes);
+#if DEBUG
+       printf("        + flipbytes = %i\n", flipbytes);
+#endif
 
-       //printf("info about wkb:\n");
+#if DEBUG
+       printf("info about wkb:\n");
+#endif
        memcpy(&type, wkb+1,4);
        if (flipbytes)
                flip_endian_int32( (char *) & type) ;
        
        is3d = 0;
  
-       if (type > 1000 )
+       if (type&WKBZOFFSET)
        {
                is3d = 1;
-               type = type - 32768;
+               type = type&(~WKBZOFFSET);
        }
-       //printf("      Type = %i (is3d = %i)\n", type, is3d);
+#if DEBUG
+       printf("        Type = %i (is3d = %i)\n", type, is3d);
+#endif
        if (type == 1)  //POINT()
        {
                printf("POINT(");
index 33c07cdbe7650f37b86683539667e4efd956c0cc..8023ff0aa522fdf7a3aaf9423440dc872362518c 100644 (file)
@@ -1,31 +1,15 @@
-#include <math.h>
-#include <float.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-
-#include "libpq-fe.h"
-
-// some type def'n -- hopefully they are the same on your machine!
-
-typedef signed int int32;               /* == 32 bits */
-typedef unsigned int uint32;    /* == 32 bits */
-typedef char bool;
-
-#define TRUE 1
-#define FALSE 0
-
+#include "wkbtest.h"
 
 /* example set-up
 
-create table tt (interesting bool,comments varchar(100), the_geom geometry);
-insert into tt values ( false, 'simple point', 'POINT( 10 10)' );
-insert into tt values ( false, 'simple line' , 'LINESTRING(0 0, 10 0, 10 10, 0 10, 0 0)');
-insert into tt values( true, 'polygon w/ hole','POLYGON( (0 0, 10 0, 10 10, 0 10, 0 0), (5 5, 7 5, 7 7 , 5 7 , 5 5))');
+create table wkbreader_test (interesting bool,comments varchar(100), the_geom geometry);
+insert into wkbreader_test values ( false, 'simple point', 'POINT( 10 10)' );
+insert into wkbreader_test values ( false, 'simple line' , 'LINESTRING(0 0, 10 0, 10 10, 0 10, 0 0)');
+insert into wkbreader_test values( true, 'polygon w/ hole','POLYGON( (0 0, 10 0, 10 10, 0 10, 0 0), (5 5, 7 5, 7 7 , 5 7 , 5 5))');
 
 
-dont forget to set the port, dbname, host, and user (below) so the postgres connection will work
+dont forget to set the port, dbname, host, and user in the
+environment so the postgres connection will work
 
 Also, change the "declare cursor" command so it returns the columns you want, and converts the geometry
 into wkb.
@@ -33,51 +17,6 @@ into wkb.
 */
 
 
-
-// This is modified from the postgres documentation for client programs (example programs)
-
-void decode_wkb(char *wkb, int *size);
-
-
-//we need to know the endian of the client machine.  This is
-// taken from postgres's os.h file 
-
-#if defined(__i386) && !defined(__i386__)
-#define __i386__
-#endif
-
-#if defined(__sparc) && !defined(__sparc__)
-#define __sparc__
-#endif
-
-#ifndef                 BIG_ENDIAN
-#define                 BIG_ENDIAN              4321
-#endif
-#ifndef                 LITTLE_ENDIAN
-#define                 LITTLE_ENDIAN   1234
-#endif
-
-
-#ifndef                 BYTE_ORDER
-#ifdef __sparc__
-#define           BYTE_ORDER      BIG_ENDIAN
-#endif
-#ifdef __i386__
-#define          BYTE_ORDER              LITTLE_ENDIAN
-#endif
-#endif
-
-
-
-//really messy debugging function for printing out wkb
-//   not included inside this .c because its a messy pile of doggy-do
-//
-// it does assume "BYTE_ORDER" and "LITTLE_ENDIAN" are defined in the same
-//  way as in postgres.h
-#include "printwkb.inc"
-
-
-
 void
 exit_nicely(PGconn *conn)
 {
@@ -111,7 +50,7 @@ int  find_WKB_typeid(PGconn  *conn)
                exit_nicely(conn); 
        } 
 
-       dbresult = PQexec(conn, "select OID from pg_type where typname = 'wkb';");
+       dbresult = PQexec(conn, "select OID from pg_type where typname = 'bytea';");
 
        if (PQresultStatus(dbresult) != PGRES_TUPLES_OK) 
        {
@@ -157,87 +96,67 @@ int        WKB_OID;
        double  *double_val;
        char            *char_val;
        char            *wkb_val;
-       char            *table_name = "t";
+       char            *table_name = "wkbreader_test";
        char            query_str[1000];
 
-    /*
-     * begin, by setting the parameters for a backend connection if the
-     * parameters are null, then the system will try to use reasonable
-     * defaults by looking up environment variables or, failing that,
-     * using hardwired constants
-     */
-
-
-        pghost = "192.168.50.3";                                
-        pgport = "5555";                                                
-        pgoptions = "user=postgres";                    
-        pgtty = NULL;                                                
-        dbName = "t2";
-       
-
-
-
-
-        sprintf(conn_string,"host=%s %s port=%s dbname=%s",pghost,pgoptions,pgport,dbName);
-
-
-    /* make a connection to the database */
-    conn = PQconnectdb( conn_string );
+       /* make a connection to the database */
+       conn = PQconnectdb("");
 
-    /*
-     * check to see that the backend connection was successfully made
-     */
-    if (PQstatus(conn) == CONNECTION_BAD)
-    {
-        fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
-        fprintf(stderr, "%s", PQerrorMessage(conn));
-        exit_nicely(conn);
-    }
+       /*
+       * check to see that the backend connection was successfully made
+       */
+       if (PQstatus(conn) == CONNECTION_BAD)
+       {
+               fprintf(stderr, "%s", PQerrorMessage(conn));
+               exit_nicely(conn);
+       }
 
-               //what is the geometry type's OID #?
+       //what is the geometry type's OID #?
        WKB_OID = find_WKB_typeid(conn);
 
 
-    /* start a transaction block */
-    res = PQexec(conn, "BEGIN");
-    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
-    {
-        fprintf(stderr, "BEGIN command failed\n");
-        PQclear(res);
-        exit_nicely(conn);
-    }
+       /* start a transaction block */
+       res = PQexec(conn, "BEGIN");
+       if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, "%s", PQerrorMessage(conn));
+               PQclear(res);
+               exit_nicely(conn);
+       }
 
-    /*
-     * should PQclear PGresult whenever it is no longer needed to avoid
-     * memory leaks
-     */
-    PQclear(res);
+       /*
+        * should PQclear PGresult whenever it is no longer needed to avoid
+        * memory leaks
+        */
+       PQclear(res);
 
-    /*
-     * fetch rows from the pg_database, the system catalog of
-     * databases
-     */
-       sprintf(query_str, "DECLARE mycursor BINARY CURSOR FOR select text(num), asbinary(the_geom,'ndr') as wkb from %s",table_name);
+       /*
+        * fetch rows from the pg_database, the system catalog of
+        * databases
+        */
+       sprintf(query_str, "DECLARE mycursor BINARY CURSOR FOR select text(num), asbinary(the_geom,'ndr') as wkb from %s", table_name);
 
        printf(query_str); printf("\n");
 
-    res = PQexec(conn, query_str);
+       res = PQexec(conn, query_str);
 
-    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
-    {
-        fprintf(stderr, "DECLARE CURSOR command failed\n");
-        PQclear(res);
-        exit_nicely(conn);
-    }
-    PQclear(res);
+       if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
+       {
+               fprintf(stderr, "DECLARE CURSOR command failed\n");
+               fprintf(stderr, "%s", PQerrorMessage(conn));
+               PQclear(res);
+               exit_nicely(conn);
+       }
+       PQclear(res);
 
-    res = PQexec(conn, "FETCH ALL in mycursor");
-    if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
-    {
-        fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
-        PQclear(res);
-        exit_nicely(conn);
-    }
+       res = PQexec(conn, "FETCH ALL in mycursor");
+       if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
+       {
+               fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
+               fprintf(stderr, "%s", PQerrorMessage(conn));
+               PQclear(res);
+               exit_nicely(conn);
+       }
 
        for (row=0; row< PQntuples(res); row++)
        {
@@ -258,31 +177,33 @@ int       WKB_OID;
                                else
                                        printf("%s: FALSE\n",field_name);
                        }
-                       if (field_type ==23 )//int4 (int)
+                       else if (field_type ==23 )//int4 (int)
                        {
                                int_val = (int *) PQgetvalue(res, row, field);
                                printf("%s: %i\n",field_name,*int_val); 
                        }
-                       if (field_type ==700 )//float4 (float)
+                       else if (field_type ==700 )//float4 (float)
                        {
                                float_val = (float *) PQgetvalue(res, row, field);
                                printf("%s: %g\n",field_name,*float_val);       
                        }
-                       if (field_type ==701 )//float8 (double)
+                       else if (field_type ==701 )//float8 (double)
                        {
                                double_val = (double *) PQgetvalue(res, row, field);
                                printf("%s: %g\n",field_name,*double_val);      
                        }
-                       if ( (field_type ==1043 ) || (field_type==25) )//varchar 
+                       else if ( (field_type ==1043 ) || (field_type==25) )//varchar 
                        {
                                char_val = (char *) PQgetvalue(res, row, field);
                                printf("%s: %s\n",field_name,char_val); 
                        }
-                       if (field_type ==WKB_OID ) //wkb
+                       else if (field_type == WKB_OID ) //wkb
                        {
                                char_val = (char *) PQgetvalue(res, row, field);
                                printf("%s: ", field_name);
-                               decode_wkb(char_val, &junk);    
+                               // skip 4 bytes varlena size 
+                               decode_wkb(char_val, &junk);
+                               printf("\n");
                        }
                        
                }
diff --git a/examples/wkb_reader/wkbtest.h b/examples/wkb_reader/wkbtest.h
new file mode 100644 (file)
index 0000000..c6542ee
--- /dev/null
@@ -0,0 +1,51 @@
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+
+#include <libpq-fe.h>
+
+typedef signed int int32;               /* == 32 bits */
+typedef unsigned int uint32;    /* == 32 bits */
+typedef char bool;
+
+#define TRUE 1
+#define FALSE 0
+
+
+
+// This is modified from the postgres documentation for client programs (example programs)
+
+void decode_wkb(char *wkb, int *size);
+
+
+//we need to know the endian of the client machine.  This is
+// taken from postgres's os.h file 
+
+#if defined(__i386) && !defined(__i386__)
+#define __i386__
+#endif
+
+#if defined(__sparc) && !defined(__sparc__)
+#define __sparc__
+#endif
+
+#ifndef                 BIG_ENDIAN
+#define                 BIG_ENDIAN              4321
+#endif
+#ifndef                 LITTLE_ENDIAN
+#define                 LITTLE_ENDIAN   1234
+#endif
+
+
+#ifndef                 BYTE_ORDER
+#ifdef __sparc__
+#define           BYTE_ORDER      BIG_ENDIAN
+#endif
+#ifdef __i386__
+#define          BYTE_ORDER              LITTLE_ENDIAN
+#endif
+#endif
+