From: Sandro Santilli Date: Thu, 9 Dec 2004 09:42:25 +0000 (+0000) Subject: Adjusted to work with new bytea WKB encoding, only supports 2d/3dz. X-Git-Tag: pgis_1_0_0RC1~169 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c8fae978cadda7aa704e53d8b5726bc2a571a4af;p=postgis Adjusted to work with new bytea WKB encoding, only supports 2d/3dz. git-svn-id: http://svn.osgeo.org/postgis/trunk@1128 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/examples/wkb_reader/.cvsignore b/examples/wkb_reader/.cvsignore new file mode 100644 index 000000000..c0abf3b70 --- /dev/null +++ b/examples/wkb_reader/.cvsignore @@ -0,0 +1 @@ +readwkb diff --git a/examples/wkb_reader/Makefile b/examples/wkb_reader/Makefile index 717386db9..ca6c9eae5 100644 --- a/examples/wkb_reader/Makefile +++ b/examples/wkb_reader/Makefile @@ -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 diff --git a/examples/wkb_reader/printwkb.inc b/examples/wkb_reader/printwkb.c similarity index 95% rename from examples/wkb_reader/printwkb.inc rename to examples/wkb_reader/printwkb.c index e1385d964..8dc1e6776 100644 --- a/examples/wkb_reader/printwkb.inc +++ b/examples/wkb_reader/printwkb.c @@ -1,3 +1,9 @@ +#include +#include +#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("); diff --git a/examples/wkb_reader/readwkb.c b/examples/wkb_reader/readwkb.c index 33c07cdbe..8023ff0aa 100644 --- a/examples/wkb_reader/readwkb.c +++ b/examples/wkb_reader/readwkb.c @@ -1,31 +1,15 @@ -#include -#include -#include -#include -#include - - -#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 index 000000000..c6542ee68 --- /dev/null +++ b/examples/wkb_reader/wkbtest.h @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include + + +#include + +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 +