[postgis-commits] svn - r2668 - trunk/lwgeom

postgis-commits at postgis.refractions.net postgis-commits at postgis.refractions.net
Mon Jul 23 11:52:23 PDT 2007


Author: mleslie
Date: 2007-07-23 11:52:22 -0700 (Mon, 23 Jul 2007)
New Revision: 2668

Modified:
   trunk/lwgeom/lwgeom_jts.c
Log:
Added the covers and coveredby functions to the jts connector.

Modified: trunk/lwgeom/lwgeom_jts.c
===================================================================
--- trunk/lwgeom/lwgeom_jts.c	2007-07-23 16:29:40 UTC (rev 2667)
+++ trunk/lwgeom/lwgeom_jts.c	2007-07-23 18:52:22 UTC (rev 2668)
@@ -17,6 +17,7 @@
 Datum crosses(PG_FUNCTION_ARGS);
 Datum within(PG_FUNCTION_ARGS);
 Datum contains(PG_FUNCTION_ARGS);
+Datum covers(PG_FUNCTION_ARGS);
 Datum overlaps(PG_FUNCTION_ARGS);
 Datum isvalid(PG_FUNCTION_ARGS);
 Datum buffer(PG_FUNCTION_ARGS);
@@ -1388,7 +1389,94 @@
 	PG_RETURN_BOOL(result);
 }
 
+/*
+ * Described at 
+ * http://lin-ear-th-inking.blogspot.com/2007/06/subtleties-of-ogc-covers-spatial.html
+ */
+PG_FUNCTION_INFO_V1(covers);
+Datum covers(PG_FUNCTION_ARGS)
+{
+	PG_LWGEOM *geom1;
+	PG_LWGEOM *geom2;
+	JTSGeometry *g1,*g2;
+	bool result;
+	BOX2DFLOAT4 box1, box2;
+        char *patt = "******FF*";
 
+#ifdef PROFILE
+	profstart(PROF_QRUN);
+#endif
+
+	geom1 = (PG_LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+	geom2 = (PG_LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+	errorIfJTSGeometryCollection(geom1,geom2);
+	errorIfSRIDMismatch(pglwgeom_getSRID(geom1), pglwgeom_getSRID(geom2));
+
+	/*
+	 * short-circuit 1: if geom2 bounding box is not completely inside
+	 * geom1 bounding box we can prematurely return FALSE.
+	 * Do the test IFF BOUNDING BOX AVAILABLE.
+	 */
+	if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) &&
+		getbox2d_p(SERIALIZED_FORM(geom2), &box2) )
+	{
+		if ( box2.xmin < box1.xmin ) PG_RETURN_BOOL(FALSE);
+		if ( box2.xmax > box1.xmax ) PG_RETURN_BOOL(FALSE);
+		if ( box2.ymin < box1.ymin ) PG_RETURN_BOOL(FALSE);
+		if ( box2.ymax > box1.ymax ) PG_RETURN_BOOL(FALSE);
+	}
+        else 
+        {
+#ifdef PGIS_DEBUG
+                lwnotice("Covers: type1: %d, type2: %d", type1, type2);
+#endif
+        }
+        
+	initJTS(lwnotice);
+
+#ifdef PROFILE
+	profstart(PROF_P2G1);
+#endif
+	g1 = POSTGIS2JTS(geom1);
+#ifdef PROFILE
+	profstop(PROF_P2G1);
+#endif
+#ifdef PROFILE
+	profstart(PROF_P2G2);
+#endif
+	g2 = POSTGIS2JTS(geom2);
+#ifdef PROFILE
+	profstop(PROF_P2G2);
+#endif
+
+#ifdef PROFILE
+	profstart(PROF_GRUN);
+#endif
+	result = JTSrelatePattern(g1,g2,patt);
+#ifdef PROFILE
+	profstop(PROF_GRUN);
+#endif
+
+        finishJTS();
+
+	if (result == 2)
+	{
+		elog(ERROR,"JTS covers() threw an error!");
+		PG_RETURN_NULL(); /* never get here */
+	}
+
+#ifdef PROFILE
+	profstop(PROF_QRUN);
+	profreport("geos",geom1, geom2, NULL);
+#endif
+
+	PG_FREE_IF_COPY(geom1, 0);
+	PG_FREE_IF_COPY(geom2, 1);
+
+	PG_RETURN_BOOL(result);
+}
+
 PG_FUNCTION_INFO_V1(within);
 Datum within(PG_FUNCTION_ARGS)
 {
@@ -1466,8 +1554,91 @@
 	PG_RETURN_BOOL(result);
 }
 
+/*
+ * Described at:
+ * http://lin-ear-th-inking.blogspot.com/2007/06/subtleties-of-ogc-covers-spatial.html
+ */
+PG_FUNCTION_INFO_V1(coveredby);
+Datum coveredby(PG_FUNCTION_ARGS)
+{
+	PG_LWGEOM *geom1;
+	PG_LWGEOM *geom2;
+	JTSGeometry *g1,*g2;
+	bool result;
+	BOX2DFLOAT4 box1, box2;
+        char *patt = "**F**F***";
 
+#ifdef PROFILE
+	profstart(PROF_QRUN);
+#endif
 
+	geom1 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+	geom2 = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
+
+	errorIfJTSGeometryCollection(geom1,geom2);
+	errorIfSRIDMismatch(pglwgeom_getSRID(geom1), pglwgeom_getSRID(geom2));
+
+	/*
+	 * short-circuit 1: if geom1 bounding box is not completely inside
+	 * geom2 bounding box we can prematurely return FALSE.
+	 * Do the test IFF BOUNDING BOX AVAILABLE.
+	 */
+	if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) &&
+		getbox2d_p(SERIALIZED_FORM(geom2), &box2) )
+	{
+		if ( box1.xmin < box2.xmin ) PG_RETURN_BOOL(FALSE);
+		if ( box1.xmax > box2.xmax ) PG_RETURN_BOOL(FALSE);
+		if ( box1.ymin < box2.ymin ) PG_RETURN_BOOL(FALSE);
+		if ( box1.ymax > box2.ymax ) PG_RETURN_BOOL(FALSE);
+
+#ifdef PGIS_DEBUG
+                lwnotice("bounding box short-circuit missed.");
+#endif
+	}
+	initJTS(lwnotice);
+
+#ifdef PROFILE
+	profstart(PROF_P2G1);
+#endif
+	g1 = POSTGIS2JTS(geom1);
+#ifdef PROFILE
+	profstop(PROF_P2G1);
+#endif
+#ifdef PROFILE
+	profstart(PROF_P2G2);
+#endif
+	g2 = POSTGIS2JTS(geom2);
+#ifdef PROFILE
+	profstop(PROF_P2G2);
+#endif
+
+#ifdef PROFILE
+	profstart(PROF_GRUN);
+#endif
+	result = JTSrelatePattern(g1,g2,patt);
+#ifdef PROFILE
+	profstop(PROF_GRUN);
+#endif
+
+        finishJTS();
+
+	if (result == 2)
+	{
+		elog(ERROR,"JTS coveredby() threw an error!");
+		PG_RETURN_NULL(); /* never get here */
+	}
+
+#ifdef PROFILE
+	profstop(PROF_QRUN);
+	profreport("geos",geom1, geom2, NULL);
+#endif
+
+	PG_FREE_IF_COPY(geom1, 0);
+	PG_FREE_IF_COPY(geom2, 1);
+
+	PG_RETURN_BOOL(result);
+}
+
 PG_FUNCTION_INFO_V1(crosses);
 Datum crosses(PG_FUNCTION_ARGS)
 {



More information about the postgis-commits mailing list