]> granicus.if.org Git - postgis/commitdiff
Fix for case where the p-i-p shortcut case and the GEOS shortcut case interleave...
authorPaul Ramsey <pramsey@cleverelephant.ca>
Wed, 5 Nov 2008 20:49:11 +0000 (20:49 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Wed, 5 Nov 2008 20:49:11 +0000 (20:49 +0000)
git-svn-id: http://svn.osgeo.org/postgis/branches/1.3@3260 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/lwgeom_geos_c.c
lwgeom/lwgeom_rtree.c
lwgeom/lwgeom_rtree.h
regress/regress_ogc_prep.sql
regress/regress_ogc_prep_expected

index 8d1e545ff48f25424d4da53a4274435483e5677e..643e37dda94d815c48656eadce1220a0e88670fe 100644 (file)
@@ -55,6 +55,7 @@
 #ifdef PREPARED_GEOM
 typedef struct
 {
+    char type;
        PG_LWGEOM*                    pg_geom1;
        PG_LWGEOM*                    pg_geom2;
        size_t                        pg_geom1_size;
@@ -1506,6 +1507,10 @@ Datum contains(PG_FUNCTION_ARGS)
        errorIfGeometryCollection(geom1,geom2);
        errorIfSRIDMismatch(pglwgeom_getSRID(geom1), pglwgeom_getSRID(geom2));
 
+#ifdef PGIS_DEBUG
+    lwnotice("Contains: entered", type1, type2);
+#endif
+
        /*
         * short-circuit 1: if geom2 bounding box is not completely inside
         * geom1 bounding box we can prematurely return FALSE.
@@ -1517,6 +1522,9 @@ Datum contains(PG_FUNCTION_ARGS)
                if ( ( box2.xmin < box1.xmin ) || ( box2.xmax > box1.xmax ) ||
                     ( box2.ymin < box1.ymin ) || ( box2.ymax > box1.ymax ) ) 
                {
+#ifdef PGIS_DEBUG
+    lwnotice("Contains: bbox short circuit", type1, type2);
+#endif
                    PG_RETURN_BOOL(FALSE);
                }
        }
@@ -1526,6 +1534,9 @@ Datum contains(PG_FUNCTION_ARGS)
          */
         type1 = lwgeom_getType((uchar)SERIALIZED_FORM(geom1)[0]);
         type2 = lwgeom_getType((uchar)SERIALIZED_FORM(geom2)[0]);
+#ifdef PGIS_DEBUG
+    lwnotice("Contains: type1: %d, type2: %d", type1, type2);
+#endif
        if((type1 == POLYGONTYPE || type1 == MULTIPOLYGONTYPE) && type2 == POINTTYPE)
                {
 #ifdef PGIS_DEBUG
@@ -1534,9 +1545,6 @@ Datum contains(PG_FUNCTION_ARGS)
 
                        lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom1));
                 point = lwpoint_deserialize(SERIALIZED_FORM(geom2));
-#ifdef PGIS_DEBUG
-                lwnotice("Precall point_in_polygon %p, %p", lwgeom, point);
-#endif
 
                 /*
                  * Switch the context to the function-scope context,
@@ -1550,14 +1558,24 @@ Datum contains(PG_FUNCTION_ARGS)
 
                                if( poly_cache->ringIndices ) 
                                {
+#ifdef PGIS_DEBUG
+                lwnotice("R-Tree Point in Polygon test.");
+#endif
+                                   
                                        result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
                                }
                                else if ( type1 == POLYGONTYPE ) 
                                {
+#ifdef PGIS_DEBUG
+                lwnotice("Brute force Point in Polygon test.");
+#endif
                                        result = point_in_polygon((LWPOLY*)lwgeom, point);
                                }
                                else if ( type1 == MULTIPOLYGONTYPE ) 
                                {
+#ifdef PGIS_DEBUG
+                lwnotice("Brute force Point in Polygon test.");
+#endif
                                        result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
                                }
                                else {
@@ -1580,9 +1598,6 @@ Datum contains(PG_FUNCTION_ARGS)
         } 
         else 
         {
-#ifdef PGIS_DEBUG
-                lwnotice("Contains: type1: %d, type2: %d", type1, type2);
-#endif
         }
         
        initGEOS(lwnotice, lwnotice);
@@ -3880,6 +3895,9 @@ GetPrepGeomCache(FunctionCallInfoData *fcinfo, PG_LWGEOM *pg_geom1, PG_LWGEOM *p
        size_t pg_geom1_size = 0;
        size_t pg_geom2_size = 0;
 
+    /* Make sure this isn't someone else's cache object. */
+    if( cache && cache->type != 2 ) cache = NULL;
+
        if (!PrepGeomHash)
                CreatePrepGeomHash();
 
@@ -3903,6 +3921,7 @@ GetPrepGeomCache(FunctionCallInfoData *fcinfo, PG_LWGEOM *pg_geom1, PG_LWGEOM *p
                cache = palloc(sizeof(PrepGeomCache));          
                MemoryContextSwitchTo(old_context);
        
+        cache->type = 2;
                cache->prepared_geom = 0;
                cache->geom = 0;
                cache->argnum = 0;
index 2ceb573b5f390c444fcea10d3c7c061a61860da0..91969abe50aaaaf29d227e9181c4bed5fc7d4ddb 100644 (file)
@@ -421,6 +421,7 @@ RTREE_POLY_CACHE * createCache()
        result->ringCount = 0;\r
        result->ringIndices = 0;\r
        result->poly = 0;\r
+    result->type = 1;\r
        return result;\r
 }\r
 \r
@@ -519,6 +520,9 @@ RTREE_POLY_CACHE *retrieveCache(LWGEOM *lwgeom, uchar *serializedPoly,
 {\r
         int length;\r
 \r
+        /* Make sure this isn't someone else's cache object. */\r
+        if( currentCache && currentCache->type != 1 ) currentCache = NULL;\r
+\r
 #ifdef PGIS_DEBUG_CALLS\r
         lwnotice("retrieveCache called with %p %p %p", lwgeom, serializedPoly, currentCache);\r
 #endif\r
index cc694cfb269336c26d4a1af2dbc023320bcae4a6..0f9c7b81c9cb21ad196067dfe7910d9bfb3762f6 100644 (file)
@@ -45,6 +45,7 @@ LWMLINE *mergeMultiLines(LWMLINE *line1, LWMLINE *line2);
 \r
 typedef struct\r
 {\r
+        char type;\r
         RTREE_NODE **ringIndices;\r
         int ringCount;\r
         int polyCount;\r
index 1b3acd11ac280272407d69573d0b475e2ec95d68..e4c64839f2fd0a66bb58310cc1f72d636a83d4f5 100644 (file)
@@ -242,6 +242,32 @@ SELECT c, ST_Covers(p1, p2) AS covers_p1p2, ST_Covers(p2, p1) AS covers_p2p1 FRO
 ('covers209', 'POLYGON((0 0, 0 10, 10 10, 11 0, 0 0))', 'POLYGON((-2 -2, -2 -3, -3 -3, -3 -2, -2 -2))')
 ) AS v(c,p1,p2);
 
+-- UNEXPECTED GEOMETRY TYPES --
+
+SELECT c, ST_Contains(p1, p2) AS contains_p1p2, ST_Contains(p2, p1) AS contains_p2p1, 
+          ST_Covers(p1, p2) AS covers_p1p2, ST_Covers(p2, p1) AS covers_p2p1,
+          ST_Intersects(p1, p2) AS intersects_p1p2, ST_Intersects(p2, p1) AS intersects_p2p1,
+          ST_ContainsProperly(p1, p2) AS containsproper_p1p2, ST_ContainsProperly(p2, p1) AS containsproper_p2p1 
+          FROM
+( VALUES
+('types100', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POINT(5 5)'), 
+('types101', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POINT(5 5)'), 
+('types102', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POINT(5 5)'), 
+('types103', 'LINESTRING(0 0, 0 10, 10 10, 10 0)', 'POINT(5 5)'), 
+('types104', 'LINESTRING(0 0, 0 10, 10 10, 10 0)', 'POINT(5 5)'), 
+('types105', 'LINESTRING(0 0, 0 10, 10 10, 10 0)', 'POINT(5 5)'), 
+('types106', 'POINT(5 5)', 'POINT(5 5)'), 
+('types107', 'POINT(5 5)', 'POINT(5 5)'), 
+('types108', 'POINT(5 5)', 'POINT(5 5)'), 
+('types109', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), 
+('types110', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), 
+('types111', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'), 
+('types112', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'LINESTRING(0 0, 0 10, 10 10, 10 0)'), 
+('types113', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'LINESTRING(0 0, 0 10, 10 10, 10 0)'), 
+('types114', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'LINESTRING(0 0, 0 10, 10 10, 10 0)') 
+) AS v(c,p1,p2);
+
+
 SELECT 'intersects310', ST_intersects('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', p) FROM ( VALUES 
 ('LINESTRING(1 10, 9 10, 9 8)'),('LINESTRING(1 10, 9 10, 9 8)'),('LINESTRING(1 10, 9 10, 9 8)')
 ) AS v(p);
index 72ecd68834537104ea5a5c01cd07651df9018562..4600388de88b421cf44c903c51810edfa9b879bb 100644 (file)
@@ -110,6 +110,21 @@ covers206|t|f
 covers207|t|f
 covers208|f|f
 covers209|f|f
+types100|t|f|t|f|t|t|t|f
+types101|t|f|t|f|t|t|t|f
+types102|t|f|t|f|t|t|t|f
+types103|f|f|f|f|f|f|f|f
+types104|f|f|f|f|f|f|f|f
+types105|f|f|f|f|f|f|f|f
+types106|t|t|t|t|t|t|t|t
+types107|t|t|t|t|t|t|t|t
+types108|t|t|t|t|t|t|t|t
+types109|t|t|t|t|t|t|f|f
+types110|t|t|t|t|t|t|f|f
+types111|t|t|t|t|t|t|f|f
+types112|f|f|t|f|t|t|f|f
+types113|f|f|t|f|t|t|f|f
+types114|f|f|t|f|t|t|f|f
 intersects310|t
 intersects310|t
 intersects310|t