/************************************************************* postGIS - geometric types for postgres This software is copyrighted (2001). This is free software; you can redistribute it and/or modify it under the GNU General Public Licence. See the file "COPYING". More Info? See the documentation, join the mailing list (postgis@yahoogroups.com), or see the web page (http://postgis.refractions.net). *************************************************************/ #include "postgres.h" #include #include #include #include #include #include "access/gist.h" #include "access/itup.h" #include "access/rtree.h" #include "fmgr.h" #include "postgis.h" #include "utils/elog.h" //Norman Vine found this problem for compiling under cygwin // it defines BYTE_ORDER and LITTLE_ENDIAN #ifdef __CYGWIN__ #include #endif #define SHOW_DIGS_DOUBLE 15 #define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 6 + 1 + 3 +1) // #define DEBUG_GIST //#define DEBUG_GIST2 void print_box2d(BOX *box); void dump_bytes( char *a, int numb) { int t; for (t=0; tLLB.x, box->LLB.y,box->LLB.z); printf(" + URT = [%g,%g,%g]\n", box->URT.x, box->URT.y,box->URT.z); } void print_box2d(BOX *box) { printf (" BOX[%g %g , %g %g] ",box->low.x, box->low.y, box->high.x, box->high.y); } //debug function - whats really in that BOX3D? void print_box_oneline(BOX3D *box) { printf(" (%p) {",box); if (box == NULL) { printf ("BOX IS NULL}"); return; } printf("[%g,%g,%g] ", box->LLB.x, box->LLB.y,box->LLB.z); printf("[%g,%g,%g]}", box->URT.x, box->URT.y,box->URT.z); } //find the size of geometry PG_FUNCTION_INFO_V1(mem_size); Datum mem_size(PG_FUNCTION_ARGS) { GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); PG_RETURN_INT32(geom1->size); } //find the size of geometry PG_FUNCTION_INFO_V1(numb_sub_objs); Datum numb_sub_objs(PG_FUNCTION_ARGS) { GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); PG_RETURN_INT32(geom1->nobjs); } //get summary info on a GEOMETRY PG_FUNCTION_INFO_V1(summary); Datum summary(PG_FUNCTION_ARGS) { GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); int32 *offsets1; char *o1; int32 type1,j,i; POLYGON3D *poly; LINE3D *line; char *result; int size; char tmp[100]; text *mytext; size = 1; result = palloc(1); result[0] = 0; //null terminate it offsets1 = (int32 *) ( ((char *) &(geom1->objType[0] ))+ sizeof(int32) * geom1->nobjs ) ; //now have to do a scan of each object for (j=0; j< geom1->nobjs; j++) //for each object in geom1 { o1 = (char *) geom1 +offsets1[j] ; type1= geom1->objType[j]; if (type1 == POINTTYPE) //point { size += 30; result = repalloc(result,size); sprintf(tmp,"Object %i is a POINT()\n",j); strcat(result,tmp); } if (type1 == LINETYPE) //line { line = (LINE3D *) o1; size += 57; result = repalloc(result,size); sprintf(tmp,"Object %i is a LINESTRING() with %i points\n",j,line->npoints); strcat(result,tmp); } if (type1 == POLYGONTYPE) //POLYGON { poly = (POLYGON3D *) o1; size += 57*(poly->nrings +1); result = repalloc(result,size); sprintf(tmp,"Object %i is a POLYGON() with %i rings\n",j,poly->nrings); strcat(result,tmp); for (i=0; inrings;i++) { sprintf(tmp," + ring %i has %i points\n",i,poly->npoints[i]); strcat(result,tmp); } } } // create a text obj to return mytext = (text *) palloc(VARHDRSZ + strlen(result) ); VARATT_SIZEP(mytext) = VARHDRSZ + strlen(result) ; memcpy(VARDATA(mytext) , result, strlen(result) ); pfree(result); PG_RETURN_POINTER(mytext); } // DO NOT USE THESE decoding function (except for debugging purposes) // The code is NOT maintained and is thrown together // unsupported debugging function. // given a wkb input thats a geometrycollection, returns its size and prints out // its contents // // Its really messy - dont even think about using this for anything // // you shouldnt call this function; just call decode_wkb() and it will // call this function // void decode_wkb_collection(char *wkb,int *size) { int offset =0; bool flipbytes; int total_size=0,sub_size; int numb_sub,t; bool first_one = TRUE; if (wkb[0] ==0 ) //big endian { if (BYTE_ORDER == LITTLE_ENDIAN) flipbytes= 1; else flipbytes= 0; } else //little { if (BYTE_ORDER == LITTLE_ENDIAN) flipbytes= 0; else flipbytes= 1; } memcpy(&numb_sub, wkb+5,4); if (flipbytes) flip_endian_int32( (char *) & numb_sub) ; printf("GEOMETRYCOLLECTION(\n"); offset = 9; for (t=0;t 1000 ) { is3d = 1; type = type - 32768; } //printf(" Type = %i (is3d = %i)\n", type, is3d); if (type == 1) //POINT() { printf("POINT("); if (is3d) { memcpy(&x, &wkb[5], 8); memcpy(&y, &wkb[5+8], 8); memcpy(&z, &wkb[5+16], 8); if (flipbytes) { flip_endian_double( (char *) & x) ; flip_endian_double( (char *) & y) ; flip_endian_double( (char *) & z) ; } printf("%g %g %g)",x,y,z ); } else { memcpy(&x, &wkb[5], 8); memcpy(&y, &wkb[5+8], 8); if (flipbytes) { flip_endian_double( (char *) & x) ; flip_endian_double( (char *) & y) ; } printf("%g %g)", x,y); } printf("\n"); if (is3d) *size = 29; else *size = 21; return; } if (type == 2) { printf("LINESTRING("); memcpy(&n1, &wkb[5],4); if (flipbytes) flip_endian_int32( (char *) & n1) ; // printf(" --- has %i sub points\n",n1); first_one = TRUE; for (t=0; tx,p->y,p->z); }