From d64fd67e4ac7d39497dd510eba9b92fbfb0ab5d1 Mon Sep 17 00:00:00 2001 From: David Blasby Date: Mon, 30 Jul 2001 17:29:33 +0000 Subject: [PATCH] Starting to integrate all the SRIDs into functions that create geometries or use two geometries. Throws error if try to compare geometries with different SRIDs. git-svn-id: http://svn.osgeo.org/postgis/trunk@46 b70326c6-7e19-0410-871a-916f4a2858ee --- Makefile | 3 +- loader/Makefile | 17 +++++- postgis.h | 13 +++++ postgis.sql.in | 41 ++++++++++++++ postgis_inout.c | 139 +++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 204 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 0c3e5979a..238c279cc 100644 --- a/Makefile +++ b/Makefile @@ -42,8 +42,7 @@ shp2pgsql: include $(top_srcdir)/src/Makefile.shlib $(NAME).sql: $(NAME).sql.in - sed -e 's:@MODULE_FILENAME@:$(libdir)/$(shlib):g' < $< > $@ - + sed -e 's:@MODULE_FILENAME@:$(libdir)/$(shlib):g;s:@POSTGIS_VERSION@:$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION):g' < $< > $@ install: all installdirs install-lib $(INSTALL_DATA) $(srcdir)/README.$(NAME) $(docdir)/contrib diff --git a/loader/Makefile b/loader/Makefile index 4d2ee46c8..084e373f7 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -1,3 +1,19 @@ +# +# PostGIS Loader Makefile +# +subdir = contrib/postgis/loader + +# Root of the pgsql source tree +ifeq (${PGSQL_SRC},) + top_builddir = ../../.. + include $(top_builddir)/src/Makefile.global + libdir := $(libdir)/contrib +else + top_builddir = ${PGSQL_SRC} + include $(top_builddir)/src/Makefile.global + libdir := ${PWD} +endif + OBJS = shp2pgsql.o shpopen.o dbfopen.o PROG = shp2pgsql @@ -8,4 +24,3 @@ $(PROG): $(OBJS) clean: @rm -f $(OBJS) $(PROG) - diff --git a/postgis.h b/postgis.h index 3be7aaa40..de4c4801e 100644 --- a/postgis.h +++ b/postgis.h @@ -168,6 +168,10 @@ typedef struct typedef struct { int32 size; // postgres variable-length type requirement + int32 SRID; // spatial reference system id + double offsetX; // for precision grid (future improvement) + double offsetY; // for precision grid (future improvement) + double scale; // for precision grid (future improvement) int32 type; // this type of geometry bool is3d; // true if the points are 3d (only for output) BOX3D bvol; // bounding volume of all the geo objects @@ -308,12 +312,19 @@ bool point_in_poly(POINT3D *p, POLYGON3D *poly); void print_point_debug(POINT3D *p); + +char *geometry_to_text(GEOMETRY *geometry); + //exposed to psql Datum box3d_in(PG_FUNCTION_ARGS); Datum box3d_out(PG_FUNCTION_ARGS); Datum geometry_in(PG_FUNCTION_ARGS); Datum geometry_out(PG_FUNCTION_ARGS); + +Datum astext_geometry(PG_FUNCTION_ARGS); + + Datum get_bbox_of_geometry(PG_FUNCTION_ARGS); Datum get_geometry_of_bbox(PG_FUNCTION_ARGS); Datum box3d_same(PG_FUNCTION_ARGS); @@ -386,6 +397,8 @@ Datum point_inside_circle(PG_FUNCTION_ARGS); Datum distance(PG_FUNCTION_ARGS); Datum expand_bbox(PG_FUNCTION_ARGS); +Datum srid_geom(PG_FUNCTION_ARGS); +Datum geometry_from_text(PG_FUNCTION_ARGS); //for GIST index typedef char* (*BINARY_UNION)(char*, char*, int*); diff --git a/postgis.sql.in b/postgis.sql.in index f92f60049..2fe7be7fa 100644 --- a/postgis.sql.in +++ b/postgis.sql.in @@ -1,5 +1,28 @@ BEGIN TRANSACTION; +CREATE FUNCTION POSTGIS_VERSION() returns char +as 'select \'@POSTGIS_VERSION@\'::char as version' +LANGUAGE 'sql'; + +-- create the table with spatial referencing information in it. spec, section 3.2.1.2 + +create table spatial_ref_sys ( srid integer not null primary key, auth_name varchar(256), auth_srid integer, srtext varchar(2048) ); + +-- create the metadata table. spec, section 3.2.2.1 + +create table geometry_columns ( +f_table_catalog varchar(256) not null, +f_table_schema varchar(256) not null, +f_table_name varchar(256) not null, +f_geometry_column varchar(256) not null, +coord_dimension integer , +srid integer, +CONSTRAINT GC_PK primary key ( f_table_catalog,f_table_schema, f_table_name,f_geometry_column) +-- # ,CONSTRAINT IS_REF1 FOREIGN KEY (f_table_name) +-- # REFERENCES pg_class (relname) ON UPDATE CASCADE ON DELETE CASCADE + +) ; + CREATE FUNCTION BOX3D_in(opaque) @@ -197,7 +220,25 @@ CREATE FUNCTION distance(GEOMETRY,GEOMETRY) AS '@MODULE_FILENAME@' LANGUAGE 'c' with (isstrict); +CREATE FUNCTION astext(geometry) + RETURNS TEXT + AS '@MODULE_FILENAME@','astext_geometry' + LANGUAGE 'c' with (isstrict); +CREATE FUNCTION srid(geometry) + RETURNS INT4 + AS '@MODULE_FILENAME@','srid_geom' + LANGUAGE 'c' with (isstrict); + +CREATE FUNCTION geometryfromtext(geometry,int4) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text' + LANGUAGE 'c' with (isstrict); + +CREATE FUNCTION setSRID(geometry,int4) + RETURNS geometry + AS '@MODULE_FILENAME@','geometry_from_text' + LANGUAGE 'c' with (isstrict); ------- spheroid calcs diff --git a/postgis_inout.c b/postgis_inout.c index 72b1f4e25..e4bf49fb2 100644 --- a/postgis_inout.c +++ b/postgis_inout.c @@ -1386,6 +1386,31 @@ BOX3D *bbox_of_geometry(GEOMETRY *geom) } +//given wkt and SRID, return a geometry +//actually we cheat, postgres will convert the string to a geometry for us... +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); + + GEOMETRY *result; + + result = (GEOMETRY *) palloc(geom1->size); + memcpy(result,geom1, geom1->size); + + if (result != NULL) + { + result->SRID = SRID; + } + else + { + PG_RETURN_NULL(); + } + PG_RETURN_POINTER(result); +} + + // Parse a geometry object // @@ -1411,13 +1436,46 @@ Datum geometry_in(PG_FUNCTION_ARGS) int32 *offsets; int t; int obj_parse_offset; + int nitems; + int32 SRID; + double scale,offx,offy; - +printf("str=%s\n",str); //trim white while (isspace((unsigned char) *str)) str++; + //test to see if it starts with a SRID= + + SRID = -1; + scale = offx = offy = 0; + + if (strstr(str,"SRID=")) + { + //its spatially located + nitems = sscanf(str,"SRID=%i;",&SRID); + if (nitems !=1 ) + { + //error + elog(ERROR,"couldnt parse objects in GEOMETRY (SRID related)\n"); + PG_RETURN_NULL() ; + } + //delete first part of string + str = strchr(str,';'); + if (str != NULL) + str++; + } + + + + if ((str==NULL) || (strlen(str) == 0) ) + { + elog(ERROR,"couldnt parse objects in GEOMETRY (null string)\n"); + PG_RETURN_NULL() ; + } + + //printf("geometry_in got string ''\n"); nobjs= objects_inside(str); //how many sub-objects @@ -1573,17 +1631,77 @@ Datum geometry_in(PG_FUNCTION_ARGS) //printf("returning from geometry_in, nobjs = %i\n", nobjs); + + + geometry->SRID = SRID; + geometry->scale = scale; + geometry->offsetX = offx; + geometry->offsetY = offy; PG_RETURN_POINTER(geometry); } +PG_FUNCTION_INFO_V1(srid_geom); +Datum srid_geom(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + PG_RETURN_INT32(geom1->SRID); +} -//Take internal rep of geometry, output string + +//Take internal rep of geometry, output string in the form of +// 'SRID=%i;' ie. 'SRID=5;POINT(1 1)' PG_FUNCTION_INFO_V1(geometry_out); Datum geometry_out(PG_FUNCTION_ARGS) { - char *result; - GEOMETRY *geometry = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char *wkt; + char *result; + int len; + + wkt = geometry_to_text(geom1); + len = strlen(wkt) + 6+ 25 + 1; + result = palloc(len);//extra space for SRID + memset(result, 0, len); //zero everything out + + sprintf(result,"SRID=%i;%s",geom1->SRID,wkt); + + pfree(wkt); + + PG_RETURN_CSTRING(result); + +} + +//Take internal rep of geometry, output string +PG_FUNCTION_INFO_V1(astext_geometry); +Datum astext_geometry(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char *wkt; + char *result; + int len; + + wkt = geometry_to_text(geom1); + len = strlen(wkt) + 5; + + result= palloc(len); + *((int *) result) = len; + + memcpy(result +4, wkt, len-4); + + pfree(wkt); + + PG_RETURN_CSTRING(result); +} + + +//Take internal rep of geometry, output string + + +//takes a GEOMETRY and returns a WKT representation +char *geometry_to_text(GEOMETRY *geometry) +{ + char *result; int t,u; int32 *offsets; char *obj; @@ -1784,7 +1902,7 @@ Datum geometry_out(PG_FUNCTION_ARGS) if (!(briefmode)) strcat(result,")"); - PG_RETURN_CSTRING(result); + return(result); } @@ -1827,6 +1945,10 @@ Datum get_geometry_of_bbox(PG_FUNCTION_ARGS) geom->size = sizeof(GEOMETRY); geom->type = BBOXONLYTYPE; geom->nobjs = -1; + geom->SRID = -1; + geom->scale = 1.0; + geom->offsetX = 0.0; + geom->offsetY = 0.0; memcpy(&(geom->bvol),bbox, sizeof(BOX3D) ); @@ -2667,10 +2789,12 @@ printf("requested NDR\n"); // if you want to change the object's type to something else (ie GEOMETRYCOLLECTION), do // that after with geom->type = GEOMETRYCOLLECTION // this does calculate the bvol +// +// sets the SRID and grid info to the given values // // do not call this with type = GEOMETRYCOLLECTION -GEOMETRY *make_oneobj_geometry(int sub_obj_size, char *sub_obj, int type, bool is3d) +GEOMETRY *make_oneobj_geometry(int sub_obj_size, char *sub_obj, int type, bool is3d,int SRID, double scale, double offx, double offy) { int size = sizeof(GEOMETRY) + 4 + sub_obj_size ; GEOMETRY *result = palloc(size); @@ -2682,6 +2806,9 @@ GEOMETRY *make_oneobj_geometry(int sub_obj_size, char *sub_obj, int type, bool i result->type = type; result->is3d = is3d; + + + result->objType[0] = type; if (type == MULTIPOINTTYPE) result->objType[0] = POINTTYPE; -- 2.49.0