geos/tests/xmltester/SingleSidedBufferResultMatcher.cpp

103 строки
3.0 KiB
C++

/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2009 Sandro Santilli <strk@kbt.io>
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Public Licence as published
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************
*
* Last port: original work
*
**********************************************************************/
#include "SingleSidedBufferResultMatcher.h"
#include <geos/geom/Geometry.h>
#include <geos/geom/BinaryOp.h>
#include <geos/operation/overlay/OverlayOp.h>
#include <geos/algorithm/distance/DiscreteHausdorffDistance.h>
#include <cmath>
namespace geos {
namespace xmltester {
double SingleSidedBufferResultMatcher::MIN_DISTANCE_TOLERANCE = 1.0e-8;
double SingleSidedBufferResultMatcher::MAX_HAUSDORFF_DISTANCE_FACTOR = 100;
bool
SingleSidedBufferResultMatcher::isBufferResultMatch(const geom::Geometry& actualBuffer,
const geom::Geometry& expectedBuffer,
double distance)
{
bool aEmpty = actualBuffer.isEmpty();
bool eEmpty = expectedBuffer.isEmpty();
// Both empty succeeds
if(aEmpty && eEmpty) {
return true;
}
// One empty and not the other is a failure
if(aEmpty || eEmpty) {
std::cerr << "isBufferResultMatch failed (one empty and one not)" << std::endl;
return false;
}
// NOTE: we need to test hausdorff distance in both directions
if(! isBoundaryHausdorffDistanceInTolerance(actualBuffer,
expectedBuffer, distance)) {
std::cerr << "isBoundaryHasudorffDistanceInTolerance failed (actual,expected)" << std::endl;
return false;
}
if(! isBoundaryHausdorffDistanceInTolerance(expectedBuffer,
actualBuffer, distance)) {
std::cerr << "isBoundaryHasudorffDistanceInTolerance failed (expected,actual)" << std::endl;
return false;
}
return true;
}
bool
SingleSidedBufferResultMatcher::isBoundaryHausdorffDistanceInTolerance(
const geom::Geometry& actualBuffer,
const geom::Geometry& expectedBuffer, double distance)
{
typedef std::unique_ptr<geom::Geometry> GeomPtr;
using geos::algorithm::distance::DiscreteHausdorffDistance;
GeomPtr actualBdy(actualBuffer.clone());
GeomPtr expectedBdy(expectedBuffer.clone());
DiscreteHausdorffDistance haus(*actualBdy, *expectedBdy);
haus.setDensifyFraction(0.25);
double maxDistanceFound = haus.orientedDistance();
double expectedDistanceTol = fabs(distance) / MAX_HAUSDORFF_DISTANCE_FACTOR;
if(expectedDistanceTol < MIN_DISTANCE_TOLERANCE) {
expectedDistanceTol = MIN_DISTANCE_TOLERANCE;
}
if(maxDistanceFound > expectedDistanceTol) {
std::cerr << "maxDistanceFound: " << maxDistanceFound << " tolerated " << expectedDistanceTol << std::endl;
return false;
}
return true;
}
} // namespace geos::xmltester
} // namespace geos