-
Notifications
You must be signed in to change notification settings - Fork 74
v0.2.47..v0.2.48 changeset IndexElementsVisitor.cpp
Garret Voltz edited this page Sep 27, 2019
·
1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/visitors/IndexElementsVisitor.cpp b/hoot-core/src/main/cpp/hoot/core/visitors/IndexElementsVisitor.cpp
index fe64e56..20af9c1 100644
--- a/hoot-core/src/main/cpp/hoot/core/visitors/IndexElementsVisitor.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/visitors/IndexElementsVisitor.cpp
@@ -33,6 +33,8 @@
#include <hoot/core/ops/RecursiveElementRemover.h>
#include <hoot/core/util/ConfigOptions.h>
#include <hoot/core/criterion/ElementCriterion.h>
+#include <hoot/core/algorithms/Distance.h>
+#include <hoot/core/criterion/ChainCriterion.h>
// TGS
#include <tgs/RStarTree/IntersectionIterator.h>
@@ -54,6 +56,12 @@ _index(index),
_indexToEid(indexToEid)
{
_map = pMap.get();
+
+ std::shared_ptr<ChainCriterion> chainCrit = std::dynamic_pointer_cast<ChainCriterion>(_criterion);
+ if (chainCrit)
+ {
+ LOG_VARD(chainCrit->toString());
+ }
}
void IndexElementsVisitor::addCriterion(const ElementCriterionPtr& e)
@@ -65,6 +73,9 @@ void IndexElementsVisitor::addCriterion(const ElementCriterionPtr& e)
void IndexElementsVisitor::finalizeIndex()
{
LOG_DEBUG("Finalizing index...");
+ LOG_VARD(_indexToEid.size());
+ LOG_VARD(_boxes.size());
+ LOG_VARD(_fids.size());
_index->bulkInsert(_boxes, _fids);
}
@@ -72,6 +83,7 @@ void IndexElementsVisitor::visit(const ConstElementPtr& e)
{
if (!_criterion || _criterion->isSatisfied(e))
{
+ LOG_VART(e->getElementId());
_fids.push_back((int)_indexToEid.size());
_indexToEid.push_back(e->getElementId());
@@ -88,10 +100,10 @@ void IndexElementsVisitor::visit(const ConstElementPtr& e)
}
}
-set<ElementId> IndexElementsVisitor::findNeighbors(const Envelope& env,
- const std::shared_ptr<Tgs::HilbertRTree>& index,
- const deque<ElementId>& indexToEid,
- ConstOsmMapPtr pMap)
+set<ElementId> IndexElementsVisitor::findNeighbors(
+ const Envelope& env, const std::shared_ptr<Tgs::HilbertRTree>& index,
+ const deque<ElementId>& indexToEid, ConstOsmMapPtr pMap, const ElementType& elementType,
+ const bool includeContainingRelations)
{
LOG_TRACE("Finding neighbors within env: " << env << "...");
LOG_VART(indexToEid.size());
@@ -100,7 +112,6 @@ set<ElementId> IndexElementsVisitor::findNeighbors(const Envelope& env,
const ElementToRelationMap& e2r = *(pMap->getIndex()).getElementToRelationMap();
LOG_VART(e2r.size());
- set<ElementId> result;
vector<double> min(2), max(2);
min[0] = env.getMinX();
min[1] = env.getMinY();
@@ -108,23 +119,84 @@ set<ElementId> IndexElementsVisitor::findNeighbors(const Envelope& env,
max[1] = env.getMaxY();
IntersectionIterator it(index.get(), min, max);
+ set<ElementId> neighborIds;
while (it.next())
{
ElementId eid = indexToEid[it.getId()];
+ if (elementType == ElementType::Unknown || eid.getType() == elementType)
+ {
+ // Map the tree id to an element id and push into result.
+ neighborIds.insert(eid);
+
+ if (includeContainingRelations)
+ {
+ // Check for relations that contain this element
+ const set<long>& relations = e2r.getRelationByElement(eid);
+ for (set<long>::const_iterator it = relations.begin(); it != relations.end(); ++it)
+ {
+ neighborIds.insert(ElementId(ElementType::Relation, *it));
+ }
+ }
+ }
+ }
+
+ LOG_VART(neighborIds);
+ return neighborIds;
+}
+
+QList<ElementId> IndexElementsVisitor::findSortedNodeNeighbors(
+ const ConstNodePtr& node, const geos::geom::Envelope& env,
+ const std::shared_ptr<Tgs::HilbertRTree>& index, const std::deque<ElementId>& indexToEid,
+ ConstOsmMapPtr pMap)
+{
+ // find the neighboring nodes
+ const set<ElementId> neighborIds =
+ findNeighbors(env, index, indexToEid, pMap, ElementType::Node, false);
- // Map the tree id to an element id and push into result.
- result.insert(eid);
+ // map neighbors to their distance from the input node
- // Check for relations that contain this element
- const set<long>& relations = e2r.getRelationByElement(eid);
- for (set<long>::const_iterator it = relations.begin(); it != relations.end(); ++it)
+ QMultiMap<double, ElementId> neighborNodeDistances;
+ for (std::set<ElementId>::const_iterator neighborIdsItr = neighborIds.begin();
+ neighborIdsItr != neighborIds.end(); ++neighborIdsItr)
+ {
+ ConstNodePtr neighborNode = pMap->getNode(*neighborIdsItr);
+ if (!neighborNode)
+ {
+ // This shouldn't happen unless the geospatial indices were set up improperly for the query
+ // node.
+ const QString errorMsg =
+ QString("Map does not contain neighbor node: %1. Skipping neighbor...")
+ .arg((*neighborIdsItr).toString());
+ throw HootException(errorMsg);
+// LOG_TRACE(errorMsg);
+// continue;
+ }
+ else
+ {
+ neighborNodeDistances.insertMulti(
+ Distance::euclidean(*node, *neighborNode), neighborNode->getElementId());
+ }
+ }
+ LOG_VART(neighborNodeDistances);
+
+ // sort neighbors by increasing distance from the input node
+
+ const QList<double> sortedDistances = neighborNodeDistances.keys();
+ LOG_VART(sortedDistances);
+ QList<ElementId> sortedNeighborIds;
+ for (QList<double>::const_iterator distancesItr = sortedDistances.begin();
+ distancesItr != sortedDistances.end(); ++distancesItr)
+ {
+ const QList<ElementId> ids = neighborNodeDistances.values(*distancesItr);
+ for (int i = 0; i < ids.size(); i++)
{
- result.insert(ElementId(ElementType::Relation, *it));
+ LOG_VART(ids.at(i));
+ sortedNeighborIds.append(ids.at(i));
}
}
- LOG_VART(result.size());
- return result;
+ LOG_VART(sortedNeighborIds);
+ return sortedNeighborIds;
}
}