-
Notifications
You must be signed in to change notification settings - Fork 74
v0.2.49..v0.2.50 changeset HighwaySnapMerger.cpp
Garret Voltz edited this page Nov 6, 2019
·
1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/conflate/highway/HighwaySnapMerger.cpp b/hoot-core/src/main/cpp/hoot/core/conflate/highway/HighwaySnapMerger.cpp
index c7d790a..dc1ebad 100644
--- a/hoot-core/src/main/cpp/hoot/core/conflate/highway/HighwaySnapMerger.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/conflate/highway/HighwaySnapMerger.cpp
@@ -37,23 +37,25 @@
#include <hoot/core/algorithms/linearreference/WaySublineCollection.h>
#include <hoot/core/algorithms/splitter/MultiLineStringSplitter.h>
#include <hoot/core/algorithms/subline-matching/SublineStringMatcher.h>
-#include <hoot/core/elements/NodeToWayMap.h>
#include <hoot/core/conflate/highway/HighwayMatch.h>
#include <hoot/core/criterion/OneWayCriterion.h>
#include <hoot/core/elements/ElementConverter.h>
+#include <hoot/core/elements/NodeToWayMap.h>
+#include <hoot/core/elements/OsmUtils.h>
#include <hoot/core/index/OsmMapIndex.h>
#include <hoot/core/io/OsmMapWriterFactory.h>
+#include <hoot/core/ops/IdSwapOp.h>
#include <hoot/core/ops/RecursiveElementRemover.h>
+#include <hoot/core/ops/ReplaceElementOp.h>
+#include <hoot/core/ops/RemoveElementByEid.h>
#include <hoot/core/ops/RemoveReviewsByEidOp.h>
#include <hoot/core/schema/TagMergerFactory.h>
+#include <hoot/core/util/Factory.h>
#include <hoot/core/util/Log.h>
#include <hoot/core/util/MapProjector.h>
#include <hoot/core/util/Validate.h>
#include <hoot/core/visitors/ElementOsmMapVisitor.h>
#include <hoot/core/visitors/WaysVisitor.h>
-#include <hoot/core/ops/ReplaceElementOp.h>
-#include <hoot/core/elements/OsmUtils.h>
-#include <hoot/core/util/Factory.h>
// Qt
#include <QSet>
@@ -251,6 +253,8 @@ bool HighwaySnapMerger::_mergePair(const OsmMapPtr& map, ElementId eid1, Element
LOG_VART(e1->getElementId());
LOG_VART(e2->getElementId());
+ bool swapWayIds = false;
+
if (e1Match->getElementType() == ElementType::Way)
{
if (e1->getElementType() == ElementType::Way && e2->getElementType() == ElementType::Way)
@@ -266,6 +270,9 @@ bool HighwaySnapMerger::_mergePair(const OsmMapPtr& map, ElementId eid1, Element
wMatch->setPid(pid);
LOG_TRACE("Set PID: " << pid << " on: " << wMatch->getElementId() << " (e1Match).");
+ // Keep the original ID from e1 for e1Match
+ swapWayIds = true;
+
if (scraps1)
{
if (scraps1->getElementType() == ElementType::Way)
@@ -274,13 +281,44 @@ bool HighwaySnapMerger::_mergePair(const OsmMapPtr& map, ElementId eid1, Element
LOG_TRACE(
"Set PID: " << w1->getPid() << " on: " << scraps1->getElementId() << " (scraps1).");
}
+ else if (scraps1->getElementType() == ElementType::Relation)
+ {
+ RelationPtr r = std::dynamic_pointer_cast<Relation>(scraps1);
+ for (size_t i = 0; i < r->getMembers().size(); ++i)
+ {
+ ElementId eid = r->getMembers()[i].getElementId();
+ if (eid.getType() == ElementType::Way)
+ {
+ map->getWay(eid)->setPid(w1->getPid());
+ LOG_TRACE(
+ "Set PID: " << w1->getPid() << " on: " << eid << " (scraps1).");
+ }
+ }
+ }
}
- if (scraps2 && scraps2->getElementType() == ElementType::Way)
+ if (scraps2)
{
- std::dynamic_pointer_cast<Way>(scraps2)->setPid(w2->getPid());
- LOG_TRACE(
- "Set PID: " << w2->getPid() << " on: " << scraps2->getElementId() << " (scraps2).");
+ if (scraps2->getElementType() == ElementType::Way)
+ {
+ std::dynamic_pointer_cast<Way>(scraps2)->setPid(w2->getPid());
+ LOG_TRACE(
+ "Set PID: " << w2->getPid() << " on: " << scraps2->getElementId() << " (scraps2).");
+ }
+ else if (scraps2->getElementType() == ElementType::Relation)
+ {
+ RelationPtr r = std::dynamic_pointer_cast<Relation>(scraps2);
+ for (size_t i = 0; i < r->getMembers().size(); ++i)
+ {
+ ElementId eid = r->getMembers()[i].getElementId();
+ if (eid.getType() == ElementType::Way)
+ {
+ map->getWay(eid)->setPid(w2->getPid());
+ LOG_TRACE(
+ "Set PID: " << w2->getPid() << " on: " << eid << " (scraps2).");
+ }
+ }
+ }
}
// Reverse the way if w2 is one way and w1 isn't the similar direction as w2
@@ -334,7 +372,26 @@ bool HighwaySnapMerger::_mergePair(const OsmMapPtr& map, ElementId eid1, Element
// remove the old way that was split and snapped
if (e1 != e1Match && scraps1)
{
- ReplaceElementOp(eid1, scraps1->getElementId(), true).apply(result);
+ if (swapWayIds)
+ {
+ ElementId eidm1 = e1Match->getElementId();
+ // Swap the old way ID back into the match element
+ IdSwapOp(eid1, eidm1).apply(result);
+ // Remove the old way with a new swapped out ID
+ RemoveElementByEid(eidm1).apply(result);
+ // Add the scraps element to all the relations that the match is in
+ if (scraps1)
+ {
+ QList<ElementPtr> list;
+ list.append(e1Match);
+ list.append(scraps1);
+ result->replace(e1Match, list);
+ // Update the scraps
+ _updateScrapParent(result, e1Match->getId(), scraps1);
+ }
+ }
+ else if (scraps1)
+ ReplaceElementOp(eid1, scraps1->getElementId(), true).apply(result);
}
else
{
@@ -348,6 +405,7 @@ bool HighwaySnapMerger::_mergePair(const OsmMapPtr& map, ElementId eid1, Element
map->addElement(scraps2);
ReplaceElementOp(e2Match->getElementId(), scraps2->getElementId(), true).apply(result);
ReplaceElementOp(eid2, scraps2->getElementId(), true).apply(result);
+// _updateScrapParent(result, e2Match->getId(), scraps2);
}
// if there is nothing to review against, drop the reviews.
else
@@ -693,4 +751,20 @@ void HighwaySnapMerger::_splitElement(const OsmMapPtr& map, const WaySublineColl
}
}
+void HighwaySnapMerger::_updateScrapParent(const OsmMapPtr& map, long id, const ElementPtr& scrap)
+{
+ if (!scrap)
+ return;
+ if (scrap->getElementType() == ElementType::Way)
+ std::dynamic_pointer_cast<Way>(scrap)->setPid(id);
+ else if (scrap->getElementType() == ElementType::Relation)
+ {
+ RelationPtr relation = std::dynamic_pointer_cast<Relation>(scrap);
+ const vector<RelationData::Entry>& members = relation->getMembers();
+ // Iterate all of the members and update the parent id recursively
+ for (size_t i = 0; i < members.size(); ++i)
+ _updateScrapParent(map, id, map->getElement(members[i].getElementId()));
+ }
+}
+
}