From a5500a9ea0dedfa15e7712ec0a85d797892387c6 Mon Sep 17 00:00:00 2001 From: Howard Butler Date: Thu, 10 May 2012 14:01:25 -0500 Subject: [PATCH] support setting data record lengths for LAS that are not just the fixed set defined by the point formats --- include/pdal/drivers/las/Header.hpp | 3 +- include/pdal/drivers/las/Writer.hpp | 1 + src/drivers/las/Header.cpp | 20 +++++++---- src/drivers/las/Writer.cpp | 56 +++++++++++++++++------------ 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/include/pdal/drivers/las/Header.hpp b/include/pdal/drivers/las/Header.hpp index 9496b892ff..9acf6ca6d4 100644 --- a/include/pdal/drivers/las/Header.hpp +++ b/include/pdal/drivers/las/Header.hpp @@ -238,6 +238,7 @@ class PDAL_DLL LasHeader /// available for the file in the form of a liblas.org VLR schema record, /// These extra bytes are available via liblas::Point::GetExtraData(). boost::uint16_t GetDataRecordLength() const; + void SetDataRecordLength(boost::uint16_t v); /// Get total number of point records stored in the LAS file. boost::uint32_t GetPointRecordsCount() const; @@ -380,7 +381,7 @@ class PDAL_DLL LasHeader PointOffsets m_offsets; bool m_isCompressed; boost::uint32_t m_headerPadding; - + boost::uint16_t m_dataRecordLength; PointFormat m_pointFormat; Bounds m_bounds; diff --git a/include/pdal/drivers/las/Writer.hpp b/include/pdal/drivers/las/Writer.hpp index b7933188c0..801967d34d 100644 --- a/include/pdal/drivers/las/Writer.hpp +++ b/include/pdal/drivers/las/Writer.hpp @@ -113,6 +113,7 @@ class PDAL_DLL Writer : public pdal::Writer bool m_headerInitialized; boost::uint64_t m_streamOffset; // the first byte of the LAS file + void setOptions(); Writer& operator=(const Writer&); // not implemented Writer(const Writer&); // not implemented diff --git a/src/drivers/las/Header.cpp b/src/drivers/las/Header.cpp index 9144ba8f68..b4254736ba 100644 --- a/src/drivers/las/Header.cpp +++ b/src/drivers/las/Header.cpp @@ -260,13 +260,23 @@ pdal::drivers::las::PointFormat LasHeader::getPointFormat() const void LasHeader::setPointFormat(pdal::drivers::las::PointFormat v) { + pdal::drivers::las::PointFormat old = m_pointFormat; + boost::uint16_t oldpad = m_dataRecordLength - Support::getPointDataSize(old); m_pointFormat = v; + m_dataRecordLength = Support::getPointDataSize(v) + oldpad; } +void LasHeader::SetDataRecordLength(boost::uint16_t v) +{ + boost::uint16_t requiredsize = Support::getPointDataSize(m_pointFormat); + if (requiredsize < v) + throw std::invalid_argument("record size too small to hold current point format required size"); + m_dataRecordLength = v; +} boost::uint16_t LasHeader::GetDataRecordLength() const { - // No matter what the schema says, this must be a short in size. - return pdal::drivers::las::Support::getPointDataSize(m_pointFormat); + return m_dataRecordLength; + //return pdal::drivers::las::Support::getPointDataSize(m_pointFormat); } boost::uint32_t LasHeader::GetPointRecordsCount() const @@ -406,24 +416,22 @@ void LasHeader::initialize() std::memset(m_signature, 0, eFileSignatureSize); std::strncpy(m_signature, FileSignature, eFileSignatureSize); -// m_signature = Header::FileSignature; std::memset(m_systemId, 0, eSystemIdSize); std::strncpy(m_systemId, SystemIdentifier, eSystemIdSize); -// m_systemId = Header::SystemIdentifier; std::memset(m_softwareId, 0, eSoftwareIdSize); std::strncpy(m_softwareId, SoftwareIdentifier, eSoftwareIdSize); -// m_softwareId = Header::SoftwareIdentifier; m_pointRecordsByReturn.resize(ePointsByReturnSize); // Zero scale value is useless, so we need to use a small value. - SetScale(0.01, 0.01, 0.01); + SetScale(1.0, 1.0, 1.0); m_isCompressed = false; m_headerPadding = 0; m_compressionInfo = std::string(""); + m_dataRecordLength = Support::getPointDataSize(m_pointFormat); } diff --git a/src/drivers/las/Writer.cpp b/src/drivers/las/Writer.cpp index 8c483598b9..c6ebf17690 100644 --- a/src/drivers/las/Writer.cpp +++ b/src/drivers/las/Writer.cpp @@ -63,30 +63,11 @@ Writer::Writer(Stage& prevStage, const Options& options) , m_headerInitialized(false) , m_streamOffset(0) { - setGeneratingSoftware(options.getValueOrDefault("software_id", LasHeader::SoftwareIdentifier)); - setDate((boost::uint16_t)options.getValueOrDefault("creation_year", 0), - (boost::uint16_t)options.getValueOrDefault("creation_doy", 0)); - setPointFormat(static_cast(options.getValueOrDefault("format", 3))); - setSystemIdentifier(options.getValueOrDefault("system_id", LasHeader::SystemIdentifier)); - - setHeaderPadding(options.getValueOrDefault("header_padding", 0)); - - if (options.hasOption("a_srs")) - { - setSpatialReference(options.getValueOrDefault("a_srs","")); - } - setCompressed(options.getValueOrDefault("compression", false)); - - return; + setOptions(); + return; } - -Writer::Writer(Stage& prevStage, std::ostream* ostream) - : pdal::Writer(prevStage, Options::none()) - , m_streamManager(ostream) - , m_numPointsWritten(0) - , m_headerInitialized(false) - , m_streamOffset(0) +void Writer::setOptions() { setGeneratingSoftware(getOptions().getValueOrDefault("software_id", LasHeader::SoftwareIdentifier)); setDate((boost::uint16_t)getOptions().getValueOrDefault("year", 0), @@ -100,7 +81,24 @@ Writer::Writer(Stage& prevStage, std::ostream* ostream) setSpatialReference(getOptions().getValueOrDefault("a_srs","")); } setCompressed(getOptions().getValueOrDefault("compression", false)); - return; + m_lasHeader.SetFileSourceId(getOptions().getValueOrDefault("filesourceid", 0)); + try + { + boost::uint16_t record_length = getOptions().getValueOrThrow("datarecordlength"); + m_lasHeader.SetDataRecordLength(record_length); + } catch (pdal::option_not_found&) {}; + + +} +Writer::Writer(Stage& prevStage, std::ostream* ostream) + : pdal::Writer(prevStage, Options::none()) + , m_streamManager(ostream) + , m_numPointsWritten(0) + , m_headerInitialized(false) + , m_streamOffset(0) +{ + setOptions(); + return; } @@ -138,6 +136,7 @@ const Options Writer::getDefaultOptions() const Option year("creation_year", 2011, "4-digit year value for file"); Option system_id("system_id", LasHeader::SystemIdentifier, "System ID for this file"); Option software_id("software_id", LasHeader::SoftwareIdentifier, "Software ID for this file"); + Option filesourceid("filesourceid", 0, "File Source ID for this file"); Option header_padding("header_padding", 0, "Header padding (space between end of VLRs and beginning of point data)"); Option set_metadata("forward_metadata", false, "forward metadata into the file as necessary"); @@ -315,6 +314,17 @@ void Writer::writeBufferBegin(PointBuffer const& data) << "from metadata" << std::endl; } catch (std::bad_cast&) {} } + boost::optional filesourceid = metadata.getEntryOptional("filesourceid"); + if (filesourceid && useMetadata) + { + try + { + m_lasHeader.SetFileSourceId(filesourceid->cast()); + log()->get(logDEBUG) << "Setting file source id to " + << filesourceid->cast() + << "from metadata" << std::endl; + } catch (std::bad_cast&) {} + } LasHeaderWriter lasHeaderWriter(m_lasHeader, m_streamManager.ostream(), m_streamOffset); lasHeaderWriter.write();