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 939875d..de488a7 100644
--- a/hoot-core/src/main/cpp/hoot/core/elements/OsmUtils.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/elements/OsmUtils.cpp
@@ -74,7 +74,7 @@ void OsmUtils::printNodes(const QString& nodeCollectionName,
}
}
-const QList<long> OsmUtils::nodesToNodeIds(const QList<std::shared_ptr<const Node>>& nodes)
+QList<long> OsmUtils::nodesToNodeIds(const QList<std::shared_ptr<const Node>>& nodes)
{
QList<long> nodeIds;
for (QList<std::shared_ptr<const Node>>::const_iterator it = nodes.constBegin();
@@ -86,6 +86,21 @@ const QList<long> OsmUtils::nodesToNodeIds(const QList<std::shared_ptr<const Nod
return nodeIds;
}
+std::vector<long> OsmUtils::nodesToNodeIds(const std::vector<std::shared_ptr<const Node>>& nodes)
+{
+ std::vector<long> nodeIds;
+ for (std::vector<std::shared_ptr<const Node>>::const_iterator it = nodes.begin();
+ it != nodes.end(); ++it)
+ {
+ std::shared_ptr<const Node> node = *it;
+ if (node)
+ {
+ nodeIds.push_back(node->getElementId().getId());
+ }
+ }
+ return nodeIds;
+}
+
QList<std::shared_ptr<const Node>> OsmUtils::nodeIdsToNodes(
const QList<long>& nodeIds, const std::shared_ptr<const OsmMap>& map)
{
@@ -97,6 +112,75 @@ QList<std::shared_ptr<const Node>> OsmUtils::nodeIdsToNodes(
return nodes;
}
+std::vector<std::shared_ptr<const Node>> OsmUtils::nodeIdsToNodes(
+ const std::vector<long>& nodeIds, const std::shared_ptr<const OsmMap>& map)
+{
+ std::vector<std::shared_ptr<const Node>> nodes;
+ for (std::vector<long>::const_iterator it = nodeIds.begin(); it != nodeIds.end(); ++it)
+ {
+ nodes.push_back(std::dynamic_pointer_cast<const Node>(map->getElement(ElementType::Node, *it)));
+ }
+ return nodes;
+}
+
+bool OsmUtils::nodeCoordsMatch(std::vector<std::shared_ptr<const Node>> nodes1,
+ std::vector<std::shared_ptr<const Node>> nodes2)
+{
+ if (nodes1.size() != nodes2.size())
+ {
+ return false;
+ }
+
+ for (size_t i = 0; i < nodes1.size(); i++)
+ {
+ ConstNodePtr node1 = nodes1[i];
+ ConstNodePtr node2 = nodes2[i];
+
+ if (!node1 || !node2)
+ {
+ return false;
+ }
+
+ if (!node1->coordsMatch(*node2))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QString OsmUtils::nodeCoordsToString(const std::vector<ConstNodePtr>& nodes)
+{
+ QString str;
+ const int comparisonSensitivity = ConfigOptions().getNodeComparisonCoordinateSensitivity();
+ for (size_t i = 0; i < nodes.size(); i++)
+ {
+ ConstNodePtr node = nodes[i];
+ if (node)
+ {
+ str +=
+ "ID: " + QString::number(node->getId()) + ", X: " +
+ QString::number(node->getX(), 'f', comparisonSensitivity) + ", Y: " +
+ QString::number(node->getY(), 'f', comparisonSensitivity) + "; ";
+ }
+ else
+ {
+ str += "null coord; ";
+ }
+ }
+ str.chop(2);
+ return str;
+}
+
+bool OsmUtils::nodeCoordsMatch(const ConstWayPtr& way1, const ConstWayPtr& way2,
+ const ConstOsmMapPtr& map)
+{
+ return
+ nodeCoordsMatch(
+ nodeIdsToNodes(way1->getNodeIds(), map), nodeIdsToNodes(way2->getNodeIds(), map));
+}
+
Coordinate OsmUtils::nodeToCoord(const std::shared_ptr<const Node>& node)
{
return Coordinate(node->getX(), node->getY());
@@ -162,6 +246,11 @@ QString OsmUtils::getRelationMembersDetailedString(const ConstRelationPtr& relat
return str;
}
+QString OsmUtils::getWayNodesDetailedString(const ConstWayPtr& way, const ConstOsmMapPtr& map)
+{
+ return nodeCoordsToString(nodeIdsToNodes(way->getNodeIds(), map));
+}
+
long OsmUtils::getFirstWayIdFromRelation(const ConstRelationPtr& relation, const OsmMapPtr& map)
{
const std::vector<RelationData::Entry>& relationMembers = relation->getMembers();
@@ -192,7 +281,12 @@ void OsmUtils::logElementDetail(const ConstElementPtr& element, const ConstOsmMa
{
LOG_VAR(message);
LOG_VAR(element);
- if (element->getElementType() == ElementType::Relation)
+ if (element->getElementType() == ElementType::Way)
+ {
+ ConstWayPtr way = std::dynamic_pointer_cast<const Way>(element);
+ LOG_VAR(OsmUtils::getWayNodesDetailedString(way, map));
+ }
+ else if (element->getElementType() == ElementType::Relation)
{
ConstRelationPtr relation = std::dynamic_pointer_cast<const Relation>(element);
LOG_VAR(OsmUtils::getRelationMembersDetailedString(relation, map));
@@ -410,6 +504,11 @@ bool OsmUtils::nodeContainedByAnyWay(const long nodeId, const std::set<long> way
return commonWayIds.size() > 0;
}
+bool OsmUtils::nodeContainedByMoreThanOneWay(const long nodeId, const ConstOsmMapPtr& map)
+{
+ return map->getIndex().getNodeToWayMap()->getWaysByNode(nodeId).size() > 1;
+}
+
bool OsmUtils::isChild(const ElementId& elementId, const ConstOsmMapPtr& map)
{
if (elementContainedByAnyRelation(elementId, map))
@@ -554,4 +653,48 @@ bool OsmUtils::anyElementsHaveAnyKvp(const QStringList& kvps,
return false;
}
+bool OsmUtils::allElementsHaveAnyTagKey(const QStringList& tagKeys,
+ const std::set<ElementId>& elementIds, OsmMapPtr& map)
+{
+ std::vector<ElementPtr> elements;
+ for (std::set<ElementId>::const_iterator it = elementIds.begin(); it != elementIds.end(); ++it)
+ {
+ elements.push_back(map->getElement(*it));
+ }
+ return allElementsHaveAnyTagKey(tagKeys, elements);
+}
+
+bool OsmUtils::allElementsHaveAnyKvp(const QStringList& kvps,
+ const std::set<ElementId>& elementIds, OsmMapPtr& map)
+{
+ std::vector<ElementPtr> elements;
+ for (std::set<ElementId>::const_iterator it = elementIds.begin(); it != elementIds.end(); ++it)
+ {
+ elements.push_back(map->getElement(*it));
+ }
+ return allElementsHaveAnyKvp(kvps, elements);
+}
+
+bool OsmUtils::anyElementsHaveAnyTagKey(const QStringList& tagKeys,
+ const std::set<ElementId>& elementIds, OsmMapPtr& map)
+{
+ std::vector<ElementPtr> elements;
+ for (std::set<ElementId>::const_iterator it = elementIds.begin(); it != elementIds.end(); ++it)
+ {
+ elements.push_back(map->getElement(*it));
+ }
+ return anyElementsHaveAnyTagKey(tagKeys, elements);
+}
+
+bool OsmUtils::anyElementsHaveAnyKvp(const QStringList& kvps,
+ const std::set<ElementId>& elementIds, OsmMapPtr& map)
+{
+ std::vector<ElementPtr> elements;
+ for (std::set<ElementId>::const_iterator it = elementIds.begin(); it != elementIds.end(); ++it)
+ {
+ elements.push_back(map->getElement(*it));
+ }
+ return anyElementsHaveAnyKvp(kvps, elements);
+}
+
}