[Liblas-commits] hg: clean up color fetcher and implementation in las2las

liblas-commits at liblas.org liblas-commits at liblas.org
Thu Nov 11 16:10:27 EST 2010


changeset 656065985885 in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=656065985885
summary: clean up color fetcher and implementation in las2las

diffstat:

 apps/laskernel.cpp              |  111 ++++++++++++++++++++++++++++++++++++++-
 include/liblas/lastransform.hpp |    6 ++
 src/lastransform.cpp            |   50 ++++++++++++++---
 3 files changed, 153 insertions(+), 14 deletions(-)

diffs (286 lines):

diff -r c84f93be7b8a -r 656065985885 apps/laskernel.cpp
--- a/apps/laskernel.cpp	Wed Nov 10 11:47:20 2010 -0600
+++ b/apps/laskernel.cpp	Thu Nov 11 15:10:13 2010 -0600
@@ -202,7 +202,6 @@
     return liblas::FilterPtr(return_filter);
 }
 
-
 liblas::FilterPtr  MakeClassFilter(std::vector<liblas::Classification> const& classes, liblas::FilterI::FilterType ftype) 
 {
 
@@ -288,6 +287,11 @@
 
     transform_options.add_options()
         ("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")
+        ("point-translate", po::value<std::string>(), "An expression to translate the X, Y, Z values of the point. For example, converting Z units that are in meters to feet: --point-translate \"x*1.0 y*1.0 z*3.2808399\"")
+        ("color-source", po::value<std::string>(), "A string to a GDAL-openable raster data source.  Use GDAL VRTs if you want to adjust the data source or set its coordinate system, etc. \n--color-source \"afile.tif\" ")
+        ("color-source-bands", po::value< std::vector<boost::uint32_t> >()->multitoken(), "A list of three bands from the --color-source to assign to the R, G, B  values for the point \n--color-source-bands 1 2 3")
+        ("color-source-scale", po::value< boost::uint32_t >(), "A number used by --color-source to scale the input R, G, B  values for the point.  For example, to scale the 8 bit color data from an input raster to 16 bit, the 8 bit data should be multiplied by 256. \n--color-source-scale 256")
+
     ;
     
     return transform_options;
@@ -303,6 +307,7 @@
         ("offset", po::value< string >(), "A comma-separated or quoted, space-separated list of offsets to set on the output file: \n--offset 0,0,0\n--offset \"1234 5678 91011\"")
         ("scale", po::value< std::vector<double> >()->multitoken(), "A list of scales to set on the output file. Scales *cannot* be negative, and should always be a negative power of 10 \n--scale 0.1 0.1 0.00001")
         ("format,f", po::value< string >(), "Set the LAS format of the new file (only 1.0-1.2 supported at this time): \n--format 1.2\n-f 1.1")
+        ("point-format", po::value< boost::uint32_t >(), "Set the LAS point format of the new file (0, 1, 2, 3): \n--point-format 3\n")
         ("pad-header", po::value< string >(), "Add extra bytes to the existing header")
         ("min-offset", po::value<bool>()->zero_tokens(), "Set the offset of the header to the minimums of all values in the file.  Note that this requires multiple read passes through the file to achieve.")
         ("file-creation", po::value< std::vector<string> >()->multitoken(), "Set the header's day/year.  Specify either as \"1 2010\" for the first day of 2010, or as \"now\" to specify the current day/year")
@@ -311,8 +316,6 @@
         ("add-vlr", po::value<std::vector<std::string> >()->multitoken(), "Add VLRs with the given name and id combination. --add-vlr hobu 1234 \"Description of the VLR\" \"filename.ext\"")
         ("system-identifier", po::value<std::string>(), "Set the SystemID for the file. --system_identifier \"MODIFICATION\"")
         ("generating-software", po::value<std::string>(), "Set the SoftwareID for the file. --generating_software \"liblas.org\"")
-        ("point-translate", po::value<std::string>(), "An expression to translate the X, Y, Z values of the point. For example, converting Z units that are in meters to feet: --point-translate \"x*1.0 y*1.0 z*3.2808399\"")
-
     ;
     
     return transform_options;
@@ -871,6 +874,20 @@
         }
         header.SetVersionMinor(static_cast<boost::uint8_t>(minor)); 
     }
+
+    if (vm.count("point-format")) 
+    {
+        boost::uint32_t format = vm["point-format"].as< boost::uint32_t >();
+        if (verbose)
+            std::cout << "Setting point format to: " << format << std::endl;
+            
+        if (format > 3){
+            ostringstream oss;
+            oss << "Point format valid range is 0-3, not " << format;
+            throw std::runtime_error(oss.str());
+        }
+        header.SetDataFormatId(static_cast<liblas::PointFormatName>(format)); 
+    }
     if (vm.count("pad-header")) 
     {
         std::string header_pad = vm["pad-header"].as< string >();
@@ -1212,6 +1229,94 @@
         transforms.push_back(srs_transform);
     }
 
+    if (vm.count("color-source")) 
+    {
+        std::string datasource = vm["color-source"].as< string >();
+        std::vector<boost::uint32_t> bands;
+        boost::uint32_t scale = 0;
+        bool bSetScale = false;
+        if (vm.count("color-source-bands"))
+        {
+            bands = vm["color-source-bands"].as< std::vector<boost::uint32_t> >();
+            if (bands.size() != 3) 
+            {
+                std::ostringstream oss;
+                oss << "The bands list must have three elements, not " << bands.size();
+                throw std::runtime_error(oss.str());
+            }
+        } 
+        else 
+        {
+            bands.resize(3);
+            bands[0] = 1;
+            bands[1] = 2;
+            bands[2] = 3;
+        }
+
+        if (vm.count("color-source-scale"))
+        {
+            bSetScale = true;
+            scale = vm["color-source-scale"].as< boost::uint32_t >();
+        }          
+        
+        
+        if (verbose)
+        {
+            // make a displayable string for the bands list
+            std::ostringstream bnds;
+            for (std::vector<uint32_t>::const_iterator i = bands.begin();
+            i != bands.end();
+            i++)
+            {
+                bnds << *i;
+                std::vector<uint32_t>::const_iterator i2 = i+1;
+                if (i2 != bands.end())
+                    bnds << ", ";
+            }
+            std::cout << "Fetching color from ' " << datasource 
+                      << "' using bands '" << bnds.str() 
+                      << "' for R, G, B";
+            if (bSetScale)
+                std::cout << " with a scale factor of " << scale;
+            std::cout<< std::endl;
+                
+        }
+
+        
+        // Check the schema to see if we have color
+        liblas::Schema const& schema = header.GetSchema();
+        
+        try
+        {
+            schema.GetDimension("Red");
+        } catch (std::runtime_error const&)
+        {
+            throw std::runtime_error("The header for this file does not allow storing red color information.  Alter the header's data format using the --point-format switch");
+        }
+
+        try
+        {
+            schema.GetDimension("Blue");
+        } catch (std::runtime_error const&)
+        {
+            throw std::runtime_error("The header for this file does not allow storing blue color information.  Alter the header's data format using the --point-format switch");
+        }
+        
+        try
+        {
+            schema.GetDimension("Green");
+        } catch (std::runtime_error const&)
+        {
+            throw std::runtime_error("The header for this file does not allow storing green color information.  Alter the header's data format using the --point-format switch");
+        }        
+        
+        liblas::TransformPtr color_fetch = liblas::TransformPtr(new liblas::ColorFetchingTransform(datasource, bands, liblas::HeaderPtr(new liblas::Header(header))));
+        if (bSetScale) {
+            liblas::ColorFetchingTransform* c = dynamic_cast<liblas::ColorFetchingTransform*>(color_fetch.get());
+            c->SetScaleFactor(scale);
+        }
+        transforms.push_back(color_fetch);
+    }
     if (vm.count("point-translate")) 
     {
         std::string translate = vm["point-translate"].as< std::string >();
diff -r c84f93be7b8a -r 656065985885 include/liblas/lastransform.hpp
--- a/include/liblas/lastransform.hpp	Wed Nov 10 11:47:20 2010 -0600
+++ b/include/liblas/lastransform.hpp	Thu Nov 11 15:10:13 2010 -0600
@@ -169,6 +169,11 @@
     ColorFetchingTransform( std::string const& datasource, 
                             std::vector<boost::uint32_t> bands
                             );
+    ColorFetchingTransform( std::string const& datasource, 
+                            std::vector<boost::uint32_t> bands,
+                            HeaderPtr header);
+    
+    void SetScaleFactor(boost::uint32_t v) {m_scale = v; }
     ~ColorFetchingTransform();
 
     bool transform(Point& point);
@@ -197,6 +202,7 @@
     std::vector<boost::uint32_t> m_bands;
     boost::array<double, 6> m_forward_transform;
     boost::array<double, 6> m_inverse_transform;
+    boost::uint32_t m_scale;
 
     ColorFetchingTransform(ColorFetchingTransform const& other);
     ColorFetchingTransform& operator=(ColorFetchingTransform const& rhs);
diff -r c84f93be7b8a -r 656065985885 src/lastransform.cpp
--- a/src/lastransform.cpp	Wed Nov 10 11:47:20 2010 -0600
+++ b/src/lastransform.cpp	Thu Nov 11 15:10:13 2010 -0600
@@ -40,6 +40,7 @@
  ****************************************************************************/
 
 #include <liblas/lastransform.hpp>
+#include <liblas/lasheader.hpp>
 // boost
 #include <boost/concept_check.hpp>
 #include <boost/tokenizer.hpp>
@@ -398,9 +399,25 @@
     std::string const& datasource, 
     std::vector<boost::uint32_t> bands
 )
-    : m_ds(DataSourcePtr())
+    : m_new_header(HeaderPtr())
+    , m_ds(DataSourcePtr())
     , m_datasource(datasource)
     , m_bands(bands)
+    , m_scale(0)
+{
+    Initialize();
+}
+
+ColorFetchingTransform::ColorFetchingTransform(
+    std::string const& datasource, 
+    std::vector<boost::uint32_t> bands,
+    HeaderPtr header
+)
+    : m_new_header(header)
+    , m_ds(DataSourcePtr())
+    , m_datasource(datasource)
+    , m_bands(bands)
+    , m_scale(0)
 {
     Initialize();
 }
@@ -426,16 +443,16 @@
             m_bands.push_back( i+1 );
         }
     }
+
+    m_forward_transform.assign(0.0);
+    m_inverse_transform.assign(0.0);
     
-    if (GDALGetGeoTransform( m_ds.get(), &m_forward_transform[0] ) != CE_None )
+    if (GDALGetGeoTransform( m_ds.get(), &(m_forward_transform.front()) ) != CE_None )
     {
         throw std::runtime_error("unable to fetch forward geotransform for raster!");
     }
 
-    m_forward_transform.assign(0.0);
-    m_inverse_transform.assign(0.0);
-
-    GDALInvGeoTransform( &m_forward_transform[0], &m_inverse_transform[0] );
+    GDALInvGeoTransform( &(m_forward_transform.front()), &(m_inverse_transform.front()) );
 
 #endif  
 }
@@ -449,8 +466,12 @@
     
     double x = point.GetX();
     double y = point.GetY();
+
+    if (m_new_header.get()) 
+    {
+        point.SetHeaderPtr(m_new_header);
+    }
     
-
     pixel = (boost::int32_t) std::floor(
         m_inverse_transform[0] 
         + m_inverse_transform[1] * x
@@ -472,21 +493,28 @@
     
     boost::array<double, 2> pix;
     boost::array<liblas::Color::value_type, 3> color;
+    color.assign(0);
     
     for( std::vector<boost::int32_t>::size_type i = 0; 
          i < m_bands.size(); i++ )
          {
              GDALRasterBandH hBand = GDALGetRasterBand( m_ds.get(), m_bands[i] );
-             if (hBand == NULL)
-                 continue;       
+             if (hBand == NULL) 
+             {
+                 continue;
+             }
              if( GDALRasterIO( hBand, GF_Read, pixel, line, 1, 1, 
                                &pix[0], 1, 1, GDT_CFloat64, 0, 0) == CE_None )
              {
-                 color[i] = static_cast<liblas::Color::value_type>(pix[0]); 
+                 color[i] = static_cast<liblas::Color::value_type>(pix[0]);
+                 if (m_scale) {
+                     color[i] = color[i] * m_scale;
+                 }
              }             
          }
+
      point.SetColor(Color(color));
-
+ 
     return true;
 #else
     boost::ignore_unused_variable_warning(point);


More information about the Liblas-commits mailing list