Skip to content

v0.2.48..v0.2.49 changeset RandomMapCropper.cpp

Garret Voltz edited this page Oct 2, 2019 · 1 revision
diff --git a/hoot-rnd/src/main/cpp/hoot/rnd/ops/RandomMapCropper.cpp b/hoot-rnd/src/main/cpp/hoot/rnd/ops/RandomMapCropper.cpp
new file mode 100644
index 0000000..dda3ae4
--- /dev/null
+++ b/hoot-rnd/src/main/cpp/hoot/rnd/ops/RandomMapCropper.cpp
@@ -0,0 +1,122 @@
+/*
+ * This file is part of Hootenanny.
+ *
+ * Hootenanny is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * --------------------------------------------------------------------
+ *
+ * The following copyright notices are generated automatically. If you
+ * have a new notice to add, please use the format:
+ * " * @copyright Copyright ..."
+ * This will properly maintain the copyright information. DigitalGlobe
+ * copyrights will be updated automatically.
+ *
+ * @copyright Copyright (C) 2019 DigitalGlobe (http://www.digitalglobe.com/)
+ */
+
+#include "RandomMapCropper.h"
+
+// Hoot
+#include <hoot/core/elements/OsmMap.h>
+#include <hoot/core/util/Factory.h>
+#include <hoot/core/util/ConfigOptions.h>
+#include <hoot/rnd/util/TileUtils.h>
+#include <hoot/core/util/GeometryUtils.h>
+#include <hoot/core/ops/SuperfluousWayRemover.h>
+#include <hoot/core/ops/SuperfluousNodeRemover.h>
+#include <hoot/core/visitors/CalculateMapBoundsVisitor.h>
+#include <hoot/core/util/MapProjector.h>
+
+namespace hoot
+{
+
+HOOT_FACTORY_REGISTER(OsmMapOperation, RandomMapCropper)
+
+RandomMapCropper::RandomMapCropper() :
+_maxNodeCount(1000),
+_randomSeed(-1),
+_pixelSize(0.001)
+{
+}
+
+void RandomMapCropper::setConfiguration(const Settings& conf)
+{
+  _cropper.setConfiguration(conf);
+  _cropper.setInvert(false);
+
+  ConfigOptions confOpts = ConfigOptions(conf);
+  _maxNodeCount = confOpts.getCropRandomMaxNodeCount();
+  _pixelSize = confOpts.getCropRandomPixelSize();
+  _randomSeed = confOpts.getRandomSeed();
+}
+
+void RandomMapCropper::apply(OsmMapPtr& map)
+{
+  //LOG_VARD(_maxNodeCount);
+  if (_maxNodeCount < 1 || _maxNodeCount > (int)map->size())
+  {
+    throw IllegalArgumentException("Invalid max node count: " + _maxNodeCount);
+  }
+
+  LOG_INFO("Cropping to random map tile of max node size: " << _maxNodeCount << "...");
+  LOG_VARD(_randomSeed);
+
+  //MapProjector::projectToWgs84(map);
+
+  const int startingMapSize = (int)map->size();
+  // Could be an expensive operation. Keep as debug.
+  geos::geom::Envelope startingBounds;
+  if (Log::getInstance().getLevel() <= Log::Debug)
+  {
+    startingBounds = CalculateMapBoundsVisitor::getGeosBounds(map);
+  }
+
+  // compute tiles for the whole dataset, select one tile at random, and crop to the bounds of
+  // the selected tile
+  // TODO: Can we intelligently calculate pixel size here somehow?
+  long minNodeCountInOneTile = 0;
+  long maxNodeCountInOneTile = 0;
+  const std::vector<std::vector<geos::geom::Envelope>> tiles =
+    TileUtils::calculateTiles(
+      _maxNodeCount, _pixelSize, map, minNodeCountInOneTile, maxNodeCountInOneTile);
+  if (!_tileFootprintOutputPath.isEmpty())
+  {
+    if (_tileFootprintOutputPath.toLower().endsWith(".geojson"))
+    {
+      TileUtils::writeTilesToGeoJson(tiles, _tileFootprintOutputPath);
+    }
+    else
+    {
+      TileUtils::writeTilesToOsm(tiles, _tileFootprintOutputPath);
+    }
+    LOG_INFO("Wrote tile footprints to: " << _tileFootprintOutputPath);
+  }
+  _cropper.setBounds(TileUtils::getRandomTile(tiles, _randomSeed));
+  _cropper.apply(map);
+
+  // cleanup
+  SuperfluousWayRemover::removeWays(map);
+  SuperfluousNodeRemover::removeNodes(map);
+
+  LOG_INFO("Starting map size: " << StringUtils::formatLargeNumber(startingMapSize));
+  LOG_DEBUG("Starting map bounds: " << GeometryUtils::envelopeToConfigString(startingBounds));
+  LOG_INFO("Cropped map size: " << StringUtils::formatLargeNumber(map->size()));
+  LOG_DEBUG(
+    "Cropped map bounds: " <<
+    GeometryUtils::envelopeToConfigString(CalculateMapBoundsVisitor::getGeosBounds(map)));
+  LOG_INFO("Minimum nodes in a single tile: " << minNodeCountInOneTile);
+  LOG_INFO("Maximum nodes in a single tile: " << maxNodeCountInOneTile);
+}
+
+}
Clone this wiki locally