v0.2.54..v0.2.55 changeset AlphaShapeGenerator.cpp
Garret Voltz edited this page Aug 14, 2020
·
1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/algorithms/alpha-shape/AlphaShapeGenerator.cpp b/hoot-core/src/main/cpp/hoot/core/algorithms/alpha-shape/AlphaShapeGenerator.cpp
index 886a428..d4d9ea8 100644
--- a/hoot-core/src/main/cpp/hoot/core/algorithms/alpha-shape/AlphaShapeGenerator.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/algorithms/alpha-shape/AlphaShapeGenerator.cpp
@@ -33,6 +33,7 @@
#include <hoot/core/util/GeometryConverter.h>
#include <hoot/core/util/Log.h>
#include <hoot/core/io/OsmMapWriterFactory.h>
+#include <hoot/core/util/StringUtils.h>
// GEOS
#include <geos/geom/GeometryFactory.h>
@@ -46,10 +47,17 @@ namespace hoot
AlphaShapeGenerator::AlphaShapeGenerator(const double alpha, const double buffer) :
_alpha(alpha),
_buffer(buffer),
-_retryOnTooSmallInitialAlpha(true)
+_retryOnTooSmallInitialAlpha(true),
+_maxTries(1)
{
- LOG_VARD(_alpha);
- LOG_VARD(_buffer);
+ LOG_VART(_alpha);
+ LOG_VART(_buffer);
+ if (_retryOnTooSmallInitialAlpha)
+ {
+ // have not seen an instance yet where more than two tries are needed to complete successfully;
+ // in all other cases, no solution could be found no matter how many tries were attempted
+ _maxTries = 2;
+ }
}
OsmMapPtr AlphaShapeGenerator::generateMap(OsmMapPtr inputMap)
@@ -60,7 +68,7 @@ OsmMapPtr AlphaShapeGenerator::generateMap(OsmMapPtr inputMap)
if (cutterShape->getArea() == 0.0)
{
- // would rather this be thrown than a warning logged, as the warning may go unoticed by web
+ // would rather this be thrown than a warning logged, as the warning may go unoticed by
// clients who are expecting the alpha shape to be generated
throw HootException("Alpha Shape area is zero. Try increasing the buffer size and/or alpha.");
}
@@ -79,7 +87,7 @@ OsmMapPtr AlphaShapeGenerator::generateMap(OsmMapPtr inputMap)
r->setTag("area", "yes");
}
- LOG_VARD(MapProjector::toWkt(result->getProjection()));
+ LOG_VART(MapProjector::toWkt(result->getProjection()));
OsmMapWriterFactory::writeDebugMap(result, "alpha-shape-result-map");
return result;
@@ -87,12 +95,12 @@ OsmMapPtr AlphaShapeGenerator::generateMap(OsmMapPtr inputMap)
std::shared_ptr<Geometry> AlphaShapeGenerator::generateGeometry(OsmMapPtr inputMap)
{
- LOG_INFO("Generating alpha shape geometry...");
+ LOG_TRACE("Generating alpha shape geometry...");
MapProjector::projectToPlanar(inputMap);
- LOG_VARD(MapProjector::toWkt(inputMap->getProjection()));
+ LOG_VART(MapProjector::toWkt(inputMap->getProjection()));
- // put all the nodes into a vector of points.
+ // put all the nodes into a vector of points
std::vector<std::pair<double, double>> points;
points.reserve(inputMap->getNodes().size());
const NodeMap& nodes = inputMap->getNodes();
@@ -103,34 +111,43 @@ std::shared_ptr<Geometry> AlphaShapeGenerator::generateGeometry(OsmMapPtr inputM
p.second = (it->second)->getY();
points.push_back(p);
}
- LOG_VARD(points.size());
+ LOG_VART(points.size());
// create a complex geometry representing the alpha shape
+
std::shared_ptr<Geometry> cutterShape;
- AlphaShape alphaShape(_alpha);
- alphaShape.insert(points);
- try
- {
- cutterShape = alphaShape.toGeometry();
- }
- catch (const IllegalArgumentException& e)
+
+ int numTries = 0;
+ while (numTries <= _maxTries)
{
- if (_retryOnTooSmallInitialAlpha && e.getWhat().startsWith("Longest face edge of size"))
+ AlphaShape alphaShape(_alpha);
+ alphaShape.insert(points);
+ try
{
- const double longestFaceEdge = alphaShape.getLongestFaceEdge();
- LOG_INFO(
- "Failed to generate alpha shape geometry with alpha value of: " << _alpha <<
- ". Attempting to generate the shape a second time using the longest face edge size of: " <<
- longestFaceEdge << " for alpha...");
- _alpha = longestFaceEdge;
- AlphaShape alphaShape2(_alpha);
- alphaShape2.insert(points);
- cutterShape = alphaShape2.toGeometry();
+ cutterShape = alphaShape.toGeometry();
}
- else
+ catch (const IllegalArgumentException& e)
{
- cutterShape.reset(GeometryFactory::getDefaultInstance()->createEmptyGeometry());
+ if (_retryOnTooSmallInitialAlpha && e.getWhat().startsWith("Longest face edge of size"))
+ {
+ const double longestFaceEdge = alphaShape.getLongestFaceEdge();
+ LOG_INFO(
+ "Failed to generate alpha shape geometry with alpha value of: " <<
+ StringUtils::formatLargeNumber(_alpha) <<
+ ". Attempting to generate the shape again using the longest face edge size of: " <<
+ StringUtils::formatLargeNumber(longestFaceEdge) << " for alpha...");
+ _alpha = longestFaceEdge;
+ }
+ else
+ {
+ break;
+ }
}
+ numTries++;
+ }
+ if (!cutterShape)
+ {
+ cutterShape.reset(GeometryFactory::getDefaultInstance()->createEmptyGeometry());
}
cutterShape.reset(cutterShape->buffer(_buffer));