[Liblas-commits] hg: we can round-trip schema XML to/from VLRs now

liblas-commits at liblas.org liblas-commits at liblas.org
Thu Sep 2 21:41:28 EDT 2010


changeset d3c46c92ab81 in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=d3c46c92ab81
summary: we can round-trip schema XML to/from VLRs now

diffstat:

 include/liblas/lasschema.hpp |   35 ++++--
 src/detail/reader/header.cpp |   19 +++
 src/lasschema.cpp            |  232 ++++++++++++++++++++++++++++++------------
 3 files changed, 210 insertions(+), 76 deletions(-)

diffs (truncated from 617 to 300 lines):

diff -r 6322659c82fe -r d3c46c92ab81 include/liblas/lasschema.hpp
--- a/include/liblas/lasschema.hpp	Thu Sep 02 15:04:25 2010 -0500
+++ b/include/liblas/lasschema.hpp	Thu Sep 02 20:41:15 2010 -0500
@@ -49,6 +49,7 @@
 #include <boost/cstdint.hpp>
 #include <boost/any.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/foreach.hpp>
 
 // std
 #include <iosfwd>
@@ -58,8 +59,8 @@
 
 namespace liblas {  
 
-class DimensionI;
-typedef boost::shared_ptr<DimensionI> DimensionPtr;
+class Dimension;
+typedef boost::shared_ptr<Dimension> DimensionPtr;
 
 class Schema
 {
@@ -88,8 +89,8 @@
     bool HasColor() const;
     bool HasTime() const; 
     
-    void AddDimension(boost::shared_ptr<DimensionI> dim);
-    boost::shared_ptr<DimensionI> GetDimension(std::string const& name) const;
+    void AddDimension(boost::shared_ptr<Dimension> dim);
+    boost::shared_ptr<Dimension> GetDimension(std::string const& name) const;
     void RemoveDimension(DimensionPtr dim);
     
     std::vector<std::string> GetDimensionNames() const;
@@ -97,13 +98,13 @@
     liblas::property_tree::ptree GetPTree() const;
     
     bool IsCustom() const;
-    VariableRecord const& GetVLR() const;
+    VariableRecord GetVLR() const;
 
 protected:
     
     boost::uint16_t m_size;
     PointFormatName m_data_format_id;
-
+    boost::uint32_t m_nextpos;
 private:
 
     std::vector<DimensionPtr> m_dimensions;    
@@ -113,13 +114,16 @@
     void add_color();
     void update_required_dimensions(PointFormatName data_format_id);
     bool IsSchemaVLR(VariableRecord const& vlr);
+    liblas::property_tree::ptree LoadPTree(VariableRecord const& v);
+    std::vector<DimensionPtr> LoadDimensions(liblas::property_tree::ptree tree);
+
 };
 
 
-class DimensionI
+class Dimension
 {
 public:
-    DimensionI(std::string const& name, boost::uint32_t size_in_bits) : 
+    Dimension(std::string const& name, boost::uint32_t size_in_bits) : 
         m_name(name), 
         m_bitsize(size_in_bits),
         m_required(false),
@@ -129,10 +133,11 @@
         m_max(0),
         m_numeric(false),
         m_signed(false),
-        m_integer(false)
+        m_integer(false),
+        m_position(0)
     {};
     
-    virtual ~DimensionI() {};
+    virtual ~Dimension() {};
         
     std::string const& GetName() { return m_name; }
     
@@ -184,7 +189,14 @@
     /// The maximum value of this dimension as a double
     double GetMaximum() { return m_max; }
     void SetMaximum(double max) { m_max = max; }
-        
+    
+    boost::uint32_t GetPosition() const { return m_position; }
+    void SetPosition(boost::uint32_t v) { m_position = v; }
+    
+    bool operator < (Dimension const& dim) const 
+    {
+        return m_position < dim.m_position;
+    }
 private:
         
     std::string m_name;
@@ -197,6 +209,7 @@
     bool m_numeric;
     bool m_signed;
     bool m_integer;
+    boost::uint32_t m_position;
 };
 
 
diff -r 6322659c82fe -r d3c46c92ab81 src/detail/reader/header.cpp
--- a/src/detail/reader/header.cpp	Thu Sep 02 15:04:25 2010 -0500
+++ b/src/detail/reader/header.cpp	Thu Sep 02 20:41:15 2010 -0500
@@ -408,6 +408,25 @@
 
     liblas::SpatialReference srs(m_header->GetVLRs());    
     m_header->SetSRS(srs);
+    
+    // Go fetch the schema from the VLRs if we've got one.
+    try {
+        liblas::Schema schema(m_header->GetVLRs());
+        m_header->SetSchema(schema);
+
+    } catch (std::runtime_error const& e) 
+    {
+        // Create one from the PointFormat if we don't have
+        // one in the VLRs.  Create a custom dimension on the schema 
+        // That comprises the rest of the bytes after the end of the 
+        // required dimensions.
+        liblas::Schema schema(m_header->GetDataFormatId());
+        
+        // FIXME: handle custom bytes here.
+        m_header->SetSchema(schema);
+        boost::ignore_unused_variable_warning(e);
+        
+    }
 
 }
 
diff -r 6322659c82fe -r d3c46c92ab81 src/lasschema.cpp
--- a/src/lasschema.cpp	Thu Sep 02 15:04:25 2010 -0500
+++ b/src/lasschema.cpp	Thu Sep 02 20:41:15 2010 -0500
@@ -55,7 +55,8 @@
 
 Schema::Schema(PointFormatName data_format_id):
     m_size(0),
-    m_data_format_id(data_format_id)
+    m_data_format_id(data_format_id),
+    m_nextpos(0)
 {
     update_required_dimensions(data_format_id);
 }
@@ -64,48 +65,51 @@
 {
     std::ostringstream text;
     
-    DimensionPtr x = DimensionPtr(new DimensionI("X", 32));
+    DimensionPtr x = DimensionPtr(new Dimension("X", 32));
     text << "x coordinate as a long integer.  You must use the scale and "
          << "offset information of the header to determine the double value.";
     x->SetDescription(text.str()); 
     x->IsInteger(true);
     x->IsNumeric(true);
     x->IsSigned(true);
+    x->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(x);
     text.str("");
 
-    DimensionPtr y = DimensionPtr(new DimensionI("Y", 32));
+    DimensionPtr y = DimensionPtr(new Dimension("Y", 32));
     text << "y coordinate as a long integer.  You must use the scale and "
          << "offset information of the header to determine the double value.";
     y->SetDescription(text.str()); 
     y->IsInteger(true);
     y->IsNumeric(true);
     y->IsSigned(true);
+    y->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(y);
     text.str("");
     
-    DimensionPtr z = DimensionPtr(new DimensionI("Z", 32));
+    DimensionPtr z = DimensionPtr(new Dimension("Z", 32));
     text << "z coordinate as a long integer.  You must use the scale and "
          << "offset information of the header to determine the double value.";
     z->SetDescription(text.str()); 
     z->IsInteger(true);
     z->IsNumeric(true);
     z->IsSigned(true);
+    z->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(z);
     text.str("");
 
-    DimensionPtr intensity = DimensionPtr(new DimensionI("Intensity", 16));
-    text << "The intensity value is the integer representation of the pulse" 
+    DimensionPtr intensity = DimensionPtr(new Dimension("Intensity", 16));
+    text << "The intensity value is the integer representation of the pulse " 
             "return magnitude. This value is optional and system specific. "
             "However, it should always be included if available.";
     intensity->SetDescription(text.str());
     intensity->IsInteger(true);
     intensity->IsNumeric(true);
-    
+    intensity->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(intensity);
     text.str("");
 
-    DimensionPtr return_no = DimensionPtr(new DimensionI("Return Number", 3));
+    DimensionPtr return_no = DimensionPtr(new Dimension("Return Number", 3));
     text << "Return Number: The Return Number is the pulse return number for "
             "a given output pulse. A given output laser pulse can have many "
             "returns, and they must be marked in sequence of return. The first "
@@ -114,10 +118,11 @@
     return_no->SetDescription(text.str());
     return_no->IsNumeric(true);
     return_no->IsInteger(true);
+    return_no->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(return_no);
     text.str("");
     
-    DimensionPtr no_returns = DimensionPtr(new DimensionI("Number of Returns", 3));
+    DimensionPtr no_returns = DimensionPtr(new Dimension("Number of Returns", 3));
     text << "Number of Returns (for this emitted pulse): The Number of Returns "
             "is the total number of returns for a given pulse. For example, "
             "a laser data point may be return two (Return Number) within a "
@@ -125,10 +130,11 @@
     no_returns->SetDescription(text.str());
     no_returns->IsNumeric(true);
     no_returns->IsInteger(true);
+    no_returns->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(no_returns);
     text.str("");
     
-    DimensionPtr scan_dir = DimensionPtr(new DimensionI("Scan Direction", 1));
+    DimensionPtr scan_dir = DimensionPtr(new Dimension("Scan Direction", 1));
     text << "The Scan Direction Flag denotes the direction at which the "
             "scanner mirror was traveling at the time of the output pulse. "
             "A bit value of 1 is a positive scan direction, and a bit value "
@@ -138,20 +144,22 @@
     scan_dir->SetDescription(text.str());
     scan_dir->IsNumeric(true);
     scan_dir->IsInteger(true);
+    scan_dir->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(scan_dir);
     text.str("");
     
-    DimensionPtr edge = DimensionPtr(new DimensionI("Flightline Edge", 1));
+    DimensionPtr edge = DimensionPtr(new Dimension("Flightline Edge", 1));
     text << "The Edge of Flight Line data bit has a value of 1 only when "
             "the point is at the end of a scan. It is the last point on "
             "a given scan line before it changes direction.";
     edge->SetDescription(text.str());
     edge->IsNumeric(true);
     edge->IsInteger(true);
+    edge->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(edge);
     text.str("");
 
-    DimensionPtr classification = DimensionPtr(new DimensionI("Classification", 8));
+    DimensionPtr classification = DimensionPtr(new Dimension("Classification", 8));
     text << "Classification in LAS 1.0 was essentially user defined and optional. "
             "LAS 1.1 defines a standard set of ASPRS classifications. In addition, "
             "the field is now mandatory. If a point has never been classified, this "
@@ -161,11 +169,12 @@
             "bit encoded field with the lower five bits used for class and the "
             "three high bits used for flags.";
     classification->SetDescription(text.str());
+    classification->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(classification);
     text.str("");
 
     
-    DimensionPtr scan_angle = DimensionPtr(new DimensionI("Scan Angle Rank", 8));
+    DimensionPtr scan_angle = DimensionPtr(new Dimension("Scan Angle Rank", 8));
     text << "The Scan Angle Rank is a signed one-byte number with a "
             "valid range from -90 to +90. The Scan Angle Rank is the "
             "angle (rounded to the nearest integer in the absolute "
@@ -179,16 +188,18 @@
     scan_angle->IsSigned(true);
     scan_angle->IsInteger(true);
     scan_angle->IsNumeric(true);
+    scan_angle->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(scan_angle);
     text.str("");
     
-    DimensionPtr user_data = DimensionPtr(new DimensionI("User Data", 8));
+    DimensionPtr user_data = DimensionPtr(new Dimension("User Data", 8));
     text << "This field may be used at the user’s discretion";
     user_data->SetDescription(text.str());
+    user_data->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(user_data);
     text.str("");
     
-    DimensionPtr point_source_id = DimensionPtr(new DimensionI("Point Source ID", 16));
+    DimensionPtr point_source_id = DimensionPtr(new Dimension("Point Source ID", 16));
     text << "This value indicates the file from which this point originated. "
             "Valid values for this field are 1 to 65,535 inclusive with zero "
             "being used for a special case discussed below. The numerical value "
@@ -201,6 +212,7 @@
     point_source_id->SetDescription(text.str());
     point_source_id->IsInteger(true);
     point_source_id->IsNumeric(true);
+    point_source_id->SetPosition(m_nextpos); m_nextpos++;
     AddDimension(point_source_id);    
     text.str("");


More information about the Liblas-commits mailing list