[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