DYT/Tool/OpenSceneGraph-3.6.5/include/geos/operation/overlayng/OverlayNGRobust.h

175 lines
5.3 KiB
C
Raw Normal View History

2024-12-24 23:49:36 +00:00
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2020 Paul Ramsey <pramsey@cleverelephant.ca>
*
* 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: operation/overlayng/OverlayNGRobust.java 6ef89b09
*
**********************************************************************/
#pragma once
#include <geos/export.h>
#include <geos/geom/PrecisionModel.h>
#include <geos/operation/union/UnionStrategy.h>
#include <geos/operation/overlayng/OverlayNG.h>
// Forward declarations
namespace geos {
namespace geom {
class Geometry;
}
}
namespace geos { // geos.
namespace operation { // geos.operation
namespace overlayng { // geos.operation.overlayng
/**
* Performs an overlay operation, increasing robustness by using a series of
* increasingly aggressive (and slower) noding strategies.
*
* The noding strategies used are:
*
* - A simple, fast noder using FLOATING precision.
* - A {@link noding::snap::SnappingNoder} using an automatically-determined snap tolerance
* - First snapping each geometry to itself,
* and then overlaying them using a SnappingNoder.
* - The above two strategies are repeated with increasing snap tolerance, up to a limit.
*
* If the above heuristics still fail to compute a valid overlay,
* the original {@link util::TopologyException} is thrown.
*
* This algorithm relies on each overlay operation execution
* throwing a {@link util::TopologyException} if it is unable
* to compute the overlay correctly.
* Generally this occurs because the noding phase does
* not produce a valid noding.
* This requires the use of a {@link noding::ValidatingNoder}
* in order to check the results of using a floating noder.
*
* @author Martin Davis
*/
class GEOS_DLL OverlayNGRobust {
private:
// Constants
static constexpr int NUM_SNAP_TRIES = 5;
/**
* A factor for a snapping tolerance distance which
* should allow noding to be computed robustly.
*/
static constexpr double SNAP_TOL_FACTOR = 1e12;
static std::unique_ptr<Geometry> overlaySnapping(
const Geometry* geom0, const Geometry* geom1, int opCode, double snapTol);
static std::unique_ptr<Geometry> overlaySnapBoth(
const Geometry* geom0, const Geometry* geom1, int opCode, double snapTol);
static std::unique_ptr<Geometry> overlaySnapTol(
const Geometry* geom0, const Geometry* geom1, int opCode, double snapTol);
static double snapTolerance(const Geometry* geom);
/**
* Computes the largest magnitude of the ordinates of a geometry,
* based on the geometry envelope.
*
* @param geom a geometry
* @return the magnitude of the largest ordinate
*/
static double ordinateMagnitude(const Geometry* geom);
/**
* Overlay using Snap-Rounding with an automatically-determined
* scale factor.
*
* NOTE: currently this strategy is not used, since all known
* test cases work using one of the Snapping strategies.
*/
static std::unique_ptr<Geometry>
overlaySR(const Geometry* geom0, const Geometry* geom1, int opCode);
/**
* Self-snaps a geometry by running a union operation with it as the only input.
* This helps to remove narrow spike/gore artifacts to simplify the geometry,
* which improves robustness.
* Collapsed artifacts are removed from the result to allow using
* it in further overlay operations.
*
* @param geom geometry to self-snap
* @param snapTol snap tolerance
* @return the snapped geometry (homogeneous)
*/
static std::unique_ptr<Geometry>
snapSelf(const Geometry* geom, double snapTol);
public:
class SRUnionStrategy : public operation::geounion::UnionStrategy {
std::unique_ptr<geom::Geometry> Union(const geom::Geometry* g0, const geom::Geometry* g1) override
{
return OverlayNGRobust::Overlay(g0, g1, OverlayNG::UNION);
};
bool isFloatingPrecision() const override
{
return true;
};
};
static std::unique_ptr<Geometry> Intersection(
const Geometry* g0, const Geometry* g1);
static std::unique_ptr<Geometry> Union(
const Geometry* g0, const Geometry* g1);
static std::unique_ptr<Geometry> Difference(
const Geometry* g0, const Geometry* g1);
static std::unique_ptr<Geometry> SymDifference(
const Geometry* g0, const Geometry* g1);
static std::unique_ptr<Geometry> Union(
const Geometry* a);
static std::unique_ptr<Geometry> Overlay(
const Geometry* geom0, const Geometry* geom1, int opCode);
static std::unique_ptr<Geometry> overlaySnapTries(
const Geometry* geom0, const Geometry* geom1, int opCode);
/**
* Computes a heuristic snap tolerance distance
* for overlaying a pair of geometries using a {@link noding::snap::SnappingNoder}.
*/
static double snapTolerance(const Geometry* geom0, const Geometry* geom1);
};
} // namespace geos.operation.overlayng
} // namespace geos.operation
} // namespace geos