[Liblas-commits] r1326 - in trunk: include/liblas
include/liblas/capi python/liblas python/tests src src/detail
liblas-commits at liblas.org
liblas-commits at liblas.org
Tue Jul 28 22:52:39 EDT 2009
Author: hobu
Date: Tue Jul 28 22:52:35 2009
New Revision: 1326
URL: http://liblas.org/changeset/1326
Log:
fix #142 to handle the case where the recordlength does not actually match a the size defined by the point format
Modified:
trunk/include/liblas/capi/liblas.h
trunk/include/liblas/lasheader.hpp
trunk/python/liblas/core.py
trunk/python/liblas/header.py
trunk/python/tests/Header.txt
trunk/src/detail/reader10.cpp
trunk/src/detail/reader11.cpp
trunk/src/detail/reader12.cpp
trunk/src/las_c_api.cpp
trunk/src/lasheader.cpp
Modified: trunk/include/liblas/capi/liblas.h
==============================================================================
--- trunk/include/liblas/capi/liblas.h (original)
+++ trunk/include/liblas/capi/liblas.h Tue Jul 28 22:52:35 2009
@@ -660,6 +660,14 @@
*/
LAS_DLL uint16_t LASHeader_GetDataRecordLength(const LASHeaderH hHeader);
+/** Explicitly set the record length for the file. If you set the DataFormatId,
+ * default values will be set for you.
+ * @param hHeader LASHeaderH instance
+ * @param value the value for the data record length (in bytes).
+ * @return LASError enum
+*/
+LAS_DLL LASError LASHeader_SetDataRecordLength(const LASHeaderH hHeader, uint16_t value);
+
/** Returns the data format id. If this value is 1, the point data have time values
* associated with them. If it is 0, the point data do not have time values.
* @param hHeader LASHeaderH instance
Modified: trunk/include/liblas/lasheader.hpp
==============================================================================
--- trunk/include/liblas/lasheader.hpp (original)
+++ trunk/include/liblas/lasheader.hpp Tue Jul 28 22:52:35 2009
@@ -249,6 +249,11 @@
/// \todo To be documented
uint16_t GetDataRecordLength() const;
+
+ /// Set the length of the point format. Evidently, there are
+ /// LAS files in the wild that contain point formats of sizes that
+ /// are different than the prescribed set specified in the specification.
+ void SetDataRecordLength(uint16_t v);
/// Get total number of point records stored in the LAS file.
uint32_t GetPointRecordsCount() const;
Modified: trunk/python/liblas/core.py
==============================================================================
--- trunk/python/liblas/core.py (original)
+++ trunk/python/liblas/core.py Tue Jul 28 22:52:35 2009
@@ -378,6 +378,10 @@
las.LASHeader_GetDataRecordLength.argtypes = [ctypes.c_void_p]
las.LASHeader_GetDataRecordLength.errcheck = check_value
+las.LASHeader_SetDataRecordLength.restype = ctypes.c_int
+las.LASHeader_SetDataRecordLength.argtypes = [ctypes.c_void_p, ctypes.c_ushort]
+las.LASHeader_SetDataRecordLength.errcheck = check_return
+
las.LASHeader_GetPointRecordsCount.restype = ctypes.c_ulong
las.LASHeader_GetPointRecordsCount.argtypes = [ctypes.c_void_p]
las.LASHeader_GetPointRecordsCount.errcheck = check_value
Modified: trunk/python/liblas/header.py
==============================================================================
--- trunk/python/liblas/header.py (original)
+++ trunk/python/liblas/header.py Tue Jul 28 22:52:35 2009
@@ -220,7 +220,11 @@
def get_datarecordlength(self):
return core.las.LASHeader_GetDataRecordLength(self.handle)
- data_record_length = property(get_datarecordlength)
+ def set_datarecordlength(self, value):
+ """Don't use this if ya know what's good for ya ;)
+ """
+ return core.las.LASHeader_SetDataRecordLength(self.handle, value)
+ data_record_length = property(get_datarecordlength, set_datarecordlength)
def get_pointrecordscount(self):
"""Returns the expected number of point records in the file.
Modified: trunk/python/tests/Header.txt
==============================================================================
--- trunk/python/tests/Header.txt (original)
+++ trunk/python/tests/Header.txt Tue Jul 28 22:52:35 2009
@@ -113,3 +113,12 @@
>>> h.data_offset
742L
+ >>> h.data_record_length
+ 20
+ >>> h.dataformat_id = 3
+ >>> h.data_record_length
+ 34
+
+ >>> h.data_record_length = 24
+ >>> h.data_record_length
+ 24
Modified: trunk/src/detail/reader10.cpp
==============================================================================
--- trunk/src/detail/reader10.cpp (original)
+++ trunk/src/detail/reader10.cpp Tue Jul 28 22:52:35 2009
@@ -168,9 +168,8 @@
}
// 17. Point Data Record Length
- // NOTE: No need to set record length because it's
- // determined on basis of point data format.
read_n(n2, m_ifs, sizeof(n2));
+ header.SetDataRecordLength(n2);
// 18. Number of point records
read_n(n4, m_ifs, sizeof(n4));
@@ -227,6 +226,10 @@
if (m_current < m_size)
{
+ // accounting to keep track of the fact that the DataRecordLength
+ // might not map to ePointSize0 or ePointSize1 (see http://liblas.org/ticket/142)
+ size_t bytesread = 0;
+
detail::PointRecord record;
// TODO: Replace with compile-time assert
assert(LASHeader::ePointSize0 == sizeof(record));
@@ -234,7 +237,8 @@
try
{
detail::read_n(record, m_ifs, sizeof(PointRecord));
- ++m_current;
+ ++m_current;
+ bytesread += sizeof(PointRecord);
}
catch (std::out_of_range const& e) // we reached the end of the file
{
@@ -251,7 +255,10 @@
detail::read_n(gpst, m_ifs, sizeof(double));
point.SetTime(gpst);
+ bytesread += sizeof(double);
}
+ if (bytesread != header.GetDataRecordLength())
+ m_ifs.seekg(header.GetDataRecordLength() - bytesread, std::ios::cur);
return true;
}
@@ -271,9 +278,15 @@
// TODO: Replace with compile-time assert
detail::PointRecord record;
assert(LASHeader::ePointSize0 == sizeof(record));
+
+ // accounting to keep track of the fact that the DataRecordLength
+ // might not map to ePointSize0 or ePointSize1 (see http://liblas.org/ticket/142)
+ size_t bytesread = 0;
detail::read_n(record, m_ifs, sizeof(record));
+ bytesread += sizeof(PointRecord);
+
Reader::FillPoint(record, point);
point.SetCoordinates(header, point.GetX(), point.GetY(), point.GetZ());
@@ -282,8 +295,12 @@
double gpst(0);
detail::read_n(gpst, m_ifs, sizeof(double));
point.SetTime(gpst);
+ bytesread += sizeof(double);
}
+ if (bytesread != header.GetDataRecordLength())
+ m_ifs.seekg(header.GetDataRecordLength() - bytesread, std::ios::cur);
+
return true;
}
Modified: trunk/src/detail/reader11.cpp
==============================================================================
--- trunk/src/detail/reader11.cpp (original)
+++ trunk/src/detail/reader11.cpp Tue Jul 28 22:52:35 2009
@@ -172,9 +172,8 @@
}
// 18. Point Data Record Length
- // NOTE: No need to set record length because it's
- // determined on basis of point data format.
read_n(n2, m_ifs, sizeof(n2));
+ header.SetDataRecordLength(n2);
// 19. Number of point records
read_n(n4, m_ifs, sizeof(n4));
@@ -231,6 +230,8 @@
if (m_current < m_size)
{
+ size_t bytesread = 0;
+
detail::PointRecord record;
// TODO: Replace with compile-time assert
assert(LASHeader::ePointSize0 == sizeof(record));
@@ -238,7 +239,8 @@
try
{
detail::read_n(record, m_ifs, sizeof(PointRecord));
- ++m_current;
+ ++m_current;
+ bytesread += sizeof(PointRecord);
}
catch (std::out_of_range const& e) // we reached the end of the file
{
@@ -254,8 +256,12 @@
double gpst = 0;
detail::read_n(gpst, m_ifs, sizeof(double));
point.SetTime(gpst);
+ bytesread += sizeof(double);
}
+ if (bytesread != header.GetDataRecordLength())
+ m_ifs.seekg(header.GetDataRecordLength() - bytesread, std::ios::cur);
return true;
+
}
return false;
@@ -272,11 +278,17 @@
m_ifs.clear();
m_ifs.seekg(pos, std::ios::beg);
+
+ // accounting to keep track of the fact that the DataRecordLength
+ // might not map to ePointSize0 or ePointSize1 (see http://liblas.org/ticket/142)
+ size_t bytesread = 0;
+
detail::PointRecord record;
// TODO: Replace with compile-time assert
assert(LASHeader::ePointSize0 == sizeof(record));
detail::read_n(record, m_ifs, sizeof(record));
+ bytesread += sizeof(PointRecord);
Reader::FillPoint(record, point);
point.SetCoordinates(header, point.GetX(), point.GetY(), point.GetZ());
@@ -286,8 +298,11 @@
double gpst = 0;
detail::read_n(gpst, m_ifs, sizeof(double));
point.SetTime(gpst);
+ bytesread += sizeof(double);
}
+ if (bytesread != header.GetDataRecordLength())
+ m_ifs.seekg(header.GetDataRecordLength() - bytesread, std::ios::cur);
return true;
}
Modified: trunk/src/detail/reader12.cpp
==============================================================================
--- trunk/src/detail/reader12.cpp (original)
+++ trunk/src/detail/reader12.cpp Tue Jul 28 22:52:35 2009
@@ -174,9 +174,8 @@
}
// 18. Point Data Record Length
- // NOTE: No need to set record length because it's
- // determined on basis of point data format.
read_n(n2, m_ifs, sizeof(n2));
+ header.SetDataRecordLength(n2);
// 19. Number of point records
read_n(n4, m_ifs, sizeof(n4));
@@ -233,6 +232,8 @@
if (m_current < m_size)
{
+ size_t bytesread = 0;
+
detail::PointRecord record;
// TODO: Replace with compile-time assert
assert(LASHeader::ePointSize0 == sizeof(record));
@@ -240,7 +241,8 @@
try
{
detail::read_n(record, m_ifs, sizeof(PointRecord));
- ++m_current;
+ ++m_current;
+ bytesread += sizeof(PointRecord);
}
catch (std::out_of_range const& e) // we reached the end of the file
{
@@ -260,6 +262,8 @@
{
detail::read_n(gpst, m_ifs, sizeof(double));
point.SetTime(gpst);
+
+ bytesread += sizeof(double);
}
else if (header.GetDataFormatId() == LASHeader::ePointFormat2)
{
@@ -269,6 +273,8 @@
LASColor color(red, green, blue);
point.SetColor(color);
+
+ bytesread += 3 * sizeof(uint16_t);
}
else if (header.GetDataFormatId() == LASHeader::ePointFormat3)
{
@@ -281,8 +287,13 @@
LASColor color(red, green, blue);
point.SetColor(color);
+
+ bytesread += sizeof(double) + 3 * sizeof(uint16_t);
}
+ if (bytesread != header.GetDataRecordLength())
+ m_ifs.seekg(header.GetDataRecordLength() - bytesread, std::ios::cur);
+
return true;
}
@@ -313,8 +324,14 @@
m_ifs.clear();
m_ifs.seekg(pos, std::ios::beg);
+
+ // accounting to keep track of the fact that the DataRecordLength
+ // might not map to ePointSize0 or ePointSize1 (see http://liblas.org/ticket/142)
+ size_t bytesread = 0;
detail::read_n(record, m_ifs, sizeof(record));
+ bytesread += sizeof(PointRecord);
+
Reader::FillPoint(record, point);
point.SetCoordinates(header, point.GetX(), point.GetY(), point.GetZ());
@@ -322,6 +339,8 @@
{
detail::read_n(t, m_ifs, sizeof(double));
point.SetTime(t);
+
+ bytesread += sizeof(double);
}
else if (header.GetDataFormatId() == LASHeader::ePointFormat2)
{
@@ -332,6 +351,8 @@
color.SetBlue(blue);
color.SetGreen(green);
point.SetColor(color);
+
+ bytesread += 3 * sizeof(uint16_t);
}
else if (header.GetDataFormatId() == LASHeader::ePointFormat3)
{
@@ -344,6 +365,8 @@
color.SetBlue(blue);
color.SetGreen(green);
point.SetColor(color);
+
+ bytesread += sizeof(double) + 3 * sizeof(uint16_t);
}
Modified: trunk/src/las_c_api.cpp
==============================================================================
--- trunk/src/las_c_api.cpp (original)
+++ trunk/src/las_c_api.cpp Tue Jul 28 22:52:35 2009
@@ -934,6 +934,20 @@
return value;
}
+LAS_DLL LASErrorEnum LASHeader_SetDataRecordLength(const LASHeaderH hHeader, liblas::uint16_t value){
+ VALIDATE_LAS_POINTER1(hHeader, "LASHeader_SetDataRecordLength", LE_Failure);
+
+ try {
+ ((LASHeader*) hHeader)->SetDataRecordLength(value);
+ } catch (std::exception const& e)
+ {
+ LASError_PushError(LE_Failure, e.what(), "LASHeader_SetDataRecordLength");
+ return LE_Failure;
+ }
+
+ return LE_None;
+}
+
LAS_DLL liblas::uint32_t LASHeader_GetPointRecordsByReturnCount(const LASHeaderH hHeader, int index) {
VALIDATE_LAS_POINTER1(hHeader, "LASHeader_GetPointRecordsByReturnCount", 0);
Modified: trunk/src/lasheader.cpp
==============================================================================
--- trunk/src/lasheader.cpp (original)
+++ trunk/src/lasheader.cpp Tue Jul 28 22:52:35 2009
@@ -394,44 +394,26 @@
m_dataFormatId = static_cast<uint8_t>(v);
if (ePointFormat0 == m_dataFormatId)
- m_dataRecordLen = ePointSize0;
+ SetDataRecordLength(ePointSize0);
else if (ePointFormat1 == m_dataFormatId)
- m_dataRecordLen = ePointSize1;
+ SetDataRecordLength(ePointSize1);
else if (ePointFormat2 == m_dataFormatId)
- m_dataRecordLen = ePointSize2;
+ SetDataRecordLength(ePointSize2);
else if (ePointFormat3 == m_dataFormatId)
- m_dataRecordLen = ePointSize3;
+ SetDataRecordLength(ePointSize3);
else
- m_dataRecordLen = ePointSize3;
+ SetDataRecordLength(ePointSize3);
}
uint16_t LASHeader::GetDataRecordLength() const
{
- // NOTE: assertions below are used to check if our assumption is correct,
- // for debugging purpose only.
-
- if (ePointFormat0 == m_dataFormatId)
- {
- assert(ePointSize0 == m_dataRecordLen);
- return ePointSize0;
- }
- if (ePointFormat1 == m_dataFormatId)
- {
- assert(ePointSize1 == m_dataRecordLen);
- return ePointSize1;
- }
- if (ePointFormat2 == m_dataFormatId)
- {
- assert(ePointSize2 == m_dataRecordLen);
- return ePointSize2;
- }
- else
- {
- assert(ePointSize3 == m_dataRecordLen);
- return ePointSize3;
- }
+ return m_dataRecordLen;
}
+void LASHeader::SetDataRecordLength( uint16_t v )
+{
+ m_dataRecordLen = v;
+}
uint32_t LASHeader::GetPointRecordsCount() const
{
return m_pointRecordsCount;
More information about the Liblas-commits
mailing list