Skip to content

v0.2.53..v0.2.54 changeset AlphaShapeGenerator.cpp

Garret Voltz edited this page Mar 31, 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 86df949..886a428 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
@@ -22,7 +22,7 @@
  * This will properly maintain the copyright information. DigitalGlobe
  * copyrights will be updated automatically.
  *
- * @copyright Copyright (C) 2015, 2016, 2017, 2018, 2019 DigitalGlobe (http://www.digitalglobe.com/)
+ * @copyright Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 DigitalGlobe (http://www.digitalglobe.com/)
  */
 
 #include "AlphaShapeGenerator.h"
@@ -34,6 +34,9 @@
 #include <hoot/core/util/Log.h>
 #include <hoot/core/io/OsmMapWriterFactory.h>
 
+// GEOS
+#include <geos/geom/GeometryFactory.h>
+
 using namespace geos::geom;
 using namespace std;
 
@@ -42,8 +45,11 @@ namespace hoot
 
 AlphaShapeGenerator::AlphaShapeGenerator(const double alpha, const double buffer) :
 _alpha(alpha),
-_buffer(buffer)
+_buffer(buffer),
+_retryOnTooSmallInitialAlpha(true)
 {
+  LOG_VARD(_alpha);
+  LOG_VARD(_buffer);
 }
 
 OsmMapPtr AlphaShapeGenerator::generateMap(OsmMapPtr inputMap)
@@ -51,6 +57,7 @@ OsmMapPtr AlphaShapeGenerator::generateMap(OsmMapPtr inputMap)
   OsmMapWriterFactory::writeDebugMap(inputMap, "alpha-shape-input-map");
 
   std::shared_ptr<Geometry> cutterShape = generateGeometry(inputMap);
+
   if (cutterShape->getArea() == 0.0)
   {
     // would rather this be thrown than a warning logged, as the warning may go unoticed by web
@@ -80,6 +87,8 @@ OsmMapPtr AlphaShapeGenerator::generateMap(OsmMapPtr inputMap)
 
 std::shared_ptr<Geometry> AlphaShapeGenerator::generateGeometry(OsmMapPtr inputMap)
 {
+  LOG_INFO("Generating alpha shape geometry...");
+
   MapProjector::projectToPlanar(inputMap);
   LOG_VARD(MapProjector::toWkt(inputMap->getProjection()));
 
@@ -94,15 +103,36 @@ std::shared_ptr<Geometry> AlphaShapeGenerator::generateGeometry(OsmMapPtr inputM
     p.second = (it->second)->getY();
     points.push_back(p);
   }
+  LOG_VARD(points.size());
 
   // create a complex geometry representing the alpha shape
   std::shared_ptr<Geometry> cutterShape;
+  AlphaShape alphaShape(_alpha);
+  alphaShape.insert(points);
+  try
   {
-    AlphaShape alphaShape(_alpha);
-    alphaShape.insert(points);
     cutterShape = alphaShape.toGeometry();
-    cutterShape.reset(cutterShape->buffer(_buffer));
   }
+  catch (const IllegalArgumentException& e)
+  {
+    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: " << _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();
+    }
+    else
+    {
+      cutterShape.reset(GeometryFactory::getDefaultInstance()->createEmptyGeometry());
+    }
+  }
+  cutterShape.reset(cutterShape->buffer(_buffer));
 
   return cutterShape;
 }
Clone this wiki locally