-
Notifications
You must be signed in to change notification settings - Fork 74
v0.2.52..v0.2.53 changeset PoiPolygonMatchVisitor.cpp
Garret Voltz edited this page Feb 12, 2020
·
1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/visitors/poi-polygon/PoiPolygonMatchVisitor.cpp b/hoot-core/src/main/cpp/hoot/core/visitors/poi-polygon/PoiPolygonMatchVisitor.cpp
index 8a89fdd..ac49811 100644
--- a/hoot-core/src/main/cpp/hoot/core/visitors/poi-polygon/PoiPolygonMatchVisitor.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/visitors/poi-polygon/PoiPolygonMatchVisitor.cpp
@@ -22,7 +22,7 @@
* This will properly maintain the copyright information. DigitalGlobe
* copyrights will be updated automatically.
*
- * @copyright Copyright (C) 2017, 2018, 2019 DigitalGlobe (http://www.digitalglobe.com/)
+ * @copyright Copyright (C) 2017, 2018, 2019, 2020 DigitalGlobe (http://www.digitalglobe.com/)
*/
#include "PoiPolygonMatchVisitor.h"
@@ -34,7 +34,7 @@
#include <hoot/core/util/ConfPath.h>
#include <hoot/core/util/ConfigOptions.h>
#include <hoot/core/util/Log.h>
-#include <hoot/core/visitors/IndexElementsVisitor.h>
+#include <hoot/core/visitors/SpatialIndexer.h>
#include <hoot/core/util/StringUtils.h>
// tgs
@@ -54,13 +54,14 @@ _map(map),
_result(result),
_filter(filter)
{
+ _timer.start();
}
PoiPolygonMatchVisitor::PoiPolygonMatchVisitor(const ConstOsmMapPtr& map,
std::vector<ConstMatchPtr>& result,
ConstMatchThresholdPtr threshold,
std::shared_ptr<PoiPolygonRfClassifier> rf,
- PoiPolygonCachePtr infoCache,
+ PoiPolygonInfoCachePtr infoCache,
ElementCriterionPtr filter) :
_map(map),
_result(result),
@@ -75,48 +76,44 @@ _filter(filter),
_infoCache(infoCache)
{
ConfigOptions opts = ConfigOptions();
- _enableAdvancedMatching = opts.getPoiPolygonEnableAdvancedMatching();
- _enableReviewReduction = opts.getPoiPolygonEnableReviewReduction();
- _reviewDistanceThreshold = opts.getPoiPolygonReviewDistanceThreshold();
+ _reviewDistanceThreshold = opts.getPoiPolygonAdditionalSearchDistance();
_taskStatusUpdateInterval = opts.getTaskStatusUpdateInterval();
-
LOG_VART(_infoCache.get());
+ _timer.start();
}
PoiPolygonMatchVisitor::~PoiPolygonMatchVisitor()
{
}
-void PoiPolygonMatchVisitor::_checkForMatch(const std::shared_ptr<const Element>& e)
+void PoiPolygonMatchVisitor::_checkForMatch(const std::shared_ptr<const Element>& e,
+ const std::set<ElementId>& surroundingPolyIds)
{
LOG_TRACE("Checking for match with POI: " << e->getElementId());
+ LOG_VART(surroundingPolyIds.size());
- std::shared_ptr<geos::geom::Envelope> env(e->getEnvelope(_map));
- env->expandBy(_getSearchRadius(e));
-
- // find other nearby candidates
- LOG_TRACE("Searching for polys neighboring the POI...");
- const std::set<ElementId> neighbors =
- IndexElementsVisitor::findNeighbors(*env, _getPolyIndex(), _polyIndexToEid, _getMap());
-
- LOG_TRACE("Attempting to match poly neighbors with POI...");
+ LOG_TRACE("Attempting to match poly neighbors with POI: " << e->getElementId() << "...");
const ElementId poiId(e->getElementType(), e->getId());
_elementsEvaluated++;
int neighborCount = 0;
- for (std::set<ElementId>::const_iterator it = neighbors.begin(); it != neighbors.end(); ++it)
+
+ for (std::set<ElementId>::const_iterator it = surroundingPolyIds.begin();
+ it != surroundingPolyIds.end(); ++it)
{
const ElementId polyId = *it;
+ LOG_VART(polyId);
if (poiId != polyId)
{
const std::shared_ptr<const Element>& poly = _map->getElement(polyId);
+ LOG_VART(poly.get());
+ LOG_VART(poly->getElementId());
if (poly->isUnknown() && _polyCrit.isSatisfied(poly))
{
// score each candidate and push it on the result vector
LOG_TRACE(
"Calculating match between: " << poiId << " and " << poly->getElementId() << "...");
std::shared_ptr<PoiPolygonMatch> m(
- new PoiPolygonMatch(
- _map, _threshold, _rf, _infoCache, _surroundingPolyIds, _surroundingPoiIds));
+ new PoiPolygonMatch(_map, _threshold, _rf, _infoCache, surroundingPolyIds));
m->setConfiguration(conf());
m->calculateMatch(poiId, polyId);
@@ -134,66 +131,48 @@ void PoiPolygonMatchVisitor::_checkForMatch(const std::shared_ptr<const Element>
_neighborCountMax = std::max(_neighborCountMax, neighborCount);
}
-void PoiPolygonMatchVisitor::_collectSurroundingPolyIds(const std::shared_ptr<const Element>& e)
+std::set<ElementId> PoiPolygonMatchVisitor::_collectSurroundingPolyIds(
+ const std::shared_ptr<const Element>& e)
{
- LOG_TRACE("Collecting surrounding poly IDs...");
-
- _surroundingPolyIds.clear();
- std::shared_ptr<geos::geom::Envelope> env(e->getEnvelope(_map));
- env->expandBy(_getSearchRadius(e));
-
- // find other nearby candidates
- LOG_TRACE("Searching for neighbors...");
- const std::set<ElementId> neighbors =
- IndexElementsVisitor::findNeighbors(*env, _getPolyIndex(), _polyIndexToEid, _getMap());
-
- LOG_TRACE("Processing neighbors...");
- ElementId from(e->getElementType(), e->getId());
- for (std::set<ElementId>::const_iterator it = neighbors.begin(); it != neighbors.end(); ++it)
- {
- if (from != *it)
- {
- const std::shared_ptr<const Element>& n = _map->getElement(*it);
- if (n->isUnknown())
- {
- _surroundingPolyIds.insert(*it);
- }
- }
- }
-}
+ LOG_TRACE("Collecting surrounding poly IDs for: " << e->getElementId());
-void PoiPolygonMatchVisitor::_collectSurroundingPoiIds(const std::shared_ptr<const Element>& e)
-{
- LOG_TRACE("Collecting surrounding POI IDs...");
+ std::set<ElementId> surroundingPolyIds;
- _surroundingPoiIds.clear();
std::shared_ptr<geos::geom::Envelope> env(e->getEnvelope(_map));
env->expandBy(_getSearchRadius(e));
// find other nearby candidates
LOG_TRACE("Searching for neighbors...");
const std::set<ElementId> neighbors =
- IndexElementsVisitor::findNeighbors(*env, _getPoiIndex(), _poiIndexToEid, _getMap());
+ SpatialIndexer::findNeighbors(*env, _getPolyIndex(), _polyIndexToEid, _getMap());
+ LOG_VART(neighbors.size());
LOG_TRACE("Processing neighbors...");
ElementId from(e->getElementType(), e->getId());
for (std::set<ElementId>::const_iterator it = neighbors.begin(); it != neighbors.end(); ++it)
{
- if (from != *it)
+ ElementId neighboringElementId = *it;
+ if (from != neighboringElementId)
{
- const std::shared_ptr<const Element>& n = _map->getElement(*it);
- if (n->isUnknown())
+ const std::shared_ptr<const Element>& poly = _map->getElement(neighboringElementId);
+ LOG_VART(neighboringElementId);
+ LOG_VART(poly->isUnknown());
+ if (poly->isUnknown())
{
- _surroundingPoiIds.insert(*it);
+ LOG_TRACE("Found neighboring poly: " << neighboringElementId);
+ surroundingPolyIds.insert(neighboringElementId);
}
}
}
+
+ LOG_VART(surroundingPolyIds.size());
+ return surroundingPolyIds;
}
Meters PoiPolygonMatchVisitor::_getSearchRadius(const std::shared_ptr<const Element>& e) const
{
const Meters searchRadius = e->getCircularError() + _reviewDistanceThreshold;
- LOG_VART(searchRadius);
+ //LOG_VART(searchRadius);
return searchRadius;
}
@@ -202,35 +181,44 @@ void PoiPolygonMatchVisitor::visit(const ConstElementPtr& e)
// See if the element is a POI as defined by poi/poly conflation.
if (isMatchCandidate(e))
{
- // If we are doing advanced matching or review reduction, let's collect all polys that surround
- // the POI and also all POIs that surround it.
- if (_enableAdvancedMatching || _enableReviewReduction)
- {
- _collectSurroundingPolyIds(e);
- _collectSurroundingPoiIds(e);
- }
// Now, let's try to match all polys in the search radius with this POI (both as defined by
// poi/poly conflation).
- _checkForMatch(e);
+
+ // If we are doing advanced matching or review reduction, let's collect all polys that surround
+ // the POI and also all POIs that surround it. If you're doing performance analysis of
+ // poi/poly getting the neighbor polys is definitely a bottleneck, but at this point not sure
+ // anything can be done about it other than running with a smaller search radius.
+
+ _checkForMatch(e, _collectSurroundingPolyIds(e));
_numMatchCandidatesVisited++;
- if (_numMatchCandidatesVisited % (_taskStatusUpdateInterval * 10) == 0)
+ if (_numMatchCandidatesVisited % _taskStatusUpdateInterval == 0)
{
PROGRESS_DEBUG(
"Processed " << StringUtils::formatLargeNumber(_numMatchCandidatesVisited) <<
- " match candidates / " << StringUtils::formatLargeNumber(_map->getElementCount()) <<
- " total elements.");
+ " match candidates / " << StringUtils::formatLargeNumber(_map->getNodeCount()) <<
+ " total nodes.");
}
}
+ // poi/poly matching can be a little slow at times compared to the other types of conflation, so
+ // throttle the log update interval accordingly.
+ if (_timer.elapsed() > 3000 && _taskStatusUpdateInterval >= 10)
+ {
+ _taskStatusUpdateInterval /= 10;
+ }
+ else if (_timer.elapsed() < 250 && _taskStatusUpdateInterval < 10000)
+ {
+ _taskStatusUpdateInterval *= 10;
+ }
+
_numElementsVisited++;
- // poi/poly matching can be a little slow at times compared to the others, so keep the log update
- // interval a little lower.
- if (_numElementsVisited % (_taskStatusUpdateInterval * 10) == 0)
+ if (_numElementsVisited % _taskStatusUpdateInterval == 0)
{
PROGRESS_INFO(
"Processed " << StringUtils::formatLargeNumber(_numElementsVisited) << " / " <<
- StringUtils::formatLargeNumber(_map->getElementCount()) << " elements.");
+ StringUtils::formatLargeNumber(_map->getNodeCount()) << " nodes.");
+ _timer.restart();
}
}
@@ -241,7 +229,7 @@ bool PoiPolygonMatchVisitor::isMatchCandidate(ConstElementPtr element)
return false;
}
- // Itssimpler logic to just examine each POI and check for surrounding polys, rather than check
+ // Its simpler logic to just examine each POI and check for surrounding polys, rather than check
// both POIs and their surrounding polys and polys and their surrounding POIs; note that this is
// different than PoiPolygonMatchCreator::isMatchCandidate, which is looking at both to appease
// the stats.
@@ -252,45 +240,26 @@ std::shared_ptr<Tgs::HilbertRTree>& PoiPolygonMatchVisitor::_getPolyIndex()
{
if (!_polyIndex)
{
+ LOG_INFO("Creating POI/Polygon feature index...");
+
// TODO: tune this? - see #3054
std::shared_ptr<Tgs::MemoryPageStore> mps(new Tgs::MemoryPageStore(728));
_polyIndex.reset(new Tgs::HilbertRTree(mps, 2));
std::shared_ptr<PoiPolygonPolyCriterion> crit(new PoiPolygonPolyCriterion());
- IndexElementsVisitor v(_polyIndex,
- _polyIndexToEid,
- crit,
- std::bind(&PoiPolygonMatchVisitor::_getSearchRadius, this, placeholders::_1),
- _getMap());
-
+ SpatialIndexer v(_polyIndex,
+ _polyIndexToEid,
+ crit,
+ std::bind(&PoiPolygonMatchVisitor::_getSearchRadius, this, placeholders::_1),
+ _getMap());
_getMap()->visitWaysRo(v);
_getMap()->visitRelationsRo(v);
v.finalizeIndex();
- }
- return _polyIndex;
-}
-std::shared_ptr<Tgs::HilbertRTree>& PoiPolygonMatchVisitor::_getPoiIndex()
-{
- if (!_poiIndex)
- {
- // TODO: tune this? - see #3054
- std::shared_ptr<Tgs::MemoryPageStore> mps(new Tgs::MemoryPageStore(728));
- _poiIndex.reset(new Tgs::HilbertRTree(mps, 2));
-
- std::shared_ptr<PoiPolygonPoiCriterion> crit(new PoiPolygonPoiCriterion());
-
- IndexElementsVisitor v(_poiIndex,
- _poiIndexToEid,
- crit,
- std::bind(&PoiPolygonMatchVisitor::_getSearchRadius, this, placeholders::_1),
- _getMap());
-
- _getMap()->visitNodesRo(v);
- v.finalizeIndex();
+ LOG_DEBUG("POI/Polygon feature index created.");
}
- return _poiIndex;
+ return _polyIndex;
}
}