v0.2.50..v0.2.51 changeset OsmApiChangesetElement.cpp
Garret Voltz edited this page Jan 15, 2020
·
1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/io/OsmApiChangesetElement.cpp b/hoot-core/src/main/cpp/hoot/core/io/OsmApiChangesetElement.cpp
index ecf659e..1d74420 100644
--- a/hoot-core/src/main/cpp/hoot/core/io/OsmApiChangesetElement.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/io/OsmApiChangesetElement.cpp
@@ -36,17 +36,26 @@
namespace hoot
{
-XmlElement::XmlElement(const XmlObject& object, ElementIdToIdMap* idMap)
+/** Custom ID sort order */
+bool id_sort_order(long lhs, long rhs)
+{
+ if (lhs > 0 && rhs > 0) return lhs < rhs; // Positive numbers count up
+ else if (lhs < 0 && rhs < 0) return lhs > rhs; // Negative numbers count down
+ else return lhs < rhs; // Negative numbers come before positive
+}
+
+ChangesetElement::ChangesetElement(const XmlObject& object, ElementIdToIdMap* idMap)
: _type(ElementType::Unknown),
_id(object.second.value("id").toString().toLong()),
_version(object.second.value("version").toString().toLong()),
- _object(object),
_idMap(idMap),
- _status(XmlElement::Available)
+ _status(ChangesetElement::Available)
{
+ for (QXmlStreamAttributes::const_iterator it = object.second.begin(); it != object.second.end(); ++it)
+ _object.push_back(std::make_pair(it->name().toString(), it->value().toString()));
}
-XmlElement::XmlElement(const XmlElement& element)
+ChangesetElement::ChangesetElement(const ChangesetElement& element)
: _type(element._type),
_id(element._id),
_version(element._version),
@@ -57,58 +66,73 @@ XmlElement::XmlElement(const XmlElement& element)
{
}
-void XmlElement::addTag(const XmlObject& tag)
+void ChangesetElement::addTag(const XmlObject& tag)
{
// Make sure that the object is in fact a tag before adding it
if (tag.first == "tag")
- _tags.push_back(tag);
+ {
+ QString key;
+ QString value;
+ for (QXmlStreamAttributes::const_iterator it = tag.second.begin(); it != tag.second.end(); ++it)
+ {
+ if (it->name() == "k")
+ key = it->value().toString();
+ else if (it->name() == "v")
+ value = it->value().toString();
+ }
+ if (key != "" and value != "")
+ _tags.push_back(std::make_pair(key, value));
+ }
}
-QString XmlElement::getTagKey(int index)
+QString ChangesetElement::getTagKey(int index)
{
- if (index < 0 || index >= _tags.size() || !_tags[index].second.hasAttribute("k"))
+ if (index < 0 || index >= (int)_tags.size())
throw IllegalArgumentException();
- return _tags[index].second.value("k").toString();
+ return _tags[index].first;
}
-QString XmlElement::getTagValue(int index)
+QString ChangesetElement::getTagValue(int index)
{
- if (index < 0 || index >= _tags.size() || !_tags[index].second.hasAttribute("v"))
+ if (index < 0 || index >= (int)_tags.size())
throw IllegalArgumentException();
- return _tags[index].second.value("v").toString();
+ return _tags[index].second;
}
-QString XmlElement::toString(const QXmlStreamAttributes& attributes, long changesetId) const
+QString ChangesetElement::toString(const ElementAttributes& attributes, long changesetId) const
{
QString buffer;
QTextStream ts(&buffer);
// Setting the codec to UTF-8 is the special sauce for foreign characters
ts.setCodec("UTF-8");
- for (int i = 0; i < attributes.size(); ++i)
+ bool hasChangeset = false;
+ for (ElementAttributes::const_iterator it = attributes.begin(); it != attributes.end(); ++it)
{
- const QXmlStreamAttribute& attribute = attributes.at(i);
- QStringRef name = attribute.name();
+ QString name = it->first;
if (name == "action")
continue;
- ts << name.toString() << "=\"";
+ ts << name << "=\"";
// Some attributes need to be overridden
if (name == "changeset") // Changeset ID is provided by the OSM API
+ {
ts << changesetId;
+ hasChangeset = true;
+ }
else if (name == "id") // Element ID could be different than provided in the file, could be from the API
- ts << (_idMap ? _idMap->getNewId(_type, _id) : _id);
+ ts << (_idMap ? _idMap->getId(_type, _id) : _id);
else if (name == "version") // Versions are updated by the API
ts << _version;
else
- ts << attribute.value().toString();
+ ts << it->second;
ts << "\" ";
}
// Add the changeset attribute if the original data didn't include it
- if (!attributes.hasAttribute("changeset"))
+ if (!hasChangeset)
ts << "changeset=\"" << changesetId << "\"";
return ts.readAll();
}
-QString& XmlElement::escapeString(QString& value) const
+QString& ChangesetElement::escapeString(QString& value) const
{
// Simple XML encoding of some problematic characters
return value.replace("&", "&")
@@ -118,18 +142,18 @@ QString& XmlElement::escapeString(QString& value) const
.replace("<", "<");
}
-QString XmlElement::toTagString(const QXmlStreamAttributes& attributes) const
+QString ChangesetElement::toTagString(const ElementTag& tag) const
{
QString buffer;
QTextStream ts(&buffer);
ts.setCodec("UTF-8");
- QString key(attributes.value("k").toString());
- QString value(attributes.value("v").toString());
+ QString key(tag.first);
+ QString value(tag.second);
// Tag values of length 255 need to be truncated
QString newValue(ApiTagTruncateVisitor::truncateTag(key, value));
// Make sure to XML encode the value
- ts << "\t\t\t<tag k=\"" << attributes.value("k").toString() << "\" v=\"";
+ ts << "\t\t\t<tag k=\"" << key << "\" v=\"";
if (newValue != "")
ts << escapeString(newValue);
else
@@ -138,29 +162,29 @@ QString XmlElement::toTagString(const QXmlStreamAttributes& attributes) const
return ts.readAll();
}
-XmlNode::XmlNode(const XmlObject& node, ElementIdToIdMap* idMap)
- : XmlElement(node, idMap)
+ChangesetNode::ChangesetNode(const XmlObject& node, ElementIdToIdMap* idMap)
+ : ChangesetElement(node, idMap)
{
// Override the type
_type = ElementType::Node;
}
-XmlNode::XmlNode(const XmlNode &node)
- : XmlElement(node)
+ChangesetNode::ChangesetNode(const ChangesetNode &node)
+ : ChangesetElement(node)
{
}
-QString XmlNode::toString(long changesetId) const
+QString ChangesetNode::toString(long changesetId) const
{
QString buffer;
QTextStream ts(&buffer);
ts.setCodec("UTF-8");
- ts << "\t\t<node " << XmlElement::toString(_object.second, changesetId);
+ ts << "\t\t<node " << ChangesetElement::toString(_object, changesetId);
if (_tags.size() > 0)
{
ts << ">\n";
- for (QVector<XmlObject>::const_iterator it = _tags.begin(); it != _tags.end(); ++it)
- ts << toTagString(it->second);
+ for (ElementTags::const_iterator it = _tags.begin(); it != _tags.end(); ++it)
+ ts << toTagString(*it);
ts << "\t\t</node>\n";
}
else
@@ -168,20 +192,20 @@ QString XmlNode::toString(long changesetId) const
return ts.readAll();
}
-XmlWay::XmlWay(const XmlObject& way, ElementIdToIdMap* idMap)
- : XmlElement(way, idMap)
+ChangesetWay::ChangesetWay(const XmlObject& way, ElementIdToIdMap* idMap)
+ : ChangesetElement(way, idMap)
{
// Override the type
_type = ElementType::Way;
}
-XmlWay::XmlWay(const XmlWay &way)
- : XmlElement(way),
+ChangesetWay::ChangesetWay(const ChangesetWay &way)
+ : ChangesetElement(way),
_nodes(way._nodes)
{
}
-void XmlWay::removeNodes(int position, int count)
+void ChangesetWay::removeNodes(int position, int count)
{
if (position < 0 || count == 0 || _nodes.size() < 1)
return;
@@ -190,40 +214,40 @@ void XmlWay::removeNodes(int position, int count)
_nodes.remove(position, count);
}
-QString XmlWay::toString(long changesetId) const
+QString ChangesetWay::toString(long changesetId) const
{
QString buffer;
QTextStream ts(&buffer);
ts.setCodec("UTF-8");
- ts << "\t\t<way " << XmlElement::toString(_object.second, changesetId) << ">\n";
+ ts << "\t\t<way " << ChangesetElement::toString(_object, changesetId) << ">\n";
for (QVector<long>::const_iterator it = _nodes.begin(); it != _nodes.end(); ++it)
- ts << "\t\t\t<nd ref=\"" << (_idMap ? _idMap->getNewId(ElementType::Node, *it) : *it) << "\"/>\n";
+ ts << "\t\t\t<nd ref=\"" << (_idMap ? _idMap->getId(ElementType::Node, *it) : *it) << "\"/>\n";
if (_tags.size() > 0)
{
- for (QVector<XmlObject>::const_iterator it = _tags.begin(); it != _tags.end(); ++it)
- ts << toTagString(it->second);
+ for (ElementTags::const_iterator it = _tags.begin(); it != _tags.end(); ++it)
+ ts << toTagString(*it);
}
ts << "\t\t</way>\n";
return ts.readAll();
}
-XmlRelation::XmlRelation(const XmlObject& relation, ElementIdToIdMap* idMap)
- : XmlElement(relation, idMap)
+ChangesetRelation::ChangesetRelation(const XmlObject& relation, ElementIdToIdMap* idMap)
+ : ChangesetElement(relation, idMap)
{
// Override the type
_type = ElementType::Relation;
}
-XmlRelation::XmlRelation(const XmlRelation &relation)
- : XmlElement(relation),
+ChangesetRelation::ChangesetRelation(const ChangesetRelation &relation)
+ : ChangesetElement(relation),
_members(relation._members)
{
}
-bool XmlRelation::hasMember(ElementType::Type type, long id)
+bool ChangesetRelation::hasMember(ElementType::Type type, long id)
{
// Iterate all of the members
- for (QList<XmlMember>::iterator it = _members.begin(); it != _members.end(); ++it)
+ for (QList<ChangesetRelationMember>::iterator it = _members.begin(); it != _members.end(); ++it)
{
switch (type)
{
@@ -249,41 +273,40 @@ bool XmlRelation::hasMember(ElementType::Type type, long id)
return false;
}
-QString XmlRelation::toString(long changesetId) const
+QString ChangesetRelation::toString(long changesetId) const
{
QString buffer;
QTextStream ts(&buffer);
ts.setCodec("UTF-8");
- ts << "\t\t<relation " << XmlElement::toString(_object.second, changesetId) << ">\n";
- for (QList<XmlMember>::const_iterator it = _members.begin(); it != _members.end(); ++it)
+ ts << "\t\t<relation " << ChangesetElement::toString(_object, changesetId) << ">\n";
+ for (QList<ChangesetRelationMember>::const_iterator it = _members.begin(); it != _members.end(); ++it)
ts << it->toString();
if (_tags.size() > 0)
{
- for (QVector<XmlObject>::const_iterator it = _tags.begin(); it != _tags.end(); ++it)
- ts << toTagString(it->second);
+ for (ElementTags::const_iterator it = _tags.begin(); it != _tags.end(); ++it)
+ ts << toTagString(*it);
}
ts << "\t\t</relation>\n";
return ts.readAll();
}
-XmlMember::XmlMember(const QXmlStreamAttributes& member, ElementIdToIdMap* idMap)
- : _type(member.value("type").toString()),
+ChangesetRelationMember::ChangesetRelationMember(const QXmlStreamAttributes& member, ElementIdToIdMap* idMap)
+ : _type(ElementType::fromString(member.value("type").toString().toLower())),
_ref(member.value("ref").toString().toLong()),
_role(member.value("role").toString()),
_idMap(idMap)
{
}
-QString XmlMember::toString() const
+QString ChangesetRelationMember::toString() const
{
QString buffer;
QTextStream ts(&buffer);
ts.setCodec("UTF-8");
- ts << "\t\t\t<member type=\"" << _type << "\" ref=\""
- << (_idMap ? _idMap->getNewId(ElementType::fromString(_type),_ref) : _ref)
+ ts << "\t\t\t<member type=\"" << ElementType(_type).toString().toLower() << "\" ref=\""
+ << (_idMap ? _idMap->getId(_type, _ref) : _ref)
<< "\" role=\"" << _role << "\"/>\n";
return ts.readAll();
}
-
}