-
Notifications
You must be signed in to change notification settings - Fork 74
v0.2.54..v0.2.55 changeset ChangesetCreator.cpp
Garret Voltz edited this page Aug 14, 2020
·
1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/algorithms/changeset/ChangesetCreator.cpp b/hoot-core/src/main/cpp/hoot/core/algorithms/changeset/ChangesetCreator.cpp
index 3401ed8..1d53c75 100644
--- a/hoot-core/src/main/cpp/hoot/core/algorithms/changeset/ChangesetCreator.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/algorithms/changeset/ChangesetCreator.cpp
@@ -51,6 +51,7 @@
#include <hoot/core/algorithms/changeset/ChangesetDeriver.h>
#include <hoot/core/io/OsmChangesetFileWriterFactory.h>
#include <hoot/core/io/OsmChangesetFileWriter.h>
+#include <hoot/core/util/FileUtils.h>
//GEOS
#include <geos/geom/Envelope.h>
@@ -64,11 +65,14 @@ namespace hoot
const QString ChangesetCreator::JOB_SOURCE = "Derive Changeset";
-ChangesetCreator::ChangesetCreator(const bool printDetailedStats, const QString osmApiDbUrl) :
+ChangesetCreator::ChangesetCreator(
+ const bool printDetailedStats, const QString& statsOutputFile, const QString osmApiDbUrl) :
_osmApiDbUrl(osmApiDbUrl),
_numTotalTasks(0),
_currentTaskNum(0),
+_includeReviews(false),
_printDetailedStats(printDetailedStats),
+_statsOutputFile(statsOutputFile),
_singleInput(false),
_numCreateChanges(0),
_numModifyChanges(0),
@@ -97,13 +101,9 @@ void ChangesetCreator::create(const QString& output, const QString& input1, cons
"Creating changeset from inputs: " << input1 << " and " << input2 << " to output: " <<
output << "...");
- QFileInfo outputInfo(output);
- LOG_VARD(outputInfo.dir().absolutePath());
- const bool outputDirSuccess = QDir().mkpath(outputInfo.dir().absolutePath());
- if (!outputDirSuccess)
- {
- throw IllegalArgumentException("Unable to create output path for: " + output);
- }
+ // write the output dir now so we don't get a nasty surprise at the end of a long job that it
+ // can't be written
+ IoUtils::writeOutputDir(output);
_singleInput = input2.trimmed().isEmpty();
LOG_VARD(_singleInput);
@@ -133,6 +133,10 @@ void ChangesetCreator::create(const QString& output, const QString& input1, cons
_numTotalTasks++;
}
}
+ if (!_includeReviews)
+ {
+ _numTotalTasks--;
+ }
}
_currentTaskNum = 1;
@@ -149,8 +153,8 @@ void ChangesetCreator::create(const QString& output, const QString& input1, cons
//sortedElements2 is the newer state of the data
ElementInputStreamPtr sortedElements2;
- // TODO: We could use OsmUtils::checkVersionLessThanOneCountAndLogWarning() somewhere in here like
- // we do with ChangesetDeriveReplacementCommand and ConflateCmd.
+ // TODO: We could use VersionUtils::checkVersionLessThanOneCountAndLogWarning() somewhere in here
+ // like we do with ChangesetDeriveReplacementCommand and ConflateCmd.
// If we have two inputs, we'll determine the difference between them as the changeset.
// Otherwise, we're passing all the input data through to the output changeset, so put it in
@@ -247,17 +251,18 @@ void ChangesetCreator::create(const QList<OsmMapPtr>& map1Inputs,
OsmMapWriterFactory::writeDebugMap(map1, "map1-before-changeset-derivation-" + map1->getName());
OsmMapWriterFactory::writeDebugMap(map2, "map2-before-changeset-derivation-" + map2->getName());
- // don't want to include review relations - may need to remove this depending on what happens
- // with #3361
- std::shared_ptr<TagKeyCriterion> elementCriterion(
- new TagKeyCriterion(MetadataTags::HootReviewNeeds()));
- RemoveElementsVisitor removeElementsVisitor;
- removeElementsVisitor.setRecursive(false);
- removeElementsVisitor.addCriterion(elementCriterion);
- map1->visitRw(removeElementsVisitor);
- map2->visitRw(removeElementsVisitor);
+ if (!_includeReviews)
+ {
+ std::shared_ptr<TagKeyCriterion> elementCriterion(
+ new TagKeyCriterion(MetadataTags::HootReviewNeeds()));
+ RemoveElementsVisitor removeElementsVisitor;
+ removeElementsVisitor.setRecursive(false);
+ removeElementsVisitor.addCriterion(elementCriterion);
+ map1->visitRw(removeElementsVisitor);
+ map2->visitRw(removeElementsVisitor);
+ }
- // Truncate tags over 255 characters to push into OSM API.
+ // Truncate tags over max tag length characters to push into OSM API.
ApiTagTruncateVisitor truncateTags;
map1->visitRw(truncateTags);
map2->visitRw(truncateTags);
@@ -366,7 +371,7 @@ void ChangesetCreator::_handleUnstreamableConvertOpsInMemory(const QString& inpu
QString("(OsmMapOperation) on two data sources with overlapping element IDs: ") +
e.what());
}
- // Rethrow the original exception
+ // rethrow the original exception
throw;
}
}
@@ -521,24 +526,26 @@ void ChangesetCreator::_readInputsFully(const QString& input1, const QString& in
_currentTaskNum++;
}
- // We don't want to include review relations.
- progress.set(
- (float)(_currentTaskNum - 1) / (float)_numTotalTasks, "Removing review relations...");
- std::shared_ptr<TagKeyCriterion> elementCriterion(
- new TagKeyCriterion(MetadataTags::HootReviewNeeds()));
- RemoveElementsVisitor removeElementsVisitor;
- removeElementsVisitor.setRecursive(false);
- removeElementsVisitor.addCriterion(elementCriterion);
- map1->visitRw(removeElementsVisitor);
- if (!_singleInput)
+ if (!_includeReviews)
{
- map2->visitRw(removeElementsVisitor);
+ progress.set(
+ (float)(_currentTaskNum - 1) / (float)_numTotalTasks, "Removing review relations...");
+ std::shared_ptr<TagKeyCriterion> elementCriterion(
+ new TagKeyCriterion(MetadataTags::HootReviewNeeds()));
+ RemoveElementsVisitor removeElementsVisitor;
+ removeElementsVisitor.setRecursive(false);
+ removeElementsVisitor.addCriterion(elementCriterion);
+ map1->visitRw(removeElementsVisitor);
+ if (!_singleInput)
+ {
+ map2->visitRw(removeElementsVisitor);
+ }
+ OsmMapWriterFactory::writeDebugMap(map1, "after-remove-reviews-map-1");
+ OsmMapWriterFactory::writeDebugMap(map2, "after-remove-reviews-map-2");
+ _currentTaskNum++;
}
- OsmMapWriterFactory::writeDebugMap(map1, "after-remove-reviews-map-1");
- OsmMapWriterFactory::writeDebugMap(map2, "after-remove-reviews-map-2");
- _currentTaskNum++;
- // Truncate tags over 255 characters to push into OSM API.
+ // Truncate tags over max tag length characters to push into OSM API.
progress.set(
(float)(_currentTaskNum - 1) / (float)_numTotalTasks, "Preparing tags for changeset...");
ApiTagTruncateVisitor truncateTags;
@@ -592,12 +599,15 @@ ElementInputStreamPtr ChangesetCreator::_getFilteredInputStream(const QString& i
LOG_DEBUG("Retrieving filtered input stream for: " << input.right(25) << "...");
QList<ElementVisitorPtr> visitors;
- // We don't want to include review relations.
- std::shared_ptr<ElementCriterion> elementCriterion(
- new NotCriterion(
- std::shared_ptr<TagKeyCriterion>(
- new TagKeyCriterion(MetadataTags::HootReviewNeeds()))));
- // Tags need to be truncated if they are over 255 characters.
+ std::shared_ptr<ElementCriterion> elementCriterion;
+ if (!_includeReviews)
+ {
+ elementCriterion.reset(
+ new NotCriterion(
+ std::shared_ptr<TagKeyCriterion>(
+ new TagKeyCriterion(MetadataTags::HootReviewNeeds()))));
+ }
+ // Tags need to be truncated if they are over max tag length characters.
visitors.append(std::shared_ptr<ApiTagTruncateVisitor>(new ApiTagTruncateVisitor()));
// open a stream to the input data
@@ -607,8 +617,16 @@ ElementInputStreamPtr ChangesetCreator::_getFilteredInputStream(const QString& i
reader->setUseDataSourceIds(true);
reader->open(input);
ElementInputStreamPtr inputStream = std::dynamic_pointer_cast<ElementInputStream>(reader);
- ElementInputStreamPtr filteredInputStream(
- new ElementCriterionVisitorInputStream(inputStream, elementCriterion, visitors));
+ ElementInputStreamPtr filteredInputStream;
+ if (elementCriterion)
+ {
+ filteredInputStream.reset(
+ new ElementCriterionVisitorInputStream(inputStream, elementCriterion, visitors));
+ }
+ else
+ {
+ filteredInputStream.reset(new ElementVisitorInputStream(inputStream, visitors.at(0)));
+ }
// Add convert ops supporting streaming into the pipeline, if there are any. TODO: Any
// OsmMapOperations in the bunch need to operate on the entire map made up of both inputs to
@@ -661,7 +679,19 @@ void ChangesetCreator::_streamChangesetOutput(const QList<ElementInputStreamPtr>
{
if (output.endsWith(".osc")) // detailed stats currently only implemented for xml output
{
- detailedStats = writer->getStatsTable();
+ // Get the stats output format from the file extension, or if no extension is there assume a
+ // text table output to the display.
+ ChangesetStatsFormat statsFormat;
+ if (!_statsOutputFile.isEmpty())
+ {
+ QFileInfo statsFileInfo(_statsOutputFile);
+ statsFormat.setFormat(ChangesetStatsFormat::fromString(statsFileInfo.completeSuffix()));
+ }
+ else
+ {
+ statsFormat.setFormat(ChangesetStatsFormat::Text);
+ }
+ detailedStats = writer->getStatsTable(statsFormat);
}
else
{
@@ -715,7 +745,14 @@ void ChangesetCreator::_streamChangesetOutput(const QList<ElementInputStreamPtr>
LOG_VART(_printDetailedStats);
if (_printDetailedStats && !detailedStats.isEmpty())
{
- LOG_STATUS("Changeset Stats:\n" << detailedStats);
+ if (_statsOutputFile.isEmpty())
+ {
+ LOG_STATUS("Changeset Stats:\n" << detailedStats);
+ }
+ else
+ {
+ FileUtils::writeFully(_statsOutputFile, detailedStats);
+ }
}
else
{