]> granicus.if.org Git - postgis/commitdiff
Fix issue where the cached object is a point and the uncached one is a polygon. ...
authorPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 5 Jul 2012 19:15:28 +0000 (19:15 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 5 Jul 2012 19:15:28 +0000 (19:15 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@10037 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/lwgeodetic_tree.c
postgis/geography_measurement.c
postgis/geography_measurement_trees.c

index 9074a3e20c1c1364c04b9d2de7dd808a40e279f1..7b840264e7cb4582c803f2f136b63108ff3ec603 100644 (file)
@@ -113,6 +113,9 @@ circ_center_spherical(const GEOGRAPHIC_POINT* c1, const GEOGRAPHIC_POINT* c2, do
 {
        /* Direction from c1 to c2 */
        double dir = sphere_direction(c1, c2, distance);
+
+       LWDEBUGF(4,"calculating spherical center", dir);
+
        LWDEBUGF(4,"dir is %g", dir);
 
        /* Catch sphere_direction when it barfs */
@@ -139,6 +142,8 @@ circ_center_cartesian(const GEOGRAPHIC_POINT* c1, const GEOGRAPHIC_POINT* c2, do
        POINT3D p1p2, pc;
        double proportion = offset/distance;
        
+       LWDEBUG(4,"calculating cartesian center");
+       
        geog2cart(c1, &p1);
        geog2cart(c2, &p2);
        
index c224a9b7684b6fd4cd854ea7c9c4af1f0f5d98c5..fec3e49e45a9ec67ff189f4264bcd5f6babddd1e 100644 (file)
@@ -148,7 +148,7 @@ Datum geography_distance_cached(PG_FUNCTION_ARGS)
        {
                LWGEOM* lwgeom1 = lwgeom_from_gserialized(g1);
                LWGEOM* lwgeom2 = lwgeom_from_gserialized(g2);
-               distance = lwgeom_distance_spheroid(lwgeom1, lwgeom2, &s, FP_TOLERANCE);
+               distance = lwgeom_distance_spheroid(lwgeom1, lwgeom2, &s, tolerance);
                lwgeom_free(lwgeom1);
                lwgeom_free(lwgeom2);
        }
@@ -281,7 +281,7 @@ Datum geography_distance_tree(PG_FUNCTION_ARGS)
        
        if ( CircTreePIP(circ_tree1, g1, lwgeom2) || CircTreePIP(circ_tree2, g2, lwgeom1) )
        {
-               PG_RETURN_BOOL(FALSE);
+               PG_RETURN_FLOAT8(0.0);
        }
        
        /* Calculate tree/tree distance */
index 93b7c706cd6a70155e05dea2648fd07e60019264..892af0460fddce5f5b022c9656608cac659520ea 100644 (file)
@@ -77,52 +77,63 @@ GetCircTreeGeomCache(FunctionCallInfoData* fcinfo, const GSERIALIZED* g1, const
 }
 
 int
-CircTreePIP(const CIRC_NODE* tree, const GSERIALIZED* g, const LWGEOM* lwgeom)
+CircTreePIP(const CIRC_NODE* tree1, const GSERIALIZED* g1, const LWGEOM* lwgeom2)
 {
-       int tree_type = gserialized_get_type(g);
-       GBOX gbox;
-       GEOGRAPHIC_POINT gp;
-       POINT3D gp3;
-       POINT4D pt;
+       int tree1_type = gserialized_get_type(g1);
+       GBOX gbox1;
+       GEOGRAPHIC_POINT in_gpoint;
+       POINT3D in_point3d;
+       POINT4D in_point;
        
-       if ( tree_type == POLYGONTYPE || tree_type == MULTIPOLYGONTYPE )
+       /* If the tree'ed argument is a polygon, do the P-i-P using the tree-based P-i-P */
+       if ( tree1_type == POLYGONTYPE || tree1_type == MULTIPOLYGONTYPE )
        {
                /* Need a gbox to calculate an outside point */
-               if ( LW_FAILURE == gserialized_get_gbox_p(g, &gbox) )
+               if ( LW_FAILURE == gserialized_get_gbox_p(g1, &gbox1) )
                {
-                       LWGEOM* lwgeom_cached = lwgeom_from_gserialized(g);
-                       lwgeom_calculate_gbox_geodetic(lwgeom_cached, &gbox);
-                       lwgeom_free(lwgeom_cached);
+                       LWGEOM* lwgeom1 = lwgeom_from_gserialized(g1);
+                       lwgeom_calculate_gbox_geodetic(lwgeom1, &gbox1);
+                       lwgeom_free(lwgeom1);
                }
                
                /* Need one point from the candidate geometry */
-               if ( LW_FAILURE == lwgeom_startpoint(lwgeom, &pt) )
+               if ( LW_FAILURE == lwgeom_startpoint(lwgeom2, &in_point) )
                {
-                       lwerror("CircTreePIP unable to generate start point for lwgeom %p", lwgeom);
+                       lwerror("CircTreePIP unable to generate start point for lwgeom %p", lwgeom2);
                        return LW_FALSE;
                }
        
                /* Flip the candidate point into geographics */
-               geographic_point_init(pt.x, pt.y, &gp);
-               geog2cart(&gp, &gp3);
+               geographic_point_init(in_point.x, in_point.y, &in_gpoint);
+               geog2cart(&in_gpoint, &in_point3d);
                
                /* If the candidate isn't in the tree box, it's not in the tree area */
-               if ( ! gbox_contains_point3d(&gbox, &gp3) )
+               if ( ! gbox_contains_point3d(&gbox1, &in_point3d) )
                {
                        return LW_FALSE;
                }
                /* The candidate point is in the box, so it *might* be inside the tree */
                else
                {
-                       POINT2D pt_outside; /* latlon */
-                       POINT2D pt_inside;
-                       pt_inside.x = pt.x; pt_inside.y = pt.y;
+                       POINT2D pt2d_outside; /* latlon */
+                       POINT2D pt2d_inside;
+                       pt2d_inside.x = in_point.x; 
+                       pt2d_inside.y = in_point.y;
                        /* Calculate a definitive outside point */
-                       gbox_pt_outside(&gbox, &pt_outside);
+                       gbox_pt_outside(&gbox1, &pt2d_outside);
                        /* Test the candidate point for strict containment */
-                       return circ_tree_contains_point(tree, &pt_inside, &pt_outside, NULL);
+                       return circ_tree_contains_point(tree1, &pt2d_inside, &pt2d_outside, NULL);
                }
-               
+       }
+       /* If the un-tree'd argument is a polygon and the tree'd argument isn't, we need to do a */
+       /* standard P-i-P on the un-tree'd side. */
+       else if ( lwgeom2->type == POLYGONTYPE || lwgeom2->type == MULTIPOLYGONTYPE )
+       {
+               int result;
+               LWGEOM* lwgeom1 = lwgeom_from_gserialized(g1);
+               result = lwgeom_covers_lwgeom_sphere(lwgeom2, lwgeom1);
+               lwfree(lwgeom1);
+               return result;
        }
        else
        {