From: David Blasby Date: Wed, 6 Aug 2003 19:31:18 +0000 (+0000) Subject: Added the WKB parser. Added all the functions like X-Git-Tag: pgis_0_8_0~96 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b9ff5141c8088827f38f575ae8e2151a079bc218;p=postgis Added the WKB parser. Added all the functions like PolyFromWKB(,[]). Added all the functions like PolyFromText(,[]) Minor problem in GEOS library fixed. git-svn-id: http://svn.osgeo.org/postgis/trunk@286 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/Attic/postgis_sql_common.sql.in b/Attic/postgis_sql_common.sql.in index b5d440eda..32d4352b7 100644 --- a/Attic/postgis_sql_common.sql.in +++ b/Attic/postgis_sql_common.sql.in @@ -12,6 +12,14 @@ -- -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- $Log$ +-- Revision 1.13 2003/08/06 19:31:18 dblasby +-- Added the WKB parser. Added all the functions like +-- PolyFromWKB(,[]). +-- +-- Added all the functions like PolyFromText(,[]) +-- +-- Minor problem in GEOS library fixed. +-- -- Revision 1.12 2003/08/01 23:58:08 dblasby -- added the functionality to convert GEOS->PostGIS geometries. Added those geos -- functions to postgis. @@ -417,7 +425,93 @@ CREATE FUNCTION bytea(wkb) RETURNS bytea AS '@MODULE_FILENAME@','WKBtoBYTEA' LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION geometry(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','geometryfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION GeomFromWKB(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','geometryfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION GeomFromWKB(wkb,int) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','geometryfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION PointFromWKB(wkb,int) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','PointfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION PointFromWKB(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','PointfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION LineFromWKB(wkb,int) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','LinefromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); +CREATE FUNCTION LineFromWKB(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','LinefromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION PolyFromWKB(wkb,int) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','PolyfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION PolyFromWKB(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','PolyfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION MPointFromWKB(wkb,int) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','MPointfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION MPointFromWKB(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','MPointfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION MLineFromWKB(wkb,int) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','MLinefromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION MLineFromWKB(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','MLinefromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION MPolyFromWKB(wkb,int) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','MPolyfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION MPolyFromWKB(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','MPolyfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION GeomCollFromWKB(wkb,int) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','GCfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + +CREATE FUNCTION GeomCollFromWKB(wkb) + RETURNS GEOMETRY + AS '@MODULE_FILENAME@','GCfromWKB_SRID' + LANGUAGE 'C' WITH (iscachable,isstrict); + + -- CREATE FUNCTION index_thing(geometry) -- RETURNS BOOL -- AS '@MODULE_FILENAME@' @@ -556,52 +650,102 @@ CREATE FUNCTION geometryfromtext(geometry,int4) RETURNS geometry AS '@MODULE_FILENAME@','geometry_from_text' LANGUAGE 'C' WITH (isstrict,iscachable); + + +CREATE FUNCTION geometryfromtext(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text' + LANGUAGE 'C' WITH (isstrict,iscachable); CREATE FUNCTION geomfromtext(geometry,int4) RETURNS geometry AS '@MODULE_FILENAME@','geometry_from_text' LANGUAGE 'C' WITH (isstrict,iscachable); -CREATE FUNCTION polygonfromtext(geometry,int4) +CREATE FUNCTION geomfromtext(geometry) RETURNS geometry AS '@MODULE_FILENAME@','geometry_from_text' LANGUAGE 'C' WITH (isstrict,iscachable); -CREATE FUNCTION multipolygonfromtext(geometry,int4) +CREATE FUNCTION polyfromtext(geometry,int4) RETURNS geometry - AS '@MODULE_FILENAME@','geometry_from_text' + AS '@MODULE_FILENAME@','geometry_from_text_poly' LANGUAGE 'C' WITH (isstrict,iscachable); -CREATE FUNCTION linestringfromtext(geometry,int4) +CREATE FUNCTION mpolyfromtext(geometry,int4) RETURNS geometry - AS '@MODULE_FILENAME@','geometry_from_text' + AS '@MODULE_FILENAME@','geometry_from_text_mpoly' LANGUAGE 'C' WITH (isstrict,iscachable); -CREATE FUNCTION multilinestringfromtext(geometry,int4) +CREATE FUNCTION linefromtext(geometry,int4) RETURNS geometry - AS '@MODULE_FILENAME@','geometry_from_text' + AS '@MODULE_FILENAME@','geometry_from_text_line' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATE FUNCTION mlinefromtext(geometry,int4) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text_mline' LANGUAGE 'C' WITH (isstrict,iscachable); CREATE FUNCTION pointfromtext(geometry,int4) RETURNS geometry - AS '@MODULE_FILENAME@','geometry_from_text' + AS '@MODULE_FILENAME@','geometry_from_text_point' LANGUAGE 'C' WITH (isstrict,iscachable); -CREATE FUNCTION multipointfromtext(geometry,int4) +CREATE FUNCTION mpointfromtext(geometry,int4) RETURNS geometry - AS '@MODULE_FILENAME@','geometry_from_text' + AS '@MODULE_FILENAME@','geometry_from_text_mpoint' LANGUAGE 'C' WITH (isstrict,iscachable); -CREATE FUNCTION geometrycollectionfromtext(geometry,int4) +CREATE FUNCTION geomcollfromtext(geometry,int4) RETURNS geometry - AS '@MODULE_FILENAME@','geometry_from_text' + AS '@MODULE_FILENAME@','geometry_from_text_gc' LANGUAGE 'C' WITH (isstrict,iscachable); CREATE FUNCTION setSRID(geometry,int4) RETURNS geometry - AS '@MODULE_FILENAME@','geometry_from_text' + AS '@MODULE_FILENAME@','geometry_from_text_gc' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATE FUNCTION polyfromtext(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text_poly' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATE FUNCTION mpolyfromtext(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text_mpoly' LANGUAGE 'C' WITH (isstrict,iscachable); +CREATE FUNCTION linefromtext(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text_line' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATE FUNCTION mlinefromtext(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text_mline' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATE FUNCTION pointfromtext(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text_point' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATE FUNCTION mpointfromtext(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text_mpoint' + LANGUAGE 'C' WITH (isstrict,iscachable); + +CREATE FUNCTION geomcollfromtext(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text_gc' + LANGUAGE 'C' WITH (isstrict,iscachable); + + + + + -- -- Special spheroid functions -- diff --git a/postgis.h b/postgis.h index bb4815d1b..742201fb4 100644 --- a/postgis.h +++ b/postgis.h @@ -8,9 +8,17 @@ * * This is free software; you can redistribute and/or modify it under * the terms of hte GNU General Public Licence. See the COPYING file. - * + * ********************************************************************** * $Log$ + * Revision 1.32 2003/08/06 19:31:18 dblasby + * Added the WKB parser. Added all the functions like + * PolyFromWKB(,[]). + * + * Added all the functions like PolyFromText(,[]) + * + * Minor problem in GEOS library fixed. + * * Revision 1.31 2003/07/25 17:08:37 pramsey * Moved Cygwin endian define out of source files into postgis.h common * header file. @@ -411,6 +419,11 @@ char *geometry_to_text(GEOMETRY *geometry); BOX3D *parse_box3d(char *str); +int getint(char *c); +double getdouble(char *c); +GEOMETRY *WKBtoGeometry(char *WKB, int length, int *bytes_read); + +POINT3D *wkb_linearring(char *WKB,char is3d, char flip_endian, int *numbPoints, int *bytes,int bytes_in_stream); //exposed to psql @@ -558,6 +571,26 @@ Datum estimate_histogram2d(PG_FUNCTION_ARGS); Datum postgisgistcostestimate(PG_FUNCTION_ARGS); +Datum geometryfromWKB(PG_FUNCTION_ARGS); +Datum geometryfromWKB_SRID(PG_FUNCTION_ARGS); + +Datum PointfromWKB_SRID(PG_FUNCTION_ARGS); +Datum LinefromWKB_SRID(PG_FUNCTION_ARGS); +Datum PolyfromWKB_SRID(PG_FUNCTION_ARGS); +Datum MPointfromWKB_SRID(PG_FUNCTION_ARGS); +Datum MLinefromWKB_SRID(PG_FUNCTION_ARGS); +Datum MPolyfromWKB_SRID(PG_FUNCTION_ARGS); +Datum GCfromWKB_SRID(PG_FUNCTION_ARGS); + + +Datum geometry_from_text_poly(PG_FUNCTION_ARGS); +Datum geometry_from_text_mpoly(PG_FUNCTION_ARGS); +Datum geometry_from_text_point(PG_FUNCTION_ARGS); +Datum geometry_from_text_mpoint(PG_FUNCTION_ARGS); +Datum geometry_from_text_line(PG_FUNCTION_ARGS); +Datum geometry_from_text_mline(PG_FUNCTION_ARGS); +Datum geometry_from_text_gc(PG_FUNCTION_ARGS); + /*-------------------------------------------------------------------- * Useful floating point utilities and constants. * from postgres geo_decls.c diff --git a/postgis_geos.c b/postgis_geos.c index dc2c2c101..4af704394 100644 --- a/postgis_geos.c +++ b/postgis_geos.c @@ -10,6 +10,14 @@ * ********************************************************************** * $Log$ + * Revision 1.7 2003/08/06 19:31:18 dblasby + * Added the WKB parser. Added all the functions like + * PolyFromWKB(,[]). + * + * Added all the functions like PolyFromText(,[]) + * + * Minor problem in GEOS library fixed. + * * Revision 1.6 2003/08/05 18:27:21 dblasby * Added null implementations of new GEOS-returning-geometry functions (ie. * buffer). @@ -1000,6 +1008,7 @@ GEOMETRY *GEOS2POSTGIS(Geometry *g,char want3d) { char *type = GEOSGeometryType(g) ; GEOMETRY *result = NULL; + BOX3D *bbox ; if (strcmp(type,"Point") ==0 ) { @@ -1076,6 +1085,12 @@ GEOMETRY *GEOS2POSTGIS(Geometry *g,char want3d) } GEOSdeleteChar( (char*) pts); + + + bbox = bbox_of_geometry( g_new ); // make bounding box + memcpy( &g_new->bvol, bbox, sizeof(BOX3D) ); // copy bounding box + pfree( bbox ); // free bounding box + return g_new; } else if (strcmp(type,"MultiLineString")==0) @@ -1108,6 +1123,10 @@ GEOMETRY *GEOS2POSTGIS(Geometry *g,char want3d) pfree(g_old); } } + bbox = bbox_of_geometry( result ); // make bounding box + memcpy( &result->bvol, bbox, sizeof(BOX3D) ); // copy bounding box + pfree( bbox ); // free bounding box + return result; } @@ -1141,6 +1160,9 @@ GEOMETRY *GEOS2POSTGIS(Geometry *g,char want3d) pfree(g_old); } } + bbox = bbox_of_geometry( result ); // make bounding box + memcpy( &result->bvol, bbox, sizeof(BOX3D) ); // copy bounding box + pfree( bbox ); // free bounding box return result; } else if (strcmp(type,"GeometryCollection")==0) diff --git a/postgis_inout.c b/postgis_inout.c index 0a3388b9b..07acc72cb 100644 --- a/postgis_inout.c +++ b/postgis_inout.c @@ -8,9 +8,17 @@ * * This is free software; you can redistribute and/or modify it under * the terms of hte GNU General Public Licence. See the COPYING file. - * + * ********************************************************************** * $Log$ + * Revision 1.24 2003/08/06 19:31:18 dblasby + * Added the WKB parser. Added all the functions like + * PolyFromWKB(,[]). + * + * Added all the functions like PolyFromText(,[]) + * + * Minor problem in GEOS library fixed. + * * Revision 1.23 2003/07/25 17:08:37 pramsey * Moved Cygwin endian define out of source files into postgis.h common * header file. @@ -56,7 +64,7 @@ //#define DEBUG_GIST2 - +#define WKB3DOFFSET 0x80000000 void swap_char(char *a,char *b) @@ -1411,10 +1419,16 @@ PG_FUNCTION_INFO_V1(geometry_from_text); Datum geometry_from_text(PG_FUNCTION_ARGS) { GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - int32 SRID = PG_GETARG_INT32(1); + int32 SRID; GEOMETRY *result; + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + result = (GEOMETRY *) palloc(geom1->size); memcpy(result,geom1, geom1->size); @@ -2071,7 +2085,7 @@ char *wkb_point(POINT3D *pt,int32 *size, bool flipbytes, char byte_order, bool u if (use3d) { *size = 29; - type = 32768 + 1; + type = ((unsigned int) WKB3DOFFSET + ((unsigned int)1)); } else { @@ -2125,7 +2139,7 @@ char *wkb_multipoint(POINT3D *pt,int32 numb_points,int32 *size, bool flipbytes, if (use3d) { *size = 9 + sub_size_3d*numb_points; - type = 32768 + 4; + type = WKB3DOFFSET + 4; } else { @@ -2189,7 +2203,7 @@ char *wkb_line(LINE3D *line,int32 *size, bool flipbytes, char byte_order,bool us if (use3d) { *size = 9 + 24*numb_points; - type = 32768 + 2; + type = WKB3DOFFSET + 2; } else { @@ -2269,7 +2283,7 @@ char *wkb_multiline(LINE3D **lines,int32 *size, int numb_lines, bool flipbytes, if (use3d) { - type = 32768 + 5; + type = WKB3DOFFSET + 5; } else { @@ -2361,7 +2375,7 @@ char *wkb_polygon(POLYGON3D *poly,int32 *size, bool flipbytes, char byte_order,b if (use3d) { *size = 9 + 4*poly->nrings + 24*total_points; - type = 32768 + 3; + type = WKB3DOFFSET + 3; } else { @@ -2475,7 +2489,7 @@ char *wkb_multipolygon(POLYGON3D **polys,int numb_polys,int32 *size, bool flipby if (use3d) { - type = 32768 + 6; + type = WKB3DOFFSET + 6; } else { @@ -2823,7 +2837,7 @@ char *to_wkb_sub(GEOMETRY *geom, bool flip_endian, int32 *wkb_size) //convert binary geometry into OGIS well know binary format with NDR (little endian) formating // see http://www.opengis.org/techno/specs/99-049.rtf page 3-24 for specification // -// 3d geometries are encode as in OGR by adding 32768 to the type. Points are then 24bytes (X,Y,Z) +// 3d geometries are encode as in OGR by adding WKB3DOFFSET to the type. Points are then 24bytes (X,Y,Z) // instead of 16 bytes (X,Y) // //dont do any flipping of endian asbinary_simple(GEOMETRY) @@ -2839,7 +2853,7 @@ Datum asbinary_simple(PG_FUNCTION_ARGS) //convert binary geometry into OGIS well know binary format with NDR (little endian) formating // see http://www.opengis.org/techno/specs/99-049.rtf page 3-24 for specification // -// 3d geometries are encode as in OGR by adding 32768 to the type. Points are then 24bytes (X,Y,Z) +// 3d geometries are encode as in OGR by adding WKB3DOFFSET to the type. Points are then 24bytes (X,Y,Z) // instead of 16 bytes (X,Y) // //flip if required asbinary_specify(GEOMETRY,'xdr') or asbinary_specify(GEOMETRY,'ndr') @@ -2855,7 +2869,7 @@ Datum asbinary_specify(PG_FUNCTION_ARGS) elog(ERROR,"asbinary(geometry, ) - type should be 'XDR' or 'NDR'. type length is %i",VARSIZE(type) -4); PG_RETURN_NULL(); } - + if ( ( strncmp(VARDATA(type) ,"xdr",3) == 0 ) || (strncmp(VARDATA(type) ,"XDR",3) == 0) ) { //printf("requested XDR\n"); @@ -3644,3 +3658,968 @@ Datum histogram2d_out(PG_FUNCTION_ARGS) } + + +int getint(char *c) +{ + return *((int*)c); +} + +double getdouble(char *c) +{ + return *((double*)c); +} + +//void flip_endian_double(char *dd); +//void flip_endian_int32(char *ii); + + +//select geometry(asbinary('POINT(1 2 3)','XDR')); +//select geometry(asbinary('POINT(1 2)','XDR')); +//select geometry(asbinary('POINT(1 2 3)','NDR')); +//select geometry(asbinary('POINT(1 2)','NDR')); + +//select geometry(asbinary('LINESTRING(1 2, 3 4)','XDR')); +//select geometry(asbinary('LINESTRING(1 2, 3 4)','NDR')); +//select geometry(asbinary('LINESTRING(1 2 5 , 3 4 6)','XDR')); +//select geometry(asbinary('LINESTRING(1 2 5 , 3 4 6)','NDR')); + + +//select geometry(asbinary('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','XDR')); +//select geometry(asbinary('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','NDR')); +//select geometry(asbinary('POLYGON((0 0 0, 10 0, 10 10, 0 10, 0 0))','XDR')); +//select geometry(asbinary('POLYGON((0 0 0, 10 0, 10 10, 0 10, 0 0))','NDR')); + +//select geometry(asbinary('POLYGON((5 5, 15 5, 15 7, 5 7, 5 5 ),(6 6,6.5 6, 6.5 6.5,6 6.5,6 6))','NDR')); +//select geometry(asbinary('POLYGON((5 5, 15 5, 15 7, 5 7, 5 5 ),(6 6,6.5 6, 6.5 6.5,6 6.5,6 6))','XDR')); +//select geometry(asbinary('POLYGON((5 5 0, 15 5, 15 7, 5 7, 5 5 ),(6 6,6.5 6, 6.5 6.5,6 6.5,6 6))','NDR')); +//select geometry(asbinary('POLYGON((5 5 0, 15 5, 15 7, 5 7, 5 5 ),(6 6,6.5 6, 6.5 6.5,6 6.5,6 6))','XDR')); + + +//select geometry(asbinary('MULTIPOINT(0 0, 10 0, 10 10, 0 10, 0 0)','NDR')); +//select geometry(asbinary('MULTIPOINT(0 0, 10 0, 10 10, 0 10, 0 0 0)','NDR')); +//select geometry(asbinary('MULTIPOINT(0 0, 10 0, 10 10, 0 10, 0 0)','XDR')); +//select geometry(asbinary('MULTIPOINT(0 0, 10 0, 10 10, 0 10, 0 0 0)','NDR')); + + +//select geometry(asbinary('MULTILINESTRING((5 5, 10 10),(1 1, 2 2) )','NDR')); +//select geometry(asbinary('MULTILINESTRING((5 5, 10 10),(1 1, 2 2 0) )','NDR')); +//select geometry(asbinary('MULTILINESTRING((5 5, 10 10),(1 1, 2 2) )','XDR')); +//select geometry(asbinary('MULTILINESTRING((5 5, 10 10),(1 1, 2 2 0) )','XDR')); + + +//select geometry(asbinary('MULTIPOLYGON(((5 5, 15 5, 15 7, 5 7, 5 5)),((1 1,1 2,2 2,1 2, 1 1)))','NDR')); +//select geometry(asbinary('MULTIPOLYGON(((5 5, 15 5, 15 7, 5 7, 5 5)),((1 1,1 2,2 2,1 2, 1 1 0)))','NDR')); +//select geometry(asbinary('MULTIPOLYGON(((5 5, 15 5, 15 7, 5 7, 5 5)),((1 1,1 2,2 2,1 2, 1 1)))','XDR')); +//select geometry(asbinary('MULTIPOLYGON(((5 5, 15 5, 15 7, 5 7, 5 5)),((1 1,1 2,2 2,1 2, 1 1 0)))','XDR')); + + +//select geometry(asbinary('GEOMETRYCOLLECTION(POINT(1 2),POINT(3 4))','NDR')); +//select geometry(asbinary('GEOMETRYCOLLECTION(POINT(1 2 3),LINESTRING(1 2, 3 4),POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)))','NDR')); +// geometryfromWKB(, [] ) +PG_FUNCTION_INFO_V1(geometryfromWKB_SRID); +Datum geometryfromWKB_SRID(PG_FUNCTION_ARGS) +{ + char *wkb_input = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + int SRID = PG_GETARG_INT32(1); + char *wkb = &wkb_input[4]; + int wkb_size = *((int *) wkb_input); + int bytes_read; + GEOMETRY *result; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + +//elog(NOTICE,"geometryfromWKB:: size = %i",wkb_size); + + result = WKBtoGeometry(wkb,wkb_size,&bytes_read); + + if (result == NULL) + { + PG_RETURN_NULL(); + } + else + { + result->SRID = SRID; + PG_RETURN_POINTER(result); + } +} + +PG_FUNCTION_INFO_V1(PointfromWKB_SRID); +Datum PointfromWKB_SRID(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometryfromWKB_SRID, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != POINTTYPE) + { + elog(ERROR,"PointfromWKB:: WKB isnt POINT"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(LinefromWKB_SRID); +Datum LinefromWKB_SRID(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometryfromWKB_SRID, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != LINETYPE) + { + elog(ERROR,"LinefromWKB_SRID:: WKB isnt LINESTRING"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(PolyfromWKB_SRID); +Datum PolyfromWKB_SRID(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometryfromWKB_SRID, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != POLYGONTYPE) + { + elog(ERROR,"PolyfromWKB_SRID:: WKB isnt POLYGON"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(MPointfromWKB_SRID); +Datum MPointfromWKB_SRID(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometryfromWKB_SRID, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != MULTIPOINTTYPE) + { + elog(ERROR,"MPointfromWKB_SRID:: WKB isnt MULTIPOINT"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(MLinefromWKB_SRID); +Datum MLinefromWKB_SRID(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometryfromWKB_SRID, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != MULTILINETYPE) + { + elog(ERROR,"MLinefromWKB_SRID:: WKB isnt MULTILINESTRING"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(MPolyfromWKB_SRID); +Datum MPolyfromWKB_SRID(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometryfromWKB_SRID, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != MULTIPOLYGONTYPE) + { + elog(ERROR,"MPolyfromWKB_SRID:: WKB isnt MULTIPOLYGON"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(GCfromWKB_SRID); +Datum GCfromWKB_SRID(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometryfromWKB_SRID, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != COLLECTIONTYPE) + { + elog(ERROR,"MPolyfromWKB_SRID:: WKB isnt GEOMETRYCOLLECTION"); + } + PG_RETURN_POINTER(geom); +} + + + + +//convert a WKB (that has length bytes) +// to a GEOMETRY. This function read bytes_read bytes during the operation +// This function will call itself "recursively" on GeometryCollections +GEOMETRY *WKBtoGeometry(char *WKB, int length, int *bytes_read) +{ + char myByteOrder; + char wkbByteOrder; + int wkbType; + char is3d; + +*bytes_read = 0; +if (length<5) + elog(ERROR,"WKB:: insufficient bytes in stream"); + + +if ( BYTE_ORDER == BIG_ENDIAN ) + myByteOrder=0; +else + myByteOrder=1; + +wkbByteOrder = *(WKB); + +if (!( (wkbByteOrder==0) || (wkbByteOrder==1) )) +{ + elog(ERROR,"WKB is not valid - endian code = %i", (int) wkbByteOrder); + return NULL; +} + +WKB ++; // skip to next byte +(*bytes_read)++; + +if (myByteOrder == wkbByteOrder) +{ + wkbType = getint(WKB); +} +else +{ + flip_endian_int32( WKB ); + wkbType = getint(WKB); +} +WKB += 4; +(*bytes_read) += 4; + +//elog(NOTICE,"my byte order is %i",myByteOrder); +//elog(NOTICE,"WKB byte order is %i",wkbByteOrder); +//elog(NOTICE,"WKB type is %i",wkbType); + +is3d = 0; + +switch (wkbType) +{ + case (0x80000000 +1): //point 3d + is3d = 1; + case 1: //point 2d + if ( (length-(*bytes_read)) < (16+is3d*8)) + elog(ERROR,"WKB:: insufficient bytes in stream"); + { + POINT3D pt; + if (myByteOrder == wkbByteOrder) + { + pt.x = getdouble(WKB); + WKB+=8; + (*bytes_read)+=8; + pt.y = getdouble(WKB); + WKB+=8; + (*bytes_read)+=8; + if (is3d) + { + pt.z = getdouble(WKB); + WKB+=8; + (*bytes_read)+=8; + } + else + { + pt.z=0; + } + } + else + { + flip_endian_double(WKB); + pt.x = getdouble(WKB); + WKB+=8; + (*bytes_read)+=8; + flip_endian_double(WKB); + pt.y = getdouble(WKB); + WKB+=8; + (*bytes_read)+=8; + if (is3d) + { + flip_endian_double(WKB); + pt.z = getdouble(WKB); + WKB+=8; + (*bytes_read)+=8; + } + else + { + pt.z =0; + } + } + return make_oneobj_geometry(sizeof(POINT3D), + (char *) &pt, + POINTTYPE, is3d, -1,1.0, 0.0, 0.0 + ); + } + + + break; + case (0x80000000 +2): //line 3d + is3d = 1; + case 2: //line 2d + if ( (length-(*bytes_read)) < (4)) + elog(ERROR,"WKB:: insufficient bytes in stream"); + { + int npoints,t; + POINT3D *pts; + int size; + LINE3D *line; + if (myByteOrder == wkbByteOrder) + { + npoints= getint(WKB); + WKB+=4; + (*bytes_read)+=4; + if ( (length-(*bytes_read)) < ((16+is3d*8))*npoints) + elog(ERROR,"WKB:: insufficient bytes in stream"); + + pts = palloc( npoints *sizeof(POINT3D)); + for (t=0;ttype = MULTIPOINTTYPE; + + if (ngeoms ==1) + return so_far; + + for (t=1;ttype = MULTILINETYPE; + + if (ngeoms ==1) + return so_far; + + for (t=1;ttype = MULTIPOLYGONTYPE; + + if (ngeoms ==1) + return so_far; + + for (t=1;ttype = COLLECTIONTYPE; + + if (ngeoms ==1) + return so_far; + + for (t=1;t1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometry_from_text, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != POLYGONTYPE) + { + elog(ERROR,"geometry_from_text_poly:: WKT isnt POLYGON"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(geometry_from_text_line); +Datum geometry_from_text_line(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometry_from_text, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != LINETYPE) + { + elog(ERROR,"geometry_from_text_line:: WKT isnt LINESTRING"); + } + PG_RETURN_POINTER(geom); +} + + +PG_FUNCTION_INFO_V1(geometry_from_text_point); +Datum geometry_from_text_point(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometry_from_text, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != POINTTYPE) + { + elog(ERROR,"geometry_from_text_point:: WKT isnt POINT"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(geometry_from_text_mpoint); +Datum geometry_from_text_mpoint(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometry_from_text, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != MULTIPOINTTYPE) + { + elog(ERROR,"geometry_from_text_mpoint:: WKT isnt MULTIPOINT"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(geometry_from_text_mline); +Datum geometry_from_text_mline(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometry_from_text, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != MULTILINETYPE) + { + elog(ERROR,"geometry_from_text_mline:: WKT isnt MULTILINESTRING"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(geometry_from_text_mpoly); +Datum geometry_from_text_mpoly(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometry_from_text, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != MULTIPOLYGONTYPE) + { + elog(ERROR,"geometry_from_text_mpoly:: WKT isnt MULTIPOLYGON"); + } + PG_RETURN_POINTER(geom); +} + +PG_FUNCTION_INFO_V1(geometry_from_text_gc); +Datum geometry_from_text_gc(PG_FUNCTION_ARGS) +{ + int SRID; + GEOMETRY *geom; + + if (PG_NARGS() >1) + SRID = PG_GETARG_INT32(1); + else + SRID = -1; + + + geom = (GEOMETRY *) DatumGetPointer( + DirectFunctionCall2(geometry_from_text, + PG_GETARG_DATUM(0),Int32GetDatum(SRID) + )); + if (geom->type != COLLECTIONTYPE) + { + elog(ERROR,"geometry_from_text_gc:: WKT isnt GEOMETRYCOLLECTION"); + } + PG_RETURN_POINTER(geom); +}