-
Notifications
You must be signed in to change notification settings - Fork 74
v0.2.47..v0.2.48 changeset BuildingMerger.cpp
Garret Voltz edited this page Sep 27, 2019
·
1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/conflate/polygon/BuildingMerger.cpp b/hoot-core/src/main/cpp/hoot/core/conflate/polygon/BuildingMerger.cpp
index 5fa8819..c172484 100644
--- a/hoot-core/src/main/cpp/hoot/core/conflate/polygon/BuildingMerger.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/conflate/polygon/BuildingMerger.cpp
@@ -33,7 +33,6 @@
#include <hoot/core/ops/RecursiveElementRemover.h>
#include <hoot/core/ops/ReplaceElementOp.h>
#include <hoot/core/schema/OverwriteTagMerger.h>
-#include <hoot/core/schema/TagComparator.h>
#include <hoot/core/schema/TagMergerFactory.h>
#include <hoot/core/util/Log.h>
#include <hoot/core/schema/MetadataTags.h>
@@ -46,6 +45,7 @@
#include <hoot/core/util/Factory.h>
#include <hoot/core/elements/OsmUtils.h>
#include <hoot/core/schema/PreserveTypesTagMerger.h>
+#include <hoot/core/visitors/UniqueElementIdVisitor.h>
using namespace std;
@@ -451,6 +451,43 @@ std::shared_ptr<Element> BuildingMerger::_buildBuilding(const OsmMapPtr& map,
return buildBuilding(map, eids, _manyToManyMatch && _mergeManyToManyMatches);
}
+void BuildingMerger::_fixStatuses(OsmMapPtr map)
+{
+ UniqueElementIdVisitor idVis;
+ map->visitRo(idVis);
+ const QList<ElementId> idVisList =
+ QList<ElementId>::fromStdList(
+ std::list<ElementId>(idVis.getElementSet().begin(), idVis.getElementSet().end()));
+ ElementPtr firstElement = map->getElement(idVisList.at(0));
+ ElementPtr secondElement = map->getElement(idVisList.at(1));
+ // not handling invalid statuses here like is done in PoiPolygonMerger::mergePoiAndPolygon b/c
+ // not sure how to do it yet
+ if (firstElement->getStatus() == Status::Conflated &&
+ secondElement->getStatus() != Status::Conflated)
+ {
+ if (secondElement->getStatus() == Status::Unknown1)
+ {
+ firstElement->getStatus() == Status::Unknown2;
+ }
+ else if (secondElement->getStatus() == Status::Unknown2)
+ {
+ firstElement->getStatus() == Status::Unknown1;
+ }
+ }
+ else if (secondElement->getStatus() == Status::Conflated &&
+ firstElement->getStatus() != Status::Conflated)
+ {
+ if (firstElement->getStatus() == Status::Unknown1)
+ {
+ secondElement->getStatus() == Status::Unknown2;
+ }
+ else if (firstElement->getStatus() == Status::Unknown2)
+ {
+ secondElement->getStatus() == Status::Unknown1;
+ }
+ }
+}
+
void BuildingMerger::mergeBuildings(OsmMapPtr map, const ElementId& mergeTargetId)
{
LOG_INFO("Merging buildings...");
@@ -465,9 +502,18 @@ void BuildingMerger::mergeBuildings(OsmMapPtr map, const ElementId& mergeTargetI
ConfigOptions().getBuildingKeepMoreComplexGeometryWhenAutoMergingKey(), "false");
LOG_VART(ConfigOptions().getBuildingKeepMoreComplexGeometryWhenAutoMerging());
- int buildingsMerged = 0;
+ // See related note about statuses in PoiPolygonMerger::mergePoiAndPolygon. Don't know how to
+ // handle this situation for more than two buildings yet. The logic below will fail in situations
+ // where we have more than one conflated building as input...haven't seen that in the wild yet
+ // though.
+ if (map->getElementCount() == 2)
+ {
+ _fixStatuses(map);
+ }
+ int buildingsMerged = 0;
BuildingCriterion buildingCrit;
+ const QString statusErrMsg = "Elements being merged must have an Unknown1 or Unknown2 status.";
const WayMap ways = map->getWays();
for (WayMap::const_iterator wayItr = ways.begin(); wayItr != ways.end(); ++wayItr)
@@ -476,6 +522,11 @@ void BuildingMerger::mergeBuildings(OsmMapPtr map, const ElementId& mergeTargetI
if (way->getElementId() != mergeTargetId && buildingCrit.isSatisfied(way))
{
LOG_VART(way);
+ if (way->getStatus() == Status::Conflated)
+ {
+ throw IllegalArgumentException(statusErrMsg);
+ }
+
std::set<std::pair<ElementId, ElementId>> pairs;
pairs.insert(std::pair<ElementId, ElementId>(mergeTargetId, way->getElementId()));
BuildingMerger merger(pairs);
@@ -493,6 +544,11 @@ void BuildingMerger::mergeBuildings(OsmMapPtr map, const ElementId& mergeTargetI
if (relation->getElementId() != mergeTargetId && buildingCrit.isSatisfied(relation))
{
LOG_VART(relation);
+ if (relation->getStatus() == Status::Conflated)
+ {
+ throw IllegalArgumentException(statusErrMsg);
+ }
+
std::set<std::pair<ElementId, ElementId>> pairs;
pairs.insert(std::pair<ElementId, ElementId>(mergeTargetId, relation->getElementId()));
BuildingMerger merger(pairs);