[postgis-devel] SRID=-1 special treatment

Markus Schaber schabi at logix-tt.com
Wed Nov 16 06:06:31 PST 2005


Hello,

I attached a first shot at the SRID=-1 special treatment. It currently
only suppresses the error messages in GIS functions about different
SRIDs if at least one of the SRIDs == -1, but does not change the result
SRID treatment and it is not really havily tested.

Some thoughts:

- By assigning the SRIDs to temporary variables, I try to avoid double
evaluation of the SRID getting methods, and with the && shortcutting,
there should be no speed decrease for equal SRIDs.

- Should I refactor the SRID comparison or even the whole SRID handling
block including the error messages into an own function or preprocessor
macro? (How to avoid double evaluation with a macro? Can we use inline
functions?)

- On geometry operations where only one of the source SRIDs is -1, and
the other one is "valid", should the resulting geometry have -1 or the
valid SRID? I'd vote for the second option, as it allows for error
checking when unioning several geometries with different SRIDs.

- For the geometry_columns special handling: I think we should omit the
check altogether for columns that have SRID=-1, but not allow insertion
of SRID=-1 geometries into "well-defined" columns. Or does it make sense
to restrict a column to SRID=-1?

Markus
-------------- next part --------------
Index: lwgeom/lwgeom_btree.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_btree.c,v
retrieving revision 1.8
diff -u -r1.8 lwgeom_btree.c
--- lwgeom/lwgeom_btree.c	15 Jun 2005 16:04:11 -0000	1.8
+++ lwgeom/lwgeom_btree.c	16 Nov 2005 13:59:05 -0000
@@ -51,7 +51,9 @@
 	elog(NOTICE, "lwgeom_lt called");
 #endif
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(BTREE_SRID_MISMATCH_SEVERITY,
 			"Operation on two GEOMETRIES with different SRIDs\n");
@@ -108,7 +110,9 @@
 	elog(NOTICE, "lwgeom_le called");
 #endif
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(BTREE_SRID_MISMATCH_SEVERITY,
 			"Operation on two GEOMETRIES with different SRIDs\n");
@@ -188,7 +192,9 @@
 	elog(NOTICE, "lwgeom_eq called");
 #endif
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(BTREE_SRID_MISMATCH_SEVERITY,
 			"Operation on two GEOMETRIES with different SRIDs\n");
@@ -248,7 +254,9 @@
 	elog(NOTICE, "lwgeom_ge called");
 #endif
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(BTREE_SRID_MISMATCH_SEVERITY,
 			"Operation on two GEOMETRIES with different SRIDs\n");
@@ -320,7 +328,9 @@
 	elog(NOTICE, "lwgeom_gt called");
 #endif
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(BTREE_SRID_MISMATCH_SEVERITY,
 			"Operation on two GEOMETRIES with different SRIDs\n");
@@ -388,7 +398,9 @@
 	elog(NOTICE, "lwgeom_cmp called");
 #endif
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(BTREE_SRID_MISMATCH_SEVERITY,
 			"Operation on two GEOMETRIES with different SRIDs\n");
Index: lwgeom/lwgeom_functions_analytic.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_functions_analytic.c,v
retrieving revision 1.24
diff -u -r1.24 lwgeom_functions_analytic.c
--- lwgeom/lwgeom_functions_analytic.c	9 Jun 2005 16:02:24 -0000	1.24
+++ lwgeom/lwgeom_functions_analytic.c	16 Nov 2005 13:59:05 -0000
@@ -920,7 +920,9 @@
 		elog(ERROR,"line_locate_point: 2st arg isnt a point");
 		PG_RETURN_NULL();
 	}
-	if ( pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2) )
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
Index: lwgeom/lwgeom_functions_basic.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_functions_basic.c,v
retrieving revision 1.124
diff -u -r1.124 lwgeom_functions_basic.c
--- lwgeom/lwgeom_functions_basic.c	11 Nov 2005 17:23:27 -0000	1.124
+++ lwgeom/lwgeom_functions_basic.c	16 Nov 2005 13:59:07 -0000
@@ -1698,7 +1698,9 @@
 	geom1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
 	geom2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(ERROR,"Operation on two GEOMETRIES with different SRIDs\n");
 		PG_RETURN_NULL();
@@ -1743,7 +1745,9 @@
 	line2 = lwline_deserialize(SERIALIZED_FORM(geom2));
 	if ( line2 == NULL ) PG_RETURN_NULL(); // not a linestring
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(ERROR,"Operation on two GEOMETRIES with different SRIDs\n");
 		PG_RETURN_NULL();
@@ -1986,7 +1990,9 @@
 	elog(NOTICE, "LWGEOM_collect(%s, %s): call", lwgeom_typename(TYPE_GETTYPE(pglwgeom1->type)), lwgeom_typename(TYPE_GETTYPE(pglwgeom2->type)));
 #endif
 	
-	if ( pglwgeom_getSRID(pglwgeom1) != pglwgeom_getSRID(pglwgeom2) )
+	int srid1 = pglwgeom_getSRID(pglwgeom1);
+	int srid2 = pglwgeom_getSRID(pglwgeom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two GEOMETRIES with different SRIDs\n");
 		PG_RETURN_NULL();
@@ -2497,7 +2503,9 @@
 		PG_RETURN_NULL();
 	}
 
-	if ( pglwgeom_getSRID(pglwg1) != pglwgeom_getSRID(pglwg2) )
+	int srid1 = pglwgeom_getSRID(pglwg1);
+	int srid2 = pglwgeom_getSRID(pglwg2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation with two geometries with different SRIDs\n");
 		PG_RETURN_NULL();
Index: lwgeom/lwgeom_geos.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_geos.c,v
retrieving revision 1.63
diff -u -r1.63 lwgeom_geos.c
--- lwgeom/lwgeom_geos.c	14 Nov 2005 09:01:15 -0000	1.63
+++ lwgeom/lwgeom_geos.c	16 Nov 2005 13:59:08 -0000
@@ -439,7 +439,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -541,7 +542,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -889,7 +891,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -1009,7 +1012,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
Index: lwgeom/lwgeom_geos_c.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_geos_c.c,v
retrieving revision 1.11
diff -u -r1.11 lwgeom_geos_c.c
--- lwgeom/lwgeom_geos_c.c	14 Nov 2005 09:01:15 -0000	1.11
+++ lwgeom/lwgeom_geos_c.c	16 Nov 2005 13:59:09 -0000
@@ -364,7 +364,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -466,7 +467,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -814,7 +816,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -934,7 +937,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
Index: lwgeom/lwgeom_gist.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_gist.c,v
retrieving revision 1.25
diff -u -r1.25 lwgeom_gist.c
--- lwgeom/lwgeom_gist.c	16 Aug 2005 11:24:06 -0000	1.25
+++ lwgeom/lwgeom_gist.c	16 Nov 2005 13:59:10 -0000
@@ -99,7 +99,9 @@
 	elog(NOTICE,"GIST: LWGEOM_overlap --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
         	PG_FREE_IF_COPY(lwgeom2, 1);
@@ -152,7 +154,9 @@
 	elog(NOTICE,"GIST: LWGEOM_overleft --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
@@ -190,7 +194,9 @@
 	elog(NOTICE,"GIST: LWGEOM_left --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
@@ -228,7 +234,9 @@
 	elog(NOTICE,"GIST: LWGEOM_right --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
@@ -266,7 +274,9 @@
 	elog(NOTICE,"GIST: LWGEOM_overright --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
@@ -304,7 +314,9 @@
 	elog(NOTICE,"GIST: LWGEOM_overbelow --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
@@ -342,7 +354,9 @@
 	elog(NOTICE,"GIST: LWGEOM_below --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
@@ -380,7 +394,9 @@
 	elog(NOTICE,"GIST: LWGEOM_above --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
@@ -418,7 +434,9 @@
 	elog(NOTICE,"GIST: LWGEOM_overabove --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -452,7 +470,9 @@
 	elog(NOTICE,"GIST: LWGEOM_contained --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
@@ -490,7 +510,9 @@
 	elog(NOTICE,"GIST: LWGEOM_contain --entry");
 #endif
 
-	if ( lwgeom_getsrid(lwgeom1+4) != lwgeom_getsrid(lwgeom2+4) )
+	int srid1 = lwgeom_getsrid(lwgeom1+4);
+	int srid2 = lwgeom_getsrid(lwgeom2+4);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		PG_FREE_IF_COPY(lwgeom1, 0);
 		PG_FREE_IF_COPY(lwgeom2, 1);
Index: lwgeom/lwgeom_jts.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_jts.c,v
retrieving revision 1.8
diff -u -r1.8 lwgeom_jts.c
--- lwgeom/lwgeom_jts.c	14 Nov 2005 09:01:15 -0000	1.8
+++ lwgeom/lwgeom_jts.c	16 Nov 2005 13:59:11 -0000
@@ -393,7 +393,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -490,7 +491,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -824,7 +826,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
@@ -939,7 +942,8 @@
 		( TYPE_NDIMS(geom2->type) > 2 );
 
 	SRID = pglwgeom_getSRID(geom1);
-	if ( SRID != pglwgeom_getSRID(geom2) )
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((SRID != srid2) && (SRID != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "Operation on two geometries with different SRIDs");
 		PG_RETURN_NULL();
Index: lwgeom/lwgeom_spheroid.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/lwgeom_spheroid.c,v
retrieving revision 1.12
diff -u -r1.12 lwgeom_spheroid.c
--- lwgeom/lwgeom_spheroid.c	21 Apr 2005 16:31:00 -0000	1.12
+++ lwgeom/lwgeom_spheroid.c	16 Nov 2005 13:59:12 -0000
@@ -498,7 +498,9 @@
 	LWPOINT *point1, *point2;
 	POINT2D p1, p2;
 
-	if (pglwgeom_getSRID(geom1) != pglwgeom_getSRID(geom2))
+	int srid1 = pglwgeom_getSRID(geom1);
+	int srid2 = pglwgeom_getSRID(geom2);
+	if ((srid1 != srid2) && (srid1 != -1) && (srid2 != -1))
 	{
 		elog(ERROR, "LWGEOM_distance_ellipsoid_point: Operation on two GEOMETRIES with different SRIDs\n");
 		PG_RETURN_NULL();