XS-libgeos
view release on metacpan or search on metacpan
geos-3.7.3/include/geos/geom/BinaryOp.h view on Meta::CPAN
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2013 Sandro Santilli <strk@kbt.io>
* Copyright (C) 2006 Refractions Research Inc.
*
* 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
*
**********************************************************************
*
* This file provides a single templated function, taking two
* const Geometry pointers, applying a binary operator to them
* and returning a result Geometry in an unique_ptr<>.
*
* The binary operator is expected to take two const Geometry pointers
* and return a newly allocated Geometry pointer, possibly throwing
* a TopologyException to signal it couldn't succeed due to robustness
* issues.
*
* This function will catch TopologyExceptions and try again with
* slightly modified versions of the input. The following heuristic
* is used:
*
* - Try with original input.
* - Try removing common bits from input coordinate values
* - Try snaping input geometries to each other
* - Try snaping input coordinates to a increasing grid (size from 1/25 to 1)
* - Try simplifiying input with increasing tolerance (from 0.01 to 0.04)
*
* If none of the step succeeds the original exception is thrown.
*
* Note that you can skip Grid snapping, Geometry snapping and Simplify policies
* by a compile-time define when building geos.
* See USE_TP_SIMPLIFY_POLICY, USE_PRECISION_REDUCTION_POLICY and
* USE_SNAPPING_POLICY macros below.
*
*
**********************************************************************/
#ifndef GEOS_GEOM_BINARYOP_H
#define GEOS_GEOM_BINARYOP_H
#include <geos/algorithm/BoundaryNodeRule.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/GeometryCollection.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/Lineal.h>
#include <geos/geom/PrecisionModel.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/precision/CommonBitsRemover.h>
#include <geos/precision/SimpleGeometryPrecisionReducer.h>
#include <geos/precision/GeometryPrecisionReducer.h>
#include <geos/operation/overlay/snap/GeometrySnapper.h>
#include <geos/simplify/TopologyPreservingSimplifier.h>
#include <geos/operation/IsSimpleOp.h>
#include <geos/operation/valid/IsValidOp.h>
#include <geos/operation/valid/TopologyValidationError.h>
#include <geos/util/TopologyException.h>
#include <geos/util.h>
#include <memory> // for unique_ptr
//#define GEOS_DEBUG_BINARYOP 1
#define GEOS_DEBUG_BINARYOP_PRINT_INVALID 1
#ifdef GEOS_DEBUG_BINARYOP
# include <iostream>
# include <iomanip>
# include <sstream>
#endif
/*
* Always try original input first
*/
#ifndef USE_ORIGINAL_INPUT
# define USE_ORIGINAL_INPUT 1
#endif
/*
* Check validity of operation between original geometries
*/
#define GEOS_CHECK_ORIGINAL_RESULT_VALIDITY 0
/*
* Define this to use PrecisionReduction policy
* in an attempt at by-passing binary operation
* robustness problems (handles TopologyExceptions)
*/
#ifndef USE_PRECISION_REDUCTION_POLICY
# define USE_PRECISION_REDUCTION_POLICY 1
#endif
/*
* Check validity of operation performed
* by precision reduction policy.
*
* Precision reduction policy reduces precision of inputs
* and restores it in the result. The restore phase may
* introduce invalidities.
*
*/
#define GEOS_CHECK_PRECISION_REDUCTION_VALIDITY 0
/*
* Define this to use TopologyPreserving simplification policy
* in an attempt at by-passing binary operation
* robustness problems (handles TopologyExceptions)
*/
#ifndef USE_TP_SIMPLIFY_POLICY
//# define USE_TP_SIMPLIFY_POLICY 1
geos-3.7.3/include/geos/geom/BinaryOp.h view on Meta::CPAN
* self-intersection of multipolygons
*
* May return the input untouched.
*/
inline std::unique_ptr<Geometry>
fix_self_intersections(std::unique_ptr<Geometry> g, const std::string& label)
{
::geos::ignore_unused_variable_warning(label);
#ifdef GEOS_DEBUG_BINARYOP
std::cerr << label << " fix_self_intersection (UnaryUnion)" << std::endl;
#endif
// Only multi-components can be fixed by UnaryUnion
if ( ! dynamic_cast<const GeometryCollection*>(g.get()) ) return g;
using operation::valid::IsValidOp;
IsValidOp ivo(g.get());
// Polygon is valid, nothing to do
if ( ivo.isValid() ) return g;
// Not all invalidities can be fixed by this code
using operation::valid::TopologyValidationError;
TopologyValidationError* err = ivo.getValidationError();
switch ( err->getErrorType() ) {
case TopologyValidationError::eRingSelfIntersection:
case TopologyValidationError::eTooFewPoints: // collapsed lines
#ifdef GEOS_DEBUG_BINARYOP
std::cerr << label << " ATTEMPT_TO_FIX: " << err->getErrorType() << ": " << *g << std::endl;
#endif
g = g->Union();
#ifdef GEOS_DEBUG_BINARYOP
std::cerr << label << " ATTEMPT_TO_FIX succeeded.. " << std::endl;
#endif
return g;
case TopologyValidationError::eSelfIntersection:
// this one is within a single component, won't be fixed
default:
#ifdef GEOS_DEBUG_BINARYOP
std::cerr << label << " invalidity is: " << err->getErrorType() << std::endl;
#endif
return g;
}
}
/// \brief
/// Apply a binary operation to the given geometries
/// after snapping them to each other after common-bits
/// removal.
///
template <class BinOp>
std::unique_ptr<Geometry>
SnapOp(const Geometry* g0, const Geometry *g1, BinOp _Op)
{
typedef std::unique_ptr<Geometry> GeomPtr;
//using geos::precision::GeometrySnapper;
using geos::operation::overlay::snap::GeometrySnapper;
// Snap tolerance must be computed on the original
// (not commonbits-removed) geoms
double snapTolerance = GeometrySnapper::computeOverlaySnapTolerance(*g0, *g1);
#if GEOS_DEBUG_BINARYOP
std::cerr<< std::setprecision(20) << "Computed snap tolerance: "<<snapTolerance<<std::endl;
#endif
#if CBR_BEFORE_SNAPPING
// Compute common bits
geos::precision::CommonBitsRemover cbr;
cbr.add(g0); cbr.add(g1);
#if GEOS_DEBUG_BINARYOP
std::cerr<<"Computed common bits: "<<cbr.getCommonCoordinate()<<std::endl;
#endif
// Now remove common bits
GeomPtr rG0( cbr.removeCommonBits(g0->clone()) );
GeomPtr rG1( cbr.removeCommonBits(g1->clone()) );
#if GEOS_DEBUG_BINARYOP
check_valid(*rG0, "CBR: removed-bits geom 0");
check_valid(*rG1, "CBR: removed-bits geom 1");
#endif
const Geometry& operand0 = *rG0;
const Geometry& operand1 = *rG1;
#else // don't CBR before snapping
const Geometry& operand0 = *g0;
const Geometry& operand1 = *g1;
#endif
GeometrySnapper snapper0( operand0 );
GeomPtr snapG0( snapper0.snapTo(operand1, snapTolerance) );
//snapG0 = fix_self_intersections(snapG0, "SNAP: snapped geom 0");
// NOTE: second geom is snapped on the snapped first one
GeometrySnapper snapper1( operand1 );
GeomPtr snapG1( snapper1.snapTo(*snapG0, snapTolerance) );
//snapG1 = fix_self_intersections(snapG1, "SNAP: snapped geom 1");
// Run the binary op
GeomPtr result( _Op(snapG0.get(), snapG1.get()) );
#if GEOS_DEBUG_BINARYOP
check_valid(*result, "SNAP: result (before common-bits addition");
#endif
#if CBR_BEFORE_SNAPPING
// Add common bits back in
cbr.addCommonBits( result.get() );
//result = fix_self_intersections(result, "SNAP: result (after common-bits addition)");
check_valid(*result, "CBR: result (after common-bits addition)", true);
#endif
return result;
( run in 2.847 seconds using v1.01-cache-2.11-cpan-63c85eba8c4 )