Skip to content

v0.2.47..v0.2.48 changeset ReplacementSnappedWayJoiner.cpp

Garret Voltz edited this page Sep 27, 2019 · 1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/algorithms/ReplacementSnappedWayJoiner.cpp b/hoot-core/src/main/cpp/hoot/core/algorithms/ReplacementSnappedWayJoiner.cpp
new file mode 100644
index 0000000..c8214b2
--- /dev/null
+++ b/hoot-core/src/main/cpp/hoot/core/algorithms/ReplacementSnappedWayJoiner.cpp
@@ -0,0 +1,151 @@
+/*
+ * This file is part of Hootenanny.
+ *
+ * Hootenanny is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * --------------------------------------------------------------------
+ *
+ * The following copyright notices are generated automatically. If you
+ * have a new notice to add, please use the format:
+ * " * @copyright Copyright ..."
+ * This will properly maintain the copyright information. DigitalGlobe
+ * copyrights will be updated automatically.
+ *
+ * @copyright Copyright (C) 2019 DigitalGlobe (http://www.digitalglobe.com/)
+ */
+
+#include "ReplacementSnappedWayJoiner.h"
+
+// Hoot
+#include <hoot/core/util/Factory.h>
+#include <hoot/core/ops/ReplaceElementOp.h>
+#include <hoot/core/io/OsmMapWriterFactory.h>
+
+namespace hoot
+{
+
+HOOT_FACTORY_REGISTER(WayJoiner, ReplacementSnappedWayJoiner)
+
+ReplacementSnappedWayJoiner::ReplacementSnappedWayJoiner()
+{
+  _leavePid = true;
+  _callingClass = QString::fromStdString(className());
+}
+
+ReplacementSnappedWayJoiner::ReplacementSnappedWayJoiner(
+  const QMap<ElementId, long>& refIdToVersionMappings) :
+WayJoinerAdvanced::WayJoinerAdvanced(),
+_refIdToVersionMappings(refIdToVersionMappings)
+{
+  _leavePid = true;
+  _callingClass = QString::fromStdString(className());
+}
+
+bool ReplacementSnappedWayJoiner::_areJoinable(const WayPtr& w1, const WayPtr& w2) const
+{
+  // We'll join up anything, as long as its not invalid.
+  return w1->getStatus() != Status::Invalid && w2->getStatus() != Status::Invalid;
+}
+
+void ReplacementSnappedWayJoiner::_determineKeeperFeatureForTags(
+  WayPtr parent, WayPtr child, WayPtr& keeper, WayPtr& toRemove) const
+{
+  // We always want to keep unknown2, which is the dough ways being joined up with the cookie cut
+  // replacement ways.
+  if (parent->getStatus() == Status::Unknown2)
+  {
+    keeper = parent;
+    toRemove = child;
+  }
+  else if (child->getStatus() == Status::Unknown2)
+  {
+    keeper = child;
+    toRemove = parent;
+  }
+  else
+  {
+    keeper = parent;
+    toRemove = child;
+  }
+}
+
+void ReplacementSnappedWayJoiner::_determineKeeperFeatureForId(
+  WayPtr parent, WayPtr child, WayPtr& keeper, WayPtr& toRemove) const
+{
+  _determineKeeperFeatureForTags(parent, child, keeper, toRemove);
+}
+
+bool ReplacementSnappedWayJoiner::_hasPid(const ConstWayPtr& way) const
+{
+  return way->hasPid() || way->getTags().contains(MetadataTags::HootSplitParentId());
+}
+
+long ReplacementSnappedWayJoiner::_getPid(const ConstWayPtr& way) const
+{
+  long pid = WayData::PID_EMPTY;
+  if (way->hasPid())
+  {
+    pid = way->getPid();
+  }
+  else if (way->getTags().contains(MetadataTags::HootSplitParentId()))
+  {
+    pid = way->getTags()[MetadataTags::HootSplitParentId()].toLong();
+  }
+  return pid;
+}
+
+void ReplacementSnappedWayJoiner::join(const OsmMapPtr& map)
+{
+  LOG_DEBUG("Joining ways...");
+
+  WayJoinerAdvanced::join(map);
+
+  if (_refIdToVersionMappings.isEmpty())
+  {
+    LOG_WARN("No version mappings exist for ref ways.");
+  }
+
+  // If anything left has a PID on it, let's make that PID its ID. This doesn't seem like a great
+  // way to do it and problems could be encountered in the future where more than one split way inside
+  // of the bounds had the same parent...haven't seen that happen yet, so will go with this for now.
+  WayMap ways = _map->getWays();
+  QSet<long> pidsUsed;
+  for (WayMap::const_iterator it = ways.begin(); it != ways.end(); ++it)
+  {
+    WayPtr way = it->second;
+    const long pid = _getPid(way);
+    if (pid != WayData::PID_EMPTY && pid > 0 && !pidsUsed.contains(pid))
+    {
+      LOG_TRACE("Setting id from pid: " << pid << " on: " << way->getElementId());
+      ElementPtr newWay(way->clone());
+      newWay->setId(pid);
+      const ElementId parentElementId = ElementId(ElementType::Way, pid);
+      if (!_refIdToVersionMappings.contains(parentElementId))
+      {
+        LOG_WARN("No version mapping for ref way: " << parentElementId);
+      }
+      else
+      {
+        newWay->setVersion(_refIdToVersionMappings[parentElementId]);
+      }
+      LOG_VART(newWay->getVersion());
+      LOG_VART(newWay->getStatus());
+      _map->replace(way, newWay);
+      pidsUsed.insert(pid);
+    }
+  }
+  OsmMapWriterFactory::writeDebugMap(map, "after-replacement-snapped-way-joiner-pid-set");
+}
+
+}
Clone this wiki locally