49 #ifndef GEOS_GEOM_BINARYOP_H 50 #define GEOS_GEOM_BINARYOP_H 52 #include <geos/algorithm/BoundaryNodeRule.h> 53 #include <geos/geom/Geometry.h> 54 #include <geos/geom/GeometryCollection.h> 55 #include <geos/geom/Polygon.h> 56 #include <geos/geom/Lineal.h> 57 #include <geos/geom/PrecisionModel.h> 58 #include <geos/geom/GeometryFactory.h> 59 #include <geos/precision/CommonBitsRemover.h> 60 #include <geos/precision/SimpleGeometryPrecisionReducer.h> 61 #include <geos/precision/GeometryPrecisionReducer.h> 63 #include <geos/operation/overlay/snap/GeometrySnapper.h> 65 #include <geos/simplify/TopologyPreservingSimplifier.h> 66 #include <geos/operation/IsSimpleOp.h> 67 #include <geos/operation/valid/IsValidOp.h> 68 #include <geos/operation/valid/TopologyValidationError.h> 69 #include <geos/util/TopologyException.h> 70 #include <geos/util.h> 76 #ifdef GEOS_DEBUG_BINARYOP 86 #ifndef USE_ORIGINAL_INPUT 87 # define USE_ORIGINAL_INPUT 1 95 #ifndef USE_PRECISION_REDUCTION_POLICY 96 # define USE_PRECISION_REDUCTION_POLICY 1 104 #ifndef USE_TP_SIMPLIFY_POLICY 113 #ifndef USE_COMMONBITS_POLICY 114 # define USE_COMMONBITS_POLICY 1 128 #define GEOS_CHECK_COMMONBITS_VALIDITY 1 133 #ifndef USE_SNAPPING_POLICY 134 # define USE_SNAPPING_POLICY 1 141 check_valid(
const Geometry& g,
const std::string& label,
bool doThrow=
false,
bool validOnly=
false)
143 if ( dynamic_cast<const Lineal*>(&g) ) {
146 if ( ! sop.isSimple() )
150 label +
" is not simple");
156 operation::valid::IsValidOp ivo(&g);
157 if ( ! ivo.isValid() )
159 using operation::valid::TopologyValidationError;
160 TopologyValidationError* err = ivo.getValidationError();
161 #ifdef GEOS_DEBUG_BINARYOP 162 std::cerr << label <<
" is INVALID: " 164 <<
" (" << std::setprecision(20)
165 << err->getCoordinate() <<
")" 170 label +
" is invalid: " + err->toString(),
171 err->getCoordinate());
185 inline std::auto_ptr<Geometry>
186 fix_self_intersections(std::auto_ptr<Geometry> g,
const std::string& label)
188 #ifdef GEOS_DEBUG_BINARYOP 189 std::cerr << label <<
" fix_self_intersection (UnaryUnion)" << std::endl;
193 if ( ! dynamic_cast<const GeometryCollection*>(g.get()) )
return g;
195 using operation::valid::IsValidOp;
197 IsValidOp ivo(g.get());
200 if ( ivo.isValid() )
return g;
204 using operation::valid::TopologyValidationError;
205 TopologyValidationError* err = ivo.getValidationError();
206 switch ( err->getErrorType() ) {
207 case TopologyValidationError::eRingSelfIntersection:
208 case TopologyValidationError::eTooFewPoints:
209 #ifdef GEOS_DEBUG_BINARYOP 210 std::cerr << label <<
" ATTEMPT_TO_FIX: " << err->getErrorType() <<
": " << *g << std::endl;
213 #ifdef GEOS_DEBUG_BINARYOP 214 std::cerr << label <<
" ATTEMPT_TO_FIX succeeded.. " << std::endl;
217 case TopologyValidationError::eSelfIntersection:
220 #ifdef GEOS_DEBUG_BINARYOP 221 std::cerr << label <<
" invalidity is: " << err->getErrorType() << std::endl;
233 template <
class BinOp>
234 std::auto_ptr<Geometry>
237 typedef std::auto_ptr<Geometry> GeomPtr;
239 #define CBR_BEFORE_SNAPPING 1 246 double snapTolerance = GeometrySnapper::computeOverlaySnapTolerance(*g0, *g1);
247 #if GEOS_DEBUG_BINARYOP 248 std::cerr<< std::setprecision(20) <<
"Computed snap tolerance: "<<snapTolerance<<std::endl;
252 #if CBR_BEFORE_SNAPPING 256 #if GEOS_DEBUG_BINARYOP 264 #if GEOS_DEBUG_BINARYOP 265 check_valid(*rG0,
"CBR: removed-bits geom 0");
266 check_valid(*rG1,
"CBR: removed-bits geom 1");
271 #else // don't CBR before snapping 277 GeometrySnapper snapper0( operand0 );
278 GeomPtr snapG0( snapper0.snapTo(operand1, snapTolerance) );
282 GeometrySnapper snapper1( operand1 );
283 GeomPtr snapG1( snapper1.snapTo(*snapG0, snapTolerance) );
287 GeomPtr result( _Op(snapG0.get(), snapG1.get()) );
289 #if GEOS_DEBUG_BINARYOP 290 check_valid(*result,
"SNAP: result (before common-bits addition");
293 #if CBR_BEFORE_SNAPPING 298 check_valid(*result,
"CBR: result (after common-bits addition)",
true);
305 template <
class BinOp>
306 std::auto_ptr<Geometry>
309 typedef std::auto_ptr<Geometry> GeomPtr;
314 #ifdef USE_ORIGINAL_INPUT 318 #if GEOS_DEBUG_BINARYOP 319 std::cerr <<
"Trying with original input." << std::endl;
321 ret.reset(_Op(g0, g1));
327 #if GEOS_DEBUG_BINARYOP 328 std::cerr <<
"Original exception: " << ex.what() << std::endl;
332 check_valid(*g0,
"Input geom 0",
true,
true);
333 check_valid(*g1,
"Input geom 1",
true,
true);
335 #if GEOS_DEBUG_BINARYOP 337 check_valid(*g0,
"Input geom 0");
338 check_valid(*g1,
"Input geom 1");
341 #endif // USE_ORIGINAL_INPUT 343 #ifdef USE_COMMONBITS_POLICY 357 #if GEOS_DEBUG_BINARYOP 358 std::cerr <<
"Trying with Common Bits Remover (CBR)" << std::endl;
367 #if GEOS_DEBUG_BINARYOP 368 check_valid(*rG0,
"CBR: geom 0 (after common-bits removal)");
369 check_valid(*rG1,
"CBR: geom 1 (after common-bits removal)");
372 ret.reset( _Op(rG0.get(), rG1.get()) );
374 #if GEOS_DEBUG_BINARYOP 375 check_valid(*ret,
"CBR: result (before common-bits addition)");
380 check_valid(*ret,
"CBR: result (after common-bits addition)",
true);
382 #if GEOS_CHECK_COMMONBITS_VALIDITY 387 IsValidOp ivo(ret.get());
388 if ( ! ivo.isValid() )
390 TopologyValidationError* e = ivo.getValidationError();
392 "Result of overlay became invalid " 393 "after re-addin common bits of operand " 394 "coordinates: " + e->toString(),
397 #endif // GEOS_CHECK_COMMONBITS_VALIDITY 403 ::geos::ignore_unused_variable_warning(ex);
404 #if GEOS_DEBUG_BINARYOP 405 std::cerr <<
"CBR: " << ex.what() << std::endl;
417 #if USE_SNAPPING_POLICY 419 #if GEOS_DEBUG_BINARYOP 420 std::cerr <<
"Trying with snapping " << std::endl;
424 ret =
SnapOp(g0, g1, _Op);
425 #if GEOS_DEBUG_BINARYOP 426 std::cerr <<
"SnapOp succeeded" << std::endl;
433 ::geos::ignore_unused_variable_warning(ex);
434 #if GEOS_DEBUG_BINARYOP 435 std::cerr <<
"SNAP: " << ex.what() << std::endl;
439 #endif // USE_SNAPPING_POLICY } 442 #if USE_PRECISION_REDUCTION_POLICY 451 #if GEOS_DEBUG_BINARYOP 452 std::cerr <<
"Original input scales are: " 459 double maxScale = 1e16;
462 if ( g0scale && g0scale < maxScale ) maxScale = g0scale;
463 if ( g1scale && g1scale < maxScale ) maxScale = g1scale;
466 for (
double scale=maxScale; scale >= 1; scale /= 10)
470 #if GEOS_DEBUG_BINARYOP 471 std::cerr <<
"Trying with scale " << scale << std::endl;
475 GeomPtr rG0( reducer.
reduce(*g0) );
476 GeomPtr rG1( reducer.
reduce(*g1) );
480 ret.reset( _Op(rG0.get(), rG1.get()) );
492 if ( scale == 1 )
throw ex;
493 #if GEOS_DEBUG_BINARYOP 494 std::cerr <<
"Reduced with scale (" << scale <<
"): " 495 << ex.what() << std::endl;
504 #if GEOS_DEBUG_BINARYOP 505 std::cerr <<
"Reduced: " << ex.what() << std::endl;
517 #if USE_TP_SIMPLIFY_POLICY 523 double maxTolerance = 0.04;
524 double minTolerance = 0.01;
525 double tolStep = 0.01;
527 for (
double tol = minTolerance; tol <= maxTolerance; tol += tolStep)
529 #if GEOS_DEBUG_BINARYOP 530 std::cerr <<
"Trying simplifying with tolerance " << tol << std::endl;
533 GeomPtr rG0( simplify::TopologyPreservingSimplifier::simplify(g0, tol) );
534 GeomPtr rG1( simplify::TopologyPreservingSimplifier::simplify(g1, tol) );
538 ret.reset( _Op(rG0.get(), rG1.get()) );
543 if ( tol >= maxTolerance )
throw ex;
544 #if GEOS_DEBUG_BINARYOP 545 std::cerr <<
"Simplified with tolerance (" << tol <<
"): " 546 << ex.what() << std::endl;
557 #if GEOS_DEBUG_BINARYOP 558 std::cerr <<
"Simplified: " << ex.what() << std::endl;
572 #endif // GEOS_GEOM_BINARYOP_H Allow computing and removing common mantissa bits from one or more Geometries.
Definition: CommonBitsRemover.h:40
Geometry * createGeometry(const Geometry *g) const
Returns a clone of given Geometry.
Implements the algorithsm required to compute the isValid() method for Geometrys. ...
Definition: IsValidOp.h:61
Specifies the precision model of the Coordinate in a Geometry.
Definition: PrecisionModel.h:87
Basic implementation of Geometry, constructed and destructed by GeometryFactory.
Definition: Geometry.h:167
virtual Geometry * clone() const =0
Make a deep-copy of this Geometry.
geom::Coordinate & getCommonCoordinate()
geom::Geometry * removeCommonBits(geom::Geometry *geom)
Removes the common coordinate bits from a Geometry. The coordinates of the Geometry are changed...
const GeometryFactory * getFactory() const
Gets the factory which contains the context in which this geometry was created.
Definition: Geometry.h:196
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition: GeometryFactory.h:67
Reduces the precision of a Geometry according to the supplied PrecisionModel, ensuring that the resul...
Definition: GeometryPrecisionReducer.h:42
Basic namespace for all GEOS functionalities.
Definition: IndexedNestedRingTester.h:25
Snaps the vertices and segments of a Geometry to another Geometry's vertices.
Definition: GeometrySnapper.h:58
std::auto_ptr< Geometry > SnapOp(const Geometry *g0, const Geometry *g1, BinOp _Op)
Apply a binary operation to the given geometries after snapping them to each other after common-bits ...
Definition: BinaryOp.h:235
int compareTo(const PrecisionModel *other) const
Compares this PrecisionModel object with the specified object for order.
const PrecisionModel * getPrecisionModel() const
Returns the PrecisionModel that Geometries created by this factory will be associated with...
Indicates an invalid or inconsistent topological situation encountered during processing.
Definition: TopologyException.h:35
static std::auto_ptr< geom::Geometry > reduce(const geom::Geometry &g, const geom::PrecisionModel &precModel)
Definition: GeometryPrecisionReducer.h:80
Contains information about the nature and location of a Geometry validation error.
Definition: TopologyValidationError.h:40
geom::Geometry * addCommonBits(geom::Geometry *geom)
Adds the common coordinate bits back into a Geometry. The coordinates of the Geometry are changed...
void add(const geom::Geometry *geom)
static const BoundaryNodeRule & getBoundaryEndPoint()
The Endpoint Boundary Node Rule.
double getScale() const
Returns the multiplying factor used to obtain a precise coordinate.