Skip to content

v0.2.47..v0.2.48 changeset IoUtils.cpp

Garret Voltz edited this page Sep 27, 2019 · 1 revision
diff --git a/hoot-core/src/main/cpp/hoot/core/util/IoUtils.cpp b/hoot-core/src/main/cpp/hoot/core/util/IoUtils.cpp
index 0e27031..85c4432 100644
--- a/hoot-core/src/main/cpp/hoot/core/util/IoUtils.cpp
+++ b/hoot-core/src/main/cpp/hoot/core/util/IoUtils.cpp
@@ -35,10 +35,18 @@
 #include <hoot/core/util/FileUtils.h>
 #include <hoot/core/util/Log.h>
 #include <hoot/core/util/Progress.h>
+#include <hoot/core/ops/MapCropper.h>
+#include <hoot/core/criterion/ElementTypeCriterion.h>
+#include <hoot/core/criterion/ChainCriterion.h>
+#include <hoot/core/criterion/TagKeyCriterion.h>
+#include <hoot/core/ops/ImmediatelyConnectedOutOfBoundsWayTagger.h>
 
 // Qt
 #include <QFileInfo>
 
+// GEOS
+#include <geos/geom/GeometryFactory.h>
+
 namespace hoot
 {
 
@@ -106,7 +114,8 @@ bool IoUtils::areSupportedOgrFormats(const QStringList& inputs, const bool allow
   return true;
 }
 
-void IoUtils::loadMap(const OsmMapPtr& map, const QString& path, bool useFileId, Status defaultStatus)
+void IoUtils::loadMap(const OsmMapPtr& map, const QString& path, bool useFileId,
+                      Status defaultStatus)
 {
   QStringList pathLayer = path.split(";");
   QString justPath = pathLayer[0];
@@ -128,4 +137,51 @@ void IoUtils::saveMap(const OsmMapPtr& map, const QString& path)
   OsmMapWriterFactory::write(map, path);
 }
 
+void IoUtils::cropToBounds(OsmMapPtr& map, const geos::geom::Envelope& bounds,
+                           const bool keepConnectedOobWays)
+{
+  LOG_INFO("Applying bounds filtering to input data: " << bounds << "...");
+  LOG_VARD(keepConnectedOobWays);
+  LOG_VARD(StringUtils::formatLargeNumber(map->getElementCount()));
+
+  // We can get more precise bounds intersection calcs for ways when passing in a geometry here
+  // instead of an envelope.
+//  std::shared_ptr<geos::geom::Geometry> boundsGeom(
+//    geos::geom::GeometryFactory::getDefaultInstance()->toGeometry(&bounds));
+//  MapCropper cropper(boundsGeom);
+  MapCropper cropper(bounds);
+
+  cropper.setKeepEntireFeaturesCrossingBounds(
+    ConfigOptions().getConvertBoundingBoxKeepEntireFeaturesCrossingBounds());
+  const bool strictBoundsHandling =
+    ConfigOptions().getConvertBoundingBoxKeepOnlyFeaturesInsideBounds();
+  cropper.setKeepOnlyFeaturesInsideBounds(strictBoundsHandling);
+
+  // If we want to keep ways that are outside of the crop bounds but connected to a way that's
+  // inside the bounds, we need to tag them before cropping and then tell the cropper to leave
+  // them alone.
+  ElementCriterionPtr inclusionCrit;
+  if (keepConnectedOobWays)
+  {
+    // The two cropper config opts above will always be opposite of one another, so we'll just
+    // determine bounds strictness off of one of them.
+    ImmediatelyConnectedOutOfBoundsWayTagger tagger(bounds, strictBoundsHandling);
+    LOG_INFO(tagger.getInitStatusMessage());
+    tagger.apply(map);
+    LOG_DEBUG(tagger.getCompletedStatusMessage());
+    inclusionCrit.reset(
+      new ChainCriterion(
+        std::shared_ptr<WayCriterion>(new WayCriterion()),
+        std::shared_ptr<TagKeyCriterion>(
+          new TagKeyCriterion(MetadataTags::HootConnectedWayOutsideBounds()))));
+  }
+  cropper.setInclusionCriterion(inclusionCrit);
+
+  LOG_VARD(StringUtils::formatLargeNumber(map->getElementCount()));
+  LOG_INFO(cropper.getInitStatusMessage());
+  cropper.apply(map);
+  LOG_DEBUG(cropper.getCompletedStatusMessage());
+  LOG_VARD(StringUtils::formatLargeNumber(map->getElementCount()));
+}
+
 }
Clone this wiki locally