liblas-devs,

 

I believe I've isolated a bug that I was having a hard time tracking down. It 
seems to require a fairly narrow set of circumstances for it to appear. The 
particular circumstances that will cause the bug are when you have an existing 
LAS file with a data offset larger than the header size(Such as when you have 
VLRs), but there are zero points in the file. In my particular case, I was 
writing out the header in one method, then populating the points in another 
existing method designed to append points to existing files.(I have sample code 
demonstrating the problem below) In the writer/header.cpp file, at the end of 
the write() method, this block of code appears to be the problem.

 

    if (!bAppendMode) 

    {

        WriteVLRs();

 

        // Write the 1.0 pad signature if we need to.

        WriteLAS10PadSignature(); 

 

    }           

    // If we already have points, we're going to put it at the end of the file. 
 

    // If we don't have any points,  we're going to leave it where it is.

    if (m_pointCount != 0)

        m_ofs.seekp(0, std::ios::end);

 

Before entering this section, the m_ofs stream is positioned at the end of the 
file header. Since the file existed before being opened to write the points, 
the "bAppendMode" variable is true, skipping that block. However, there are no 
points in the file, so the stream position remains unchanged. Any VLRs after 
the header will be overridden when points are added to the file. Later, when 
the header write() method is called when the writer's destructor is called, the 
method uses the file size and data offset to calculate the number of points. 
Because the point data started before the data offset mark, the resulting file 
size is off by the difference between the header size and the offset. This 
results in the number of points reported by the header being changed to a lower 
figure than the number of points you've actually written. For a quick fix here, 
I've add an "else" block locally:

if (m_pointCount != 0)

      {

        m_ofs.seekp(0, std::ios::end);

      }

      else

      {

        m_ofs.seekp(0, m_header.getDataOffset();

      }

 

I used the following code to duplicate the problem. If you comment out the line 
setting the data offset, the resulting file will have 500k points. With that 
line in place, the point count will be 499981.

                

                std::string path( "MyTestFile.las" );

std::fstream out;

      out.open( path.c_str(), std::ios::out | std::ios::binary );

      liblas::LASHeader newHeader;

      newHeader.SetPointRecordsCount( 500000 );

      newHeader.SetDataOffset(759);//Toggle to see the differences

      newHeader.SetDataFormatId( liblas::ePointFormat1 );

      {

            liblas::LASWriter testWriter( out, newHeader );

      }

      liblas::LASWriter test2Writer( out, newHeader);

      for ( size_t i = 0; i < 500000 ; i++ )

      {

            liblas::LASPoint point;

            point.SetCoordinates( 10 + i, 20 + i, 30 + i );

            test2Writer.WritePoint( point );

      }

 

Tim Black

Ball Aerospace

571-357-2158

 




This message and any enclosures are intended only for the addressee.  Please  
notify the sender by email if you are not the intended recipient.  If you are  
not the intended recipient, you may not use, copy, disclose, or distribute this 
 
message or its contents or enclosures to any other person and any such actions  
may be unlawful.  Ball reserves the right to monitor and review all messages  
and enclosures sent to or from this email address.
_______________________________________________
Liblas-devel mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/liblas-devel

Reply via email to