DYT/Tool/OpenSceneGraph-3.6.5/include/geos/index/chain/MonotoneChain.h

207 lines
6.6 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) 2001-2002 Vivid Solutions 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: index/chain/MonotoneChain.java rev. 1.15 (JTS-1.10)
*
**********************************************************************/
#pragma once
#include <geos/export.h>
#include <geos/geom/CoordinateSequence.h> // for inline
#include <geos/geom/Envelope.h> // for inline
#include <geos/geom/LineSegment.h> // for inline
#include <memory> // for unique_ptr
// Forward declarations
namespace geos {
namespace geom {
class LineSegment;
class CoordinateSequence;
}
namespace index {
namespace chain {
class MonotoneChainSelectAction;
class MonotoneChainOverlapAction;
}
}
}
namespace geos {
namespace index { // geos::index
namespace chain { // geos::index::chain
/** \brief
* Monotone Chains are a way of partitioning the segments of a linestring to
* allow for fast searching of intersections.
*
* They have the following properties:
*
* - the segments within a monotone chain never intersect each other
* - the envelope of any contiguous subset of the segments in a monotone
* chain is equal to the envelope of the endpoints of the subset.
*
* Property 1 means that there is no need to test pairs of segments from
* within the same monotone chain for intersection.
* Property 2 allows an efficient binary search to be used to find the
* intersection points of two monotone chains.
*
* For many types of real-world data, these properties eliminate
* a large number of segment comparisons, producing substantial speed gains.
*
* One of the goals of this implementation of MonotoneChains is to be
* as space and time efficient as possible. One design choice that aids this
* is that a MonotoneChain is based on a subarray of a list of points.
* This means that new arrays of points (potentially very large) do not
* have to be allocated.
*
* MonotoneChains support the following kinds of queries:
*
* - Envelope select: determine all the segments in the chain which
* intersect a given envelope
* - Overlap: determine all the pairs of segments in two chains whose
* envelopes overlap
*
* This implementation of MonotoneChains uses the concept of internal iterators
* to return the resultsets for the above queries.
* This has time and space advantages, since it
* is not necessary to build lists of instantiated objects to represent the segments
* returned by the query.
* However, it does mean that the queries are not thread-safe.
*
*/
class GEOS_DLL MonotoneChain {
public:
/// @param pts
/// Ownership left to caller, this class holds a reference.
///
/// @param start
///
/// @param end
///
/// @param context
/// Ownership left to caller, this class holds a reference.
///
MonotoneChain(const geom::CoordinateSequence& pts,
std::size_t start, std::size_t end, void* context);
~MonotoneChain() = default;
/// Returned envelope is owned by this class
const geom::Envelope& getEnvelope() const;
const geom::Envelope& getEnvelope(double expansionDistance) const;
size_t
getStartIndex() const
{
return start;
}
size_t
getEndIndex() const
{
return end;
}
/** \brief
* Set given LineSegment with points of the segment starting
* at the given index.
*/
void getLineSegment(std::size_t index, geom::LineSegment& ls) const {
pts->getAt(index, ls.p0);
pts->getAt(index + 1, ls.p1);
}
/**
* Return the subsequence of coordinates forming this chain.
* Allocates a new CoordinateSequence to hold the Coordinates
*
*/
std::unique_ptr<geom::CoordinateSequence> getCoordinates() const;
/**
* Determine all the line segments in the chain whose envelopes overlap
* the searchEnvelope, and process them
*/
void select(const geom::Envelope& searchEnv,
MonotoneChainSelectAction& mcs) const;
void computeOverlaps(const MonotoneChain* mc,
MonotoneChainOverlapAction* mco) const;
void computeOverlaps(const MonotoneChain* mc, double overlapTolerance,
MonotoneChainOverlapAction* mco) const;
void*
getContext() const
{
return context;
}
private:
void computeSelect(const geom::Envelope& searchEnv,
std::size_t start0,
std::size_t end0,
MonotoneChainSelectAction& mcs) const;
void computeOverlaps(std::size_t start0, std::size_t end0, const MonotoneChain& mc,
std::size_t start1, std::size_t end1,
double overlapTolerance,
MonotoneChainOverlapAction& mco) const;
bool overlaps(std::size_t start0, std::size_t end0,
const MonotoneChain& mc, std::size_t start1, std::size_t end1,
double overlapTolerance) const {
if (overlapTolerance > 0.0) {
return overlaps(pts->getAt<geom::CoordinateXY>(start0),
pts->getAt<geom::CoordinateXY>(end0),
mc.pts->getAt<geom::CoordinateXY>(start1),
mc.pts->getAt<geom::CoordinateXY>(end1),
overlapTolerance);
}
return geom::Envelope::intersects(pts->getAt<geom::CoordinateXY>(start0),
pts->getAt<geom::CoordinateXY>(end0),
mc.pts->getAt<geom::CoordinateXY>(start1),
mc.pts->getAt<geom::CoordinateXY>(end1));
}
static bool overlaps(const geom::CoordinateXY& p1, const geom::CoordinateXY& p2,
const geom::CoordinateXY& q1, const geom::CoordinateXY& q2,
double overlapTolerance);
/// Externally owned
const geom::CoordinateSequence* pts;
/// user-defined information
void* context;
/// Index of chain start vertex into the CoordinateSequence, 0 based.
std::size_t start;
/// Index of chain end vertex into the CoordinateSequence, 0 based.
std::size_t end;
/// Owned by this class
mutable geom::Envelope env;
};
} // namespace geos::index::chain
} // namespace geos::index
} // namespace geos