17#include <geos/constants.h> 
   18#include <geos/index/strtree/TemplateSTRNode.h> 
   19#include <geos/index/strtree/TemplateSTRNodePair.h> 
   20#include <geos/util/IllegalArgumentException.h> 
   31template<
typename ItemType, 
typename BoundsType, 
typename ItemDistance>
 
   32class TemplateSTRtreeDistance {
 
   33    using Node = TemplateSTRNode<ItemType, BoundsType>;
 
   34    using NodePair = TemplateSTRNodePair<ItemType, BoundsType, ItemDistance>;
 
   35    using ItemPair = std::pair<ItemType, ItemType>;
 
   37    struct PairQueueCompare {
 
   38        bool operator()(
const NodePair& a, 
const NodePair& b) {
 
   39            return a.getDistance() > b.getDistance();
 
   43    using PairQueue = std::priority_queue<NodePair, std::vector<NodePair>, PairQueueCompare>;
 
   46    explicit TemplateSTRtreeDistance(ItemDistance& 
id) : m_id(id) {}
 
   48    ItemPair nearestNeighbour(
const Node& root1, 
const Node& root2) {
 
   49        NodePair initPair(root1, root2, m_id);
 
   50        return nearestNeighbour(initPair);
 
   53    ItemPair nearestNeighbour(NodePair& initPair) {
 
   54        return nearestNeighbour(initPair, DoubleInfinity);
 
   57    bool isWithinDistance(
const Node& root1, 
const Node& root2, 
double maxDistance) {
 
   58        NodePair initPair(root1, root2, m_id);
 
   59        return isWithinDistance(initPair, maxDistance);
 
   64    ItemPair nearestNeighbour(NodePair& initPair, 
double maxDistance) {
 
   65        double distanceLowerBound = maxDistance;
 
   66        std::unique_ptr<NodePair> minPair;
 
   71        while (!priQ.empty() && distanceLowerBound > 0) {
 
   72            NodePair pair = priQ.top();
 
   74            double currentDistance = pair.getDistance();
 
   83            if (minPair && currentDistance >= distanceLowerBound) {
 
   94            if (pair.isLeaves()) {
 
   95                distanceLowerBound = currentDistance;
 
   99                    minPair = detail::make_unique<NodePair>(pair);
 
  107                expandToQueue(pair, priQ, distanceLowerBound);
 
  112            throw util::GEOSException(
"Error computing nearest neighbor");
 
  115        return minPair->getItems();
 
  118    void expandToQueue(
const NodePair& pair, PairQueue& priQ, 
double minDistance) {
 
  119        const Node& node1 = pair.getFirst();
 
  120        const Node& node2 = pair.getSecond();
 
  122        bool isComp1 = node1.isComposite();
 
  123        bool isComp2 = node2.isComposite();
 
  130        if (isComp1 && isComp2) {
 
  131            if (node1.getSize() > node2.getSize()) {
 
  132                expand(node1, node2, 
false, priQ, minDistance);
 
  135                expand(node2, node1, 
true, priQ, minDistance);
 
  138        } 
else if (isComp1) {
 
  139            expand(node1, node2, 
false, priQ, minDistance);
 
  141        } 
else if (isComp2) {
 
  142            expand(node2, node1, 
true, priQ, minDistance);
 
  146        throw util::IllegalArgumentException(
"neither boundable is composite");
 
  150    void expand(
const Node &nodeComposite, 
const Node &nodeOther, 
bool isFlipped, PairQueue& priQ,
 
  151                double minDistance) {
 
  152        for (
const auto *child = nodeComposite.beginChildren();
 
  153             child < nodeComposite.endChildren(); ++child) {
 
  154            NodePair sp = isFlipped ? NodePair(nodeOther, *child, m_id) : NodePair(*child, nodeOther, m_id);
 
  157            if (minDistance == DoubleInfinity || sp.getDistance() < minDistance) {
 
  163    bool isWithinDistance(
const NodePair& initPair, 
double maxDistance) {
 
  164        double distanceUpperBound = DoubleInfinity;
 
  170        while (! priQ.empty()) {
 
  172            NodePair pair = priQ.top();
 
  173            double pairDistance = pair.getDistance();
 
  182            if (pairDistance > maxDistance)
 
  198            if (pair.maximumDistance() <= maxDistance)
 
  205            if (pair.isLeaves()) {
 
  207                distanceUpperBound = pairDistance;
 
  212                if (distanceUpperBound <= maxDistance)
 
  221                expandToQueue(pair, priQ, distanceUpperBound);
 
Basic namespace for all GEOS functionalities.
Definition geos.h:38