Skip to content

v0.2.48..v0.2.49 changeset OsmUtils.cpp

Garret Voltz edited this page Oct 2, 2019 · 1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/elements/OsmUtils.cpp b/hoot-core/src/main/cpp/hoot/core/elements/OsmUtils.cpp
index ebcd898..939875d 100644
--- a/hoot-core/src/main/cpp/hoot/core/elements/OsmUtils.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/elements/OsmUtils.cpp
@@ -42,6 +42,9 @@
 #include <hoot/core/algorithms/Distance.h>
 #include <hoot/core/criterion/ChainCriterion.h>
 #include <hoot/core/ops/CopyMapSubsetOp.h>
+#include <hoot/core/criterion/AttributeValueCriterion.h>
+#include <hoot/core/util/StringUtils.h>
+#include <hoot/core/criterion/PointCriterion.h>
 
 // Qt
 #include <QDateTime>
@@ -142,10 +145,18 @@ QString OsmUtils::getRelationMembersDetailedString(const ConstRelationPtr& relat
 {
   QString str = "\nMember Detail:\n\n";
   const std::vector<RelationData::Entry> relationMembers = relation->getMembers();
+  LOG_VART(relationMembers.size());
   for (size_t i = 0; i < relationMembers.size(); i++)
   {
     str += "Member #" + QString::number(i + 1) + ":\n\n";
     ConstElementPtr member = map->getElement(relationMembers[i].getElementId());
+    if (!member)
+    {
+      throw HootException(
+        "Unable to retrieve relation member: " + relationMembers[i].getElementId().toString() +
+        ". Skipping adding it to output...");
+    }
+    LOG_VART(member->getElementId());
     str += member->toString() + "\n\n";
   }
   return str;
@@ -378,6 +389,16 @@ OsmMapPtr OsmUtils::getMapSubset(const ConstOsmMapPtr& map, const ElementCriteri
   return output;
 }
 
+bool OsmUtils::elementContainedByAnyRelation(const ElementId& elementId, const ConstOsmMapPtr& map)
+{
+  return map->getIndex().getElementToRelationMap()->getRelationByElement(elementId).size() > 0;
+}
+
+bool OsmUtils::nodeContainedByAnyWay(const long nodeId, const ConstOsmMapPtr& map)
+{
+  return map->getIndex().getNodeToWayMap()->getWaysByNode(nodeId).size() > 0;
+}
+
 bool OsmUtils::nodeContainedByAnyWay(const long nodeId, const std::set<long> wayIds,
                                      const ConstOsmMapPtr& map)
 {
@@ -389,4 +410,148 @@ bool OsmUtils::nodeContainedByAnyWay(const long nodeId, const std::set<long> way
   return commonWayIds.size() > 0;
 }
 
+bool OsmUtils::isChild(const ElementId& elementId, const ConstOsmMapPtr& map)
+{
+  if (elementContainedByAnyRelation(elementId, map))
+  {
+    return true;
+  }
+  if (elementId.getType() == ElementType::Node && nodeContainedByAnyWay(elementId.getId(), map))
+  {
+    return true;
+  }
+  return false;
+}
+
+int OsmUtils::versionLessThanOneCount(const OsmMapPtr& map)
+{
+  std::shared_ptr<AttributeValueCriterion> attrCrit(
+    new AttributeValueCriterion(
+      ElementAttributeType(ElementAttributeType::Version), 1, NumericComparisonType::LessThan));
+  return
+    (int)FilteredVisitor::getStat(
+      attrCrit, std::shared_ptr<ElementCountVisitor>(new ElementCountVisitor()), map);
+}
+
+void OsmUtils::checkVersionLessThanOneCountAndLogWarning(const OsmMapPtr& map)
+{
+  const int numberOfRefElementsWithVersionLessThan1 = OsmUtils::versionLessThanOneCount(map);
+  if (numberOfRefElementsWithVersionLessThan1 > 0)
+  {
+    LOG_WARN(
+      StringUtils::formatLargeNumber(numberOfRefElementsWithVersionLessThan1) << " features in " <<
+      "the reference map have a version less than one. This could lead to difficulties when " <<
+      "applying the resulting changeset back to an authoritative data store. Are the versions " <<
+      "on the features being populated correctly?")
+  }
+}
+
+bool OsmUtils::mapIsPointsOnly(const OsmMapPtr& map)
+{
+  std::shared_ptr<PointCriterion> pointCrit(new PointCriterion());
+  pointCrit->setOsmMap(map.get());
+  return
+    (int)FilteredVisitor::getStat(
+      pointCrit, ElementVisitorPtr(new ElementCountVisitor()), map) ==
+    (int)map->getElementCount();
+}
+
+bool OsmUtils::allElementsHaveAnyTagKey(const QStringList& tagKeys,
+                                        const std::vector<ElementPtr>& elements)
+{
+  for (std::vector<ElementPtr>::const_iterator it = elements.begin(); it != elements.end(); ++it)
+  {
+    ElementPtr element = *it;
+    bool elementHasTagKey = false;
+    for (int i = 0; i < tagKeys.size(); i++)
+    {
+      if (element->getTags().contains(tagKeys.at(i)))
+      {
+        elementHasTagKey = true;
+        break;
+      }
+    }
+    if (!elementHasTagKey)
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool OsmUtils::allElementsHaveAnyKvp(const QStringList& kvps,
+                                     const std::vector<ElementPtr>& elements)
+{
+
+  for (std::vector<ElementPtr>::const_iterator it = elements.begin(); it != elements.end(); ++it)
+  {
+    ElementPtr element = *it;
+    bool elementHasKvp = false;
+    for (int i = 0; i < kvps.size(); i++)
+    {
+      const QString kvp = kvps.at(i);
+      const QStringList kvpParts = kvp.split("=");
+      if (kvpParts.size() != 2)
+      {
+        throw IllegalArgumentException("Invalid kvp: " + kvp);
+      }
+      const QString key = kvpParts[0];
+      const QString val = kvpParts[1];
+      if (element->getTags()[key] == val)
+      {
+        elementHasKvp = true;
+        break;
+      }
+    }
+    if (!elementHasKvp)
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool OsmUtils::anyElementsHaveAnyTagKey(const QStringList& tagKeys,
+                                        const std::vector<ElementPtr>& elements)
+{
+  for (std::vector<ElementPtr>::const_iterator it = elements.begin(); it != elements.end(); ++it)
+  {
+    ElementPtr element = *it;
+    for (int i = 0; i < tagKeys.size(); i++)
+    {
+      if (element->getTags().contains(tagKeys.at(i)))
+      {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool OsmUtils::anyElementsHaveAnyKvp(const QStringList& kvps,
+                                     const std::vector<ElementPtr>& elements)
+{
+
+  for (std::vector<ElementPtr>::const_iterator it = elements.begin(); it != elements.end(); ++it)
+  {
+    ElementPtr element = *it;
+    for (int i = 0; i < kvps.size(); i++)
+    {
+      const QString kvp = kvps.at(i);
+      const QStringList kvpParts = kvp.split("=");
+      if (kvpParts.size() != 2)
+      {
+        throw IllegalArgumentException("Invalid kvp: " + kvp);
+      }
+      const QString key = kvpParts[0];
+      const QString val = kvpParts[1];
+      if (element->getTags()[key] == val)
+      {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 }
Clone this wiki locally