[Liblas-commits] hg: 2 new changesets
liblas-commits at liblas.org
liblas-commits at liblas.org
Tue Aug 3 23:49:29 EDT 2010
changeset 13ee5a7fab5e in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=13ee5a7fab5e
summary: support making BoundsFilter from liblas::Bounds
changeset 42a00f65d667 in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=42a00f65d667
summary: update las2las2 to use boost::program_options, provide file splitting capability
diffstat:
CMakeLists.txt | 4 +-
apps/CMakeLists.txt | 2 +-
apps/las2las2.cpp | 365 +++++++++++++++++++++++++-----------------
include/liblas/lasfilter.hpp | 1 +
src/lasfilter.cpp | 12 +
5 files changed, 229 insertions(+), 155 deletions(-)
diffs (truncated from 470 to 300 lines):
diff -r 97cf289d06da -r 42a00f65d667 CMakeLists.txt
--- a/CMakeLists.txt Tue Aug 03 13:37:12 2010 -0500
+++ b/CMakeLists.txt Tue Aug 03 22:49:18 2010 -0500
@@ -124,9 +124,9 @@
# Boost C++ Libraries support - required
message(STATUS "Searching for Boost 1.38+ - done")
-find_package(Boost 1.38 REQUIRED)
+find_package(Boost 1.38 REQUIRED program_options)
-if(Boost_FOUND)
+if(Boost_FOUND AND Boost_program_options_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
diff -r 97cf289d06da -r 42a00f65d667 apps/CMakeLists.txt
--- a/apps/CMakeLists.txt Tue Aug 03 13:37:12 2010 -0500
+++ b/apps/CMakeLists.txt Tue Aug 03 22:49:18 2010 -0500
@@ -89,7 +89,7 @@
if(LAS2LAS2)
add_executable(${LAS2LAS2} las2las2.cpp)
- target_link_libraries(${LAS2LAS2} ${APPS_CPP_DEPENDENCIES})
+ target_link_libraries(${LAS2LAS2} ${APPS_CPP_DEPENDENCIES} ${Boost_LIBRARIES})
endif()
# Build las2txt
diff -r 97cf289d06da -r 42a00f65d667 apps/las2las2.cpp
--- a/apps/las2las2.cpp Tue Aug 03 13:37:12 2010 -0500
+++ b/apps/las2las2.cpp Tue Aug 03 22:49:18 2010 -0500
@@ -19,7 +19,15 @@
#include <vector>
#include <string>
+#include <boost/program_options.hpp>
+#include <boost/tokenizer.hpp>
+
+typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+
+namespace po = boost::program_options;
+
using namespace liblas;
+using namespace std;
#ifdef _WIN32
#define compare_no_case(a,b,n) _strnicmp( (a), (b), (n) )
@@ -61,185 +69,238 @@
}
-void tokenize(const std::string& str,
- std::vector<std::string>& tokens,
- const std::string& delimiters = ",")
+
+
+liblas::Writer* start_writer( std::ofstream* strm,
+ std::string const& output,
+ liblas::Header const& header)
{
- // stolen from http://www.linuxselfhelp.com/HOWTO/C++Programming-HOWTO-7.html
- // Skip delimiters at beginning.
- std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
- // Find first "non-delimiter".
- std::string::size_type pos = str.find_first_of(delimiters, lastPos);
-
- while (std::string::npos != pos || std::string::npos != lastPos)
+ if (!liblas::Create(*strm, output.c_str()))
{
- // Found a token, add it to the vector.
- tokens.push_back(str.substr(lastPos, pos - lastPos));
- // Skip delimiters. Note the "not_of"
- lastPos = str.find_first_not_of(delimiters, pos);
- // Find next "non-delimiter"
- pos = str.find_first_of(delimiters, lastPos);
- }
+ std::cerr << "Cannot create " << output << "for write. Exiting...";
+
+ }
+ liblas::Writer* writer = new liblas::Writer(*strm, header);
+ return writer;
+
}
+bool process( std::string const& input,
+ std::string const& output,
+ liblas::Bounds const& bounds,
+ uint32_t split_size,
+ std::vector<uint8_t> keep_classes,
+ std::vector<uint8_t> drop_classes)
+{
-void usage() {}
+ std::vector<liblas::FilterI*> filters;
+
+ //
+ // Source
+ //
+ std::cout << "Processing:" << "\n - dataset: " << input << std::endl;
+
+ // Make the filters
+
+ if (keep_classes.size() > 0) {
+ liblas::ClassificationFilter* class_filter = new ClassificationFilter(keep_classes);
+ class_filter->SetType(liblas::FilterI::eInclusion);
+ filters.push_back(class_filter);
+
+ }
+
+ if (drop_classes.size() > 0)
+ {
+ liblas::ClassificationFilter* class_filter = new ClassificationFilter(drop_classes);
+ class_filter->SetType(liblas::FilterI::eExclusion);
+ filters.push_back(class_filter);
+ }
+
+ if (bounds.dimension() > 0) {
+ liblas::BoundsFilter* bounds_filter = new BoundsFilter(bounds);
+ filters.push_back(bounds_filter);
+ }
+
+ std::ifstream ifs;
+ if (!liblas::Open(ifs, input.c_str()))
+ {
+ std::cerr << "Cannot open " << input << "for read. Exiting...";
+ return false;
+ }
+ liblas::Reader reader(ifs);
+
+ reader.SetFilters(&filters);
+
+ std::ofstream* ofs = new std::ofstream;
+ std::string out = output;
+ liblas::Writer* writer = 0;
+ if (!split_size) {
+ writer = start_writer(ofs, output, reader.GetHeader());
+
+ } else {
+ string::size_type dot_pos = output.find_first_of(".");
+ out = output.substr(0, dot_pos);
+ writer = start_writer(ofs, out+"-1"+".las", reader.GetHeader());
+ }
+
+
+ std::cout << "Target:"
+ << "\n - : " << output
+ << std::endl;
+
+ //
+ // Translation of points cloud to features set
+ //
+ boost::uint32_t i = 0;
+ boost::uint32_t const size = reader.GetHeader().GetPointRecordsCount();
+
+ boost::int32_t split_bytes_count = 1024*1024*split_size;
+ std::cout << "count: " << split_bytes_count;
+ int k = 2;
+ while (reader.ReadNextPoint())
+ {
+ liblas::Point const& p = reader.GetPoint();
+ writer->WritePoint(p);
+ split_bytes_count = split_bytes_count - reader.GetHeader().GetSchema().GetByteSize();
+ term_progress(std::cout, (i + 1) / static_cast<double>(size));
+ i++;
+ if (split_bytes_count < 0) {
+ delete writer;
+ delete ofs;
+
+ ofs = new std::ofstream;
+ ostringstream oss;
+ oss << out << "-"<< k <<".las";
+
+ // out = std::string(oss.str());
+ writer = start_writer(ofs, oss.str(), reader.GetHeader());
+ k++;
+ split_bytes_count = 1024*1024*split_size;
+ }
+ }
+
+ delete writer;
+ delete ofs;
+ return true;
+}
int main(int argc, char* argv[])
{
- int rc = 0;
- std::vector<std::string> tokens;
- std::vector<boost::uint8_t> classes;
- std::vector<double> bounds;
- std::vector<liblas::FilterI*> filters;
+ uint32_t split_size;
+ std::string input;
+ std::string output;
+
+ std::vector<boost::uint8_t> keep_classes;
+ std::vector<boost::uint8_t> drop_classes;
+ liblas::Bounds bounds;
- try
- {
+ try {
- // Parse command-line options
- std::string in_file;
- std::string out_file;
- std::string keep_classes;
+ po::options_description desc("Allowed options");
+ po::positional_options_description p;
+ p.add("input", 1);
+ p.add("output", 1);
+
+ desc.add_options()
+ ("help", "produce help message")
+ ("split,s", po::value<uint32_t>(&split_size)->default_value(0), "Split file into multiple files with each being this size in MB or less. If this value is 0, no splitting is done")
+ ("input,i", po::value< string >(), "input LAS file")
+ ("output,o", po::value< string >(&output)->default_value("output.las"), "output LAS file")
+ ("keep-classes,k", po::value< string >(), "Classifications to keep.\nUse a comma-separated list, for example, -k 2,4,12")
+ ("drop-classes,d", po::value< string >(), "Classifications to drop.\nUse a comma-separated list, for example, -d 1,7,8")
+ ("extent,e", po::value< string >(), "Extent window that points must fall within to keep.\nUse a comma-separated list, for example, \n -e minx, miny, maxx, maxy\n or \n -e minx, miny, maxx, maxy, minz, maxz")
+
+ ;
+
+ po::variables_map vm;
+ po::store(po::command_line_parser(argc, argv).
+ options(desc).positional(p).run(), vm);
+
+ po::notify(vm);
+
+ if (vm.count("help"))
{
- int on_arg = 1;
- while (on_arg < argc)
- {
- std::string arg(argv[on_arg]);
- if (arg == "-h")
- {
- usage();
- return 0;
- }
- else if (arg == "-i" && (on_arg + 1 < argc))
- {
- ++on_arg;
- assert(on_arg < argc);
- in_file = argv[on_arg];
- }
- else if (arg == "-c" && (on_arg + 1 < argc))
- {
- ++on_arg;
- assert(on_arg < argc);
- tokenize(std::string(argv[on_arg]), tokens);
- std::vector<std::string>::const_iterator i;
- for (i = tokens.begin(); i != tokens.end(); ++i) {
- classes.push_back(atoi((*i).c_str()));
- std::cout << ", "<<*i;
- }
- std::cout << std::endl;
- tokens.clear();
-
- }
- else if (arg == "-b" && (on_arg + 1 < argc))
- {
- ++on_arg;
- assert(on_arg < argc);
- tokenize(std::string(argv[on_arg]), tokens);
- std::vector<std::string>::const_iterator i;
- for (i = tokens.begin(); i != tokens.end(); ++i) {
- bounds.push_back(atof((*i).c_str()));
- std::cout << ", "<<*i;
- }
- tokens.clear();
- std::cout << std::endl;
-
- }
- else if (arg == "-o" && (on_arg + 1 < argc))
- {
- ++on_arg;
- assert(on_arg < argc);
- out_file = argv[on_arg];
- }
+ std::cout << desc << "\n";
+ return 1;
+ }
- else
- {
- throw std::runtime_error(std::string("unrecognized parameter: ") + arg);
- }
- ++on_arg;
- }
+ boost::char_separator<char> sep(",");
- if (in_file.empty() || out_file.empty())
- {
- throw std::runtime_error("missing input paremeters");
+ if (vm.count("keep-classes"))
+ {
+ tokenizer tokens(vm["keep-classes"].as< string >(), sep);
More information about the Liblas-commits
mailing list