[Liblas-commits] hg-main-tree: SRS bugs all stomped out

liblas-commits at liblas.org liblas-commits at liblas.org
Wed Apr 27 13:51:27 EDT 2011


details:   http://hg.libpc.orghg-main-tree/rev/7ca4284e61a9
changeset: 675:7ca4284e61a9
user:      Michael P. Gerlek <mpg at flaxen.com>
date:      Wed Apr 27 10:51:18 2011 -0700
description:
SRS bugs all stomped out

diffstat:

 include/libpc/drivers/las/VariableLengthRecord.hpp |    5 +-
 src/drivers/las/VariableLengthRecord.cpp           |  167 ++++++++++++--------
 test/unit/SpatialReferenceTest.cpp                 |   18 +-
 3 files changed, 108 insertions(+), 82 deletions(-)

diffs (truncated from 436 to 300 lines):

diff -r 83d65a4a4707 -r 7ca4284e61a9 include/libpc/drivers/las/VariableLengthRecord.hpp
--- a/include/libpc/drivers/las/VariableLengthRecord.hpp	Wed Apr 27 10:58:33 2011 -0500
+++ b/include/libpc/drivers/las/VariableLengthRecord.hpp	Wed Apr 27 10:51:18 2011 -0700
@@ -73,7 +73,8 @@
     };
     static void clearVLRs(GeoVLRType eType, std::vector<VariableLengthRecord>& vlrs);
 
-    bool compareUserId(const std::string& str) const;
+    bool isMatch(const std::string& userId) const;
+    bool isMatch(const std::string& userId, boost::uint16_t recordId) const;
 
     bool operator==(const VariableLengthRecord&) const;
     VariableLengthRecord& operator=(const VariableLengthRecord&);
@@ -86,7 +87,7 @@
     static void setSRSFromVLRs(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs);
     static void setVLRsFromSRS(const SpatialReference& srs, std::vector<VariableLengthRecord>& vlrs);
 
-    static std::string bytes2string(boost::uint8_t* bytes, boost::uint32_t len);
+    static std::string bytes2string(const boost::uint8_t* bytes, boost::uint32_t len);
 
     // bytes array is return, user responsible for deleting
     // len is the size of the array he wants, it will be padded with zeros if str.length() < len
diff -r 83d65a4a4707 -r 7ca4284e61a9 src/drivers/las/VariableLengthRecord.cpp
--- a/src/drivers/las/VariableLengthRecord.cpp	Wed Apr 27 10:58:33 2011 -0500
+++ b/src/drivers/las/VariableLengthRecord.cpp	Wed Apr 27 10:51:18 2011 -0700
@@ -41,6 +41,18 @@
 
 namespace libpc { namespace drivers { namespace las {
 
+static const std::string s_geotiffUserId = "LASF_Projection";
+static const boost::uint16_t s_geotiffRecordId_directory = 34735;
+static const boost::uint16_t s_geotiffRecordId_doubleparams = 34736;
+static const boost::uint16_t s_geotiffRecordId_asciiparams = 34737;
+static const std::string s_geotiffDescriptionId_directory = "GeoTIFF GeoKeyDirectoryTag";
+static const std::string s_geotiffDescriptionId_doubleparams = "GeoTIFF GeoDoubleParamsTag";
+static const std::string s_geotiffDescriptionId_asciiparams = "GeoTIFF GeoAsciiParamsTag";
+        
+static const std::string s_wktUserId = "liblas";
+static const boost::uint16_t s_wktRecordId = 2112;
+static const std::string s_wktDescription = "OGR variant of OpenGIS WKT SRS";
+
 
 VariableLengthRecord::VariableLengthRecord(boost::uint16_t reserved,
                                            std::string userId, 
@@ -78,7 +90,7 @@
 
 VariableLengthRecord::~VariableLengthRecord()
 {
-    delete m_bytes;
+    delete[] m_bytes;
     m_bytes = 0;
     m_length = 0;
     return;
@@ -92,6 +104,7 @@
         m_length = rhs.m_length;
         delete[] m_bytes;
         m_bytes = new boost::uint8_t[m_length];
+        memcpy(m_bytes, rhs.m_bytes, m_length);
 
         m_reserved = rhs.m_reserved;
         m_recordId = rhs.m_recordId;
@@ -122,7 +135,7 @@
 }
 
 
-std::string VariableLengthRecord::bytes2string(boost::uint8_t* bytes, boost::uint32_t len)
+std::string VariableLengthRecord::bytes2string(const boost::uint8_t* bytes, boost::uint32_t len)
 {
     std::string s = "";
     for (boost::uint32_t i=0; i<len; i++)
@@ -160,38 +173,56 @@
 }
 
 
-bool VariableLengthRecord::compareUserId(const std::string& userId) const
+bool VariableLengthRecord::isMatch(const std::string& userId) const
 {
-    const std::string& p = m_userId;
-    const std::string& q = userId;
-           
-    return p==q;
+    return (userId == m_userId);
 }
 
 
-void VariableLengthRecord::setSRSFromVLRs(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs)
+bool VariableLengthRecord::isMatch(const std::string& userId, boost::uint16_t recordId) const
 {
-    if (vlrs.size() == 0)
+    return (userId == m_userId && recordId == m_recordId);
+}
+
+
+static bool setSRSFromVLRs_wkt(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs)
+{
+    for (std::size_t i = 0; i < vlrs.size(); ++i)
     {
-        srs.setWKT("");
-        return;
+        const VariableLengthRecord& vlr = vlrs[i];
+        
+        if (vlr.isMatch(s_wktUserId, s_wktRecordId))
+        {
+            const boost::uint8_t* data = vlr.getBytes();
+            std::size_t length = vlr.getLength();
+
+            const std::string wkt = VariableLengthRecord::bytes2string(data, length);
+            srs.setWKT(wkt);
+            return true;
+        }
     }
 
+    return false;
+}
+
+
+static bool setSRSFromVLRs_geotiff(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs)
+{
     GeotiffSupport geotiff;
 
     geotiff.resetTags();
 
-    const std::string uid("LASF_Projection");
-    
     bool gotSomething = false;
 
+    // first we try to get the 2212 VLR
+
     // nothing is going to happen here if we don't have any vlrs describing
     // srs information on the spatialreference.  
     for (std::size_t i = 0; i < vlrs.size(); ++i)
     {
         const VariableLengthRecord& vlr = vlrs[i];
         
-        if (!vlr.compareUserId(uid))
+        if (!vlr.isMatch(s_geotiffUserId))
             continue;
 
         const boost::uint8_t* datax = vlr.getBytes();
@@ -203,7 +234,7 @@
 
         switch (vlr.getRecordId())
         {
-        case 34735:
+        case s_geotiffRecordId_directory:
             {
                 int count = length / sizeof(short);
                 // discard invalid "zero" geotags some software emits.
@@ -217,23 +248,23 @@
                     data[3] -= 1;
                 }
 
-                geotiff.setKey(34735, count, GeotiffSupport::Geotiff_KeyType_SHORT, data);
+                geotiff.setKey(s_geotiffRecordId_directory, count, GeotiffSupport::Geotiff_KeyType_SHORT, data);
             }
             gotSomething = true;
             break;
 
-        case 34736:
+        case s_geotiffRecordId_doubleparams:
             {
                 int count = length / sizeof(double);
-                geotiff.setKey(34736, count, GeotiffSupport::Geotiff_KeyType_DOUBLE, data);
+                geotiff.setKey(s_geotiffRecordId_doubleparams, count, GeotiffSupport::Geotiff_KeyType_DOUBLE, data);
             }        
             gotSomething = true;
             break;
 
-        case 34737:
+        case s_geotiffRecordId_asciiparams:
             {
                 int count = length/sizeof(uint8_t);
-                geotiff.setKey(34737, count, GeotiffSupport::Geotiff_KeyType_ASCII, data);
+                geotiff.setKey(s_geotiffRecordId_asciiparams, count, GeotiffSupport::Geotiff_KeyType_ASCII, data);
             }
             gotSomething = true;
             break;
@@ -248,8 +279,7 @@
 
     if (!gotSomething)
     {
-        srs.setWKT("");
-        return;
+        return false;
     }
 
     geotiff.setTags();
@@ -258,6 +288,31 @@
 
     srs.setFromUserInput(wkt);
 
+    return true;
+}
+
+
+void VariableLengthRecord::setSRSFromVLRs(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs)
+{
+    srs.setWKT("");
+
+    if (vlrs.size() == 0)
+    {
+        return;
+    }
+
+    bool ok = setSRSFromVLRs_wkt(vlrs, srs);
+    if (ok)
+    {
+        return;
+    }
+
+    ok = setSRSFromVLRs_geotiff(vlrs, srs);
+    if (ok)
+    {
+        return;
+    }
+
     return;
 }
 
@@ -280,22 +335,13 @@
     int acount = 0;
     int atype =0;
 
-    const std::string userId123 = "LASF_Projection";
-    const std::string description1 = "GeoTIFF GeoKeyDirectoryTag";
-    const std::string description2 = "GeoTIFF GeoDoubleParamsTag";
-    const std::string description3 = "GeoTIFF GeoAsciiParamsTag";
-        
-    const std::string userId4 = "liblas";
-    const std::string description4 = "OGR variant of OpenGIS WKT SRS";
-
     GeotiffSupport geotiff;
     {
         const std::string wkt = srs.getWKT(SpatialReference::eCompoundOK, false);
         geotiff.setWkt(wkt);
     }
 
-    //GTIFF_GEOKEYDIRECTORY == 34735
-    ret = geotiff.getKey(34735, &kcount, &ktype, (void**)&kdata);
+    ret = geotiff.getKey(s_geotiffRecordId_directory, &kcount, &ktype, (void**)&kdata);
     if (ret)
     {    
         uint16_t length = 2 * static_cast<uint16_t>(kcount);
@@ -313,12 +359,11 @@
             data.push_back(v[1]);
         }
 
-        VariableLengthRecord record(0, userId123, 34735, description1, &data[0], length);
+        VariableLengthRecord record(0, s_geotiffUserId, s_geotiffRecordId_directory, s_geotiffDescriptionId_directory, &data[0], length);
         vlrs.push_back(record);
     }
 
-    // GTIFF_DOUBLEPARAMS == 34736
-    ret = geotiff.getKey(34736, &dcount, &dtype, (void**)&ddata);
+    ret = geotiff.getKey(s_geotiffRecordId_doubleparams, &dcount, &dtype, (void**)&ddata);
     if (ret)
     {    
         uint16_t length = 8 * static_cast<uint16_t>(dcount);
@@ -342,13 +387,12 @@
             data.push_back(v[7]);   
         }        
 
-        VariableLengthRecord record(0, userId123, 34736, description2, &data[0], length);
+        VariableLengthRecord record(0, s_geotiffUserId, s_geotiffRecordId_doubleparams, s_geotiffDescriptionId_doubleparams, &data[0], length);
 
         vlrs.push_back(record);
     }
     
-    // GTIFF_ASCIIPARAMS == 34737
-    ret = geotiff.getKey(34737, &acount, &atype, (void**)&adata);
+    ret = geotiff.getKey(s_geotiffRecordId_asciiparams, &acount, &atype, (void**)&adata);
     if (ret) 
     {                    
          uint16_t length = static_cast<uint16_t>(acount);
@@ -375,7 +419,7 @@
              data.push_back(v[0]);
          }
 
-         VariableLengthRecord record(0, userId123, 34737, description3, &data[0], length);
+         VariableLengthRecord record(0, s_geotiffUserId, s_geotiffRecordId_asciiparams, s_geotiffDescriptionId_asciiparams, &data[0], length);
 
 
         if (data.size() > (std::numeric_limits<boost::uint16_t>::max()))
@@ -412,7 +456,7 @@
             throw std::runtime_error(oss.str()); 
         }
 
-        VariableLengthRecord wkt_record(0, userId4, 2112, description4, wkt_bytes, len);
+        VariableLengthRecord wkt_record(0, s_wktUserId, s_wktRecordId, s_wktDescription, wkt_bytes, len);
 
         vlrs.push_back( wkt_record );
     }
@@ -424,22 +468,20 @@
 void VariableLengthRecord::clearVLRs(GeoVLRType eType, std::vector<VariableLengthRecord>& vlrs)
 {
     std::vector<VariableLengthRecord>::iterator it;
-    std::string const liblas_id("liblas");
     
     for (it = vlrs.begin(); it != vlrs.end(); )
     {


More information about the Liblas-commits mailing list