[geos-devel] [GEOS] #492: DistanceOp result failed

GEOS geos-trac at osgeo.org
Wed Oct 19 11:23:42 EDT 2011


#492: DistanceOp result failed
--------------------------+-------------------------------------------------
 Reporter:  xavierraffin  |       Owner:  geos-devel@…              
     Type:  defect        |      Status:  new                       
 Priority:  major         |   Milestone:  3.2.4                     
Component:  Default       |     Version:  3.2.3                     
 Severity:  Unassigned    |    Keywords:  DistanceOp , distance     
--------------------------+-------------------------------------------------
 When I tried to calculate a projection of a point on a linestring I have
 got an bad distance result.

 '''When I compiled with -g and without gcc optimisation, the error doesn't
 appear !!'''

 This is an extract of my code :


 {{{
 boost::shared_ptr<geos::geom::Linestring> line = ...;
 boost::shared_ptr<geos::geom::Point> point = ...;
 ...
 double distance line->distance(point);
 }}}

 Here distance is 64.9363 if compiled in debug (-g and no -O) mode.
 but distance is 1.79769e+308 if compiled in release mode (without -g and
 with -O3).

 So I looked at the geos source code.

 First the distance function in Geometry

 {{{
 double
 Geometry::distance(const Geometry *other) const
 {
         return DistanceOp::distance(this, other);
 }
 }}}

 So I looked at DistanceOp.cpp and see (in computeFacetDistance):


 {{{
 PointExtracter::getPoints(*(geom[1]),pts1);
 }}}

 with GEOS_DEBUG activated I see in debug mode:

 {{{
 PointExtracter found 0 points in geometry 1 and 1 points in geometry 2
 }}}

 and in release mode


 {{{
 PointExtracter found 0 points in geometry 1 and 0 points in geometry 2
 }}}

 The issue is that in release mode the second Geometry object (the Point)
 is not detected as a point.

 So I go further and see that PointExtracter::getPoints static method call
 a Point method apply_ro wich call in return PointExtracter (subclass of
 GeometryFilter) method apply_ro.

 The code is (PointExtracter.h):

 {{{
         void filter_ro(const Geometry *geom)
         {
 if ( const Point *p=dynamic_cast<const Point *>(geom) )
                 comps.push_back(p);
         }
 }}}

 So I add some trace and see that in release mode the
 PointExtracter::filter_ro method wasn't called by Point::filter_ro
 (in debug that works).

 So I change DistanceOp.cpp to use non-static method instead of the static
 one (see joined patch).

 That solve the issue.

 Patch is very short:

 {{{
 ===================================================================
 --- 3rd/dev/geos/src/operation/distance/DistanceOp.cpp  (révision 3499)
 +++ 3rd/dev/geos/src/operation/distance/DistanceOp.cpp  (copie de travail)
 @@ -402,8 +402,12 @@

         Point::ConstVect pts0;
         Point::ConstVect pts1;
 -       PointExtracter::getPoints(*(geom[0]), pts0);
 -       PointExtracter::getPoints(*(geom[1]), pts1);
 +
 +       PointExtracter pe(pts0);
 +       geom[0]->apply_ro(&pe);
 +
 +       PointExtracter pe1(pts1);
 +       geom[1]->apply_ro(&pe1);

  #if GEOS_DEBUG
         std::cerr << "PointExtracter found "
 }}}

 I can add that I try using valgrind to detect some memory errors but I
 found nothing.

 My source code is branches/3.2 rev 3477.

 Regards,

 Xavier Raffin

-- 
Ticket URL: <http://trac.osgeo.org/geos/ticket/492>
GEOS <http://geos.refractions.net/>
GEOS (Geometry Engine - Open Source) is a C++ port of the Java Topology Suite (JTS).


More information about the geos-devel mailing list