Skip to content

v0.2.53..v0.2.54 changeset RemoveDuplicateWayNodesVisitor.cpp

Garret Voltz edited this page Mar 31, 2020 · 1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/visitors/RemoveDuplicateWayNodesVisitor.cpp b/hoot-core/src/main/cpp/hoot/core/visitors/RemoveDuplicateWayNodesVisitor.cpp
index fba9de6..af39f81 100644
--- a/hoot-core/src/main/cpp/hoot/core/visitors/RemoveDuplicateWayNodesVisitor.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/visitors/RemoveDuplicateWayNodesVisitor.cpp
@@ -22,7 +22,7 @@
  * This will properly maintain the copyright information. DigitalGlobe
  * copyrights will be updated automatically.
  *
- * @copyright Copyright (C) 2018, 2019 DigitalGlobe (http://www.digitalglobe.com/)
+ * @copyright Copyright (C) 2018, 2019, 2020 DigitalGlobe (http://www.digitalglobe.com/)
  */
 
 #include "RemoveDuplicateWayNodesVisitor.h"
@@ -31,6 +31,9 @@
 #include <hoot/core/elements/Way.h>
 #include <hoot/core/util/Factory.h>
 #include <hoot/core/util/Log.h>
+#include <hoot/core/criterion/LinearCriterion.h>
+#include <hoot/core/criterion/PolygonCriterion.h>
+#include <hoot/core/ops/RecursiveElementRemover.h>
 
 // Qt
 #include <QVector>
@@ -54,41 +57,43 @@ void RemoveDuplicateWayNodesVisitor::visit(const ElementPtr& e)
 {
   if (e->getElementType() == ElementType::Way)
   {
-    LOG_TRACE("Looking for duplicate way nodes...");
-
     WayPtr way = std::dynamic_pointer_cast<Way>(e);
     assert(way.get());
+    LOG_TRACE("Looking for duplicate way nodes in: " << way->getElementId() << "...");
     const std::vector<long>& wayNodeIds = way->getNodeIds();
     LOG_VART(wayNodeIds);
 
+    // This is invalid. Not even sure if it would get loaded or if it is being cleaned somewhere
+    // else but removing it anyway.
+    if (wayNodeIds.size() == 2 && way->isSimpleLoop())
+    {
+      RecursiveElementRemover(way->getElementId()).apply(_map);
+      return;
+    }
+
     QVector<long> parsedNodeIds;
     QVector<long> duplicateWayNodeIds;
+    long lastNodeId = 0;
     bool foundDuplicateWayNode = false;
     for (size_t i = 0; i < wayNodeIds.size(); i++)
     {
       const long nodeId = wayNodeIds[i];
-      LOG_VART(nodeId);
-      if (!parsedNodeIds.contains(nodeId))
-      {
-        // we haven't seen this node ID yet
-        LOG_TRACE("Valid way node: " << nodeId);
-        parsedNodeIds.append(nodeId);
-      }
-      else if (i == wayNodeIds.size() -1 && nodeId == parsedNodeIds.at(0))
+      // We're only removing consecutive duplicates. Other duplicate entries could be part of a
+      // valid loop feature.
+      if (nodeId != lastNodeId)
       {
-        // this node ID is duplicated, but its the end node duplicating the start node, which is ok
-        // (closed way)
-        LOG_TRACE("End node matches start node: " << nodeId);
+        LOG_TRACE("Valid way node: " << ElementId(ElementType::Node, nodeId));
         parsedNodeIds.append(nodeId);
       }
       else
       {
         // we've found a duplicate where both nodes aren't start and end nodes...not allowed
-        LOG_TRACE("Found duplicate way node: " << nodeId);
+        LOG_TRACE("Found duplicate way node: " << ElementId(ElementType::Node, nodeId));
         duplicateWayNodeIds.append(nodeId);
         foundDuplicateWayNode = true;
         _numAffected++;
       }
+      lastNodeId = nodeId;
     }
     if (foundDuplicateWayNode)
     {
@@ -99,4 +104,12 @@ void RemoveDuplicateWayNodesVisitor::visit(const ElementPtr& e)
   }
 }
 
+QStringList RemoveDuplicateWayNodesVisitor::getCriteria() const
+{
+  QStringList criteria;
+  criteria.append(QString::fromStdString(LinearCriterion::className()));
+  criteria.append(QString::fromStdString(PolygonCriterion::className()));
+  return criteria;
+}
+
 }
Clone this wiki locally