v0.2.47..v0.2.48 changeset OsmXmlChangesetFileWriter.cpp
Garret Voltz edited this page Sep 27, 2019
·
1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/io/OsmXmlChangesetFileWriter.cpp b/hoot-core/src/main/cpp/hoot/core/io/OsmXmlChangesetFileWriter.cpp
index 72f4c69..cc0f05e 100644
--- a/hoot-core/src/main/cpp/hoot/core/io/OsmXmlChangesetFileWriter.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/io/OsmXmlChangesetFileWriter.cpp
@@ -45,7 +45,6 @@ namespace hoot
OsmXmlChangesetFileWriter::OsmXmlChangesetFileWriter() :
_precision(ConfigOptions().getWriterPrecision()),
-_changesetMaxSize(ConfigOptions().getChangesetMaxSize()),
_multipleChangesetsWritten(false),
_addTimestamp(ConfigOptions().getChangesetXmlWriterAddTimestamp()),
_includeDebugTags(ConfigOptions().getWriterIncludeDebugTags())
@@ -74,116 +73,97 @@ void OsmXmlChangesetFileWriter::write(const QString& path, const ChangesetProvid
LOG_VARD(path);
LOG_VARD(cs->hasMoreChanges());
- QFileInfo info(path);
- info.setCaching(false);
- QString file = info.baseName();
- QString dir = info.path();
- QString ext = info.completeSuffix();
- int fileCount = 0;
QString filepath = path;
_initIdCounters();
- while (cs->hasMoreChanges())
- {
- long changesetProgress = 1;
- // Create a new filepath if the file is split in multiple files because of the
- // changeset.max.size setting
- // i.e. <filepath>/<filename>-001.<ext>
- if (fileCount > 0)
- {
- filepath =
- QString("%1/%2-%3.%4").arg(dir).arg(file).arg(fileCount, 3, 10, QChar('0')).arg(ext);
- _multipleChangesetsWritten = true;
- }
- LOG_INFO("Writing changeset to " << filepath);
+ long changesetProgress = 1;
- QFile f;
- f.setFileName(filepath);
- if (!f.open(QIODevice::WriteOnly | QIODevice::Text))
- {
- throw HootException(QObject::tr("Error opening %1 for writing").arg(path));
- }
+ LOG_INFO("Writing changeset to " << filepath);
+
+ QFile f;
+ f.setFileName(filepath);
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Text))
+ {
+ throw HootException(QObject::tr("Error opening %1 for writing").arg(path));
+ }
- QXmlStreamWriter writer(&f);
- writer.setCodec("UTF-8");
- writer.setAutoFormatting(true);
- writer.writeStartDocument();
+ QXmlStreamWriter writer(&f);
+ writer.setCodec("UTF-8");
+ writer.setAutoFormatting(true);
+ writer.writeStartDocument();
- writer.writeStartElement("osmChange");
- writer.writeAttribute("version", "0.6");
- writer.writeAttribute("generator", HOOT_PACKAGE_NAME);
+ writer.writeStartElement("osmChange");
+ writer.writeAttribute("version", "0.6");
+ writer.writeAttribute("generator", HOOT_PACKAGE_NAME);
- Change::ChangeType last = Change::Unknown;
+ Change::ChangeType last = Change::Unknown;
- while (cs->hasMoreChanges() && changesetProgress <= _changesetMaxSize)
+ while (cs->hasMoreChanges())
+ {
+ LOG_TRACE("Reading next XML change...");
+ _change = cs->readNextChange();
+ LOG_VART(_change.toString());
+ if (_change.getType() != last)
{
- LOG_TRACE("Reading next XML change...");
- _change = cs->readNextChange();
- LOG_VART(_change.toString());
- if (_change.getType() != last)
+ if (last != Change::Unknown)
{
- if (last != Change::Unknown)
- {
- writer.writeEndElement();
- }
- switch (_change.getType())
- {
- case Change::Create:
- writer.writeStartElement("create");
- break;
- case Change::Delete:
- writer.writeStartElement("delete");
- break;
- case Change::Modify:
- writer.writeStartElement("modify");
- break;
- case Change::Unknown:
- //see comment in ChangesetDeriver::_nextChange() when
- //_fromE->getElementId() < _toE->getElementId() as to why we do a no-op here.
- break;
- default:
- throw IllegalArgumentException("Unexpected change type.");
- }
- last = _change.getType();
- LOG_VART(last);
+ writer.writeEndElement();
}
-
- if (_change.getType() != Change::Unknown)
+ switch (_change.getType())
{
- ElementType::Type type = _change.getElement()->getElementType().getEnum();
- switch (type)
- {
- case ElementType::Node:
- _writeNode(writer, std::dynamic_pointer_cast<const Node>(_change.getElement()));
- break;
- case ElementType::Way:
- _writeWay(writer, std::dynamic_pointer_cast<const Way>(_change.getElement()));
- break;
- case ElementType::Relation:
- _writeRelation(
- writer, std::dynamic_pointer_cast<const Relation>(_change.getElement()));
- break;
- default:
- throw IllegalArgumentException("Unexpected element type.");
- }
- changesetProgress++;
- // Update the stats
- _stats(last, type)++;
+ case Change::Create:
+ writer.writeStartElement("create");
+ break;
+ case Change::Delete:
+ writer.writeStartElement("delete");
+ break;
+ case Change::Modify:
+ writer.writeStartElement("modify");
+ break;
+ case Change::Unknown:
+ //see comment in ChangesetDeriver::_nextChange() when
+ //_fromE->getElementId() < _toE->getElementId() as to why we do a no-op here.
+ break;
+ default:
+ throw IllegalArgumentException("Unexpected change type.");
}
+ last = _change.getType();
+ LOG_VART(last);
}
- if (last != Change::Unknown)
+ if (_change.getType() != Change::Unknown)
{
- writer.writeEndElement();
+ ElementType::Type type = _change.getElement()->getElementType().getEnum();
+ switch (type)
+ {
+ case ElementType::Node:
+ _writeNode(writer, std::dynamic_pointer_cast<const Node>(_change.getElement()));
+ break;
+ case ElementType::Way:
+ _writeWay(writer, std::dynamic_pointer_cast<const Way>(_change.getElement()));
+ break;
+ case ElementType::Relation:
+ _writeRelation(
+ writer, std::dynamic_pointer_cast<const Relation>(_change.getElement()));
+ break;
+ default:
+ throw IllegalArgumentException("Unexpected element type.");
+ }
+ changesetProgress++;
+ // Update the stats
+ _stats(last, type)++;
}
- writer.writeEndElement();
- writer.writeEndDocument();
+ }
- f.close();
- // Increment the file number if needed for split files
- fileCount++;
+ if (last != Change::Unknown)
+ {
+ writer.writeEndElement();
}
+ writer.writeEndElement();
+ writer.writeEndDocument();
+
+ f.close();
}
void OsmXmlChangesetFileWriter::_writeNode(QXmlStreamWriter& writer, ConstNodePtr n)
@@ -208,8 +188,15 @@ void OsmXmlChangesetFileWriter::_writeNode(QXmlStreamWriter& writer, ConstNodePt
// for xml changeset OSM rails port expects created elements to have version = 0
if (_change.getType() == Change::Create)
version = 0;
+ else if (n->getVersion() < 1)
+ {
+ throw HootException(
+ QString("Elements being modified or deleted in an .osc changeset must always have a ") +
+ QString("version greater than zero: ") + n->getElementId().toString());
+ }
else
version = n->getVersion();
+ LOG_VART(version);
writer.writeAttribute("version", QString::number(version));
writer.writeAttribute("lat", QString::number(n->getY(), 'f', _precision));
@@ -250,8 +237,15 @@ void OsmXmlChangesetFileWriter::_writeWay(QXmlStreamWriter& writer, ConstWayPtr
// for xml changeset OSM rails port expects created elements to have version = 0
if (_change.getType() == Change::Create)
version = 0;
+ else if (w->getVersion() < 1)
+ {
+ throw HootException(
+ QString("Elements being modified or deleted in an .osc changeset must always have a ") +
+ QString("version greater than zero: ") + w->getElementId().toString());
+ }
else
version = w->getVersion();
+ LOG_VART(version);
writer.writeAttribute("version", QString::number(version));
if (_addTimestamp)
{
@@ -304,8 +298,15 @@ void OsmXmlChangesetFileWriter::_writeRelation(QXmlStreamWriter& writer, ConstRe
// for xml changeset OSM rails port expects created elements to have version = 0
if (_change.getType() == Change::Create)
version = 0;
+ else if (r->getVersion() < 1)
+ {
+ throw HootException(
+ QString("Elements being modified or deleted in an .osc changeset must always have a ") +
+ QString("version greater than zero: ") + r->getElementId().toString());
+ }
else
version = r->getVersion();
+ LOG_VART(version);
writer.writeAttribute("version", QString::number(version));
if (_addTimestamp)
{
@@ -358,14 +359,18 @@ void OsmXmlChangesetFileWriter::setConfiguration(const Settings &conf)
{
ConfigOptions co(conf);
_precision = co.getWriterPrecision();
- _changesetMaxSize = co.getChangesetMaxSize();
}
-void OsmXmlChangesetFileWriter::_writeTags(QXmlStreamWriter& writer, Tags& tags, const Element* element)
+void OsmXmlChangesetFileWriter::_writeTags(QXmlStreamWriter& writer, Tags& tags,
+ const Element* element)
{
if (_includeDebugTags)
{
tags.set(MetadataTags::HootStatus(), QString::number(element->getStatus().getEnum()));
+ tags.set(MetadataTags::HootId(), QString::number(element->getId()));
+ // This just makes sifting through the xml elements a little bit easier during debugging vs
+ // having to scroll around looking for the change type for each element.
+ tags.set(MetadataTags::HootChangeType(), Change::changeTypeToString(_change.getType()));
}
for (Tags::const_iterator it = tags.constBegin(); it != tags.constEnd(); ++it)
{