DYT/Tool/OpenSceneGraph-3.6.5/include/geos/operation/relateng/RelateGeometry.h

273 lines
7.9 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) 2024 Martin Davis
* Copyright (C) 2024 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.
*
**********************************************************************/
#pragma once
#include <geos/algorithm/BoundaryNodeRule.h>
#include <geos/geom/Coordinate.h>
#include <geos/geom/Dimension.h>
#include <geos/geom/Location.h>
#include <geos/operation/relateng/RelatePointLocator.h>
#include <geos/operation/relateng/RelateSegmentString.h>
#include <geos/export.h>
#include <string>
#include <sstream>
// Forward declarations
namespace geos {
namespace geom {
class CoordinateSequence;
class Envelope;
class Geometry;
class LinearRing;
class LineString;
class MultiPolygon;
class Point;
}
namespace noding {
class SegmentString;
}
}
namespace geos { // geos.
namespace operation { // geos.operation
namespace relateng { // geos.operation.relateng
using namespace geos::geom;
using geos::algorithm::BoundaryNodeRule;
using geos::noding::SegmentString;
class GEOS_DLL RelateGeometry {
private:
// Members
const Geometry* geom;
bool m_isPrepared = false;
const Envelope* geomEnv;
const BoundaryNodeRule& boundaryNodeRule;
int geomDim = Dimension::False;
bool isLineZeroLen = false;
bool isGeomEmpty = false;
Coordinate::ConstXYSet uniquePoints;
std::unique_ptr<RelatePointLocator> locator;
int elementId = 0;
bool hasPoints = false;
bool hasLines = false;
bool hasAreas = false;
/*
* Memory contexts for lower level allocations
*/
std::vector<std::unique_ptr<const RelateSegmentString>> segStringTempStore;
std::vector<std::unique_ptr<const RelateSegmentString>> segStringPermStore;
std::vector<std::unique_ptr<CoordinateSequence>> csStore;
// Methods
void analyzeDimensions();
/**
* Tests if all geometry linear elements are zero-length.
* For efficiency the test avoids computing actual length.
*
* @param geom
* @return
*/
static bool isZeroLength(const Geometry* geom);
static bool isZeroLength(const LineString* line);
bool isZeroLengthLine(const Geometry* g) const {
// avoid expensive zero-length calculation if not linear
if (getDimension() != Dimension::L)
return false;
return isZeroLength(g);
};
RelatePointLocator* getLocator();
Coordinate::ConstXYSet createUniquePoints();
void extractSegmentStringsFromAtomic(bool isA,
const Geometry* geom, const MultiPolygon* parentPolygonal,
const Envelope* env,
std::vector<const SegmentString*>& segStrings,
std::vector<std::unique_ptr<const RelateSegmentString>>& segStore);
void extractRingToSegmentString(bool isA,
const LinearRing* ring, int ringId, const Envelope* env,
const Geometry* parentPoly,
std::vector<const SegmentString*>& segStrings,
std::vector<std::unique_ptr<const RelateSegmentString>>& segStore);
void extractSegmentStrings(bool isA,
const Envelope* env, const Geometry* geom,
std::vector<const SegmentString*>& segStrings,
std::vector<std::unique_ptr<const RelateSegmentString>>& segStore);
const CoordinateSequence* orientAndRemoveRepeated(
const CoordinateSequence* cs, bool orientCW);
const CoordinateSequence* removeRepeated(
const CoordinateSequence* cs);
public:
static constexpr bool GEOM_A = true;
static constexpr bool GEOM_B = false;
RelateGeometry(const Geometry* input)
: RelateGeometry(input, false, BoundaryNodeRule::getBoundaryRuleMod2())
{};
RelateGeometry(const Geometry* input, const BoundaryNodeRule& bnRule)
: RelateGeometry(input, false, bnRule)
{};
RelateGeometry(const Geometry* input, bool p_isPrepared, const BoundaryNodeRule& bnRule);
static std::string name(bool isA);
const Geometry* getGeometry() const {
return geom;
}
bool isPrepared() const {
return m_isPrepared;
}
const Envelope* getEnvelope() const {
return geomEnv;
}
inline int getDimension() const {
return geomDim;
}
bool hasDimension(int dim) const {
switch (dim) {
case Dimension::P: return hasPoints;
case Dimension::L: return hasLines;
case Dimension::A: return hasAreas;
}
return false;
}
/**
* Gets the actual non-empty dimension of the geometry.
* Zero-length LineStrings are treated as Points.
*
* @return the real (non-empty) dimension
*/
int getDimensionReal() const;
bool hasEdges() const;
bool isNodeInArea(const CoordinateXY* nodePt, const Geometry* parentPolygonal);
int locateLineEndWithDim(const CoordinateXY* p);
/**
* Locates a vertex of a polygon.
* A vertex of a Polygon or MultiPolygon is on
* the {@link Location#BOUNDARY}.
* But a vertex of an overlapped polygon in a GeometryCollection
* may be in the {@link Location#INTERIOR}.
*
* @param pt the polygon vertex
* @return the location of the vertex
*/
Location locateAreaVertex(const CoordinateXY* pt);
Location locateNode(const CoordinateXY* pt, const Geometry* parentPolygonal);
int locateWithDim(const CoordinateXY* pt);
/**
* Indicates whether the geometry requires self-noding
* for correct evaluation of specific spatial predicates.
* Self-noding is required for geometries which may self-cross
* - i.e. lines, and overlapping elements in GeometryCollections.
* Self-noding is not required for polygonal geometries,
* since they can only touch at vertices.
* This ensures that the coordinates of nodes created by
* crossing segments are computed explicitly.
* This ensures that node locations match in situations
* where a self-crossing and mutual crossing occur at the same logical location.
* E.g. a self-crossing line tested against a single segment
* identical to one of the crossed segments.
*
* @return true if self-noding is required for this geometry
*/
bool isSelfNodingRequired() const;
/**
* Tests whether the geometry has polygonal topology.
* This is not the case if it is a GeometryCollection
* containing more than one polygon (since they may overlap
* or be adjacent).
* The significance is that polygonal topology allows more assumptions
* about the location of boundary vertices.
*
* @return true if the geometry has polygonal topology
*/
bool isPolygonal() const;
bool isEmpty() const;
bool hasBoundary();
Coordinate::ConstXYSet& getUniquePoints();
std::vector<const Point*> getEffectivePoints();
/**
* Extract RSegmentStrings from the geometry which
* intersect a given envelope.
* If the envelope is null all edges are extracted.
* @param geomA
*
* @param env the envelope to extract around (may be null)
* @return a list of SegmentStrings
*/
std::vector<const SegmentString*> extractSegmentStrings(bool isA, const Envelope* env);
std::string toString() const;
friend std::ostream& operator<<(std::ostream& os, const RelateGeometry& rg);
/**
* Disable copy construction and assignment. Needed to make this
* class compile under MSVC. (See https://stackoverflow.com/q/29565299)
* Classes with members that are vector<> of unique_ptr<> need this.
*/
RelateGeometry(const RelateGeometry&) = delete;
RelateGeometry& operator=(const RelateGeometry&) = delete;
};
} // namespace geos.operation.relateng
} // namespace geos.operation
} // namespace geos