[Liblas-commits] hg: add support for setting scales/offsets

liblas-commits at liblas.org liblas-commits at liblas.org
Tue Aug 10 11:01:28 EDT 2010


changeset b8eca9d978c9 in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=b8eca9d978c9
summary: add support for setting scales/offsets

diffstat:

 apps/las2las2.cpp |  154 +++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 125 insertions(+), 29 deletions(-)

diffs (truncated from 321 to 300 lines):

diff -r 6a6ee5406bd3 -r b8eca9d978c9 apps/las2las2.cpp
--- a/apps/las2las2.cpp	Tue Aug 10 09:07:08 2010 -0500
+++ b/apps/las2las2.cpp	Tue Aug 10 10:01:20 2010 -0500
@@ -188,6 +188,7 @@
 
 bool process(   std::string const& input,
                 std::string const& output,
+                liblas::Header const& header,
                 std::vector<liblas::FilterI*>& filters,
                 std::vector<liblas::TransformI*>& transforms,
                 uint32_t split_size,
@@ -211,16 +212,16 @@
     std::string out = output;
     liblas::Writer* writer = 0;
     if (!split_size) {
-        writer = start_writer(ofs, output, reader.GetHeader());
+        writer = start_writer(ofs, output, header);
         
     } 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());
+        writer = start_writer(ofs, out+"-1"+".las", header);
     }
 
     if (verbose)
-    std::cout << "Target:" 
+    std::cout << "Writing output:" 
         << "\n - : " << output
         << std::endl;
 
@@ -228,7 +229,7 @@
     // Translation of points cloud to features set
     //
     boost::uint32_t i = 0;
-    boost::uint32_t const size = reader.GetHeader().GetPointRecordsCount();
+    boost::uint32_t const size = header.GetPointRecordsCount();
     
     boost::int32_t split_bytes_count = 1024*1024*split_size;
     int fileno = 2;
@@ -241,7 +242,7 @@
             term_progress(std::cout, (i + 1) / static_cast<double>(size));
         i++;
 
-        split_bytes_count = split_bytes_count - reader.GetHeader().GetSchema().GetByteSize();        
+        split_bytes_count = split_bytes_count - header.GetSchema().GetByteSize();        
         if (split_bytes_count < 0 && split_size > 0) {
             // The user specifies a split size in mb, and we keep counting 
             // down until we've written that many points into the file.  
@@ -255,7 +256,7 @@
             ostringstream oss;
             oss << out << "-"<< fileno <<".las";
 
-            writer = start_writer(ofs, oss.str(), reader.GetHeader());
+            writer = start_writer(ofs, oss.str(), header);
             fileno++;
             split_bytes_count = 1024*1024*split_size;
         }
@@ -288,6 +289,7 @@
     std::vector<liblas::FilterI*> filters;
     std::vector<liblas::TransformI*> transforms;
     
+    liblas::Header header;
 
     try {
 
@@ -307,8 +309,8 @@
             ("thin,t", po::value<uint32_t>(&thin)->default_value(0), "Simple decimation-style thinning.\nThin the file by removing every t'th point from the file.")
             ("last_return_only", po::value<bool>(&last_return_only)->zero_tokens(), "Keep last returns (cannot be used with --first_return_only)")
             ("first_return_only", po::value<bool>(&first_return_only)->zero_tokens(), "Keep first returns (cannot be used with --last_return_only")
-            ("keep-returns", po::value< string >(), "A comma-separated list of return numbers to keep in the output file: \n--keep-returns 1\nUse --last_return_only ")
-            ("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.")
+            ("keep-returns", po::value< string >(), "A comma-separated list of return numbers to keep in the output file: \n--keep-returns 1,2,3")
+            ("drop-returns", po::value< string >(), "Return numbers to drop.\nUse a comma-separated list, for example, --drop-returns 2,3,4,5")
             ("valid_only", po::value<bool>(&valid_only)->zero_tokens(), "Keep only valid points")
             ("keep-intensity", po::value< string >(), "Range in which to keep intensity.\nThe following expression types are supported:  \n--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:  \n--drop-intensity <200 \n--drop-intensity >400 \n--drop-intensity >=200")
@@ -317,6 +319,8 @@
             ("verbose,v", po::value<bool>(&verbose)->zero_tokens(), "Keep only valid points")
             ("a_srs", po::value< string >(), "Coordinate system to assign to input LAS file")
             ("t_srs", po::value< string >(), "Coordinate system to reproject output LAS file to.  Use --a_srs or verify that your input LAS file has a coordinate system according to lasinfo")   
+            ("offset", po::value< string >(), "A comma-separated list of offsets to set on the output file: \n--offset 0,0,0 \n--offset  min,min,min\n ")
+            ("scale", po::value< string >(), "A comma-separated list of scales to set on the output file: \n--scale 0.1,0.1,0.00001\n ")
 
     ;
     
@@ -337,6 +341,16 @@
         if (vm.count("input")) 
         {
             input = vm["input"].as< string >();
+            std::ifstream ifs;
+            if (verbose)
+                std::cout << "Opening " << input << " to fetch Header" << std::endl;
+            if (!liblas::Open(ifs, input.c_str()))
+            {
+                std::cerr << "Cannot open " << input << "for read.  Exiting...";
+                return 1;
+            }
+            liblas::Reader reader(ifs);
+            header = reader.GetHeader();
         } else {
             std::cerr << "Input LAS file not specified!\n" << desc << "\n";
             return 1;
@@ -344,23 +358,32 @@
         
         if (vm.count("keep-classes")) 
         {
-            std::string returns = vm["keep-classes"].as< string >();
-            liblas::FilterI* return_filter = MakeClassFilter(  returns, 
-                                                                liblas::FilterI::eInclusion);
-            filters.push_back(return_filter); 
+            std::string classes = vm["keep-classes"].as< string >();
+            if (verbose)
+                std::cout << "Keeping classes with the values: " << classes << std::endl;
+                
+            liblas::FilterI* class_filter = MakeClassFilter(  classes, 
+                                                              liblas::FilterI::eInclusion);
+            filters.push_back(class_filter); 
         }
 
         if (vm.count("drop-classes")) 
         {
-            std::string returns = vm["drop-classes"].as< string >();
-            liblas::FilterI* return_filter = MakeClassFilter(  returns, 
+            std::string classes = vm["drop-classes"].as< string >();
+            if (verbose)
+                std::cout << "Dropping classes with the values: " << classes << std::endl;
+                
+            liblas::FilterI* class_filter = MakeClassFilter(  classes, 
                                                                 liblas::FilterI::eExclusion);
-            filters.push_back(return_filter);
+            filters.push_back(class_filter);
         }
 
         if (vm.count("keep-returns")) 
         {
             std::string returns = vm["keep-returns"].as< string >();
+            if (verbose)
+                std::cout << "Keeping returns with the values: " << returns << std::endl;
+                
             liblas::FilterI* return_filter = MakeReturnFilter(  returns, 
                                                                 liblas::FilterI::eInclusion);
             filters.push_back(return_filter); 
@@ -369,6 +392,9 @@
         if (vm.count("drop-returns")) 
         {
             std::string returns = vm["drop-returns"].as< string >();
+            if (verbose)
+                std::cout << "Dropping returns with the values: " << returns << std::endl;
+                
             liblas::FilterI* return_filter = MakeReturnFilter(  returns, 
                                                                 liblas::FilterI::eExclusion);
             filters.push_back(return_filter); 
@@ -377,6 +403,8 @@
         if (vm.count("extent")) 
         {
             std::string bounds = vm["extent"].as< string >();
+            if (verbose)
+                std::cout << "Clipping file to the extent : " << bounds << std::endl;
             liblas::FilterI* bounds_filter = MakeBoundsFilter(bounds, liblas::FilterI::eInclusion);
             filters.push_back(bounds_filter);
             
@@ -384,6 +412,8 @@
         if (vm.count("keep-intensity")) 
         {
             std::string intensities = vm["keep-intensity"].as< string >();
+            if (verbose)
+                std::cout << "Keeping intensities with values: " << intensities << std::endl;
             if (IsDualRangeFilter(intensities)) {
                 // We need to make two filters
                 // Given a range 0-200, split the expression into two filters 
@@ -404,6 +434,9 @@
         if (vm.count("drop-intensity")) 
         {
             std::string intensities = vm["drop-intensity"].as< string >();
+            if (verbose)
+                std::cout << "Dropping intensities with values: " << intensities << std::endl;
+
             if (IsDualRangeFilter(intensities)) {
                 std::cerr << "Range filters are not supported for drop-intensity" << std::endl;
                 return(1);
@@ -415,6 +448,8 @@
         if (vm.count("keep-time")) 
         {
             std::string times = vm["keep-time"].as< string >();
+            if (verbose)
+                std::cout << "Keeping times with values: " << times << std::endl;
             if (IsDualRangeFilter(times)) {
                 // We need to make two filters
                 // Given a range 0-200, split the expression into two filters 
@@ -435,6 +470,9 @@
         if (vm.count("drop-time")) 
         {
             std::string times = vm["drop-time"].as< string >();
+            if (verbose)
+                std::cout << "Dropping times with values: " << times << std::endl;
+                
             if (IsDualRangeFilter(times)) {
                 std::cerr << "Range filters are not supported for drop-time" << std::endl;
                 return(1);
@@ -444,40 +482,97 @@
             }
         }
 
+        if (vm.count("a_srs")) 
+        {
+            liblas::SpatialReference in_ref;
+            
+            std::string input_srs = vm["a_srs"].as< string >();
+            if (verbose)
+                std::cout << "Setting input SRS to " << input_srs << std::endl;
+            in_ref.SetFromUserInput(input_srs);
+            header.SetSRS(in_ref);
+        }
+        
         if (vm.count("t_srs")) 
         {
             liblas::SpatialReference in_ref;
             liblas::SpatialReference out_ref;
             
             std::string output_srs = vm["t_srs"].as< string >();
+            if (verbose)
+                std::cout << "Setting output SRS to " << output_srs << std::endl;
             out_ref.SetFromUserInput(output_srs);
 
             if (vm.count("a_srs")){
                 std::string input_srs = vm["a_srs"].as< string >();
                 in_ref.SetFromUserInput(input_srs);
             } else {
-                // If the user didn't assign an input SRS, we'll read the 
-                // file and fetch it from there.
-                std::ifstream ifs;
-                if (verbose)
-                    std::cout << "Opening " << input << " to fetch SRS" << std::endl;
-                if (!liblas::Open(ifs, input.c_str()))
-                {
-                    std::cerr << "Cannot open " << input << "for read.  Exiting...";
-                    return 1;
-                }
-                liblas::Reader reader(ifs);
-                in_ref = reader.GetHeader().GetSRS();
+                // If the user didn't assign an input SRS, we'll try to take 
+                // it from our existing header.
+                in_ref = header.GetSRS();
                 if (in_ref.GetVLRs().size() == 0)
                 {
                     std::cerr << "No input SRS is available on the file you have specified.  Please use --a_srs to assign one" << std::endl;
                     return 1;
                 }
+                
             }
+            // Set the header's SRS to the output SRS now.  We've already 
+            // made the transformation, and this SRS will be used to 
+            // write the new file(s)
+            header.SetSRS(out_ref);
             liblas::TransformI* srs_transform = new liblas::ReprojectionTransform(in_ref, out_ref);
             transforms.push_back(srs_transform);
         }
-        
+
+        if (vm.count("offset")) 
+        {
+            std::string offset_string = vm["offset"].as< string >();
+            if (verbose)
+                std::cout << "Setting offsets to: " << offset_string << std::endl;
+            boost::char_separator<char> sep(SEPARATORS);
+            std::vector<double> offsets;
+            tokenizer tokens(offset_string, sep);
+            bool mins = false;
+            std::string m("min");
+            for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) {
+                // Check if the user set --offset min,min,min
+                // FIXME: make this so the user could do --offset min,min,20.00
+                if (!(*t).compare(m))
+                {   
+                    mins = true;
+                    continue;
+                }
+                else
+                {
+                    mins = false;
+                    offsets.push_back(atof((*t).c_str()));
+                }
+            }
+            if (offsets.size() != 3) 
+            {
+                std::cerr << "All three values for setting the offset must be floats"<< std::endl;
+                return (1);
+            }
+            header.SetOffset(offsets[0], offsets[1], offsets[2]);
+        }
+
+        if (vm.count("scale")) 
+        {
+            std::string scale_string = vm["scale"].as< string >();
+            if (verbose)
+                std::cout << "Setting scales to: " << scale_string << std::endl;
+
+            boost::char_separator<char> sep(SEPARATORS);
+            std::vector<double> scales;


More information about the Liblas-commits mailing list