]> granicus.if.org Git - postgis/commitdiff
Should be working (with a tonne of notices) for points lines and polygons (2d
authorDavid Blasby <dblasby@gmail.com>
Thu, 11 Mar 2004 00:54:37 +0000 (00:54 +0000)
committerDavid Blasby <dblasby@gmail.com>
Thu, 11 Mar 2004 00:54:37 +0000 (00:54 +0000)
and 3d)

git-svn-id: http://svn.osgeo.org/postgis/trunk@486 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/lwgeom.h
lwgeom/lwgeom.sql.in
lwgeom/lwgeom_api.c
lwgeom/lwgeom_inout.c

index 39c1ebeb4f22f26b3ac2d7b05004a2a4c2bde9ec..f22d6226c3be582c2197637660d16fc5c1c799a9 100644 (file)
@@ -8,9 +8,9 @@
 
 
 
-#define TWODIMS 00
-#define THREEDIMS 01
-#define FOURDIMS 10
+#define TWODIMS 0
+#define THREEDIMS 1
+#define FOURDIMS 2
 
 typedef struct
 {
@@ -113,12 +113,12 @@ extern int pointArray_ptsize(POINTARRAY *pa);
 
  LWGEOM types are an 8-bit char in this format:
 
-xxSDtttt
+xSDDtttt
 
 WHERE
     x = unused
     S = 4 byte SRID attached (0= not attached (-1), 1= attached)
-    D = dimentionality (0=2d, 1=3d)
+    DD = dimentionality (0=2d, 1=3d, 2= 4d)
     tttt = actual type (as per the WKB type):
 
     enum wkbGeometryType {
@@ -409,6 +409,12 @@ extern void pfree_POINTARRAY(POINTARRAY *pa);
 
 extern uint32 get_uint32(char *loc);
 extern int32 get_int32(char *loc);
+extern void printPA(POINTARRAY *pa);
+extern void printLWLINE(LWLINE *line);
+extern void printLWPOLY(LWPOLY *poly);
+extern void printBYTES(unsigned char *a, int n);
+extern void deparse_hex(unsigned char str, unsigned char *result);
+
 
 //------------------------------------------------------------
 //------------------------------------------------------------
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..43f68c74ba67dade4a86b493b791c978cdcc1eb9 100644 (file)
@@ -0,0 +1,47 @@
+BEGIN;
+
+CREATE OR REPLACE FUNCTION lwgeom_in(cstring)
+        RETURNS lwgeom
+        AS '/net/lion/raid/share/Refractions/Projects/PostGIS/work_dave2/postgis/lwgeom/liblwgeom.so.0.1','LWGEOM_in'
+        LANGUAGE 'C' WITH (isstrict,iscachable);
+
+CREATE OR REPLACE FUNCTION lwgeom_out(lwgeom)
+        RETURNS cstring
+        AS '/net/lion/raid/share/Refractions/Projects/PostGIS/work_dave2/postgis/lwgeom/liblwgeom.so.0.1','LWGEOM_out'
+        LANGUAGE 'C' WITH (isstrict,iscachable);
+
+CREATE TYPE lwgeom (
+        internallength = variable,
+        input = lwgeom_in,
+        output = lwgeom_out,
+        storage = main
+);
+
+
+CREATE FUNCTION lwgeom(wkb)
+        RETURNS lwgeom
+        AS '/net/lion/raid/share/Refractions/Projects/PostGIS/work_dave2/postgis/lwgeom/liblwgeom.so.0.1','LWGEOMFromWKB'
+        LANGUAGE 'C' WITH (isstrict,iscachable);
+
+
+CREATE FUNCTION wkb(lwgeom)
+        RETURNS wkb
+        AS '/net/lion/raid/share/Refractions/Projects/PostGIS/work_dave2/postgis/lwgeom/liblwgeom.so.0.1','WKBFromLWGEOM'
+        LANGUAGE 'C' WITH (isstrict,iscachable);
+
+COMMIT;
+
+
+---- test stuff
+
+select geometry(wkb(lwgeom(asbinary('POINT(1 2)'::geometry))));
+select geometry(wkb(lwgeom(asbinary('POINT(1 2 3)'::geometry))));
+
+select geometry(wkb(lwgeom(asbinary('LINESTRING(1 2, 3 4)'::geometry))));
+select geometry(wkb(lwgeom(asbinary('LINESTRING(1 2 -999, 3 4 -999, 5 6 -999)'::geometry))));
+
+
+select geometry(wkb(lwgeom(asbinary('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'::geometry))));
+select geometry(wkb(lwgeom(asbinary('POLYGON((0 0 -99, 10 0 -99, 10 10 -99, 0 10 -99, 0 0 -99))'::geometry))));
+
+
index 77a1eb2f4a2be0fd8b921b3dc808ff9a900efa70..1afc661220a9834a960cef24ab04ff15705cb448 100644 (file)
@@ -224,9 +224,7 @@ BOX3D *combine_boxes(BOX3D *b1, BOX3D *b2)
                 return result; //error
         }
 
-        size = sizeof(double)*2; // x,y
-        if (pa->is3d)
-               size += sizeof(double); //(x,y) & z
+        size = pointArray_ptsize(pa);
 
                // this does x,y
         memcpy(&result.x, &pa->serialized_pointlist[size*n],sizeof(double)*2 );
@@ -251,9 +249,7 @@ void getPoint3d_p(POINTARRAY *pa, int n, char *point)
                 return ; //error
         }
 
-        size = sizeof(double)*2; // x,y
-        if (pa->is3d)
-               size += sizeof(double); //(x,y) & z
+       size = pointArray_ptsize(pa);
 
                // this does x,y
         memcpy(point, &pa->serialized_pointlist[size*n],sizeof(double)*2 );
@@ -281,9 +277,7 @@ POINT2D getPoint2d(POINTARRAY *pa, int n)
                         return result; //error
                 }
 
-                size = sizeof(double)*2; // x,y
-                if (pa->is3d)
-                       size += sizeof(double); //(x,y) & z
+                size = pointArray_ptsize(pa);
 
                        // this does x,y
                 memcpy(&result.x, &pa->serialized_pointlist[size*n],sizeof(double)*2 );
@@ -304,9 +298,7 @@ void getPoint2d_p(POINTARRAY *pa, int n, char *point)
                         return; //error
                 }
 
-                size = sizeof(double)*2; // x,y
-                if (pa->is3d)
-                       size += sizeof(double); //(x,y) & z
+                size = pointArray_ptsize(pa);
 
                        // this does x,y
                 memcpy(point, &pa->serialized_pointlist[size*n],sizeof(double)*2 );
@@ -322,6 +314,9 @@ POINTARRAY *pointArray_construct(char *points, char is3d, uint32 npoints)
        POINTARRAY  *pa;
        pa = (POINTARRAY*)palloc(sizeof(pa));
 
+       if (is3d>2)
+               elog(ERROR,"pointArray_construct:: called with dims = %i", (int) is3d);
+
        pa->is3d = is3d;
        pa->npoints = npoints;
        pa->serialized_pointlist = points;
@@ -388,12 +383,12 @@ int pointArray_ptsize(POINTARRAY *pa)
 
 bool lwgeom_hasSRID(char type)
 {
-       return (type & 0x20);
+       return (type & 0x40);
 }
 
 bool lwgeom_is3d(char type)
 {
-       return (type & 0x10);
+       return ( (type & 0x30) >>4);
 }
 
 int  lwgeom_getType(char type)
@@ -472,7 +467,10 @@ LWLINE *lwline_deserialize(char *serialized_form)
 
 
        if ( lwgeom_getType(type) != LINETYPE)
+       {
+               elog(ERROR,"lwline_deserialize: attempt to deserialize a line when its not really a line");
                return NULL;
+       }
 
        if ( lwgeom_hasSRID(type))
        {
@@ -494,6 +492,7 @@ LWLINE *lwline_deserialize(char *serialized_form)
        result->points = pa;
        result->is3d = lwgeom_is3d(type);
 
+//elog(NOTICE,"npoints in deserialize line = %i",npoints);
        return result;
 }
 
@@ -507,6 +506,7 @@ char  *lwline_serialize(LWLINE *line)
        int t;
        char *loc;
 
+elog(NOTICE,"lwline_serialize::entry");
        hasSRID = (line->SRID != -1);
 
        if (hasSRID)
@@ -518,9 +518,13 @@ char  *lwline_serialize(LWLINE *line)
        }
        else
        {
-               size += 16 * line->points->npoints; //x,y,z
+               size += 16 * line->points->npoints; //x,y
        }
 
+       size+=4; // npoints
+
+elog(NOTICE,"lwline_serialize:: size = %i",size);
+
        result = palloc(size);
 
        result[0] = lwgeom_makeType(line->is3d,hasSRID, LINETYPE);
@@ -532,6 +536,8 @@ char  *lwline_serialize(LWLINE *line)
                loc += 4;
        }
 
+       memcpy(loc, &line->points->npoints, sizeof(int32));
+       loc +=4;
        //copy in points
 
        if (line->is3d)
@@ -550,6 +556,7 @@ char  *lwline_serialize(LWLINE *line)
                        loc += 16; // size of a 2d point
                }
        }
+       printBYTES((unsigned char *)result, size);
        return result;
 }
 
@@ -571,7 +578,7 @@ uint32 lwline_findlength(char *serialized_line)
                uint32 npoints;
 
                if ( lwgeom_getType(type) != LINETYPE)
-                       return -9999;
+                       elog(ERROR,"lwline_findlength::attempt to find the length of a non-line");
 
                if ( lwgeom_hasSRID(type))
                {
@@ -586,6 +593,9 @@ uint32 lwline_findlength(char *serialized_line)
                // we've read the type (1 byte) and SRID (4 bytes, if present)
 
                npoints = get_uint32(loc);
+elog(NOTICE,"npoint in lwline_findlength= %i",npoints);
+               result += 4; //npoints
+
                if (lwgeom_is3d(type) )
                {
                        return result + npoints * 24;
@@ -831,8 +841,9 @@ LWPOLY *lwpoly_deserialize(char *serialized_form)
        }
 
        nrings = get_uint32(loc);
+       result->nrings = nrings;
        loc +=4;
-
+elog(NOTICE,"lwpoly_deserialize:: polygon with %i rings",nrings);
        result->rings = (POINTARRAY**) palloc(nrings* sizeof(POINTARRAY*));
 
        for (t =0;t<nrings;t++)
@@ -879,11 +890,12 @@ char *lwpoly_serialize(LWPOLY *poly)
                        total_points  += poly->rings[t]->npoints;
                }
                if (poly->is3d)
-                       size += 24*npoints;
+                       size += 24*total_points;
                else
-                       size += 16*npoints;
+                       size += 16*total_points;
 
                result = palloc(size);
+       elog(NOTICE,"lwpoly_serialize size = %i", size);
 
                result[0] = lwgeom_makeType(poly->is3d,hasSRID, POLYGONTYPE);
                loc = result+1;
@@ -895,12 +907,15 @@ char *lwpoly_serialize(LWPOLY *poly)
                }
 
                memcpy(loc, &poly->nrings, sizeof(int32));  // nrings
+               loc+=4;
+
+
 
                for (t=0;t<poly->nrings;t++)
                {
                        POINTARRAY *pa = poly->rings[t];
                        npoints = poly->rings[t]->npoints;
-
+elog(NOTICE,"doing ring #%i with %i points",t,npoints);
                        memcpy(loc, &npoints, sizeof(int32)); //npoints this ring
                        loc+=4;
                        if (poly->is3d)
@@ -908,15 +923,16 @@ char *lwpoly_serialize(LWPOLY *poly)
                                for (u=0;u<npoints;u++)
                                {
                                        getPoint3d_p(pa, u, loc);
-                                       loc+= 24*npoints;
+                                       loc+= 24;
                                }
                        }
                        else
                        {
                                for (u=0;u<npoints;u++)
                                {
+elog(NOTICE,"pt %i",u);
                                        getPoint2d_p(pa, u, loc);
-                                       loc+= 16*npoints;
+                                       loc+= 16;
                                }
                        }
                }
@@ -1655,4 +1671,75 @@ void pfree_POINTARRAY(POINTARRAY *pa)
 
 
 
+//************************************************
+//** debugging routines
+
+
+void printLWLINE(LWLINE *line)
+{
+       elog(NOTICE,"LWLINE {");
+       elog(NOTICE,"    is3d = %i", (int)line->is3d);
+       elog(NOTICE,"    SRID = %i", (int)line->SRID);
+       printPA(line->points);
+       elog(NOTICE,"}");
+}
+
+
+void printPA(POINTARRAY *pa)
+{
+       int t;
+       POINT2D pt2;
+       POINT3D pt3;
+
+       elog(NOTICE,"      POINTARRAY{");
+       elog(NOTICE,"                 is3d =%i,   ptsize=%i", (int) pa->is3d,pointArray_ptsize(pa));
+       elog(NOTICE,"                 npoints = %i", pa->npoints);
+
+       for (t =0; t<pa->npoints;t++)
+       {
+               if (pa->is3d == TWODIMS)
+               {
+                       pt2 = getPoint2d(pa,t);
+                       elog(NOTICE,"                    %i : %lf,%lf",t,pt2.x,pt2.y);
+               }
+               if (pa->is3d == THREEDIMS)
+               {
+                       pt3 = getPoint3d(pa,t);
+                       elog(NOTICE,"                    %i : %lf,%lf,%lf",t,pt3.x,pt3.y,pt3.z);
+               }
+       }
+
+       elog(NOTICE,"      }");
+}
+
+void printBYTES(unsigned char *a, int n)
+{
+       int t;
+       char buff[3];
+
+       buff[2] = 0; //null terminate
+
+       elog(NOTICE," BYTE ARRAY (n=%i) {", n);
+       for (t=0;t<n;t++)
+       {
+               deparse_hex(a[t], buff);
+               elog(NOTICE, "    %i : %s", t,buff );
+       }
+       elog(NOTICE, "  }");
+}
+
 
+void printLWPOLY(LWPOLY *poly)
+{
+       int t;
+       elog(NOTICE,"LWPOLY {");
+       elog(NOTICE,"    is3d = %i", (int)poly->is3d);
+       elog(NOTICE,"    SRID = %i", (int)poly->SRID);
+       elog(NOTICE,"    nrings = %i", (int)poly->nrings);
+       for (t=0;t<poly->nrings;t++)
+       {
+               elog(NOTICE,"    RING # %i :",t);
+               printPA(poly->rings[t]);
+       }
+       elog(NOTICE,"}");
+}
index fe4468b7641eea67d0185bbaddd97dcd28b9913b..11977db66f48626c8ad065f6ed2f137b18abf903 100644 (file)
 
 #include "lwgeom.h"
 
+
+
+#define DEBUG
+
+
+
+
+
 extern char *wkb_to_lwgeom(char *wkb, int SRID,int *size);
 extern char *lwgeom_to_wkb(char *serialized_form,int *wkblength,char desiredWKBEndian);
 extern void swap_char(char     *a,char *b);
@@ -36,6 +44,11 @@ extern char *lwline_to_wkb(LWLINE *line, char desiredWKBEndian, int *wkbsize);
 extern char *lwpoint_to_wkb(LWPOINT *point, char desiredWKBEndian, int *wkbsize);
 extern char *lwpoly_to_wkb(LWPOLY *poly, char desiredWKBEndian, int *wkbsize);
 
+
+extern unsigned char   parse_hex(char *str);
+extern void deparse_hex(unsigned char str, unsigned char *result);
+
+
 // 3d or 4d.  There is NOT a (x,y,m) point type!!!
 #define WKB3DOFFSET 0x80000000
 #define WKB4DOFFSET 0x40000000
@@ -43,22 +56,125 @@ extern char *lwpoly_to_wkb(LWPOLY *poly, char desiredWKBEndian, int *wkbsize);
 Datum LWGEOMFromWKB(PG_FUNCTION_ARGS);
 Datum WKBFromLWGEOM(PG_FUNCTION_ARGS);
 
+
+Datum LWGEOM_in(PG_FUNCTION_ARGS);
+Datum LWGEOM_out(PG_FUNCTION_ARGS);
+
+
+// WKB structure  -- exactly the same as TEXT
+typedef struct Well_known_bin {
+    int32 size;    // total size of this structure
+    unsigned char  data[1]; //THIS HOLD VARIABLE LENGTH DATA
+} WellKnownBinary;
+
+
+
+PG_FUNCTION_INFO_V1(LWGEOM_in);
+Datum LWGEOM_in(PG_FUNCTION_ARGS)
+{
+           char                    *str = PG_GETARG_CSTRING(0);
+           WellKnownBinary         *wkb;
+           char                                        *result,*lwgeom;
+        int                     size;
+        int                     t;
+        int                     input_str_len;
+
+        int SRID = -1; //default (change)
+
+       input_str_len = strlen(str);
+
+       if  ( ( ( (int)(input_str_len/2.0) ) *2.0) != input_str_len)
+       {
+                       elog(ERROR,"LWGEOM_in parser - should be even number of characters!");
+                       PG_RETURN_NULL();
+       }
+
+       if (strspn(str,"0123456789ABCDEF") != strlen(str) )
+       {
+                       elog(ERROR,"WKB_in parser - input contains bad characters.  Should only have '0123456789ABCDEF'!");
+                       PG_RETURN_NULL();
+       }
+       size = (input_str_len/2) + 4;
+       wkb = (WellKnownBinary *) palloc(size);
+       wkb->size = size;
+
+       for (t=0;t<input_str_len/2;t++)
+       {
+                       ((unsigned char *)wkb)[t+4] = parse_hex( &str[t*2]) ;
+       }
+
+       //have WKB string (and we can safely modify it)
+                       lwgeom = wkb_to_lwgeom(((char *) wkb)+4, SRID,&size);
+
+                       pfree(wkb); // no longer referenced!
+
+                       result = palloc(size+4);
+
+                       memcpy(result+4, lwgeom, size);
+                       size+=4;
+                       memcpy(result, &size, 4);
+
+                       pfree(lwgeom);
+
+               PG_RETURN_POINTER(result);
+}
+
+PG_FUNCTION_INFO_V1(LWGEOM_out);
+Datum LWGEOM_out(PG_FUNCTION_ARGS)
+{
+               char                    *lwgeom = (char *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+               char                            *result;
+               int                                     size_result;
+               int                                     t;
+               int                                     size;
+
+               char *wkb = lwgeom_to_wkb(lwgeom+4,&size,1); // 0=XDR, 1=NDR
+
+               size_result = size *2 +1; //+1 for null char
+               result = palloc (size_result);
+               result[size_result-1] = 0; //null terminate
+
+               for (t=0; t< size; t++)
+               {
+                       deparse_hex( ((unsigned char *) wkb)[t], &result[t*2]);
+               }
+
+               pfree(wkb);
+
+               PG_RETURN_CSTRING(result);
+}
+
+
+
 // LWGEOMFromWKB(wkb,  [SRID] )
 PG_FUNCTION_INFO_V1(LWGEOMFromWKB);
 Datum LWGEOMFromWKB(PG_FUNCTION_ARGS)
 {
                char   *wkb_input = (char *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-               int    SRID ;
+               int    SRID = -1;
                int    size;
                char *lwgeom;
                char * result;
+               char    *wkb_copy;
+
 
-                               if ( ! PG_ARGISNULL(1) )
+                               if (  ( PG_NARGS()>1) && ( ! PG_ARGISNULL(1) ))
                                        SRID = PG_GETARG_INT32(1);
                                else
                                        SRID = -1;
 
-               lwgeom = wkb_to_lwgeom(wkb_input, SRID,&size);
+#ifdef DEBUG
+        elog(NOTICE,"LWGEOMFromWKB: entry with SRID=%i\n",SRID);
+#endif
+
+                                       // need to do this because there might be a bunch of endian flips!
+               wkb_copy = palloc( *((int32 *) wkb_input));
+               memcpy(wkb_copy, wkb_input+4, *((int32 *) wkb_input) -4);
+
+               lwgeom = wkb_to_lwgeom(wkb_copy, SRID,&size);
+
+               pfree(wkb_copy); // no longer referenced!
+
                result = palloc(size+4);
 
                memcpy(result+4, lwgeom, size);
@@ -123,6 +239,11 @@ char *wkb_to_lwgeom(char *wkb, int SRID,int *size)
        dims = wkb_dims(wkbtype);
        simpletype = wkb_simpletype(wkbtype);
 
+#ifdef DEBUG
+        elog(NOTICE,"wkb_to_lwgeom: entry with SRID=%i, dims=%i, simpletype=%i\n",SRID,(int) dims, (int) simpletype);
+#endif
+
+
        switch (simpletype)
        {
                case POINTTYPE:
@@ -133,14 +254,21 @@ char *wkb_to_lwgeom(char *wkb, int SRID,int *size)
                                                break;
                case LINETYPE:
                                                line = wkb_line_to_lwline(wkb, SRID);
+       printLWLINE(line);
+       elog(NOTICE,"have line with %i points",line->points->npoints);
                                                result  = lwline_serialize(line);
+       elog(NOTICE,"serialized it");
                                                *size = lwline_findlength(result);
+       elog(NOTICE,"serialized length=%i",*size);
                                                pfree_line(line);
                                                break;
                case POLYGONTYPE:
                                                poly = wkb_poly_to_lwpoly(wkb, SRID);
+       printLWPOLY(poly);
                                                result  = lwpoly_serialize(poly);
+       elog(NOTICE,"serialized polygon");
                                                *size = lwpoly_findlength(result);
+       elog(NOTICE,"serialized polygon has length = %i",*size);
                                                pfree_polygon(poly);
                                                break;
                case MULTIPOINTTYPE:
@@ -153,6 +281,10 @@ char *wkb_to_lwgeom(char *wkb, int SRID,int *size)
                case COLLECTIONTYPE:
                                                break;
        }
+#ifdef DEBUG
+        elog(NOTICE,"wkb_to_lwgeom:returning");
+#endif
+
        return result;
 }
 
@@ -175,11 +307,20 @@ LWPOINT *wkb_point_to_lwpoint(char *wkb,int SRID)
        dims = wkb_dims(wkbtype);
        simpletype = wkb_simpletype(wkbtype);
 
+#ifdef DEBUG
+        elog(NOTICE,"wkb_point_to_lwpoint: entry with SRID=%i, dims=%i, simpletype=%i\n",SRID,(int) dims, (int) simpletype);
+#endif
+
+
+
+
        if (simpletype != POINTTYPE)
                elog(ERROR,"WKB::point parser - go wrong type");
 
        pa = pointArray_construct(wkb+5, dims, 1);
 
+
+
        return lwpoint_construct(dims, SRID, pa);
 }
 
@@ -211,7 +352,7 @@ LWLINE *wkb_line_to_lwline(char *wkb,int SRID)
                flipPoints(wkb+9,npoints,dims);
 
        pa = pointArray_construct(wkb+9, dims, npoints);
-
+printPA(pa);
        return lwline_construct(dims, SRID, pa);
 }
 
@@ -244,10 +385,11 @@ LWPOLY *wkb_poly_to_lwpoly(char *wkb,int SRID)
 
                nrings = get_uint32(wkb+5);
 
-               loc = wkb+5;
+               loc = wkb+9;
 
                        //point size
 
+               ptsize =16;
                if (dims == FOURDIMS)
                {
                        ptsize = 32;
@@ -271,7 +413,7 @@ LWPOLY *wkb_poly_to_lwpoly(char *wkb,int SRID)
                                        // read a ring
                        if (need_flip)
                                flipPoints(loc+4,npoints,dims);
-
+elog(NOTICE,"wkb_poly_to_lwpoly:: doing ring %i with %i points", t, npoints);
                        pa = pointArray_construct(loc+4, dims, npoints);
 
                        loc += 4;
@@ -296,6 +438,10 @@ char *lwgeom_to_wkb(char *serialized_form,int *wkblength,char desiredWKBEndian)
        LWPOLY *poly;
        char   *multigeom = NULL;
 
+#ifdef DEBUG
+        elog(NOTICE,"lwgeom_to_wkb: entry with  simpletype=%i, dims=%i\n",(int) simple_type,(int)  lwgeom_is3d( serialized_form[0]) );
+#endif
+
 
        switch (simple_type)
        {
@@ -310,7 +456,9 @@ char *lwgeom_to_wkb(char *serialized_form,int *wkblength,char desiredWKBEndian)
                                                pfree_line(line);
                                                break;
                case POLYGONTYPE:
+       elog(NOTICE,"lwgeom_to_wkb :: deserializing polygon");
                                                poly = lwpoly_deserialize(serialized_form);
+       printLWPOLY(poly);
                                                result = lwpoly_to_wkb(poly, desiredWKBEndian, wkblength);
                                                pfree_polygon(poly );
                                                break;
@@ -334,6 +482,10 @@ char *lwpoint_to_wkb(LWPOINT *pt, char desiredWKBEndian, int *wkbsize)
        uint32 wkbtype ;
        bool need_flip =  requiresflip( desiredWKBEndian );
 
+#ifdef DEBUG
+        elog(NOTICE,"lwpoint_to_wkb:  pa dims = %i\n", (int)pt->point->is3d );
+#endif
+
 
        *wkbsize = 1+ 4+ ptsize; //endian, type, point
 
@@ -342,6 +494,13 @@ char *lwpoint_to_wkb(LWPOINT *pt, char desiredWKBEndian, int *wkbsize)
        result[0] = desiredWKBEndian; //endian flag
 
        wkbtype = constructWKBType(POINTTYPE, pt->point->is3d);
+
+#ifdef DEBUG
+        elog(NOTICE,"lwpoint_to_wkb: entry with wkbtype=%i, pa dims = %i\n",wkbtype, (int)pt->point->is3d );
+#endif
+
+
+
        memcpy(result+1, &wkbtype, 4);
        if (need_flip)
                flip_endian_int32(result+1);
@@ -361,7 +520,9 @@ char *lwline_to_wkb(LWLINE *line, char desiredWKBEndian, int *wkbsize)
                bool need_flip =  requiresflip( desiredWKBEndian );
 
 
-               *wkbsize = 1+ 4+ line->points->npoints * ptsize; //endian, type, points
+printLWLINE(line);
+
+               *wkbsize = 1+ 4+4+ line->points->npoints * ptsize; //endian, type, npoints, points
 
                result = palloc(*wkbsize);
 
@@ -372,9 +533,13 @@ char *lwline_to_wkb(LWLINE *line, char desiredWKBEndian, int *wkbsize)
                if (need_flip)
                        flip_endian_int32(result+1);
 
-               memcpy(result+5, line->points->serialized_pointlist, pointArray_ptsize(line->points) * line->points->npoints);
+               memcpy(result+5, &line->points->npoints, 4);
                if (need_flip)
-                       flipPoints(result+5, line->points->npoints, line->points->is3d);
+                       flip_endian_int32(result+5);
+
+               memcpy(result+9, line->points->serialized_pointlist, ptsize * line->points->npoints);
+               if (need_flip)
+                       flipPoints(result+9, line->points->npoints, line->points->is3d);
                return result;
 }
 
@@ -518,3 +683,237 @@ uint32 constructWKBType(int simple_type, char dims)
        return simple_type | 0x40000000;
 }
 
+
+//given one byte, populate result with two byte representing
+// the hex number
+// ie deparse_hex( 255, mystr)
+//             -> mystr[0] = 'F' and mystr[1] = 'F'
+// no error checking done
+void deparse_hex(unsigned char str, unsigned char *result)
+{
+       int     input_high;
+       int  input_low;
+
+       input_high = (str>>4);
+       input_low = (str & 0x0F);
+
+       switch (input_high)
+       {
+               case 0:
+                       result[0] = '0';
+                       break;
+               case 1:
+                       result[0] = '1';
+                       break;
+               case 2:
+                       result[0] = '2';
+                       break;
+               case 3:
+                       result[0] = '3';
+                       break;
+               case 4:
+                       result[0] = '4';
+                       break;
+               case 5:
+                       result[0] = '5';
+                       break;
+               case 6:
+                       result[0] = '6';
+                       break;
+               case 7:
+                       result[0] = '7';
+                       break;
+               case 8:
+                       result[0] = '8';
+                       break;
+               case 9:
+                       result[0] = '9';
+                       break;
+               case 10:
+                       result[0] = 'A';
+                       break;
+               case 11:
+                       result[0] = 'B';
+                       break;
+               case 12:
+                       result[0] = 'C';
+                       break;
+               case 13:
+                       result[0] = 'D';
+                       break;
+               case 14:
+                       result[0] = 'E';
+                       break;
+               case 15:
+                       result[0] = 'F';
+                       break;
+       }
+
+       switch (input_low)
+       {
+               case 0:
+                       result[1] = '0';
+                       break;
+               case 1:
+                       result[1] = '1';
+                       break;
+               case 2:
+                       result[1] = '2';
+                       break;
+               case 3:
+                       result[1] = '3';
+                       break;
+               case 4:
+                       result[1] = '4';
+                       break;
+               case 5:
+                       result[1] = '5';
+                       break;
+               case 6:
+                       result[1] = '6';
+                       break;
+               case 7:
+                       result[1] = '7';
+                       break;
+               case 8:
+                       result[1] = '8';
+                       break;
+               case 9:
+                       result[1] = '9';
+                       break;
+               case 10:
+                       result[1] = 'A';
+                       break;
+               case 11:
+                       result[1] = 'B';
+                       break;
+               case 12:
+                       result[1] = 'C';
+                       break;
+               case 13:
+                       result[1] = 'D';
+                       break;
+               case 14:
+                       result[1] = 'E';
+                       break;
+               case 15:
+                       result[1] = 'F';
+                       break;
+       }
+}
+
+
+//given a string with at least 2 chars in it, convert them to
+// a byte value.  No error checking done!
+unsigned char  parse_hex(char *str)
+{
+       //do this a little brute force to make it faster
+
+       unsigned char           result_high = 0;
+       unsigned char           result_low = 0;
+
+       switch (str[0])
+       {
+               case '0' :
+                       result_high = 0;
+                       break;
+               case '1' :
+                       result_high = 1;
+                       break;
+               case '2' :
+                       result_high = 2;
+                       break;
+               case '3' :
+                       result_high = 3;
+                       break;
+               case '4' :
+                       result_high = 4;
+                       break;
+               case '5' :
+                       result_high = 5;
+                       break;
+               case '6' :
+                       result_high = 6;
+                       break;
+               case '7' :
+                       result_high = 7;
+                       break;
+               case '8' :
+                       result_high = 8;
+                       break;
+               case '9' :
+                       result_high = 9;
+                       break;
+               case 'A' :
+                       result_high = 10;
+                       break;
+               case 'B' :
+                       result_high = 11;
+                       break;
+               case 'C' :
+                       result_high = 12;
+                       break;
+               case 'D' :
+                       result_high = 13;
+                       break;
+               case 'E' :
+                       result_high = 14;
+                       break;
+               case 'F' :
+                       result_high = 15;
+                       break;
+       }
+       switch (str[1])
+       {
+               case '0' :
+                       result_low = 0;
+                       break;
+               case '1' :
+                       result_low = 1;
+                       break;
+               case '2' :
+                       result_low = 2;
+                       break;
+               case '3' :
+                       result_low = 3;
+                       break;
+               case '4' :
+                       result_low = 4;
+                       break;
+               case '5' :
+                       result_low = 5;
+                       break;
+               case '6' :
+                       result_low = 6;
+                       break;
+               case '7' :
+                       result_low = 7;
+                       break;
+               case '8' :
+                       result_low = 8;
+                       break;
+               case '9' :
+                       result_low = 9;
+                       break;
+               case 'A' :
+                       result_low = 10;
+                       break;
+               case 'B' :
+                       result_low = 11;
+                       break;
+               case 'C' :
+                       result_low = 12;
+                       break;
+               case 'D' :
+                       result_low = 13;
+                       break;
+               case 'E' :
+                       result_low = 14;
+                       break;
+               case 'F' :
+                       result_low = 15;
+                       break;
+       }
+       return (unsigned char) ((result_high<<4) + result_low);
+}
+