diff --git a/hoot-core/src/main/cpp/hoot/core/io/OsmApiChangeset.h b/hoot-core/src/main/cpp/hoot/core/io/OsmApiChangeset.h
index 522aad5..bff126f 100644
--- a/hoot-core/src/main/cpp/hoot/core/io/OsmApiChangeset.h
+++ b/hoot-core/src/main/cpp/hoot/core/io/OsmApiChangeset.h
@@ -38,6 +38,7 @@
// Standard
#include <array>
#include <map>
+#include <mutex>
#include <set>
#include <vector>
@@ -52,8 +53,8 @@ namespace hoot
class ChangesetInfo;
/** Helpful typedefs for pointers and vectors of maps */
typedef std::shared_ptr<ChangesetInfo> ChangesetInfoPtr;
-typedef std::map<long, XmlElementPtr, osm_id_sort> XmlElementMap;
-typedef QVector<XmlElementMap> ChangesetTypeMap;
+typedef std::map<long, ChangesetElementPtr, osm_id_sort> ChangesetElementMap;
+typedef std::vector<ChangesetElementMap> ChangesetTypeMap;
typedef std::map<long, std::set<long>> NodeIdToWayIdMap;
typedef std::map<long, std::set<long>> NodeIdToRelationIdMap;
typedef std::map<long, std::set<long>> WayIdToRelationIdMap;
@@ -146,11 +147,11 @@ public:
*/
QString getFailedChangesetString();
/**
- * @brief setMaxSize Set the soft maximum size of the changeset. Max is soft because if while creating a way there are still
+ * @brief setMaxPushSize Set the maximum size of the push changeset. Max is soft because if while creating a way there are still
* more required nodes to add and the max is hit, those nodes are added to the changeset to make it atomic
* @param size - Number of elements in the soft max size
*/
- void setMaxSize(long size) { _maxChangesetSize = size; }
+ void setMaxPushSize(long size) { _maxPushSize = size; }
/**
* @brief hasFailedElements
* @return true if any elements failed upload
@@ -247,6 +248,16 @@ public:
static bool matchesChangesetConflictVersionMismatchFailure(const QString& hint,
long& element_id, ElementType::Type& element_type,
long& version_old, long& version_new);
+ /**
+ * @brief setErrorPathname Record the pathname of the error changeset
+ * @param path Pathname
+ */
+ void setErrorPathname(const QString& path) { _errorPathname = path; }
+ /**
+ * @brief writeErrorFile Writes our the error changeset
+ * @return true if the file was written successfully
+ */
+ bool writeErrorFile();
private:
/**
@@ -318,9 +329,9 @@ private:
* @param node/way/relation Pointer to the element that is being added
* @return success
*/
- bool addNode(ChangesetInfoPtr& changeset, ChangesetType type, XmlNode* node);
- bool addWay(ChangesetInfoPtr& changeset, ChangesetType type, XmlWay* way);
- bool addRelation(ChangesetInfoPtr& changeset, ChangesetType type, XmlRelation* relation);
+ bool addNode(ChangesetInfoPtr& changeset, ChangesetType type, ChangesetNode* node);
+ bool addWay(ChangesetInfoPtr& changeset, ChangesetType type, ChangesetWay* way);
+ bool addRelation(ChangesetInfoPtr& changeset, ChangesetType type, ChangesetRelation* relation);
/**
* @brief addParentWays/Relations Add any parents (ways, relations) to the changeset if needed
* by a modify or delete operation. For example, to delete a node, any way or relation parent
@@ -340,9 +351,9 @@ private:
* @param node/way/relation Pointer to the element to be moved
* @return
*/
- bool moveNode(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlNode* node);
- bool moveWay(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlWay* way);
- bool moveRelation(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlRelation* relation);
+ bool moveNode(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetNode* node);
+ bool moveWay(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetWay* way);
+ bool moveRelation(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetRelation* relation);
/**
* @brief moveOrRemoveNode/Way/Relation Move an element from one subset to another, or if all related elements aren't
* able to be moved, the element is removed from the subset and returned to the `available` state
@@ -351,9 +362,9 @@ private:
* @param type Type of operation (create/modify/delete)
* @param node/way/relation Pointer to the element to be moved
*/
- void moveOrRemoveNode(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlNode* node);
- void moveOrRemoveWay(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlWay* way);
- void moveOrRemoveRelation(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlRelation* relation);
+ void moveOrRemoveNode(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetNode* node);
+ void moveOrRemoveWay(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetWay* way);
+ void moveOrRemoveRelation(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetRelation* relation);
/**
* @brief canMoveNode/Way/Relation Query if a node/way/relation can be moved. This checks downstream relations, ways,
* and nodes to see if they can also be moved.
@@ -363,37 +374,37 @@ private:
* @param node/way/relation Pointer to the element to be checked
* @return
*/
- bool canMoveNode(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlNode* node);
- bool canMoveWay(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlWay* way);
- bool canMoveRelation(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, XmlRelation* relation);
+ bool canMoveNode(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetNode* node);
+ bool canMoveWay(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetWay* way);
+ bool canMoveRelation(ChangesetInfoPtr& source, ChangesetInfoPtr& destination, ChangesetType type, ChangesetRelation* relation);
/**
* @brief getObjectCount Get the number of elements affected by this node/way/relation
* @param changeset Subset containing the element
* @param node/way/relation Pointer to the element to count
* @return total number of elements within this element
*/
- size_t getObjectCount(ChangesetInfoPtr& changeset, XmlNode* node);
- size_t getObjectCount(ChangesetInfoPtr& changeset, XmlWay* way);
- size_t getObjectCount(ChangesetInfoPtr& changeset, XmlRelation* relation);
+ size_t getObjectCount(ChangesetInfoPtr& changeset, ChangesetNode* node);
+ size_t getObjectCount(ChangesetInfoPtr& changeset, ChangesetWay* way);
+ size_t getObjectCount(ChangesetInfoPtr& changeset, ChangesetRelation* relation);
/**
* @brief isSent Check if this element's status is buffering, sent, or finalized
* @param element Pointer to the element to check
* @return true if the element has been sent to the API
*/
- bool isSent(XmlElement* element);
+ bool isSent(ChangesetElement* element);
/**
* @brief canSend Check if the node/way/relation can be sent (if it is available) along with all of its downstream elements
* @param node/way/relation Pointer to the element to check
* @return true if element and all downstream elements are available to send
*/
- bool canSend(XmlNode* node);
- bool canSend(XmlWay* way);
- bool canSend(XmlRelation* relation);
+ bool canSend(ChangesetNode* node);
+ bool canSend(ChangesetWay* way);
+ bool canSend(ChangesetRelation* relation);
/**
* @brief markBuffered Mark the element as buffered
* @param element Pointer to the element to mark
*/
- void markBuffered(XmlElement* element);
+ void markBuffered(ChangesetElement* element);
/**
* @brief getNextNode/Way/RelationId searches the Create section of the changeset to find the next available ID
* for the desired element type
@@ -419,21 +430,24 @@ private:
void failWay(long id, bool beforeSend = false);
void failRelation(long id, bool beforeSend = false);
/**
- * @brief getNodes/Ways/Relations Output node/way/relation text to the text stream
+ * @brief writeNodes/Ways/Relations Output node/way/relation text to the text stream
* @param changeset Pointer to the changeset to output
* @param ts TextStream to output the element to
* @param type Changeset type (create, modify, delete)
* @param changeset_id ID of the changeset to write to the element attribute
*/
- void getNodes(const ChangesetInfoPtr& changeset, QTextStream& ts, ChangesetType type, long changeset_id);
- void getWays(const ChangesetInfoPtr& changeset, QTextStream& ts, ChangesetType type, long changeset_id);
- void getRelations(const ChangesetInfoPtr& changeset, QTextStream& ts, ChangesetType type, long changeset_id);
+ void writeNodes(const ChangesetInfoPtr& changeset, QTextStream& ts, ChangesetType type, long changeset_id);
+ void writeWays(const ChangesetInfoPtr& changeset, QTextStream& ts, ChangesetType type, long changeset_id);
+ void writeRelations(const ChangesetInfoPtr& changeset, QTextStream& ts, ChangesetType type, long changeset_id);
+ void writeElements(const ChangesetInfoPtr& changeset, QTextStream& ts, ChangesetType type, long changeset_id,
+ ElementType::Type elementType, const ChangesetElementMap& elements);
+
/** Sorted map of all nodes, original node ID and a pointer to the element object */
- XmlElementMap _allNodes;
+ ChangesetElementMap _allNodes;
/** Sorted map of all ways, original node ID and a pointer to the element object */
- XmlElementMap _allWays;
+ ChangesetElementMap _allWays;
/** Sorted map of all relations, original node ID and a pointer to the element object */
- XmlElementMap _allRelations;
+ ChangesetElementMap _allRelations;
/** Three element (create/modify/delete) vector of node IDs */
ChangesetTypeMap _nodes;
/** Three element (create/modify/delete) vector of way IDs */
@@ -442,8 +456,8 @@ private:
ChangesetTypeMap _relations;
/** Element ID to ID data structure for checking old ID to new ID and new ID to old ID lookups */
ElementIdToIdMap _idMap;
- /** Soft maximum changeset size */
- long _maxChangesetSize;
+ /** Maximum changeset push size */
+ long _maxPushSize;
/** Count of elements that have been sent */
long _sentCount;
/** Count of elements that have been processed */
@@ -451,7 +465,7 @@ private:
/** Count of elements that failed to upload */
long _failedCount;
/** Buffer of elements that are about to be pushed into a subset */
- std::vector<XmlElement*> _sendBuffer;
+ std::vector<ChangesetElement*> _sendBuffer;
/** Negative ID generator */
DefaultIdGenerator _idGen;
/** Reverse ID to ID maps for deleting elements validation */
@@ -459,6 +473,9 @@ private:
NodeIdToRelationIdMap _nodeIdsToRelations;
WayIdToRelationIdMap _wayIdsToRelations;
RelationIdToRelationIdMap _relationIdsToRelations;
+ /** Full pathname of the error file changeset, if any errors occur */
+ QString _errorPathname;
+ std::mutex _errorMutex;
};
/** Atomic subset of IDs that are sent to the OSM API, header only class */