Skip to content

v0.2.53..v0.2.54 changeset PoiPolygonReviewReducer.cpp

Garret Voltz edited this page Mar 31, 2020 · 1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/conflate/poi-polygon/PoiPolygonReviewReducer.cpp b/hoot-core/src/main/cpp/hoot/core/conflate/poi-polygon/PoiPolygonReviewReducer.cpp
index ca02f8e..06a10d0 100644
--- a/hoot-core/src/main/cpp/hoot/core/conflate/poi-polygon/PoiPolygonReviewReducer.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/conflate/poi-polygon/PoiPolygonReviewReducer.cpp
@@ -39,6 +39,10 @@
 #include <hoot/core/algorithms/extractors/OverlapExtractor.h>
 #include <hoot/core/criterion/BuildingWayNodeCriterion.h>
 #include <hoot/core/conflate/poi-polygon/PoiPolygonSchema.h>
+#include <hoot/core/elements/Node.h>
+
+// geos
+#include <geos/util/TopologyException.h>
 
 // Std
 #include <float.h>
@@ -81,7 +85,6 @@ _infoCache(infoCache)
   LOG_VART(_matchDistanceThreshold);
   LOG_VART(_addressMatch);
   LOG_VART(_addressParsingEnabled);
-
   LOG_VART(_infoCache.get());
 }
 
@@ -97,7 +100,7 @@ bool PoiPolygonReviewReducer::_nonDistanceSimilaritiesPresent() const
 
 bool PoiPolygonReviewReducer::triggersRule(ConstNodePtr poi, ConstElementPtr poly)
 {
-  LOG_TRACE("Checking review reduction rules...");
+  LOG_DEBUG("Checking review reduction rules...");
   _triggeredRuleDescription = "";
   //QElapsedTimer timer;
   //const int timingThreshold = 1000000;  //nanosec
@@ -372,7 +375,8 @@ bool PoiPolygonReviewReducer::triggersRule(ConstNodePtr poi, ConstElementPtr pol
   //building ways.
   ruleDescription = "#20: building way node";
   LOG_TRACE("Checking rule : " << ruleDescription << "...");
-  const long matchingWayId = BuildingWayNodeCriterion(_map).getMatchingWayId(poi);
+  const long matchingWayId =
+    BuildingWayNodeCriterion(_map).getFirstOwningWayId(std::dynamic_pointer_cast<const Node>(poi));
   if (matchingWayId != 0)
   {
     ConstWayPtr matchingWay = _map->getWay(matchingWayId);
@@ -506,6 +510,7 @@ bool PoiPolygonReviewReducer::triggersRule(ConstNodePtr poi, ConstElementPtr pol
   }
 
   //QElapsedTimer timer2;
+  LOG_DEBUG("Checking neighbors...");
   LOG_VART(_polyNeighborIds.size());
   // This loop becomes more expensive as the search radius is increased.
   for (std::set<ElementId>::const_iterator polyNeighborItr = _polyNeighborIds.begin();
@@ -513,149 +518,157 @@ bool PoiPolygonReviewReducer::triggersRule(ConstNodePtr poi, ConstElementPtr pol
   {
     ConstElementPtr polyNeighbor = _map->getElement(*polyNeighborItr);
     if (polyNeighbor->getElementId() != poly->getElementId())
-    {
-      //this is a little loose, b/c there could be more than one type match set of tags...
-      //timer.restart();
-      if (poiIsSport && _infoCache->isType(polyNeighbor, PoiPolygonSchemaType::Sport) &&
-          _infoCache->elementContains(polyNeighbor, poi) &&
-          PoiPolygonTypeScoreExtractor(_infoCache).extract(*_map, poi, polyNeighbor) >=
-           _typeScoreThreshold)
-      {
-        sportPoiOnOtherSportPolyWithTypeMatch = true;
-      }
-      else if (_infoCache->hasCriterion(
-                 polyNeighbor, QString::fromStdString(BuildingCriterion::className())) &&
-               _infoCache->elementContains(polyNeighbor, poi))
-      {
-        poiOnBuilding = true;
-      }
-      else if (_infoCache->isType(polyNeighbor, PoiPolygonSchemaType::Park))
+    { 
+      try
       {
-        // Should this be OsmSchema::elementHasName instead?
-        otherParkPolyHasName = !polyNeighbor->getTags().get("name").trimmed().isEmpty();
-        otherParkPolyNameScore = PoiPolygonNameScoreExtractor().extract(*_map, poi, polyNeighbor);
-        otherParkPolyNameMatch = otherParkPolyNameScore >= _nameScoreThreshold;
-
-        if (_infoCache->elementContains(polyNeighbor, poi))
+        //this is a little loose, b/c there could be more than one type match set of tags...
+        //timer.restart();
+        if (poiIsSport && _infoCache->isType(polyNeighbor, PoiPolygonSchemaType::Sport) &&
+            _infoCache->elementContains(polyNeighbor, poi) &&
+            PoiPolygonTypeScoreExtractor(_infoCache).extract(*_map, poi, polyNeighbor) >=
+             _typeScoreThreshold)
         {
-          poiContainedInAnotherParkPoly = true;
-          LOG_TRACE(
-            "poi examined and found to be contained within a park poly outside of this match " <<
-            "comparison: " << poi->toString());
-          LOG_TRACE("park poly it is very close to: " << polyNeighbor->toString());
+          sportPoiOnOtherSportPolyWithTypeMatch = true;
         }
-
-        if (_infoCache->elementsIntersect(polyNeighbor, poly))
+        else if (_infoCache->hasCriterion(
+                   polyNeighbor, QString::fromStdString(BuildingCriterion::className())) &&
+                 _infoCache->elementContains(polyNeighbor, poi))
         {
-          parkPolyAngleHistVal = AngleHistogramExtractor().extract(*_map, polyNeighbor, poly);
-          LOG_VART(parkPolyAngleHistVal);
-
-          parkPolyOverlapVal =  OverlapExtractor().extract(*_map, polyNeighbor, poly);
-          LOG_VART(parkPolyOverlapVal);
+          poiOnBuilding = true;
+        }
+        else if (_infoCache->isType(polyNeighbor, PoiPolygonSchemaType::Park))
+        {
+          // Should this be OsmSchema::elementHasName instead?
+          otherParkPolyHasName = !polyNeighbor->getTags().get("name").trimmed().isEmpty();
+          otherParkPolyNameScore = PoiPolygonNameScoreExtractor().extract(*_map, poi, polyNeighbor);
+          otherParkPolyNameMatch = otherParkPolyNameScore >= _nameScoreThreshold;
 
-          //When just using intersection as the criteria, only found one instance when something
-          //was considered as "very close" to a park poly when I didn't want it to be...so these
-          //values set very low to weed that instance out...overlap at least.
-          if (parkPolyAngleHistVal != -1.0 && parkPolyOverlapVal != 1.0 &&
-              parkPolyAngleHistVal >= 0.05 && parkPolyOverlapVal >= 0.02)
+          if (_infoCache->elementContains(polyNeighbor, poi))
           {
-            polyVeryCloseToAnotherParkPoly = true;
-
-            //Calc the distance from the poi to the poly line instead of the poly itself.
-            //Calcing distance to the poly itself will always return 0 when the poi is in the
-            //poly.
-            poiToPolyNodeDist = _infoCache->getDistance(poly, poi);
-            poiToOtherParkPolyNodeDist = _infoCache->getDistance(polyNeighbor, poi);
+            poiContainedInAnotherParkPoly = true;
             LOG_TRACE(
-              "poly examined and found very close to a another park poly: " << poly->toString());
+              "poi examined and found to be contained within a park poly outside of this match " <<
+              "comparison: " << poi->toString());
             LOG_TRACE("park poly it is very close to: " << polyNeighbor->toString());
           }
+
+          if (_infoCache->elementsIntersect(polyNeighbor, poly))
+          {
+            parkPolyAngleHistVal = AngleHistogramExtractor().extract(*_map, polyNeighbor, poly);
+            LOG_VART(parkPolyAngleHistVal);
+
+            parkPolyOverlapVal =  OverlapExtractor().extract(*_map, polyNeighbor, poly);
+            LOG_VART(parkPolyOverlapVal);
+
+            //When just using intersection as the criteria, only found one instance when something
+            //was considered as "very close" to a park poly when I didn't want it to be...so these
+            //values set very low to weed that instance out...overlap at least.
+            if (parkPolyAngleHistVal != -1.0 && parkPolyOverlapVal != 1.0 &&
+                parkPolyAngleHistVal >= 0.05 && parkPolyOverlapVal >= 0.02)
+            {
+              polyVeryCloseToAnotherParkPoly = true;
+
+              //Calc the distance from the poi to the poly line instead of the poly itself.
+              //Calcing distance to the poly itself will always return 0 when the poi is in the
+              //poly.
+              poiToPolyNodeDist = _infoCache->getDistance(poly, poi);
+              poiToOtherParkPolyNodeDist = _infoCache->getDistance(polyNeighbor, poi);
+              LOG_TRACE(
+                "poly examined and found very close to a another park poly: " << poly->toString());
+              LOG_TRACE("park poly it is very close to: " << polyNeighbor->toString());
+            }
+          }
         }
-      }
 
-      LOG_VART(poiToOtherParkPolyNodeDist);
-      LOG_VART(polyVeryCloseToAnotherParkPoly);
-      LOG_VART(poiToPolyNodeDist);
-      LOG_VART(poiToOtherParkPolyNodeDist);
-      LOG_VART(otherParkPolyHasName);
-      LOG_VART(otherParkPolyNameMatch);
-      LOG_VART(otherParkPolyNameScore);
-      LOG_VART(poiContainedInAnotherParkPoly);
-      LOG_VART(sportPoiOnOtherSportPolyWithTypeMatch);
-      LOG_VART(poiOnBuilding);
-
-      //If the POI is inside a poly that is very close to another park poly, declare miss if
-      //the distance to the outer ring of the other park poly is shorter than the distance to the
-      //outer ring of this poly and the other park poly has a name.
-      ruleDescription = "#25: park poly neighbor 1";
-      LOG_TRACE("Checking rule : " << ruleDescription << "...");
-      if ((poiIsPark || poiIsParkish) && polyVeryCloseToAnotherParkPoly && _distance == 0 &&
-          poiToOtherParkPolyNodeDist < poiToPolyNodeDist && poiToPolyNodeDist != DBL_MAX &&
-          poiToPolyNodeDist != -1.0 && poiToOtherParkPolyNodeDist != DBL_MAX &&
-          poiToOtherParkPolyNodeDist != -1.0 && otherParkPolyHasName && parkPolyOverlapVal < 0.9)
-      {
-        LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
-        _triggeredRuleDescription = ruleDescription;
-        return true;
-      }
+        LOG_VART(poiToOtherParkPolyNodeDist);
+        LOG_VART(polyVeryCloseToAnotherParkPoly);
+        LOG_VART(poiToPolyNodeDist);
+        LOG_VART(poiToOtherParkPolyNodeDist);
+        LOG_VART(otherParkPolyHasName);
+        LOG_VART(otherParkPolyNameMatch);
+        LOG_VART(otherParkPolyNameScore);
+        LOG_VART(poiContainedInAnotherParkPoly);
+        LOG_VART(sportPoiOnOtherSportPolyWithTypeMatch);
+        LOG_VART(poiOnBuilding);
+
+        //If the POI is inside a poly that is very close to another park poly, declare miss if
+        //the distance to the outer ring of the other park poly is shorter than the distance to the
+        //outer ring of this poly and the other park poly has a name.
+        ruleDescription = "#25: park poly neighbor 1";
+        LOG_TRACE("Checking rule : " << ruleDescription << "...");
+        if ((poiIsPark || poiIsParkish) && polyVeryCloseToAnotherParkPoly && _distance == 0 &&
+            poiToOtherParkPolyNodeDist < poiToPolyNodeDist && poiToPolyNodeDist != DBL_MAX &&
+            poiToPolyNodeDist != -1.0 && poiToOtherParkPolyNodeDist != DBL_MAX &&
+            poiToOtherParkPolyNodeDist != -1.0 && otherParkPolyHasName && parkPolyOverlapVal < 0.9)
+        {
+          LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
+          _triggeredRuleDescription = ruleDescription;
+          return true;
+        }
 
-      //If the poi is a park, the poly it is being compared to is not a park or building, and that
-      //poly is "very close" to another park poly that has a name match with the poi, then
-      //declare a miss (exclude poly playgrounds from this).
-      ruleDescription = "#26: park poly neighbor 2";
-      LOG_TRACE("Checking rule : " << ruleDescription << "...");
-      if (poiIsPark && !polyIsPark && !polyIsBuilding && polyVeryCloseToAnotherParkPoly &&
-          otherParkPolyNameMatch)
-      {
-        LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
-        _triggeredRuleDescription = ruleDescription;
-        return true;
-      }
+        //If the poi is a park, the poly it is being compared to is not a park or building, and that
+        //poly is "very close" to another park poly that has a name match with the poi, then
+        //declare a miss (exclude poly playgrounds from this).
+        ruleDescription = "#26: park poly neighbor 2";
+        LOG_TRACE("Checking rule : " << ruleDescription << "...");
+        if (poiIsPark && !polyIsPark && !polyIsBuilding && polyVeryCloseToAnotherParkPoly &&
+            otherParkPolyNameMatch)
+        {
+          LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
+          _triggeredRuleDescription = ruleDescription;
+          return true;
+        }
 
-      //If a park poi is contained within one park poly, then there's no reason for it to trigger
-      //reviews in another one that its not contained in.
-      ruleDescription = "#27: park poly neighbor 3";
-      LOG_TRACE("Checking rule : " << ruleDescription << "...");
-      if (poiIsPark && polyIsPark && _distance > 0 && poiContainedInAnotherParkPoly)
-      {
-        LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
-        _triggeredRuleDescription = ruleDescription;
-        return true;
-      }
+        //If a park poi is contained within one park poly, then there's no reason for it to trigger
+        //reviews in another one that its not contained in.
+        ruleDescription = "#27: park poly neighbor 3";
+        LOG_TRACE("Checking rule : " << ruleDescription << "...");
+        if (poiIsPark && polyIsPark && _distance > 0 && poiContainedInAnotherParkPoly)
+        {
+          LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
+          _triggeredRuleDescription = ruleDescription;
+          return true;
+        }
 
-      //If a sport poi is contained within a type match sport poi poly, don't let it be
-      //matched against anything else.
-      ruleDescription = "#28: park poly neighbor 4";
-      LOG_TRACE("Checking rule : " << ruleDescription << "...");
-      if (poiIsSport && poiContainedInParkPoly && sportPoiOnOtherSportPolyWithTypeMatch)
-      {
-        LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
-        _triggeredRuleDescription = ruleDescription;
-        return true;
-      }
+        //If a sport poi is contained within a type match sport poi poly, don't let it be
+        //matched against anything else.
+        ruleDescription = "#28: park poly neighbor 4";
+        LOG_TRACE("Checking rule : " << ruleDescription << "...");
+        if (poiIsSport && poiContainedInParkPoly && sportPoiOnOtherSportPolyWithTypeMatch)
+        {
+          LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
+          _triggeredRuleDescription = ruleDescription;
+          return true;
+        }
 
-      //If the poi is not a park and being compared to a park polygon or a polygon that is
-      //"very close" to another park poly, we want to be more restrictive on type matching, but
-      //only if the poi has any type at all.  If the poi has no type, then behave as normal.
-      //Also, let an exact name match cause a review here, rather than a miss.
-      ruleDescription = "#29: park poly neighbor 5";
-      LOG_TRACE("Checking rule : " << ruleDescription << "...");
-      if ((polyIsPark || (polyVeryCloseToAnotherParkPoly && !polyHasType)) &&
-          !polyHasMoreThanOneType && !poiIsPark && !poiIsParkish && poiHasType && _exactNameMatch)
-      {
-        LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
-        _triggeredRuleDescription = ruleDescription;
-        return true;
-      }
+        //If the poi is not a park and being compared to a park polygon or a polygon that is
+        //"very close" to another park poly, we want to be more restrictive on type matching, but
+        //only if the poi has any type at all.  If the poi has no type, then behave as normal.
+        //Also, let an exact name match cause a review here, rather than a miss.
+        ruleDescription = "#29: park poly neighbor 5";
+        LOG_TRACE("Checking rule : " << ruleDescription << "...");
+        if ((polyIsPark || (polyVeryCloseToAnotherParkPoly && !polyHasType)) &&
+            !polyHasMoreThanOneType && !poiIsPark && !poiIsParkish && poiHasType && _exactNameMatch)
+        {
+          LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
+          _triggeredRuleDescription = ruleDescription;
+          return true;
+        }
 
-      //If a poi is like and on top of a building, don't review it against a non-building poly.
-      ruleDescription = "#30: building neighbor 1";
-      LOG_TRACE("Checking rule : " << ruleDescription << "...");
-      if (poiIsBuilding && poiOnBuilding && !polyIsBuilding)
+        //If a poi is like and on top of a building, don't review it against a non-building poly.
+        ruleDescription = "#30: building neighbor 1";
+        LOG_TRACE("Checking rule : " << ruleDescription << "...");
+        if (poiIsBuilding && poiOnBuilding && !polyIsBuilding)
+        {
+          LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
+          _triggeredRuleDescription = ruleDescription;
+          return true;
+        }
+      }
+      catch (const geos::util::TopologyException& e)
       {
-        LOG_TRACE("Returning miss per review reduction rule: " << ruleDescription << "...");
-        _triggeredRuleDescription = ruleDescription;
-        return true;
+        // Not doing anything here for now.
+        LOG_TRACE("PoiPolygonReviewReducer neighbor loop: " << e.what());
       }
     }
   }
Clone this wiki locally