[Liblas-commits] hg: enable Seek and ReadAt, though slowly

liblas-commits at liblas.org liblas-commits at liblas.org
Wed Jan 5 11:23:23 EST 2011


details:   http://hg.liblas.orghg/rev/52f6184926f8
changeset: 2688:52f6184926f8
user:      Michael P. Gerlek <mpg at flaxen.com>
date:      Wed Jan 05 08:18:43 2011 -0800
description:
enable Seek and ReadAt, though slowly
Subject: hg: added disclaimer

details:   http://hg.liblas.orghg/rev/2eb36567790c
changeset: 2689:2eb36567790c
user:      Michael P. Gerlek <mpg at flaxen.com>
date:      Wed Jan 05 08:22:59 2011 -0800
description:
added disclaimer
Subject: hg: pull-merge

details:   http://hg.liblas.orghg/rev/439c024e009f
changeset: 2690:439c024e009f
user:      Michael P. Gerlek <mpg at flaxen.com>
date:      Wed Jan 05 08:23:09 2011 -0800
description:
pull-merge

diffstat:

 apps/lasblock.cpp                          |  41 ++++++------
 include/liblas/detail/reader/zipreader.hpp |   8 ++-
 src/detail/reader/zipreader.cpp            |  97 ++++++++++++++++++++++-------
 test/unit/zipreader_test.cpp               |  78 ++++++++++++++++++-----
 4 files changed, 159 insertions(+), 65 deletions(-)

diffs (truncated from 354 to 300 lines):

diff -r 86ba5e9da0dd -r 439c024e009f apps/lasblock.cpp
--- a/apps/lasblock.cpp	Tue Jan 04 15:39:40 2011 -0800
+++ b/apps/lasblock.cpp	Wed Jan 05 08:23:09 2011 -0800
@@ -102,35 +102,34 @@
     
     for ( boost::uint32_t i = 0; i < c.GetBlockCount(); ++i )
     {
-        OStreamPtr ofs(new std::ofstream);
-        SummaryPtr summary(new::liblas::CoordinateSummary);
-
         std::ostringstream name;
         name << out << "-" << i <<".las";
+        SummaryPtr summary(new::liblas::CoordinateSummary);        
 
-        const liblas::chipper::Block& b = c.GetBlock(i);
-        header.SetExtent(b.GetBounds());
+        {
+            OStreamPtr ofs(new std::ofstream);
 
-        WriterPtr writer = start_writer(ofs, name.str(), header);
+            const liblas::chipper::Block& b = c.GetBlock(i);
+            header.SetExtent(b.GetBounds());
+        
+            WriterPtr writer = start_writer(ofs, name.str(), header);
 
+            std::vector<boost::uint32_t> ids = b.GetIDs();
         
+        
+            for ( boost::uint32_t pi = 0; pi < ids.size(); ++pi )
+            {
+            
+                bool read = reader.ReadPointAt(ids[pi]);
+                if (read) {
+                    liblas::Point const& p = reader.GetPoint();
+                    summary->AddPoint(p);
+                    writer->WritePoint(p);
+                }
+            }
 
-        std::vector<boost::uint32_t> ids = b.GetIDs();
-        
-        
-        for ( boost::uint32_t pi = 0; pi < ids.size(); ++pi )
-        {
-            bool read = reader.ReadPointAt(pi);
-            if (read) {
-                liblas::Point const& p = reader.GetPoint();
-                summary->AddPoint(p);
-                writer->WritePoint(p);
-            }
+            
         }
-
-
-        writer = WriterPtr();
-        ofs = OStreamPtr();
         
         liblas::Header hnew = FetchHeader(name.str());
         RepairHeader(*summary, hnew);
diff -r 86ba5e9da0dd -r 439c024e009f include/liblas/detail/reader/zipreader.hpp
--- a/include/liblas/detail/reader/zipreader.hpp	Tue Jan 04 15:39:40 2011 -0800
+++ b/include/liblas/detail/reader/zipreader.hpp	Wed Jan 05 08:23:09 2011 -0800
@@ -72,6 +72,11 @@
     void SetHeader(liblas::Header const& header);
     liblas::Point const& GetPoint() const { return *m_point; }
     void ReadNextPoint();
+
+    // Warning: seeking is not supporting in the laszip format, so 
+    // ReadPointAt() and Seek() are implemented to rewind to the 
+    // beginning of the file and read through all the N-1 previous
+    // point first.  That is, these functions are SLOW.
     liblas::Point const& ReadPointAt(std::size_t n);
     void Seek(std::size_t n);
     
@@ -101,7 +106,8 @@
     std::vector<liblas::TransformPtr> m_transforms;
 
 private:
-    void ReadIdiom();
+    void ReadIdiom(bool recordPoint);
+    void ResetUnzipper();
 
     LASunzipper* m_unzipper;
     ZipPoint* m_zipPoint;
diff -r 86ba5e9da0dd -r 439c024e009f src/detail/reader/zipreader.cpp
--- a/src/detail/reader/zipreader.cpp	Tue Jan 04 15:39:40 2011 -0800
+++ b/src/detail/reader/zipreader.cpp	Wed Jan 05 08:23:09 2011 -0800
@@ -194,7 +194,7 @@
     m_header = HeaderPtr(new liblas::Header(header));
 }
     
-void ZipReaderImpl::ReadIdiom()
+void ZipReaderImpl::ReadIdiom(bool recordPoint)
 {
     //////m_point_reader->read();
     //////++m_current;
@@ -214,15 +214,20 @@
         throw liblas_error("Error reading compressed point data (2)");
     }
 
-    std::vector<boost::uint8_t> v(m_zipPoint->m_lz_point_size);
-    for (unsigned int i=0; i<m_zipPoint->m_lz_point_size; i++)
+    if (recordPoint)
     {
-        v[i] = m_zipPoint->m_lz_point_data[i];
-        //printf("%d %d\n", v[i], i);
+        std::vector<boost::uint8_t> v(m_zipPoint->m_lz_point_size);
+        for (unsigned int i=0; i<m_zipPoint->m_lz_point_size; i++)
+        {
+            v[i] = m_zipPoint->m_lz_point_data[i];
+            //printf("%d %d\n", v[i], i);
+        }
+        m_point->SetData(v);
+
+        ++m_current;
     }
-    m_point->SetData(v);
 
-    ++m_current;
+    return;
 }
 
 void ZipReaderImpl::ReadNextPoint()
@@ -237,7 +242,7 @@
         throw std::out_of_range("ReadNextPoint: file has no more points to read, end of file reached");
     } 
 
-    ReadIdiom();    
+    ReadIdiom(true);
 
     // Filter the points and continue reading until we either find 
     // one to keep or throw an exception.
@@ -245,11 +250,11 @@
     bool bLastPoint = false;
     if (!FilterPoint(*m_point))
     {
-        ReadIdiom();
+        ReadIdiom(true);
 
         while (!FilterPoint(*m_point))
         {
-            ReadIdiom();
+            ReadIdiom(true);
             if (m_current == m_size) 
             {
                 bLastPoint = true;
@@ -258,7 +263,6 @@
         }
     }
 
-
     if (!m_transforms.empty())
     {
         TransformPoint(*m_point);
@@ -270,6 +274,34 @@
 
 }
 
+
+// laszip doesn't support seeking, or any want to do a reset, so we do it manually instead
+void ZipReaderImpl::ResetUnzipper()
+{
+    PointFormatName format = m_header->GetDataFormatId();
+
+    if (!m_unzipper)
+        throw liblas_error("Error resetting uncompression engine (1)");
+ 
+    unsigned int stat = 1;
+    try
+    {
+        m_unzipper->close();
+        stat = m_unzipper->open(m_ifs, m_zipPoint->m_num_items, m_zipPoint->m_items, LASzip::COMPRESSION_DEFAULT);
+    }
+    catch(...)
+    {
+        throw liblas_error("Error resetting uncompression engine (2)");
+    }
+    if (stat != 0)
+    {
+        throw liblas_error("Error resetting uncompression engine (3)");
+    }
+
+    return;
+}
+
+
 liblas::Point const& ZipReaderImpl::ReadPointAt(std::size_t n)
 {
     if (m_size == n) {
@@ -280,27 +312,36 @@
         throw std::runtime_error(msg.str());
     } 
 
-    if (n!=0)
-    {
-        throw not_yet_implemented("not yet implemented");
-    }
-
-    std::streamsize const pos = /*(static_cast<std::streamsize>(n) * m_header->GetDataRecordLength()) +*/ m_header->GetDataOffset();    
+    std::streamsize const pos = m_header->GetDataOffset();    
 
     m_ifs.clear();
     m_ifs.seekg(pos, std::ios::beg);
 
-    ReadIdiom();
-    --m_current; // undo what was done in Idiom
+    ResetUnzipper();
+
+    // skip over a whole bunch
+    if (n > 0)
+    {
+        for (std::size_t idx = 0; idx < n; idx++)
+        {
+            ReadIdiom(false);
+        }
+    }
+
+    // read the one we want (and undo the counter update)
+    ReadIdiom(true);
+    --m_current;
 
     if (!m_transforms.empty())
     {
         std::cout << "Should be transforming point" << std::endl;
         TransformPoint(*m_point);
     }
+
     return *m_point;
 }
 
+
 void ZipReaderImpl::Seek(std::size_t n)
 {
     if (m_size == n) {
@@ -311,16 +352,22 @@
         throw std::runtime_error(msg.str());
     } 
 
-    if (n!=0)
-    {
-        throw not_yet_implemented("not yet implemented");
-    }
-
-    std::streamsize pos = /*(static_cast<std::streamsize>(n) * m_header->GetDataRecordLength()) +*/ m_header->GetDataOffset();    
+    std::streamsize pos = m_header->GetDataOffset();    
 
     m_ifs.clear();
     m_ifs.seekg(pos, std::ios::beg);
     
+    ResetUnzipper();
+
+    // skip over a whole bunch
+    if (n > 0)
+    {
+        for (std::size_t idx = 0; idx < n; idx++)
+        {
+            ReadIdiom(false);
+        }
+    }
+
     m_current = n;
 }
 
diff -r 86ba5e9da0dd -r 439c024e009f test/unit/zipreader_test.cpp
--- a/test/unit/zipreader_test.cpp	Tue Jan 04 15:39:40 2011 -0800
+++ b/test/unit/zipreader_test.cpp	Wed Jan 05 08:23:09 2011 -0800
@@ -110,27 +110,69 @@
         liblas::Reader reader_las = factory.CreateWithStream(ifs_las);
         liblas::Reader reader_laz = factory.CreateWithStream(ifs_laz);
 
-        reader_las.ReadNextPoint();
-        liblas::Point p0_las = reader_las.GetPoint();
-        reader_las.ReadNextPoint();
-        liblas::Point p1_las = reader_las.GetPoint();
-        reader_las.ReadNextPoint();
-        liblas::Point p2_las = reader_las.GetPoint();
+        // test ReadPointAt()
+        {
+            reader_las.ReadPointAt(2);
+            liblas::Point p2_las = reader_las.GetPoint();
+            reader_las.ReadPointAt(1);
+            liblas::Point p1_las = reader_las.GetPoint();
+            reader_las.ReadPointAt(0);
+            liblas::Point p0_las = reader_las.GetPoint();
 
-        //reader_laz.ReadPointAt(2);
-        //liblas::Point p2_laz = reader_laz.GetPoint();
-        //reader_laz.ReadPointAt(1);
-        //liblas::Point p1_laz = reader_laz.GetPoint();
-        reader_laz.ReadPointAt(0);
-        liblas::Point p0_laz = reader_laz.GetPoint();
+            test_file_12Color_point0(p0_las);
+            test_file_12Color_point1(p1_las);
+            test_file_12Color_point2(p2_las);
+
+            reader_laz.ReadPointAt(2);
+            liblas::Point p2_laz = reader_laz.GetPoint();
+            reader_laz.ReadPointAt(1);
+            liblas::Point p1_laz = reader_laz.GetPoint();
+            reader_laz.ReadPointAt(0);


More information about the Liblas-commits mailing list