Reduce Example Source Files

Main.cpp

  1/*
  2 * Copyright (c) 2014-2023 National Technology and Engineering
  3 * Solutions of Sandia, LLC. Under the terms of Contract DE-NA0003525
  4 * with National Technology and Engineering Solutions of Sandia, LLC,
  5 * the U.S. Government retains certain rights in this software.
  6 *
  7 * Redistribution and use in source and binary forms, with or without
  8 * modification, are permitted provided that the following conditions
  9 * are met:
 10 *
 11 * 1. Redistributions of source code must retain the above copyright
 12 * notice, this list of conditions and the following disclaimer.
 13 *
 14 * 2. Redistributions in binary form must reproduce the above copyright
 15 * notice, this list of conditions and the following disclaimer in the
 16 * documentation and/or other materials provided with the distribution.
 17 *
 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 22 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 29 */
 30
 31#include <tracktable/CommandLineFactories/AssemblerFromCommandLine.h>
 32#include <tracktable/CommandLineFactories/PointReaderFromCommandLine.h>
 33#include <tracktable/Domain/Terrestrial.h>
 34#include <tracktable/RW/TrajectoryWriter.h>
 35
 36using TrajectoryT = tracktable::domain::terrestrial::trajectory_type;
 37using PointT = typename TrajectoryT::point_type;
 38using PointReaderT = tracktable::PointReader<PointT>;
 39using PointReaderIteratorT = typename PointReaderT::iterator;
 40using AssemblerT = tracktable::AssembleTrajectories<TrajectoryT, PointReaderIteratorT>;
 41
 42static constexpr auto helpmsg = R"(
 43--------------------------------------------------------------------------------
 44The reduce example demonstrates:
 45    - Using command line factories to read points and assemble trajectories
 46    - using tracktable::simplify to remove unnecessary points
 47    - Writing trajectories to file for later use
 48
 49Typical use:
 50    ./reduce --tolerance=0.00001 --input=/data/flights.tsv --output=/data/reduced.traj
 51
 52Defaults assume a tab separated file formatted as :
 53
 54OBJECTID TIMESTAMP LON LAT
 55
 56Default output is standard out
 57--------------------------------------------------------------------------------)";
 58
 59int main(int _argc, char* _argv[]) {
 60    // Set log level to reduce unecessary output
 61    tracktable::set_log_level(tracktable::log::info);
 62    // Create a basic command line option with boost
 63    boost::program_options::options_description commandLineOptions("Options");
 64    double tolerance = 0.00001;
 65    // clang-format off
 66  commandLineOptions.add_options()
 67    ("help", "Print help")
 68  ;
 69    // clang-format on
 70    // Create command line factories
 71    tracktable::PointReaderFromCommandLine<PointT> readerFactory;
 72    tracktable::AssemblerFromCommandLine<TrajectoryT> assemblerFactory;
 73    // Add options from the factories
 74    readerFactory.addOptions(commandLineOptions);
 75    assemblerFactory.addOptions(commandLineOptions);
 76
 77    // And a command line option for output
 78    // clang-format off
 79    commandLineOptions.add_options()
 80      ("output", bpo::value<std::string>()->default_value("-"),
 81      "file to write to (use '-' for stdout)")
 82      ("tolerance", bpo::value<double>(&tolerance)->default_value(0.00001),
 83      "Tolerance for the simplify routine");
 84    // clang-format on
 85
 86    /** Boost program options using a variable map to tie everything together.
 87     * one parse will have a single variable map. We need to let the factories know
 88     * about this variable map so they can pull information out of it */
 89    auto vm = std::make_shared<boost::program_options::variables_map>();
 90    readerFactory.setVariables(vm);
 91    assemblerFactory.setVariables(vm);
 92
 93    // Parse the command lines, don't forget the 'notify' after
 94    try {
 95        // We use this try/catch to automatically display help when an unknown option is used
 96        boost::program_options::store(
 97            boost::program_options::command_line_parser(_argc, _argv).options(commandLineOptions).run(), *vm);
 98        boost::program_options::notify(*vm);
 99    } catch (boost::program_options::error e) {
100        std::cerr << e.what();
101        std::cerr << helpmsg << "\n\n";
102        std::cerr << commandLineOptions << std::endl;
103        return 1;
104    }
105    /** Parsing will give an error of an incorrect option is used, but it won't
106     * display the help unless we tell it too */
107    if (vm->count("help") != 0) {
108        std::cerr << helpmsg << "\n\n";
109        std::cerr << commandLineOptions << std::endl;
110        return 1;
111    }
112
113    // Create Point Reader and assembler
114    auto pointReader = readerFactory.createPointReader();
115    auto assembler = assemblerFactory.createAssembler(pointReader);
116
117    // We default to standard out
118    std::ostream* o = &std::cout;
119    auto filename = (*vm)["output"].as<std::string>();
120    std::cerr << "Writing to ";
121    if ("-" != filename) {
122        // we swap in a file if a filename is specified
123        std::cerr << filename << std::endl;
124        o = new std::ofstream(filename);
125    } else {
126        std::cerr << "standard out" << std::endl;
127    }
128
129    // trajectory writer with default options
130    tracktable::TrajectoryWriter writer(*o);
131
132    auto count = 0u;
133    std::cerr << std::right;
134    // We don't need to bother storing trajectories, we can just write them
135    auto sum = 0u;
136    for (auto t = assembler->begin(); t != assembler->end(); ++t) {
137        auto s = tracktable::simplify(*t, tolerance);
138        sum += (*t).size() - s.size();
139        writer.write(s);
140        std::cerr << "\b\b\b\b\b\b\b\b\b\b" << std::setw(10)  // Using backspaces for in place counter
141                  << count++;
142    }
143    std::cerr << "\nRemoved " << sum << " points" << std::endl;
144    return 0;
145}