Skip to content

v0.2.47..v0.2.48 changeset OsmApiDbSqlChangesetFileWriter.cpp

Garret Voltz edited this page Sep 27, 2019 · 1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/io/OsmApiDbSqlChangesetFileWriter.cpp b/hoot-core/src/main/cpp/hoot/core/io/OsmApiDbSqlChangesetFileWriter.cpp
index 3d43fa8..46d8153 100644
--- a/hoot-core/src/main/cpp/hoot/core/io/OsmApiDbSqlChangesetFileWriter.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/io/OsmApiDbSqlChangesetFileWriter.cpp
@@ -43,7 +43,6 @@ namespace hoot
 
 OsmApiDbSqlChangesetFileWriter::OsmApiDbSqlChangesetFileWriter(const QUrl& url) :
 _changesetId(0),
-_changesetMaxSize(ConfigOptions().getChangesetMaxSize()),
 _changesetUserId(ConfigOptions().getChangesetUserId()),
 _includeDebugTags(ConfigOptions().getWriterIncludeDebugTags())
 {
@@ -63,6 +62,7 @@ void OsmApiDbSqlChangesetFileWriter::write(const QString& path,
   LOG_VARD(path);
   LOG_VARD(changesetProvider->hasMoreChanges());
 
+  _remappedIds.clear();
   _changesetBounds.init();
 
   _outputSql.setFileName(path);
@@ -106,13 +106,6 @@ void OsmApiDbSqlChangesetFileWriter::write(const QString& path,
       }
       changes++;
     }
-
-    if (changes > _changesetMaxSize)
-    {
-      _updateChangeset(changes);
-      _createChangeSet();
-      changes = 0;
-    }
   }
 
   _updateChangeset(changes);
@@ -195,13 +188,14 @@ void OsmApiDbSqlChangesetFileWriter::_createNewElement(ConstElementPtr element)
   const QString elementTypeStr = element->getElementType().toString().toLower();
   ElementPtr changeElement = _getChangeElement(element);
 
-  //we only grab and assign a new id if we have a new element with a negative id, since we'll be
-  //writing this directly to the database and negative ids aren't allowed
+  // we only grab and assign a new id if we have a new element with a negative id, since we'll be
+  // writing this directly to the database and negative ids aren't allowed
   LOG_TRACE("ID before: " << changeElement->getElementId());
   long id;
   if (changeElement->getId() < 0)
   {
     id = _db.getNextId(element->getElementType().getEnum());
+    _remappedIds[changeElement->getElementId()] = ElementId(changeElement->getElementType(), id);
   }
   else
   {
@@ -292,6 +286,12 @@ void OsmApiDbSqlChangesetFileWriter::_updateExistingElement(ConstElementPtr elem
   //if another parsed change previously modified the element with this id, we want to get the
   //modified version
   const long currentVersion = changeElement->getVersion();
+  if (currentVersion < 1)
+  {
+    throw HootException(
+      "Elements being modified in an .osc.sql changeset must always have a version greater than one: " +
+      element->getElementId().toString());
+  }
   const long newVersion = currentVersion + 1;
 
   changeElement->setVersion(newVersion);
@@ -344,6 +344,12 @@ void OsmApiDbSqlChangesetFileWriter::_deleteExistingElement(ConstElementPtr elem
   ElementPtr changeElement = _getChangeElement(element);
 
   const long currentVersion = changeElement->getVersion();
+  if (currentVersion < 1)
+  {
+    throw HootException(
+      "Elements being deleted in an .osc.sql changeset must always have a version greater than one: " +
+      element->getElementId().toString());
+  }
   const long newVersion = currentVersion + 1;
 
   changeElement->setVersion(newVersion);
@@ -470,6 +476,7 @@ void OsmApiDbSqlChangesetFileWriter::_createTags(ConstElementPtr element)
   Tags tags = element->getTags();
   if (_includeDebugTags)
   {
+    tags.set(MetadataTags::HootId(), QString::number(element->getId()));
     tags.set(MetadataTags::HootStatus(), QString::number(element->getStatus().getEnum()));
   }
   LOG_VART(tags);
@@ -525,20 +532,26 @@ void OsmApiDbSqlChangesetFileWriter::_createWayNodes(ConstWayPtr way)
   const std::vector<long> nodeIds = way->getNodeIds();
   for (size_t i = 0; i < nodeIds.size(); i++)
   {
-    const long nodeId = nodeIds.at(i);
-    LOG_VART(ElementId(ElementType::Node, nodeId));
+    // If this was a newly created node its id was remapped when it was created, but the way still
+    // has the old way node id.
+    ElementId nodeElementId = ElementId(ElementType::Node, nodeIds.at(i));
+    if (_remappedIds.contains(nodeElementId))
+    {
+      nodeElementId = _remappedIds[nodeElementId];
+    }
+    LOG_VART(nodeElementId);
 
     QString values =
       QString("(way_id, node_id, version, sequence_id) VALUES (%1, %2, 1, %3);\n")
         .arg(way->getId())
-        .arg(nodeId)
+        .arg(nodeElementId.getId())
         .arg(i + 1);
     _outputSql.write(("INSERT INTO " + ApiDb::getWayNodesTableName() + " " + values).toUtf8());
 
     values =
       QString("(way_id, node_id, sequence_id) VALUES (%1, %2, %3);\n")
         .arg(way->getId())
-        .arg(nodeId)
+        .arg(nodeElementId.getId())
         .arg(i + 1);
     _outputSql.write(("INSERT INTO " + ApiDb::getCurrentWayNodesTableName() + " " + values).toUtf8());
   }
@@ -553,13 +566,21 @@ void OsmApiDbSqlChangesetFileWriter::_createRelationMembers(ConstRelationPtr rel
   {
     const RelationData::Entry member = members[i];
     LOG_VART(member.getElementId());
+    // If the member was a newly created element its id was remapped when it was created, but the
+    // relation still has the old element id.
+    ElementId memberElementId = member.getElementId();
+    if (_remappedIds.contains(memberElementId))
+    {
+      memberElementId = _remappedIds[memberElementId];
+    }
+    LOG_VART(memberElementId);
 
     QString values =
       QString(
         "(relation_id, member_type, member_id, member_role, version, sequence_id) VALUES (%1, '%2', %3, '%4', 1, %5);\n")
         .arg(relation->getId())
-        .arg(member.getElementId().getType().toString())
-        .arg(member.getElementId().getId())
+        .arg(memberElementId.getType().toString())
+        .arg(memberElementId.getId())
         .arg(member.getRole())
         .arg(i + 1);
     _outputSql.write(("INSERT INTO " + ApiDb::getRelationMembersTableName() + " " + values).toUtf8());
@@ -568,8 +589,8 @@ void OsmApiDbSqlChangesetFileWriter::_createRelationMembers(ConstRelationPtr rel
       QString(
         "(relation_id, member_type, member_id, member_role, sequence_id) VALUES (%1, '%2', %3, '%4', %5);\n")
         .arg(relation->getId())
-        .arg(member.getElementId().getType().toString())
-        .arg(member.getElementId().getId())
+        .arg(memberElementId.getType().toString())
+        .arg(memberElementId.getId())
         .arg(member.getRole())
         .arg(i + 1);
     _outputSql.write(
@@ -605,7 +626,8 @@ void OsmApiDbSqlChangesetFileWriter::_deleteAll(const QString& tableName, const
 void OsmApiDbSqlChangesetFileWriter::setConfiguration(const Settings &conf)
 {
   ConfigOptions co(conf);
-  _changesetMaxSize = co.getChangesetMaxSize();
+  _changesetUserId = co.getChangesetUserId();
+  _includeDebugTags = co.getWriterIncludeDebugTags();
 }
 
 }
Clone this wiki locally