[Liblas-commits] hg-main-tree: add some more user fields
liblas-commits at liblas.org
liblas-commits at liblas.org
Fri May 6 11:59:58 EDT 2011
details: http://hg.libpc.orghg-main-tree/rev/eea5ec3e2d46
changeset: 701:eea5ec3e2d46
user: Howard Butler <hobu.inc at gmail.com>
date: Fri May 06 10:58:56 2011 -0500
description:
add some more user fields
Subject: hg-main-tree: construct schema for QFIT data based on the three possible formats and calculate a point count based on point format size and header offset information
details: http://hg.libpc.orghg-main-tree/rev/3114d8b05ac7
changeset: 702:3114d8b05ac7
user: Howard Butler <hobu.inc at gmail.com>
date: Fri May 06 10:59:44 2011 -0500
description:
construct schema for QFIT data based on the three possible formats and calculate a point count based on point format size and header offset information
diffstat:
include/libpc/Dimension.hpp | 6 +
include/libpc/drivers/qfit/Reader.hpp | 47 +++
src/drivers/qfit/Reader.cpp | 442 +++++++++++++++++++++++----------
test/unit/QFITReaderTest.cpp | 2 +
4 files changed, 365 insertions(+), 132 deletions(-)
diffs (truncated from 606 to 300 lines):
diff -r b24b73d5636d -r 3114d8b05ac7 include/libpc/Dimension.hpp
--- a/include/libpc/Dimension.hpp Fri May 06 09:25:56 2011 -0500
+++ b/include/libpc/Dimension.hpp Fri May 06 10:59:44 2011 -0500
@@ -97,6 +97,12 @@
Field_User7,
Field_User8,
Field_User9,
+ Field_User10,
+ Field_User11,
+ Field_User12,
+ Field_User13,
+ Field_User14,
+ Field_User15,
// ...
// feel free to use your own int here
diff -r b24b73d5636d -r 3114d8b05ac7 include/libpc/drivers/qfit/Reader.hpp
--- a/include/libpc/drivers/qfit/Reader.hpp Fri May 06 09:25:56 2011 -0500
+++ b/include/libpc/drivers/qfit/Reader.hpp Fri May 06 10:59:44 2011 -0500
@@ -38,16 +38,60 @@
#include <libpc/libpc.hpp>
#include <libpc/Stage.hpp>
+
+#include <libpc/SchemaLayout.hpp>
+
#include <libpc/Iterator.hpp>
+#include <libpc/exceptions.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <vector>
+#include <boost/detail/endian.hpp>
+
+#ifdef BOOST_LITTLE_ENDIAN
+# define QFIT_SWAP_BE_TO_LE(p) \
+ do { \
+ char* first = static_cast<char*>(static_cast<void*>(&p)); \
+ char* last = first + sizeof(p) - 1; \
+ for(; first < last; ++first, --last) { \
+ char const x = *last; \
+ *last = *first; \
+ *first = x; \
+ }} while(false)
+
+# define QFIT_SWAP_BE_TO_LE_N(p, n) \
+ do { \
+ char* first = static_cast<char*>(static_cast<void*>(&p)); \
+ char* last = first + n - 1; \
+ for(; first < last; ++first, --last) { \
+ char const x = *last; \
+ *last = *first; \
+ *first = x; \
+ }} while(false)
+#endif
+
namespace libpc { namespace drivers { namespace qfit {
+enum QFIT_Format_Type
+{
+ QFIT_Format_10 = 10,
+ QFIT_Format_12 = 12,
+ QFIT_Format_14 = 14,
+ QFIT_Format_Unknown = 128
+};
+
+class qfit_error : public libpc_error
+{
+public:
+
+ qfit_error(std::string const& msg)
+ : libpc_error(msg)
+ {}
+};
class LIBPC_DLL Reader : public libpc::Stage
{
@@ -71,6 +115,8 @@
Options& getOptions() const { return m_options; }
+protected:
+ inline QFIT_Format_Type getFormat() const { return m_format; }
private:
@@ -78,6 +124,7 @@
Reader(const Reader&); // not implemented
Options& m_options;
+ QFIT_Format_Type m_format;
void registerFields();
diff -r b24b73d5636d -r 3114d8b05ac7 src/drivers/qfit/Reader.cpp
--- a/src/drivers/qfit/Reader.cpp Fri May 06 09:25:56 2011 -0500
+++ b/src/drivers/qfit/Reader.cpp Fri May 06 10:59:44 2011 -0500
@@ -32,6 +32,141 @@
* OF SUCH DAMAGE.
****************************************************************************/
+/*
+
+Airborne Topographic Mapper (ATM) Project
+NASA, Goddard Space Flight Center, Wallops Flight Facility
+Principal Investigator: Bill Krabill (William.B.Krabill at nasa.gov)
+
+Description of ATM QFIT Output Data
+(revised 2009-feb-13 sm)
+
+ATM data is generally distributed in the output format of the
+processing program, qfit, which combines airborne laser ranging
+data and aircraft attitude from the INS with positioning
+information from a processed kinematic differential GPS
+trajectory. Qfit output files, which usually have names ending
+in a .qi extension, are organized as 32-bit (4-byte)
+binary words, equivalent to a C or IDL long integer, which are
+scaled to retain the precision of the measurements. The format
+and the scaling factors are presented below. The qfit program is
+run on an Apple PowerPC processor (and formerly Sun/Motorola).
+Accordingly, the output is written in a big-endian format and
+must be byte-swapped to be read with a PC (Intel processor)
+which uses a little-endian format to store 32-bit integers.
+
+The files are organized into fixed-length logical records. The
+beginning of the file contains a header of one or more records
+followed by a data segment, in which there is one record per
+laser shot. It is not necessary to interpret the header
+to use the laser data.
+
+The first word of the header (and the file) is a 32-bit binary
+integer giving the number of bytes in each logical record. Commonly
+qfit files have 12 words per record and this integer will be the
+number 48. The remainder of the initial logical record is padded
+with blank bytes (in this case 44 blank bytes). 10-word and 14-word
+formats have also been used, as described below.
+
+The remainder of the header is generally a series of logical
+records containing the processing history of the file. In these
+logical records, the initial word contains a 32-bit binary
+integer with a value between -9000000 and -9000008. The
+remaining bytes in each header record is filled with a string of
+ascii characters containing information on file processing
+history. In this case, the byte offset (as a longword integer)
+from the start of file to the start of laser data will be the
+second word of the second record of the header. (Note: The header
+records can be removed by eliminating records that begin with a
+negative value since the first word of records in the data segment
+is always a positive number.)
+
+In the data segment of the file, the information contained in
+words 1-11 of the output record pertains to the laser pulse, its
+footprint, and aircraft attitude. The last word of each record is
+always the GPS time of day when the laser measurement was acquired.
+
+Prior to 2008 surveys, the GPS trajectory was edited to restrict PDOP<9
+in order to limit GPS errors to be less than roughly 5cm. The output
+survey data would therefore have occasional gaps where the PDOP>9.
+Some applications of ATM data have less stringent accuracy requirements
+that would be better served by preserving the data in these gaps.
+Starting in 2008, the PDOP limit was changed to 20, which could allow
+occasional GPS errors up to about 15cm. The PDOP value is carried in
+the qfit output and can be used to edit data for applications requiring
+greater precision. Any file in the 10-word format, or files in the 12-word
+format processed prior to January 2009, will have PDOP limited
+<9.
+
+The three data formats are described below. The format is designated by
+the logical record length given in the first word of the data file.
+
+The qi 12-word format (in use since 2006):
+Word # Content
+ 1 Relative Time (msec from start of data file)
+ 2 Laser Spot Latitude (degrees X 1,000,000)
+ 3 Laser Spot Longitude (degrees X 1,000,000)
+ 4 Elevation (millimeters)
+ 5 Start Pulse Signal Strength (relative)
+ 6 Reflected Laser Signal Strength (relative)
+ 7 Scan Azimuth (degrees X 1,000)
+ 8 Pitch (degrees X 1,000)
+ 9 Roll (degrees X 1,000)
+ 10 GPS PDOP (dilution of precision) (X 10)
+ 11 Laser received pulse width (digitizer samples)
+ 12 GPS Time packed (example: 153320100 = 15h 33m 20s 100ms)
+
+10-word format (used prior to 2006):
+Word # Content
+ 1 Relative Time (msec from start of data file)
+ 2 Laser Spot Latitude (degrees X 1,000,000)
+ 3 Laser Spot Longitude (degrees X 1,000,000)
+ 4 Elevation (millimeters)
+ 5 Start Pulse Signal Strength (relative)
+ 6 Reflected Laser Signal Strength (relative)
+ 7 Scan Azimuth (degrees X 1,000)
+ 8 Pitch (degrees X 1,000)
+ 9 Roll (degrees X 1,000)
+ 10 GPS Time packed (example: 153320100 = 15h 33m 20s 100ms)
+
+
+Between 1997 and 2004 some ATM surveys included
+a separate sensor to measure passive brightness.
+In the 14-word format, words 10-13 pertain to the
+passive brightness signal, which is essentially a relative
+measure of radiance reflected from the earth's surface within
+the vicinity of the laser pulse. The horizontal position of the
+passive footprint is determined relative to the laser footprint
+by a delay formulated during ground testing at Wallops. The
+elevation of the footprint is synthesized from surrounding laser
+elevation data. NOTE: The passive data is not calibrated and
+its use, if any, should be qualitative in nature. It may aid
+the interpretation of terrain features. The measurement capability
+was engineered into the ATM sensors to aid in the identification
+of the water/beach interface acquired with the instrument in
+coastal mapping applications.
+
+14-word format:
+Word # Content
+ 1 Relative Time (msec from start of data file)
+ 2 Laser Spot Latitude (degrees X 1,000,000)
+ 3 Laser Spot Longitude (degrees X 1,000,000)
+ 4 Elevation (millimeters)
+ 5 Start Pulse Signal Strength (relative)
+ 6 Reflected Laser Signal Strength (relative)
+ 7 Scan Azimuth (degrees X 1,000)
+ 8 Pitch (degrees X 1,000)
+ 9 Roll (degrees X 1,000)
+ 10 Passive Signal (relative)
+ 11 Passive Footprint Latitude (degrees X 1,000,000)
+ 12 Passive Footprint Longitude (degrees X 1,000,000)
+ 13 Passive Footprint Synthesized Elevation (millimeters)
+ 14 GPS Time packed (example: 153320100 = 15h 33m 20s 100ms)
+
+
+*/
+
+
#include <libpc/drivers/qfit/Reader.hpp>
#include <libpc/drivers/oci/Iterator.hpp>
#include <libpc/Utils.hpp>
@@ -48,8 +183,80 @@
: libpc::Stage()
, m_options(options)
{
+ std::string filename= m_options.GetPTree().get<std::string>("input");
+
+ std::istream* str = Utils::openFile(filename);
+
+ str->seekg(0);
+
+ boost::int32_t int4(0);
+
+ Utils::read_n(int4, *str, sizeof(int4));
+ QFIT_SWAP_BE_TO_LE(int4);
+
+ if ( int4 % 4 != 0)
+ throw qfit_error("Base QFIT format is not a multiple of 4, unrecognized format!");
+
+ m_format = static_cast<QFIT_Format_Type>(int4/sizeof(int4));
+ // std::cout << "QFIT Point format " << m_format << std::endl;
+
+ // The offset to start reading point data should be here.
+ str->seekg(44);
+ Utils::read_n(int4, *str, sizeof(int4));
+ QFIT_SWAP_BE_TO_LE(int4);
+ std::size_t off = static_cast<std::size_t>(int4);
+
+ registerFields();
+
+ SchemaLayout layout(getSchemaRef());
+ // Seek to the beginning
+ str->seekg(0, std::ios::beg);
+ std::ios::pos_type beginning = str->tellg();
+
+ // Seek to the end
+ str->seekg(0, std::ios::end);
+ std::ios::pos_type end = str->tellg();
+ std::ios::off_type size = end - beginning;
+
+ // First integer is the format of the file
+ std::ios::off_type offset = static_cast<std::ios::off_type>(off);
+ std::ios::off_type length = static_cast<std::ios::off_type>(layout.getByteSize());
+ std::ios::off_type point_bytes = end - offset;
+
+ // Figure out how many points we have and whether or not we have
+ // extra slop in there.
+ std::ios::off_type count = point_bytes / length;
+ std::ios::off_type remainder = point_bytes % length;
+
+ // std::cout << "count: " << count << std::endl;
+ // std::cout <<" point_bytes: " << point_bytes << std::endl;
+ // std::cout <<" length: " << length << std::endl;
+ // std::cout <<" offset: " << offset << std::endl;
+ // std::cout <<" remainder: " << remainder << std::endl;
+ // std::cout <<" beginning: " << beginning << std::endl;
+
More information about the Liblas-commits
mailing list