[Liblas-commits] hg: finish ContinuousValueFilter to take in std::binary_predicat...

liblas-commits at liblas.org liblas-commits at liblas.org
Mon Aug 9 16:50:45 EDT 2010


changeset 8426f4b8d999 in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=8426f4b8d999
summary: finish ContinuousValueFilter to take in std::binary_predicate, as well as a simple expression string that ContinuousValueFilter can consume.  Add intensity filtering to las2las2

diffstat:

 apps/las2las2.cpp            |  205 ++++++++++++++++++++++++++++++------------
 include/liblas/lasfilter.hpp |  139 +++++++++++++++++++++++++++-
 2 files changed, 280 insertions(+), 64 deletions(-)

diffs (truncated from 482 to 300 lines):

diff -r 51f7a84a025f -r 8426f4b8d999 apps/las2las2.cpp
--- a/apps/las2las2.cpp	Thu Aug 05 16:39:06 2010 -0500
+++ b/apps/las2las2.cpp	Mon Aug 09 15:50:39 2010 -0500
@@ -15,6 +15,7 @@
 
 #include <fstream>
 #include <iostream>
+#include <sstream>
 #include <string>
 #include <vector>
 #include <string>
@@ -36,7 +37,7 @@
 #define compare_no_case(a,b,n)  strncasecmp( (a), (b), (n) )
 #endif
 
-
+#define SEPARATORS ",|"
 
 bool term_progress(std::ostream& os, double complete)
 {
@@ -84,7 +85,7 @@
 {
     
     if (!liblas::Create(*strm, output.c_str()))
-    {
+{
         std::cerr << "Cannot create " << output << "for write.  Exiting...";
     
     }        
@@ -93,7 +94,92 @@
     
 }
 
+bool IsDualRangeFilter(std::string parse_string) 
+{
 
+string::size_type dash = parse_string.find_first_of("-");
+
+if (dash != std::string::npos) {
+    return true;
+}
+return false;
+}
+
+liblas::FilterI*  MakeReturnFilter(std::string return_string, liblas::FilterI::FilterType ftype) 
+{
+    boost::char_separator<char> sep(SEPARATORS);
+
+    std::vector<uint16_t> returns;
+    tokenizer tokens(return_string, sep);
+    for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
+        returns.push_back(atoi((*t).c_str()));
+    }
+
+    liblas::ReturnFilter* return_filter = new ReturnFilter(returns, false);
+    return_filter->SetType(ftype);
+    return return_filter;
+}
+
+
+liblas::FilterI*  MakeClassFilter(std::string class_string, liblas::FilterI::FilterType ftype) 
+{
+    boost::char_separator<char> sep(SEPARATORS);
+
+    std::vector<uint8_t> classes;
+    tokenizer tokens(class_string, sep);
+    for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
+        classes.push_back(atoi((*t).c_str()));
+    }
+
+    liblas::ClassificationFilter* class_filter = new ClassificationFilter(classes); 
+    class_filter->SetType(ftype);
+    return class_filter;
+}
+
+liblas::FilterI*  MakeBoundsFilter(std::string bounds_string, liblas::FilterI::FilterType ftype) 
+{
+    boost::char_separator<char> sep(SEPARATORS);
+    std::vector<double> vbounds;
+    tokenizer tokens(bounds_string, sep);
+    liblas::Bounds bounds;
+    for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
+        vbounds.push_back(atof((*t).c_str()));
+    }
+    if (vbounds.size() == 4) 
+    {
+        bounds = liblas::Bounds(vbounds[0], 
+                                vbounds[1], 
+                                vbounds[2], 
+                                vbounds[3]);
+    } else if (vbounds.size() == 6)
+    {
+        bounds = liblas::Bounds(vbounds[0], 
+                                vbounds[1], 
+                                vbounds[2], 
+                                vbounds[3], 
+                                vbounds[4], 
+                                vbounds[5]);
+    } else {
+        ostringstream oss;
+        oss << "Bounds must be specified as a 4-tuple or "
+               "6-tuple, not a "<< vbounds.size()<<"-tuple" << "\n";
+        throw std::runtime_error(oss.str());
+    }
+    liblas::BoundsFilter* bounds_filter = new BoundsFilter(bounds);
+    bounds_filter->SetType(ftype);
+    return bounds_filter;
+}
+
+liblas::FilterI*  MakeIntensityFilter(std::string intensities, liblas::FilterI::FilterType ftype) 
+{
+    liblas::ContinuousValueFilter<uint16_t>::filter_func f = &liblas::Point::GetIntensity;
+    liblas::ContinuousValueFilter<uint16_t>* intensity_filter = new liblas::ContinuousValueFilter<uint16_t>(f, intensities);
+    intensity_filter->SetType(ftype);
+    return intensity_filter;
+}
+
+            
+            
 
 bool process(   std::string const& input,
                 std::string const& output,
@@ -166,10 +252,16 @@
         }
     }
     
+    std::cout << std::endl;
+    
     delete writer;
     delete ofs;
     
-    //FIXME: clean up filters
+    for(std::vector<liblas::FilterI*>::iterator i=filters.begin(); i!=filters.end(); i++)
+    {
+        delete *i;
+    }
+    
     return true;
 }
 int main(int argc, char* argv[])
@@ -182,7 +274,7 @@
 
 
 
-    std::vector<boost::uint8_t> drop_returns;
+    // std::vector<boost::uint16_t> returns;
     
     liblas::Bounds bounds;
     
@@ -212,7 +304,8 @@
             ("keep-returns", po::value< string >(), "Return numbers to keep.\nUse a comma-separated list, for example, --keep-returns 1\nUse --last_return_only or --first_return_only if you want to ensure getting either one of these.")
             ("drop-returns", po::value< string >(), "Return numbers to drop.\nUse a comma-separated list, for example, --drop-returns 2,3,4,5\nUse --last_return_only or --first_return_only if you want to ensure getting either one of these.")
             ("valid_only", po::value<bool>(&valid_only)->zero_tokens(), "Keep only valid points")
-            ("keep-intensity", po::value< string >(), "Range in which to keep intensity.\nUse a comma-separated list, for example, --keep-intensity 0-100 --keep-intensity <200\n")
+            ("keep-intensity", po::value< string >(), "Range in which to keep intensity.\nThe following expression types are supported.  --keep-intensity 0-100\n --keep-intensity <200\n --keep-intensity >400\n--keep-intensity >=200")
+            ("drop-intensity", po::value< string >(), "Range in which to drop intensity.\nThe following expression types are supported.  --drop-intensity <200\n --drop-intensity >400\n--drop-intensity >=200")
             
 
     ;
@@ -229,85 +322,79 @@
             return 1;
         }
 
-        boost::char_separator<char> sep(",|");
+        boost::char_separator<char> sep(SEPARATORS);
 
         if (vm.count("keep-classes")) 
         {
-            std::vector<boost::uint8_t> keep_classes;
-            tokenizer tokens(vm["keep-classes"].as< string >(), sep);
-            for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
-                keep_classes.push_back(atoi((*t).c_str()));
-            }
-            liblas::ClassificationFilter* class_filter = new ClassificationFilter(keep_classes);
-            class_filter->SetType(liblas::FilterI::eInclusion);
-            filters.push_back(class_filter);
+            std::string returns = vm["keep-classes"].as< string >();
+            liblas::FilterI* return_filter = MakeClassFilter(  returns, 
+                                                                liblas::FilterI::eInclusion);
+            filters.push_back(return_filter); 
         }
 
         if (vm.count("drop-classes")) 
         {
-            std::vector<boost::uint8_t> drop_classes;            
-            tokenizer tokens(vm["drop-classes"].as< string >(), sep);
-            for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
-                drop_classes.push_back(atoi((*t).c_str()));
-            }
-            liblas::ClassificationFilter* class_filter = new ClassificationFilter(drop_classes);
-            class_filter->SetType(liblas::FilterI::eExclusion);
-            filters.push_back(class_filter);       
+            std::string returns = vm["drop-classes"].as< string >();
+            liblas::FilterI* return_filter = MakeClassFilter(  returns, 
+                                                                liblas::FilterI::eExclusion);
+            filters.push_back(return_filter);
         }
 
         if (vm.count("keep-returns")) 
         {
-            std::vector<boost::uint16_t> keep_returns;
-            tokenizer tokens(vm["keep-returns"].as< string >(), sep);
-            for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
-                keep_returns.push_back(atoi((*t).c_str()));
-            }
-            liblas::ReturnFilter* return_filter = new ReturnFilter(keep_returns, false);
-            return_filter->SetType(liblas::FilterI::eInclusion);
-            filters.push_back(return_filter);
+            std::string returns = vm["keep-returns"].as< string >();
+            liblas::FilterI* return_filter = MakeReturnFilter(  returns, 
+                                                                liblas::FilterI::eInclusion);
+            filters.push_back(return_filter); 
         }
 
         if (vm.count("drop-returns")) 
         {
-            std::vector<boost::uint16_t> drop_returns;
-            tokenizer tokens(vm["drop-returns"].as< string >(), sep);
-            for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
-                drop_returns.push_back(atoi((*t).c_str()));
-            }
-            liblas::ReturnFilter* return_filter = new ReturnFilter(drop_returns, false);
-            return_filter->SetType(liblas::FilterI::eInclusion);
+            std::string returns = vm["drop-returns"].as< string >();
+            liblas::FilterI* return_filter = MakeReturnFilter(  returns, 
+                                                                liblas::FilterI::eExclusion);
             filters.push_back(return_filter); 
         }
                 
         if (vm.count("extent")) 
         {
-            std::vector<double> vbounds;
-            tokenizer tokens(vm["extent"].as< string >(), sep);
-            for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
-                vbounds.push_back(atof((*t).c_str()));
-            }
-            if (vbounds.size() == 4) 
-            {
-                bounds = liblas::Bounds(vbounds[0], vbounds[1], vbounds[2], vbounds[3]);
-            } else if (vbounds.size() == 6)
-            {
-                bounds = liblas::Bounds(vbounds[0], vbounds[1], vbounds[2], vbounds[3], vbounds[4], vbounds[5]);
-            } else {
-                std::cerr << "Bounds must be specified as a 4-tuple or 6-tuple, not a "<< vbounds.size()<<"-tuple" << "\n";
-                return 1;
-            }
-            liblas::BoundsFilter* bounds_filter = new BoundsFilter(bounds);
+            std::string bounds = vm["extent"].as< string >();
+            liblas::FilterI* bounds_filter = MakeBoundsFilter(bounds, liblas::FilterI::eInclusion);
             filters.push_back(bounds_filter);
             
         }
         if (vm.count("keep-intensity")) 
         {
             std::string intensities = vm["keep-intensity"].as< string >();
-            boost::function<uint16_t (const Point*) > f =&liblas::Point::GetIntensity;
+            if (IsDualRangeFilter(intensities)) {
+                // We need to make two filters
+                // Given a range 0-200, split the expression into two filters 
+                string::size_type dash = intensities.find_first_of("-");
+                std::string low = intensities.substr(0,dash);
+                std::string high = intensities.substr(dash+1, intensities.size());
 
-            liblas::ContinuousValueFilter<uint16_t>* intensity_filter = new liblas::ContinuousValueFilter<uint16_t>(f, atoi(intensities.c_str()));
-            intensity_filter->SetType(liblas::FilterI::eInclusion);
-            filters.push_back(intensity_filter);
+                liblas::FilterI* lt_filter = MakeIntensityFilter(">="+low, liblas::FilterI::eInclusion);
+                filters.push_back(lt_filter);
+                liblas::FilterI* gt_filter = MakeIntensityFilter("<="+high, liblas::FilterI::eInclusion);
+                filters.push_back(gt_filter);                
+            } else {
+                liblas::FilterI* intensity_filter = MakeIntensityFilter(intensities, liblas::FilterI::eInclusion);
+                filters.push_back(intensity_filter);
+                
+            }
+        }
+        if (vm.count("drop-intensity")) 
+        {
+            std::string intensities = vm["drop-intensity"].as< string >();
+            if (IsDualRangeFilter(intensities)) {
+                std::cerr << "Range filters are not supported for drop-intensity" << std::endl;
+                return(1);
+            } else {
+                liblas::FilterI* intensity_filter = MakeIntensityFilter(intensities, liblas::FilterI::eExclusion);
+                filters.push_back(intensity_filter);
+                
+            }
+
         }
 
         if (thin > 0) 
@@ -317,7 +404,9 @@
         }
         
         if (first_return_only && last_return_only) {
-            std::cerr << "--first_return_only and --last_return_only cannot be used simultaneously.  Use --keep-returns";
+            std::cerr << "--first_return_only and --last_return_only cannot "
+                         "be used simultaneously.  Use --keep-returns 1 in "
+                         "combination with --last_return_only";
             return 1;


More information about the Liblas-commits mailing list