[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