diff --git a/include/pdal/Charbuf.hpp b/include/pdal/Charbuf.hpp index 021380e8b7..76a2664e2b 100644 --- a/include/pdal/Charbuf.hpp +++ b/include/pdal/Charbuf.hpp @@ -32,6 +32,8 @@ * OF SUCH DAMAGE. ****************************************************************************/ +#pragma once + #include #include @@ -63,4 +65,4 @@ class Charbuf : public std::streambuf pos_type m_bufOffset; }; -} //namespace +} //namespace pdal diff --git a/include/pdal/IStream.hpp b/include/pdal/IStream.hpp index 1740af53a8..0546569678 100644 --- a/include/pdal/IStream.hpp +++ b/include/pdal/IStream.hpp @@ -54,13 +54,22 @@ class IStream friend class IStreamMarker; public: - IStream(const std::string& filename) - { m_stream = m_fstream = new std::ifstream(filename); } + IStream() : m_stream(NULL), m_fstream(NULL) + {} + IStream(const std::string& filename) : m_stream(NULL), m_fstream(NULL) + { open(filename); } IStream(std::istream *stream) : m_stream(stream), m_fstream(NULL) {} ~IStream() { delete m_fstream; } + int open(const std::string& filename) + { + if (m_stream) + return -1; + m_stream = m_fstream = new std::ifstream(filename); + return 0; + } operator bool () { return (bool)(*m_stream); } void seek(std::streampos pos) @@ -98,6 +107,8 @@ class IStream class ILeStream : public IStream { public: + ILeStream() : IStream() + {} ILeStream(const std::string& filename) : IStream(filename) {} ILeStream(std::istream *stream) : IStream(stream) diff --git a/include/pdal/Reader.hpp b/include/pdal/Reader.hpp index 2683b949a3..f1dad38e36 100644 --- a/include/pdal/Reader.hpp +++ b/include/pdal/Reader.hpp @@ -32,46 +32,39 @@ * OF SUCH DAMAGE. ****************************************************************************/ -#ifndef INCLUDED_READER_HPP -#define INCLUDED_READER_HPP +#pragma once #include #include -#include namespace pdal { -// -// supported options: -// id -// debug -// verbose -// - class PDAL_DLL Reader : public Stage { public: - Reader() - {} - Reader(Options const& options) : Stage(options) - {}; - virtual ~Reader() - {}; + Reader(Options const& options) : Stage(options), + m_count(std::numeric_limits::max()) + {} + +protected: + std::string m_filename; + point_count_t m_count; private: virtual PointBufferSet run(PointBufferPtr buffer) { PointBufferSet pbSet; - StageSequentialIterator *it = createSequentialIterator(); - it->read(*buffer); + read(*buffer, m_count); pbSet.insert(buffer); return pbSet; } + virtual void readerProcessOptions(const Options& options); + virtual point_count_t read(PointBuffer& buf, point_count_t num) + { return 0; } virtual boost::property_tree::ptree serializePipeline() const; }; } // namespace pdal -#endif diff --git a/include/pdal/ReaderIterator.hpp b/include/pdal/ReaderIterator.hpp deleted file mode 100644 index 0b7798e663..0000000000 --- a/include/pdal/ReaderIterator.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com) -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#ifndef INCLUDED_READERITERATOR_HPP -#define INCLUDED_READERITERATOR_HPP - -#include - -#include - -namespace pdal -{ -class Reader; -class PointBuffer; - -class PDAL_DLL ReaderSequentialIterator : public StageSequentialIterator -{ -public: - ReaderSequentialIterator(PointBuffer& buffer); - ReaderSequentialIterator() - {} - virtual ~ReaderSequentialIterator(); -}; - - -class PDAL_DLL ReaderRandomIterator : public StageRandomIterator -{ -public: - ReaderRandomIterator(PointBuffer& buffer); - virtual ~ReaderRandomIterator(); -}; - -} // namespace pdal - -#endif diff --git a/include/pdal/Stage.hpp b/include/pdal/Stage.hpp index 0f89fa40ee..8a1b6c2696 100644 --- a/include/pdal/Stage.hpp +++ b/include/pdal/Stage.hpp @@ -121,13 +121,7 @@ class PDAL_DLL Stage static bool s_isEnabled() { return YES_OR_NO; } \ bool isEnabled() const { return YES_OR_NO; } - virtual StageSequentialIterator* - createSequentialIterator(PointBuffer&) const - { return NULL; } - virtual StageSequentialIterator* - createSequentialIterator() const - { std::cerr << "Created crap sequential iterator!\n"; return NULL; } - virtual StageRandomIterator* createRandomIterator(PointBuffer&) const + virtual StageSequentialIterator* createSequentialIterator() const { return NULL; } inline MetadataNode getMetadata() const { return m_metadata; } @@ -151,6 +145,8 @@ class PDAL_DLL Stage void l_processOptions(const Options& options); virtual void processOptions(const Options& /*options*/) {} + virtual void readerProcessOptions(const Options& /*options*/) + {} virtual void writerProcessOptions(const Options& /*options*/) {} void l_initialize(PointContext ctx); diff --git a/include/pdal/StageIterator.hpp b/include/pdal/StageIterator.hpp deleted file mode 100644 index 1fd1b85a25..0000000000 --- a/include/pdal/StageIterator.hpp +++ /dev/null @@ -1,196 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com) -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#ifndef INCLUDED_STAGEITERATOR_HPP -#define INCLUDED_STAGEITERATOR_HPP - -#include - -namespace pdal -{ -class Stage; -class PointBuffer; - - - -class PDAL_DLL StageIterator -{ -public: - StageIterator(PointBuffer& buffer); - StageIterator(); - virtual ~StageIterator() - {} - - // This reads a set of points at the current position in the file. - // - // The schema of the PointBuffer buffer we are given here might - // not match our own header's schema. That's okay, though: all - // that matters is that the buffer we are given has the fields - // we need to write into. - // - // Returns the number of valid points read. - // - // (This function really just performs the readBegin..readEnd sequence) - point_count_t read(PointBuffer& buffer); - - point_count_t read(PointBuffer& buffer, point_count_t count) - { - point_count_t numRead = readImpl(buffer, count); - m_index += numRead; - return numRead; - } - - // These functions just call into the corresponding 'Impls that the derived - // stage provides, plus some of them do a little internal bookkeeping we - // don't want to have to make the derived stages keep track of. - // - // Mortal users are not intended to use these functions. For read - // workflows, just call the above read() method. For write workflows, - // Writer::write() will take care of calling these guys for you. - // - // Sequence: - // - readBegin - // - for each buffer chunk, do - // . readBufferBegin - // . readBuffer - // . readBufferEnd - // - readEnd - void readBegin(); - void readBufferBegin(PointBuffer&); - boost::uint32_t readBuffer(PointBuffer&); - void readBufferEnd(PointBuffer&); - void readEnd(); - - // advance N points ahead in the file - // - // In some cases, this might be a very slow, painful function to call - // because it might entail physically reading the N points (and dropping - // the data on the floor) - // - // Returns the number actually skipped (which might be less than count, - // if the end of the stage was reached first). - // - virtual boost::uint64_t skip(boost::uint64_t count); - - // Returns the current point number. The first point is 0. - // If this number if > getNumPoints(), then no more points - // may be read (and atEnd() should be true). - // - // All stages have the notion of a current point number, even for stages - // that are not really "ordered", in that the index just starts at zero - // and increments by N every time another N points are read - boost::uint64_t getIndex() const; - - // used to control intermediate buffering needed by some stages - void setChunkSize(boost::uint32_t size); - boost::uint32_t getChunkSize() const; - -/** - PointBuffer& getBuffer() - { - return m_buffer; - } -**/ - -protected: - virtual point_count_t readImpl(PointBuffer& data, point_count_t count) = 0; - virtual void readBeginImpl() {} - virtual void readBufferBeginImpl(PointBuffer&) {} - virtual point_count_t readBufferImpl(PointBuffer&) = 0; - virtual void readBufferEndImpl(PointBuffer&) {} - virtual void readEndImpl() {} - virtual boost::uint64_t skipImpl(boost::uint64_t pointNum) = 0; - - boost::uint64_t m_index; - -private: -// PointBuffer& m_buffer; - boost::uint32_t m_chunkSize; - - bool m_readBeginPerformed; - bool m_readBufferBeginPerformed; - - StageIterator& operator=(const StageIterator&); // not implemented - StageIterator(const StageIterator&); // not implemented - void Construct(); -}; - - -class PDAL_DLL StageSequentialIterator : public StageIterator -{ -public: - StageSequentialIterator(PointBuffer& buffer); - StageSequentialIterator() - {} - virtual ~StageSequentialIterator(); - - // returns true after we've read all the points available to this stage - bool atEnd() const; - -protected: - // from Iterator - virtual point_count_t readImpl(PointBuffer& /*data*/, point_count_t /*count*/) - { std::cerr << "No sequential readImpl for stage/iterator!\n"; return 0; } - virtual point_count_t readBufferImpl(PointBuffer&) = 0; - virtual bool atEndImpl() const = 0; -}; - - -class PDAL_DLL StageRandomIterator : public StageIterator -{ -public: - StageRandomIterator(PointBuffer& buffer); - virtual ~StageRandomIterator(); - - // seek to point N (an absolute value) - // - // In some cases, this might be a very slow, painful function to call - // because it might entail physically reading the N points (and dropping - // the data on the floor) - // - // Returns the number actually seeked to (which might be less than asked - // for, if the end of the stage was reached first). - boost::uint64_t seek(boost::uint64_t position); - -protected: - // from Iterator - virtual point_count_t readImpl(PointBuffer& /*data*/, point_count_t /*count*/) - { std::cerr << "No random readImpl for stage/iterator!\n"; return 0; } - virtual boost::uint64_t seekImpl(boost::uint64_t position) = 0; - virtual boost::uint64_t skipImpl(boost::uint64_t position); -}; - -} // namespace pdal - -#endif diff --git a/include/pdal/drivers/bpf/BpfReader.hpp b/include/pdal/drivers/bpf/BpfReader.hpp index 4d4a99698a..7795f27962 100644 --- a/include/pdal/drivers/bpf/BpfReader.hpp +++ b/include/pdal/drivers/bpf/BpfReader.hpp @@ -34,9 +34,11 @@ #pragma once +#include + +#include #include #include -#include #include "BpfHeader.hpp" @@ -50,15 +52,11 @@ class PDAL_DLL BpfReader : public Reader SET_STAGE_LINK("http://pdal.io/stages/drivers.bpf.reader.html") SET_STAGE_ENABLED(true) - BpfReader(const Options&); - BpfReader(const std::string&); - - virtual boost::uint64_t getNumPoints() const - { return m_header.m_numPts; } - - StageSequentialIterator* createSequentialIterator() const; - StageRandomIterator* createRandomIterator(PointBuffer& buffer) const; + BpfReader(const Options& options) : Reader(options) + {} + virtual point_count_t numPoints() const + { return (point_count_t)m_header.m_numPts; } private: ILeStream m_stream; BpfHeader m_header; @@ -68,12 +66,36 @@ class PDAL_DLL BpfReader : public Reader std::vector m_ulemFrames; BpfPolarHeader m_polarHeader; std::vector m_polarFrames; + /// Stream position at the beginning of point records. + std::streampos m_start; + /// Index of the next point to read. + point_count_t m_index; + /// Buffer for deflated data. + std::vector m_deflateBuf; + /// Streambuf for deflated data. + Charbuf m_charbuf; + virtual void processOptions(const Options& options); virtual void initialize(); virtual void addDimensions(PointContext ctx); + virtual void ready(PointContext ctx); + virtual point_count_t read(PointBuffer& buf, point_count_t num); + virtual void done(PointContext ctx); + virtual bool eof(); + bool readUlemData(); bool readPolarData(); + point_count_t readPointMajor(PointBuffer& data, point_count_t count); + point_count_t readDimMajor(PointBuffer& data, point_count_t count); + point_count_t readByteMajor(PointBuffer& data, point_count_t count); + size_t readBlock(std::vector& outBuf, size_t index); +#ifdef PDAL_HAVE_ZLIB + int inflate(char *inbuf, size_t insize, char *outbuf, size_t outsize); +#endif + void seekPointMajor(PointId ptIdx); + void seekDimMajor(size_t dimIdx, PointId ptIdx); + void seekByteMajor(size_t dimIdx, size_t byteIdx, PointId ptIdx); }; -} // namespace +} // namespace pdal diff --git a/include/pdal/drivers/bpf/BpfSeqIterator.hpp b/include/pdal/drivers/bpf/BpfSeqIterator.hpp deleted file mode 100644 index 566031bdbe..0000000000 --- a/include/pdal/drivers/bpf/BpfSeqIterator.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2014, Hobu Inc. -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#pragma once - -#include -#include -#include -#include "BpfHeader.hpp" - -#include - -namespace pdal -{ - -class BpfReader; -class PointBuffer; - -class BpfSeqIterator : public ReaderSequentialIterator -{ -public: - BpfSeqIterator(const BpfDimensionList& dims, point_count_t numPoints, - BpfFormat::Enum pointFormat, bool compression, ILeStream& stream); - ~BpfSeqIterator(); - -protected: - point_count_t readBufferImpl(PointBuffer&); - virtual point_count_t readImpl(PointBuffer& data, point_count_t count); - boost::uint64_t skipImpl(uint64_t); - bool atEndImpl() const; - - point_count_t read(PointBuffer& data, point_count_t count); - point_count_t readPointMajor(PointBuffer& data, point_count_t count); - point_count_t readDimMajor(PointBuffer& data, point_count_t count); - point_count_t readByteMajor(PointBuffer& data, point_count_t count); - -private: - size_t readBlock(std::vector& outBuf, size_t index); -#ifdef PDAL_HAVE_ZLIB - int inflate(char *inbuf, size_t insize, char *outbuf, size_t outsize); -#endif - void seekPointMajor(uint32_t ptIdx); - void seekDimMajor(size_t dimIdx, uint32_t ptIdx); - void seekByteMajor(size_t dimIdx, size_t byteIdx, uint32_t ptIdx); - - /// Dimensions - BpfDimensionList m_dims; - /// Total number of points in the file. - point_count_t m_numPoints; - /// Bpf point format being read. - BpfFormat::Enum m_pointFormat; - /// Input stream - ILeStream& m_stream; - /// Index of the next point to read. - point_count_t m_index; - /// Stream position when the iterator is created (should always be - /// the start of point data). - std::streampos m_start; - /// Buffer for deflated data. - std::vector m_deflateBuf; - /// Streambuf for deflated data. - Charbuf m_charbuf; -}; - -} // namespace pdal - diff --git a/include/pdal/drivers/caris/CloudIterator.hpp b/include/pdal/drivers/caris/CloudIterator.hpp deleted file mode 100644 index 40cac29794..0000000000 --- a/include/pdal/drivers/caris/CloudIterator.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************ - * Copyright (c) 2012, CARIS - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of CARIS nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ************************************************************************/ -#ifndef INCLUDED_DRIVERS_CSAR_CLOUDITERATOR_HPP -#define INCLUDED_DRIVERS_CSAR_CLOUDITERATOR_HPP - -#include "config.h" -#include "caris/caris_pc_wrapper.h" -#include "CloudReader.hpp" - -#ifdef _MSC_VER -# pragma warning(push, 3) -# pragma warning(disable : DISABLED_3RDPARTY_WARNINGS) -#endif - -#include - -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -namespace csar { - -//! Sequential iterator for CloudReader -class CloudIterator : public pdal::ReaderSequentialIterator -{ -public: - CloudIterator(pdal::PointBuffer & in_buffer, caris_cloud *cloud); - virtual ~CloudIterator(); - -protected: - virtual point_count_t readBufferImpl(pdal::PointBuffer& io_buffer); - virtual boost::uint64_t skipImpl(boost::uint64_t in_pointNum); - virtual bool atEndImpl() const; - -private: - void throwIfItrError() const; - -private: - caris_itr * m_itr; - std::map m_dimInfo; - int32_t m_currentOffset; -}; - -} // namespace - -#endif diff --git a/include/pdal/drivers/caris/CloudReader.hpp b/include/pdal/drivers/caris/CloudReader.hpp index 940c5e2f16..7c98042909 100644 --- a/include/pdal/drivers/caris/CloudReader.hpp +++ b/include/pdal/drivers/caris/CloudReader.hpp @@ -25,26 +25,31 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ************************************************************************/ -#ifndef INCLUDED_DRIVERS_CSAR_CLOUDREADER_HPP -#define INCLUDED_DRIVERS_CSAR_CLOUDREADER_HPP -#include "config.h" +#pragma once -#include "caris/caris_pc_wrapper.h" +//#include "config.h" +//#include "caris/caris_pc_wrapper.h" #ifdef _MSC_VER # pragma warning(push, 3) # pragma warning(disable : DISABLED_3RDPARTY_WARNINGS) #endif -#include #include #ifdef _MSC_VER # pragma warning(pop) #endif -namespace csar { +struct caris_dimension; +struct caris_cloud; +struct caris_itr; + +namespace pdal +{ +namespace csar +{ //! Base Reader implementaion of CARIS Clouds class CloudReader : public pdal::Reader @@ -57,72 +62,59 @@ class CloudReader : public pdal::Reader SET_STAGE_ENABLED(false) #endif - - explicit CloudReader(const pdal::Options& options); + explicit CloudReader(const pdal::Options& options) : pdal::Reader(options) + {} virtual ~CloudReader(); - - virtual void initialize(); - virtual pdal::StageSequentialIterator* - createSequentialIterator(pdal::PointBuffer& in_buffer) const; - //! Info for mapping between pdal and caris dimensions struct DimInfo { DimInfo() - : dimIndex(), tupleIndex(), dimension() + : dimIndex(), tupleIndex(), type(Dimension::Type::None), dimension() {} + DimInfo(int in_dimIndex, int in_tupleIndex, + Dimension::Type::Enum in_type, caris_dimension const* in_dimension) : dimIndex(in_dimIndex), tupleIndex(in_tupleIndex), - dimension(in_dimension) + type(in_type), dimension(in_dimension) {} //! index of the dimension in the related caris_cloud int dimIndex; //! the tuple index of the caris_dimension to be mapped to pdal int tupleIndex; + // PDAL type of the dimension + Dimension::Type::Enum type; //! related dimension caris_dimension const* dimension; }; - std::map const& getDimInfo() const; - caris_cloud * getCarisCloud() const; + caris_cloud* getCarisCloud() const + { return m_cloud; } + + point_count_t numPoints(); protected: virtual std::string getURI() const = 0; private: caris_cloud * m_cloud; - std::map m_dimInfo; -}; + std::map m_dims; + caris_itr * m_itr; + int32_t m_currentOffset; -//************************************************************************ -//! info for mapping from pdal to caris dimensions -/*! -\return - \li info for mapping from pdal to caris dimensions -*/ -//************************************************************************ -inline -std::map const& CloudReader::getDimInfo() const -{ - return m_dimInfo; -} - -//************************************************************************ -//! get underlying caris_cloud -/*! -\return - \li underlying caris_cloud -*/ -//************************************************************************ -inline -caris_cloud * CloudReader::getCarisCloud() const -{ - return m_cloud; -} + + virtual void initialize(); + virtual void addDimensions(PointContext ctx); + virtual void ready(PointContext ctx); + virtual point_count_t read(PointBuffer& buf, point_count_t num); + virtual bool eof(); + virtual void done(PointContext ctx); + + void throwIfItrError() const; +}; -} // namespace +} // namespace csar +} // namespace pdal -#endif diff --git a/include/pdal/drivers/faux/Reader.hpp b/include/pdal/drivers/faux/Reader.hpp index 7d2f64399e..90c665b48f 100644 --- a/include/pdal/drivers/faux/Reader.hpp +++ b/include/pdal/drivers/faux/Reader.hpp @@ -35,7 +35,6 @@ #pragma once #include -#include namespace pdal { @@ -85,35 +84,10 @@ class PDAL_DLL Reader : public pdal::Reader Reader(const Options& options); - static Options getDefaultOptions(); static Dimension::IdList getDefaultDimensions(); - pdal::StageSequentialIterator *createSequentialIterator() const; - private: - uint64_t m_numPoints; Mode m_mode; - uint8_t m_numberOfReturns; - - Bounds m_bounds; - - virtual void processOptions(const Options& options); - virtual void addDimensions(PointContext ctx); - - Reader& operator=(const Reader&); // not implemented - Reader(const Reader&); // not implemented -}; - -} // namespace faux -} // namespace drivers - -class PDAL_DLL FauxSeqIterator : public pdal::ReaderSequentialIterator -{ -public: - FauxSeqIterator(const Bounds& bounds, drivers::faux::Mode mode, - point_count_t numPoints, uint8_t numberOfReturns, LogPtr log); - -private: double m_minX; double m_maxX; double m_minY; @@ -121,25 +95,25 @@ class PDAL_DLL FauxSeqIterator : public pdal::ReaderSequentialIterator double m_minZ; double m_maxZ; uint64_t m_time; - drivers::faux::Mode m_mode; - point_count_t m_numPoints; - uint8_t m_returnNumber; - uint8_t m_numberOfReturns; - LogPtr m_log; + int m_numReturns; + int m_returnNum; - point_count_t readBufferImpl(PointBuffer& buf) - { return readImpl(buf, m_numPoints); } - - uint64_t skipImpl(uint64_t numPts) + virtual void processOptions(const Options& options); + virtual void addDimensions(PointContext ctx); + virtual void ready(PointContext ctx) { - m_time += numPts; - return numPts; + m_returnNum = 1; + m_time = 0; } - - point_count_t readImpl(PointBuffer& buf, point_count_t count); - bool atEndImpl() const + virtual point_count_t read(PointBuffer& buf, point_count_t count); + virtual bool eof() { return false; } + + Reader& operator=(const Reader&); // not implemented + Reader(const Reader&); // not implemented }; +} // namespace faux +} // namespace drivers } // namespace pdal diff --git a/include/pdal/drivers/icebridge/Reader.hpp b/include/pdal/drivers/icebridge/Reader.hpp index d9bffcfbec..e6ccd0254d 100644 --- a/include/pdal/drivers/icebridge/Reader.hpp +++ b/include/pdal/drivers/icebridge/Reader.hpp @@ -35,7 +35,6 @@ #pragma once #include -#include #include #include @@ -68,44 +67,20 @@ class PDAL_DLL Reader : public pdal::Reader static Options getDefaultOptions(); static Dimension::IdList getDefaultDimensions(); - StageSequentialIterator* createSequentialIterator() const; - private: - std::string m_filename; Hdf5Handler m_hdf5Handler; + point_count_t m_index; - virtual void processOptions(const Options& options); virtual void addDimensions(PointContext ctx); virtual void ready(PointContext ctx); + virtual point_count_t read(PointBuffer& data, point_count_t count); virtual void done(PointContext ctx); + virtual bool eof(); Reader& operator=(const Reader&); // Not implemented. Reader(const Reader&); // Not implemented. }; -namespace iterators -{ -namespace sequential -{ - -class PDAL_DLL IcebridgeSeqIter : public ReaderSequentialIterator -{ -public: - IcebridgeSeqIter(Hdf5Handler *hdf5Handler) : m_hdf5Handler(hdf5Handler) - {} - -private: - Hdf5Handler *m_hdf5Handler; - - virtual point_count_t readImpl(PointBuffer& data, point_count_t count); - virtual uint64_t skipImpl(boost::uint64_t); - virtual point_count_t readBufferImpl(PointBuffer& pointBuffer); - virtual bool atEndImpl() const; -}; - -} // namespace sequential -} // namespace iterators - } // namespace icebridge } // namespace drivers } // namespace pdal diff --git a/include/pdal/drivers/las/Reader.hpp b/include/pdal/drivers/las/Reader.hpp index 0417b6fb1d..aab0019e49 100644 --- a/include/pdal/drivers/las/Reader.hpp +++ b/include/pdal/drivers/las/Reader.hpp @@ -35,14 +35,11 @@ #pragma once #include -#include #include - #include #include - -#include +#include namespace pdal { @@ -68,97 +65,45 @@ class PDAL_DLL Reader : public pdal::Reader SET_STAGE_LINK("http://pdal.io/stages/drivers.las.reader.html") SET_STAGE_ENABLED(true) - Reader(const Options&); - Reader(const std::string&); + Reader(const Options& options) : pdal::Reader(options), m_index(0), + m_istream(NULL) + {} + virtual ~Reader(); static Options getDefaultOptions(); - StreamFactory& getStreamFactory() const; - - pdal::StageSequentialIterator* createSequentialIterator() const; const LasHeader& getLasHeader() const { return m_lasHeader; } point_count_t getNumPoints() const { return m_lasHeader.GetPointRecordsCount(); } -protected: - typedef std::unique_ptr StreamFactoryPtr; - LasHeader& getLasHeaderRef() - { - return m_lasHeader; - } - private: + typedef std::unique_ptr StreamFactoryPtr; StreamFactoryPtr m_streamFactory; LasHeader m_lasHeader; - std::string m_filename; + std::unique_ptr m_zipPoint; + std::unique_ptr m_unzipper; + point_count_t m_index; + std::istream* m_istream; + virtual StreamFactoryPtr createFactory() const + { return StreamFactoryPtr(new FilenameStreamFactory(m_filename)); } virtual void initialize(); virtual void initialize(MetadataNode& m); virtual void addDimensions(PointContext ctx); void extractMetadata(MetadataNode& m); virtual void processOptions(const Options& options); - virtual StreamFactoryPtr createFactory() const - { return StreamFactoryPtr(new FilenameStreamFactory(m_filename)); } + virtual void ready(PointContext ctx); + virtual point_count_t read(PointBuffer& buf, point_count_t count); + virtual void done(PointContext ctx); + virtual bool eof() + { return m_index >= getNumPoints(); } + void loadPoint(PointBuffer& data, char *buf, size_t bufsize); Reader& operator=(const Reader&); // not implemented Reader(const Reader&); // not implemented }; - -namespace iterators -{ - -class Base -{ -public: - Base(pdal::drivers::las::Reader const& reader); - ~Base(); - -protected: - point_count_t processBuffer(PointBuffer& PointBuffer, - std::istream& stream, point_count_t count, LASunzipper* unzipper, - ZipPoint* zipPoint); - - Bounds m_bounds; - const pdal::drivers::las::Reader& m_reader; - std::istream& m_istream; -#ifdef PDAL_HAVE_LASZIP - boost::scoped_ptr m_zipPoint; - boost::scoped_ptr m_unzipper; -#else - void* m_zipPoint; - void* m_unzipper; -#endif - -private: - Base& operator=(Base const&); - Base(Base const&); // not implemented - - void initialize(); - void loadPoint(PointBuffer& data, char *buf, size_t bufsize); -}; - -namespace sequential -{ - -class Reader : public Base, public pdal::ReaderSequentialIterator -{ -public: - Reader(const pdal::drivers::las::Reader& reader); - -private: - boost::uint64_t skipImpl(boost::uint64_t); - point_count_t readBufferImpl(PointBuffer&); - point_count_t readImpl(PointBuffer&, point_count_t count); - bool atEndImpl() const - { return getIndex() >= m_reader.getNumPoints(); } -}; - -} // sequential - -} // iterators - } // namespace las } // namespace drivers } // namespace pdal diff --git a/include/pdal/drivers/las/Support.hpp b/include/pdal/drivers/las/Support.hpp index e96488b578..ad0813c208 100644 --- a/include/pdal/drivers/las/Support.hpp +++ b/include/pdal/drivers/las/Support.hpp @@ -32,35 +32,18 @@ * OF SUCH DAMAGE. ****************************************************************************/ -#pragma once - -#include - -#include - -#ifdef PDAL_HAVE_LASZIP -#include -#include -#include +#include -#else -typedef struct LASzipH *LASzip; -typedef struct LASunzipperH *LASunzipper; -#endif +#pragma once namespace pdal { - -class Stage; - namespace drivers { namespace las { -class Reader; class SummaryData; -class ZipPoint; class PDAL_DLL Support { diff --git a/include/pdal/drivers/las/Writer.hpp b/include/pdal/drivers/las/Writer.hpp index 0d9a6f7bc9..f71f22e633 100644 --- a/include/pdal/drivers/las/Writer.hpp +++ b/include/pdal/drivers/las/Writer.hpp @@ -38,9 +38,9 @@ #include #include #include +#include #include #include -#include namespace pdal { @@ -107,11 +107,9 @@ class PDAL_DLL Writer : public pdal::Writer LasHeader m_lasHeader; boost::uint32_t m_numPointsWritten; SummaryData m_summaryData; + std::unique_ptr m_zipper; + std::unique_ptr m_zipPoint; -#ifdef PDAL_HAVE_LASZIP - boost::scoped_ptr m_zipper; - boost::scoped_ptr m_zipPoint; -#endif virtual void processOptions(const Options& options); virtual void ready(PointContext ctx); virtual void write(const PointBuffer& pointBuffer); diff --git a/src/drivers/las/ZipPoint.hpp b/include/pdal/drivers/las/ZipPoint.hpp similarity index 83% rename from src/drivers/las/ZipPoint.hpp rename to include/pdal/drivers/las/ZipPoint.hpp index 7bdba1c37c..da12653f8d 100644 --- a/src/drivers/las/ZipPoint.hpp +++ b/include/pdal/drivers/las/ZipPoint.hpp @@ -32,20 +32,25 @@ * OF SUCH DAMAGE. ****************************************************************************/ -#ifndef INCLUDED_DRIVERS_LAS_ZIPPOINT_HPP -#define INCLUDED_DRIVERS_LAS_ZIPPOINT_HPP +#pragma once +#ifdef PDAL_HAVE_LASZIP +#include +#include +#include +#endif #include -#include -#include #include #include -namespace pdal { namespace drivers { namespace las { +namespace pdal { +namespace drivers { +namespace las { +#ifdef PDAL_HAVE_LASZIP class VariableLengthRecord; class ZipPoint @@ -70,14 +75,21 @@ class ZipPoint int his_vlr_num; unsigned char* his_vlr_data; - boost::scoped_ptr m_zip; + std::unique_ptr m_zip; unsigned char** m_lz_point; boost::scoped_array m_lz_point_data; unsigned int m_lz_point_size; }; +#else // PDAL_HAVE_LASZIP +// The types here just need to be something suitable for a smart pointer. +// They aren't ever used beyond testing for NULL. +typedef char LASzipper; +typedef char LASunzipper; +typedef char ZipPoint; +#endif + +} // namespace las +} // namespace drivers +} // namespace pdal -} } } // namespace - - -#endif // LIBLAS_DETAIL_ZIPPOINT_HPP_INCLUDED diff --git a/include/pdal/drivers/oci/OciReader.hpp b/include/pdal/drivers/oci/OciReader.hpp index 604f2b0c05..91801f4ef7 100644 --- a/include/pdal/drivers/oci/OciReader.hpp +++ b/include/pdal/drivers/oci/OciReader.hpp @@ -64,17 +64,32 @@ class PDAL_DLL OciReader : public pdal::Reader {} static Options getDefaultOptions(); - StageSequentialIterator* createSequentialIterator() const; private: virtual void initialize(); virtual void processOptions(const Options& options); virtual void addDimensions(PointContext ctx); + virtual void ready(PointContext ctx) + { m_atEnd = false; } + virtual point_count_t read(PointBuffer& buf, point_count_t); + virtual bool eof() + { return m_atEnd; } + void validateQuery(); void defineBlock(Statement statement, BlockPtr block) const; pdal::SpatialReference fetchSpatialReference(Statement statement, BlockPtr block) const; + void readBlob(Statement stmt, BlockPtr block); + point_count_t readDimMajor(PointBuffer& buffer, BlockPtr block, + point_count_t numPts); + point_count_t readPointMajor(PointBuffer& buffer, BlockPtr block, + point_count_t numPts); + char *seekDimMajor(const schema::DimInfo& d, BlockPtr block); + char *seekPointMajor(BlockPtr block); + bool readOci(Statement stmt, BlockPtr block); + schema::XMLSchema *findSchema(Statement stmt, BlockPtr block); + Connection m_connection; Statement m_stmt; BlockPtr m_block; @@ -82,6 +97,8 @@ class PDAL_DLL OciReader : public pdal::Reader std::string m_schemaFile; std::string m_connSpec; boost::optional m_spatialRef; + bool m_atEnd; + std::map m_schemas; OciReader& operator=(const OciReader&); // not implemented OciReader(const OciReader&); // not implemented diff --git a/include/pdal/drivers/oci/OciSeqIterator.hpp b/include/pdal/drivers/oci/OciSeqIterator.hpp deleted file mode 100644 index aff18bb8df..0000000000 --- a/include/pdal/drivers/oci/OciSeqIterator.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2011, Howard Butler, hobu.inc@gmail.com -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#pragma once - -#include -#include - -#include -#include - -namespace pdal -{ - -namespace drivers -{ -namespace oci -{ -namespace iterators -{ -namespace sequential -{ - -class OciSeqIterator : public ReaderSequentialIterator -{ -public: - OciSeqIterator(Statement stmt, BlockPtr block) : - m_stmt(stmt), m_block(block), m_atEnd(false) - {} - -protected: - point_count_t readBufferImpl(PointBuffer& buffer) - { - return readImpl(buffer, (std::numeric_limits::max)()); - } - point_count_t readImpl(PointBuffer& buffer, point_count_t count); - uint64_t skipImpl(uint64_t count); - bool atEndImpl() const - { return m_atEnd; } - -private: - void readBlob(Statement stmt, BlockPtr block); - point_count_t read(PointBuffer& buffer, BlockPtr block, - point_count_t numPts); - point_count_t readDimMajor(PointBuffer& buffer, BlockPtr block, - point_count_t numPts); - point_count_t readPointMajor(PointBuffer& buffer, BlockPtr block, - point_count_t numPts); - char *seekDimMajor(const schema::DimInfo& d, BlockPtr block); - char *seekPointMajor(BlockPtr block); - bool readOci(Statement stmt, BlockPtr block); - schema::XMLSchema *findSchema(Statement stmt, BlockPtr block); - pdal::Bounds getBounds(Statement stmt, BlockPtr block); - - Statement m_stmt; - BlockPtr m_block; - bool m_atEnd; - std::map m_schemas; -}; - -} // namespace sequential -} // namespace iterators -} // namespace oci -} // namespace driver -} // namespace pdal - diff --git a/include/pdal/drivers/pcd/Reader.hpp b/include/pdal/drivers/pcd/Reader.hpp index 6f9a549dca..6c58735a3c 100644 --- a/include/pdal/drivers/pcd/Reader.hpp +++ b/include/pdal/drivers/pcd/Reader.hpp @@ -36,7 +36,6 @@ #include #include -#include #include namespace pdal @@ -55,48 +54,18 @@ class PDAL_DLL PcdReader : public pdal::Reader PcdReader(const Options& options) : Reader(options) {}; - static Options getDefaultOptions(); static Dimension::IdList getDefaultDimensions() { return fileDimensions(); }; - virtual StageSequentialIterator* createSequentialIterator() const; - private: - std::string m_filename; point_count_t m_numPts; - virtual void processOptions(const Options& options); virtual void addDimensions(PointContext ctx); virtual void ready(PointContext ctx); + virtual point_count_t read(PointBuffer& buf, point_count_t count); }; -namespace iterators -{ -namespace sequential -{ - -class PDAL_DLL PcdSeqIterator : public pdal::ReaderSequentialIterator -{ -public: - PcdSeqIterator(const Dimension::IdList& dims, std::string filename) : m_dims(dims), m_filename(filename) - {}; - -private: - boost::uint64_t skipImpl(boost::uint64_t) {}; - point_count_t readImpl(PointBuffer& buf, std::string filename); - bool atEndImpl() const {}; - - virtual point_count_t readBufferImpl(PointBuffer& buf) - { return readImpl(buf, m_filename); } - - Dimension::IdList m_dims; - std::string m_filename; -}; - -} // sequential -} // iterators - -} -} -} // namespaces +} // namespace pcd +} // namespace drivers +} // namespace pdal diff --git a/include/pdal/drivers/pgpointcloud/PgIterator.hpp b/include/pdal/drivers/pgpointcloud/PgIterator.hpp deleted file mode 100644 index ba81a0e3a9..0000000000 --- a/include/pdal/drivers/pgpointcloud/PgIterator.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2012, Howard Butler, hobu.inc@gmail.com -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#pragma once - -#include - -#include -#include -#include -#include - -#include - -namespace pdal -{ -namespace drivers -{ -namespace pgpointcloud -{ - -class PgReader; - -namespace iterators -{ -namespace sequential -{ - class Patch; - -class PgIterator : public pdal::StageSequentialIterator -{ -public: - PgIterator(const PgReader& reader, const schema::DimInfoList& dims); - ~PgIterator(); - -protected: - // Skip count points, return number of points skipped - uint64_t skipImpl(uint64_t count); - - // Fill the provided pointbuffer, return the number of points written - point_count_t readImpl(PointBuffer& user_buffer, point_count_t count); - point_count_t readBufferImpl(PointBuffer& buffer) - { - return readImpl(buffer, (std::numeric_limits::max)()); - } - // True when there are no more points to read - bool atEndImpl() const; - -private: - point_count_t readPgPatch(PointBuffer& buffer, point_count_t numPts); - - // Internal functions for managing scroll cursor - bool CursorSetup(); - bool CursorTeardown(); - bool NextBuffer(); - - const PgReader& m_reader; - bool m_at_end; - bool m_cursor; - PGconn* m_session; - schema::DimInfoList m_dims; - size_t m_point_size; - uint32_t m_cur_row; - uint32_t m_cur_nrows; - PGresult* m_cur_result; - std::unique_ptr m_patch; -}; - -class Patch -{ -public: - Patch() : count(0), remaining(0) - {} - - point_count_t count; - point_count_t remaining; - std::string hex; - - std::vector binary; - static const uint32_t trim = 26; - -#define _base(x) ((x >= '0' && x <= '9') ? '0' : \ - (x >= 'a' && x <= 'f') ? 'a' - 10 : \ - (x >= 'A' && x <= 'F') ? 'A' - 10 : \ - '\255') -#define HEXOF(x) (x - _base(x)) - - inline void update_binary() - { - // http://stackoverflow.com/questions/8197838/convert-a-long-hex-string-in-to-int-array-with-sscanf - binary.resize((hex.size() - trim)/2); - - char const* source = hex.c_str() + trim; - char const* p = 0; - - for (p = source; p && *p; p += 2) - binary[(p - source) >> 1] = ((HEXOF(*p)) << 4) + HEXOF(*(p + 1)); - } -}; - -} // sequential -} // iterators - -} // pgpointcloud -} // driver -} // pdal - diff --git a/include/pdal/drivers/pgpointcloud/PgReader.hpp b/include/pdal/drivers/pgpointcloud/PgReader.hpp index d02bc49f76..315459182e 100644 --- a/include/pdal/drivers/pgpointcloud/PgReader.hpp +++ b/include/pdal/drivers/pgpointcloud/PgReader.hpp @@ -35,17 +35,13 @@ #pragma once #include -#include #include +#include #include -#include -#include #include -#include - namespace pdal { namespace drivers @@ -55,8 +51,42 @@ namespace pgpointcloud class PDAL_DLL PgReader : public pdal::Reader { + class Patch + { + public: + Patch() : count(0), remaining(0) + {} + + point_count_t count; + point_count_t remaining; + std::string hex; + + std::vector binary; + static const uint32_t trim = 26; + +#define _base(x) ((x >= '0' && x <= '9') ? '0' : \ + (x >= 'a' && x <= 'f') ? 'a' - 10 : \ + (x >= 'A' && x <= 'F') ? 'A' - 10 : \ + '\255') +#define HEXOF(x) (x - _base(x)) + + inline void update_binary() + { + // http://stackoverflow.com/questions/8197838/convert-a-long-hex-string-in-to-int-array-with-sscanf + binary.resize((hex.size() - trim)/2); + + char const* source = hex.c_str() + trim; + char const* p = 0; + + for (p = source; p && *p; p += 2) + binary[(p - source) >> 1] = + ((HEXOF(*p)) << 4) + HEXOF(*(p + 1)); + } + }; + public: - SET_STAGE_NAME("drivers.pgpointcloud.reader", "PostgreSQL Pointcloud Database Reader") + SET_STAGE_NAME("drivers.pgpointcloud.reader", + "PostgreSQL Pointcloud Database Reader") SET_STAGE_LINK("http://pdal.io/stages/drivers.pgpointcloud.reader.html") #ifdef PDAL_HAVE_POSTGRESQL SET_STAGE_ENABLED(true) @@ -68,22 +98,30 @@ class PDAL_DLL PgReader : public pdal::Reader ~PgReader(); static Options getDefaultOptions(); - virtual boost::uint64_t getNumPoints() const; - boost::uint64_t getMaxPoints() const; + virtual point_count_t getNumPoints() const; + point_count_t getMaxPoints() const; std::string getDataQuery() const; std::string connString() const { return m_connection; } void getSession() const; - StageSequentialIterator* createSequentialIterator() const; - private: virtual void addDimensions(PointContext ctx); virtual void processOptions(const Options& options); virtual void ready(PointContext ctx); + virtual point_count_t read(PointBuffer& buf, point_count_t count); + virtual void done(PointContext ctx); + virtual bool eof() + { return m_atEnd; } - pdal::SpatialReference fetchSpatialReference() const; - boost::uint32_t fetchPcid() const; + SpatialReference fetchSpatialReference() const; + uint32_t fetchPcid() const; + point_count_t readPgPatch(PointBuffer& buffer, point_count_t numPts); + + // Internal functions for managing scroll cursor + void CursorSetup(); + void CursorTeardown(); + bool NextBuffer(); PGconn* m_session; std::string m_connection; @@ -91,11 +129,18 @@ class PDAL_DLL PgReader : public pdal::Reader std::string m_schema_name; std::string m_column_name; std::string m_where; - mutable boost::uint32_t m_pcid; - mutable boost::uint64_t m_cached_point_count; - mutable boost::uint64_t m_cached_max_points; + mutable uint32_t m_pcid; + mutable point_count_t m_cached_point_count; + mutable point_count_t m_cached_max_points; schema::XMLSchema m_schema; - boost::optional m_spatialRef; + + bool m_atEnd; + size_t m_point_size; + uint32_t m_cur_row; + uint32_t m_cur_nrows; + PGresult* m_cur_result; + Patch m_patch; + PgReader& operator=(const PgReader&); // not implemented PgReader(const PgReader&); // not implemented }; diff --git a/include/pdal/drivers/qfit/Reader.hpp b/include/pdal/drivers/qfit/Reader.hpp index d44f68febc..048e617649 100644 --- a/include/pdal/drivers/qfit/Reader.hpp +++ b/include/pdal/drivers/qfit/Reader.hpp @@ -39,9 +39,7 @@ #include #include -#include #include -#include #ifdef BOOST_LITTLE_ENDIAN # define QFIT_SWAP_BE_TO_LE(p) \ @@ -72,14 +70,6 @@ namespace drivers namespace qfit { -namespace iterators -{ -namespace sequential -{ -class Reader; -} //namespace sequential -} //namespace iterators - enum QFIT_Format_Type { QFIT_Format_10 = 10, @@ -97,15 +87,8 @@ class qfit_error : public pdal_error {} }; -// supported options: -// id -// debug -// verbose -// filename [required] -// class PDAL_DLL Reader : public pdal::Reader { - friend class iterators::sequential::Reader; public: SET_STAGE_NAME("drivers.qfit.reader", "QFIT Reader") SET_STAGE_LINK("http://pdal.io/stages/drivers.qfit.reader.html") @@ -118,22 +101,20 @@ class PDAL_DLL Reader : public pdal::Reader std::string getFileName() const; - pdal::StageSequentialIterator* - createSequentialIterator(PointBuffer& buffer) const; - std::size_t getPointDataOffset() const { return m_offset; } - boost::uint32_t getPointDataSize() const + uint32_t getPointDataSize() const { return m_size; } point_count_t getNumPoints() const { return m_numPoints; } + bool eof() + { return m_index >= m_numPoints; } // this is called by the stage's iterator point_count_t processBuffer(PointBuffer& PointBuffer, std::istream& stream, point_count_t count) const; private: - std::string m_filename; QFIT_Format_Type m_format; std::ios::off_type m_point_bytes; std::size_t m_offset; @@ -142,40 +123,20 @@ class PDAL_DLL Reader : public pdal::Reader double m_scale_z; bool m_littleEndian; point_count_t m_numPoints; + std::istream* m_istream; + point_count_t m_index; virtual void processOptions(const Options& ops); virtual void initialize(); virtual void addDimensions(PointContext ctx); virtual void ready(PointContext ctx); + virtual point_count_t read(PointBuffer& buf, point_count_t count); + virtual void done(PointContext ctx); Reader& operator=(const Reader&); // not implemented Reader(const Reader&); // not implemented }; -namespace iterators -{ -namespace sequential -{ - -class Reader : public pdal::ReaderSequentialIterator -{ -public: - Reader(const qfit::Reader& reader); - ~Reader(); - -private: - uint64_t skipImpl(uint64_t); - point_count_t readBufferImpl(PointBuffer&); - bool atEndImpl() const - { return getIndex() >= m_reader.getNumPoints(); } - - const pdal::drivers::qfit::Reader& m_reader; - std::istream* m_istream; -}; - -} // namespace sequential -} // namespace iterators - } // namespace qfit } // namespace drivers } // namespace pdal diff --git a/include/pdal/drivers/sbet/Reader.hpp b/include/pdal/drivers/sbet/Reader.hpp index 203fb3c6c1..4865221844 100644 --- a/include/pdal/drivers/sbet/Reader.hpp +++ b/include/pdal/drivers/sbet/Reader.hpp @@ -37,7 +37,6 @@ #include #include #include -#include #include namespace pdal @@ -61,47 +60,20 @@ class PDAL_DLL SbetReader : public pdal::Reader static Dimension::IdList getDefaultDimensions() { return fileDimensions(); } - virtual StageSequentialIterator* createSequentialIterator() const; private: - std::string m_filename; std::unique_ptr m_stream; + // Number of points in the file. point_count_t m_numPts; + point_count_t m_index; - virtual void processOptions(const Options& options); virtual void addDimensions(PointContext ctx); virtual void ready(PointContext ctx); -}; - -namespace iterators -{ -namespace sequential -{ - -class PDAL_DLL SbetSeqIterator : public pdal::ReaderSequentialIterator -{ -public: - SbetSeqIterator(const Dimension::IdList& dims, point_count_t numPts, - ILeStream& stream) : - m_dims(dims), m_numPts(numPts), m_stream(stream) - {} - -private: - Dimension::IdList m_dims; - point_count_t m_numPts; - ILeStream& m_stream; - - virtual point_count_t readBufferImpl(PointBuffer& buf) - { return readImpl(buf, std::numeric_limits::max()); } + virtual point_count_t read(PointBuffer& buf, point_count_t count); + virtual bool eof(); - boost::uint64_t skipImpl(boost::uint64_t); - point_count_t readImpl(PointBuffer& buf, point_count_t numPts); - bool atEndImpl() const; void seek(PointId idx); }; -} // namespace sequential -} // namespace iterators - } // namespace sbet } // namespace drivers } // namespace pdal diff --git a/include/pdal/drivers/sqlite/SQLiteIterator.hpp b/include/pdal/drivers/sqlite/SQLiteIterator.hpp deleted file mode 100644 index 858992f737..0000000000 --- a/include/pdal/drivers/sqlite/SQLiteIterator.hpp +++ /dev/null @@ -1,143 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2012, Howard Butler, hobu.inc@gmail.com -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#pragma once - -#include -#include - - -#include -#include -#include - -#include - - -namespace pdal -{ -namespace drivers -{ -namespace sqlite -{ - - class SQLiteReader; - -namespace iterators -{ - -namespace sequential -{ - - -// class IteratorBase -// { -// public: -// IteratorBase(const pdal::drivers::sqlite::SQLiteReader& reader); -// -// protected: -// const pdal::drivers::sqlite::SQLiteReader& getReader() const; -// -// boost::uint32_t myReadBuffer(PointBuffer& data); -// -// boost::uint32_t myReadBlocks(PointBuffer& data); -// // -// // PointBufferPtr fetchPointBuffer( boost::int32_t const& cloud_id, -// // std::string const& schema_xml, -// // boost::uint32_t capacity); -// -// bool m_at_end; -// boost::int32_t m_active_cloud_id; -// PointBufferPtr m_active_buffer; -// BufferMap m_buffers; -// -// -// private: -// const pdal::drivers::sqlite::SQLiteReader& m_reader; -// sqlite3* m_session; -// -// -// // ::soci::statement getNextCloud(std::string const& cloud_table_name, -// // boost::int32_t& cloud_id, ::soci::row& r); -// // void readBlob(::soci::row& block, boost::uint32_t howMany); -// // void fillUserBuffer(PointBuffer& user_buffer); -// // -// // pdal::Bounds getBounds(Statement statement, BlockPtr block); -// IteratorBase& operator=(const IteratorBase&); // not implemented -// IteratorBase(const IteratorBase&); // not implemented; -// }; - - -class SQLiteIterator : public pdal::StageSequentialIterator -{ -public: - SQLiteIterator(const pdal::drivers::sqlite::SQLiteReader& reader, PatchPtr patch); - -protected: - // Skip count points, return number of points skipped - boost::uint64_t skipImpl(boost::uint64_t count); - - // Fill the provided pointbuffer, return the number of points written - point_count_t readImpl(PointBuffer& user_buffer, point_count_t count); - - point_count_t readBufferImpl(PointBuffer& buffer) - { - return readImpl(buffer, (std::numeric_limits::max)()); - } - // True when there are no more points to read - bool atEndImpl() const; - -private: - const pdal::drivers::sqlite::SQLiteReader& m_reader; - point_count_t readPatch(PointBuffer& buffer, - point_count_t numPts); - bool NextBuffer(); - bool doQuery(); - void validateQuery() const; - bool m_at_end; - std::unique_ptr m_session; - bool b_doneQuery; - PatchPtr m_patch; - int32_t m_point_size; -}; - - - -} // sequential - -} // iterators -} -} -} // namespace pdal::driver::sqlite - diff --git a/include/pdal/drivers/sqlite/SQLiteReader.hpp b/include/pdal/drivers/sqlite/SQLiteReader.hpp index 43a35fea23..e4088f7549 100644 --- a/include/pdal/drivers/sqlite/SQLiteReader.hpp +++ b/include/pdal/drivers/sqlite/SQLiteReader.hpp @@ -35,17 +35,12 @@ #pragma once #include -#include #include - #include -#include -#include #include - namespace pdal { namespace drivers @@ -53,8 +48,6 @@ namespace drivers namespace sqlite { - - class PDAL_DLL SQLiteReader : public pdal::Reader { public: @@ -67,33 +60,39 @@ class PDAL_DLL SQLiteReader : public pdal::Reader SQLiteReader(const Options&); static Options getDefaultOptions(); - pdal::StageSequentialIterator* - createSequentialIterator() const; - pdal::schema::XMLSchema fetchSchema(std::string const& query) const; - pdal::SpatialReference - fetchSpatialReference(std::string const& query) const; - + schema::XMLSchema fetchSchema(std::string const& query) const; + SpatialReference fetchSpatialReference(std::string const& query) const; SQLite& getSession() { return *m_session.get(); } private: - SQLiteReader& operator=(const SQLiteReader&); // not implemented - SQLiteReader(const SQLiteReader&); // not implemented + std::unique_ptr m_session; + std::string m_query; + std::string m_schemaFile; + std::string m_connection; + boost::optional m_spatialRef; + PatchPtr m_patch; + + bool m_at_end; + bool b_doneQuery; + int32_t m_point_size; virtual void initialize(); virtual void processOptions(const Options& options); virtual void addDimensions(PointContext ctx); + virtual void ready(PointContext ctx); + point_count_t read(PointBuffer& buf, point_count_t count); + bool eof() + { return m_at_end; } void validateQuery() const; + point_count_t readPatch(PointBuffer& buffer, point_count_t count); + bool NextBuffer(); - std::unique_ptr m_session; - std::string m_query; - std::string m_schemaFile; - std::string m_connection; - boost::optional m_spatialRef; - PatchPtr m_patch; + SQLiteReader& operator=(const SQLiteReader&); // not implemented + SQLiteReader(const SQLiteReader&); // not implemented }; -} -} -} // namespace pdal::driver::oci +} // namespace sqlite +} // namespace drivers +} // namespace pdal diff --git a/include/pdal/drivers/terrasolid/Reader.hpp b/include/pdal/drivers/terrasolid/Reader.hpp index 0fe378ebac..758d2238cb 100644 --- a/include/pdal/drivers/terrasolid/Reader.hpp +++ b/include/pdal/drivers/terrasolid/Reader.hpp @@ -35,11 +35,8 @@ #pragma once #include -#include #include -#include - #include #include @@ -76,21 +73,20 @@ struct TerraSolidHeader Color(0) {} - boost::int32_t HdrSize; - boost::int32_t HdrVersion; - boost::int32_t RecogVal; + int32_t HdrSize; + int32_t HdrVersion; + int32_t RecogVal; char RecogStr[4]; - boost::int32_t PntCnt; - boost::int32_t Units; + int32_t PntCnt; + int32_t Units; double OrgX; double OrgY; double OrgZ; - boost::int32_t Time; - boost::int32_t Color; - + int32_t Time; + int32_t Color; }; -typedef boost::scoped_ptr TerraSolidHeaderPtr ; +typedef boost::scoped_ptr TerraSolidHeaderPtr; class terrasolid_error : public pdal_error { public: @@ -100,34 +96,18 @@ class terrasolid_error : public pdal_error {} }; -// -// -// supported options: -// id -// debug -// verbose -// filename [required] -// - class PDAL_DLL Reader : public pdal::Reader { public: SET_STAGE_NAME("drivers.terrasolid.reader", "TerraSolid Reader") SET_STAGE_ENABLED(true) - Reader(const Options&); + Reader(const Options& options) : pdal::Reader(options), + m_format(TERRASOLID_Format_Unknown) + {} - static Options getDefaultOptions(); static Dimension::IdList getDefaultDimensions(); - std::string getFileName() const; - pdal::StageSequentialIterator* - createSequentialIterator(PointBuffer& buffer) const; - pdal::StageRandomIterator* createRandomIterator(PointBuffer& buffer) const; - - std::size_t getPointDataOffset() const - { return m_offset; } - boost::uint32_t getPointDataSize() const - { return m_size; } + point_count_t getNumPoints() const { return m_header->PntCnt; } @@ -135,73 +115,28 @@ class PDAL_DLL Reader : public pdal::Reader uint32_t processBuffer(PointBuffer& PointBuffer, std::istream& stream, uint64_t numPointsLeft) const; -protected: - inline TERRASOLID_Format_Type getFormat() const - { - return m_format; - } - private: TerraSolidHeaderPtr m_header; TERRASOLID_Format_Type m_format; - std::size_t m_offset; uint32_t m_size; bool m_haveColor; bool m_haveTime; + uint32_t m_baseTime; + std::istream* m_istream; + point_count_t m_index; virtual void initialize(); virtual void addDimensions(PointContext ctx); + virtual void ready(PointContext ctx); + virtual point_count_t read(PointBuffer& buf, point_count_t count); + virtual void done(PointContext ctx); + virtual bool eof() + { return m_index >= getNumPoints(); } Reader& operator=(const Reader&); // not implemented Reader(const Reader&); // not implemented }; -namespace iterators -{ - -namespace sequential -{ - -class Reader : public pdal::ReaderSequentialIterator -{ -public: - Reader(const pdal::drivers::terrasolid::Reader& reader, - PointBuffer& buffer); - ~Reader(); - -private: - boost::uint64_t skipImpl(boost::uint64_t); - point_count_t readBufferImpl(PointBuffer&); - bool atEndImpl() const; - - const pdal::drivers::terrasolid::Reader& m_reader; - std::istream* m_istream; -}; - - -} // sequential - -namespace random -{ - -class Reader : public pdal::ReaderRandomIterator -{ -public: - Reader(const pdal::drivers::terrasolid::Reader& reader, - PointBuffer& buffer); - ~Reader(); - -private: - boost::uint64_t seekImpl(boost::uint64_t); - point_count_t readBufferImpl(PointBuffer&); - - const pdal::drivers::terrasolid::Reader& m_reader; - std::istream* m_istream; -}; - -} // random -} // iterators - } // namespace terrasolid } // namespace drivers } // namespace pdal diff --git a/include/pdal/kernel/Delta.hpp b/include/pdal/kernel/Delta.hpp index 368594d14b..44253a8ef3 100644 --- a/include/pdal/kernel/Delta.hpp +++ b/include/pdal/kernel/Delta.hpp @@ -36,7 +36,6 @@ #define INCLUDED_PDAL_KERNEL_DELTA_HPP #include -#include #include #include #include diff --git a/include/pdal/kernel/Diff.hpp b/include/pdal/kernel/Diff.hpp index 26c4f9ab98..c442ba6af7 100644 --- a/include/pdal/kernel/Diff.hpp +++ b/include/pdal/kernel/Diff.hpp @@ -36,7 +36,6 @@ #define INCLUDED_PDAL_KERNEL_DIFF_HPP #include -#include #include #include diff --git a/include/pdal/kernel/Info.hpp b/include/pdal/kernel/Info.hpp index 0fd47f9b39..eda328b3b6 100644 --- a/include/pdal/kernel/Info.hpp +++ b/include/pdal/kernel/Info.hpp @@ -35,7 +35,6 @@ #pragma once #include -#include #include #include #include diff --git a/include/pdal/kernel/Pipeline.hpp b/include/pdal/kernel/Pipeline.hpp index cc30693a42..70205198bf 100644 --- a/include/pdal/kernel/Pipeline.hpp +++ b/include/pdal/kernel/Pipeline.hpp @@ -36,13 +36,11 @@ #define INCLUDED_PDAL_KERNEL_PIPELINE_HPP - #include #include #include #include #include -#include #include "Application.hpp" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7827e7fdc5..5d9634e8cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,12 +50,10 @@ set(PDAL_BASE_HPP "${PDAL_HEADERS_DIR}/Range.hpp" "${PDAL_HEADERS_DIR}/RawPtBuf.hpp" "${PDAL_HEADERS_DIR}/Reader.hpp" - "${PDAL_HEADERS_DIR}/ReaderIterator.hpp" "${PDAL_HEADERS_DIR}/SpatialReference.hpp" "${PDAL_HEADERS_DIR}/Stage.hpp" "${PDAL_HEADERS_DIR}/StageFactory.hpp" "${PDAL_HEADERS_DIR}/StageInfo.hpp" - "${PDAL_HEADERS_DIR}/StageIterator.hpp" "${PDAL_HEADERS_DIR}/StageRunner.hpp" "${PDAL_HEADERS_DIR}/StreamFactory.hpp" "${PDAL_HEADERS_DIR}/UserCallback.hpp" @@ -97,12 +95,10 @@ set(PDAL_BASE_CPP QuadIndex.cpp Range.cpp Reader.cpp - ReaderIterator.cpp SpatialReference.cpp Stage.cpp StageFactory.cpp StageInfo.cpp - StageIterator.cpp StreamFactory.cpp Utils.cpp Vector.cpp @@ -141,12 +137,12 @@ set (PDAL_DRIVERS_LAS_HPP "${PDAL_LAS_SRC}/GeotiffSupport.hpp" "${PDAL_LAS_SRC}/LasHeaderReader.hpp" "${PDAL_LAS_SRC}/LasHeaderWriter.hpp" - "${PDAL_LAS_SRC}/ZipPoint.hpp" "${PDAL_LAS_HEADERS}/Header.hpp" "${PDAL_LAS_HEADERS}/Reader.hpp" "${PDAL_LAS_HEADERS}/SummaryData.hpp" "${PDAL_LAS_HEADERS}/Support.hpp" "${PDAL_LAS_HEADERS}/Writer.hpp" + "${PDAL_LAS_HEADERS}/ZipPoint.hpp" "${PDAL_LAS_HEADERS}/VariableLengthRecord.hpp" ) @@ -182,14 +178,12 @@ set(PDAL_BPF_SRC "${PROJECT_SOURCE_DIR}/src/${PDAL_BPF_PATH}") set(PDAL_DRIVERS_BPF_HPP "${PDAL_BPF_HEADERS}/BpfReader.hpp" - "${PDAL_BPF_HEADERS}/BpfSeqIterator.hpp" "${PDAL_BPF_HEADERS}/BpfHeader.hpp" ) set(PDAL_DRIVERS_BPF_CPP "${PDAL_BPF_SRC}/BpfHeader.cpp" "${PDAL_BPF_SRC}/BpfReader.cpp" - "${PDAL_BPF_SRC}/BpfSeqIterator.cpp" ) list (APPEND PDAL_CPP ${PDAL_DRIVERS_BPF_CPP} ) @@ -261,7 +255,6 @@ set(PDAL_CARIS_SRC "${PROJECT_SOURCE_DIR}/src/${PDAL_CARIS_PATH}") set(PDAL_DRIVERS_CARIS_HPP "${PDAL_CARIS_HEADERS}/CloudReader.hpp" - "${PDAL_CARIS_HEADERS}/CloudIterator.hpp" "${PDAL_CARIS_SRC}/Utils.hpp" "${PDAL_CARIS_SRC}/config.h" "${PDAL_CARIS_SRC}/caris/caris_pc_wrapper.h" @@ -269,7 +262,6 @@ set(PDAL_DRIVERS_CARIS_HPP set (PDAL_DRIVERS_CARIS_CPP "${PDAL_CARIS_SRC}/CloudReader.cpp" - "${PDAL_CARIS_SRC}/CloudIterator.cpp" "${PDAL_CARIS_SRC}/pdal_csar.cpp" "${PDAL_CARIS_SRC}/Utils.cpp" "${PDAL_CARIS_SRC}/caris/caris_pc_wrapper.c" @@ -291,7 +283,6 @@ set(PDAL_ORACLE_SRC "${PROJECT_SOURCE_DIR}/src/${PDAL_ORACLE_PATH}") set(PDAL_DRIVERS_OCI_HPP "${PDAL_ORACLE_HEADERS}/Writer.hpp" "${PDAL_ORACLE_HEADERS}/OciReader.hpp" - "${PDAL_ORACLE_HEADERS}/OciSeqIterator.hpp" "${PDAL_ORACLE_HEADERS}/oci_wrapper.h" "${PDAL_ORACLE_HEADERS}/common.hpp" ) @@ -300,7 +291,6 @@ set (PDAL_DRIVERS_OCI_CPP "${PDAL_ORACLE_SRC}/oci_wrapper.cpp" "${PDAL_ORACLE_SRC}/common.cpp" "${PDAL_ORACLE_SRC}/OciReader.cpp" - "${PDAL_ORACLE_SRC}/OciSeqIterator.cpp" "${PDAL_ORACLE_SRC}/Writer.cpp" ) @@ -461,13 +451,11 @@ set(PDAL_SQLITE_SRC "${PROJECT_SOURCE_DIR}/src/${PDAL_SQLITE_PATH}") set(PDAL_DRIVERS_SQLITE_HPP "${PDAL_SQLITE_HEADERS}/SQLiteCommon.hpp" - "${PDAL_SQLITE_HEADERS}/SQLiteIterator.hpp" "${PDAL_SQLITE_HEADERS}/SQLiteReader.hpp" "${PDAL_SQLITE_HEADERS}/SQLiteWriter.hpp" ) set (PDAL_DRIVERS_SQLITE_CPP - "${PDAL_SQLITE_SRC}/SQLiteIterator.cpp" "${PDAL_SQLITE_SRC}/SQLiteReader.cpp" "${PDAL_SQLITE_SRC}/SQLiteWriter.cpp" ) @@ -492,13 +480,11 @@ set(PDAL_DRIVERS_PGPOINTCLOUD_HPP "${PDAL_PGPOINTCLOUD_HEADERS}/common.hpp" "${PDAL_PGPOINTCLOUD_HEADERS}/Writer.hpp" "${PDAL_PGPOINTCLOUD_HEADERS}/PgReader.hpp" - "${PDAL_PGPOINTCLOUD_HEADERS}/PgIterator.hpp" ) set (PDAL_DRIVERS_PGPOINTCLOUD_CPP "${PDAL_PGPOINTCLOUD_SRC}/Writer.cpp" "${PDAL_PGPOINTCLOUD_SRC}/PgReader.cpp" - "${PDAL_PGPOINTCLOUD_SRC}/PgIterator.cpp" ) # no provision is made for building as a plugin diff --git a/src/Reader.cpp b/src/Reader.cpp index 14fe6086c3..f4dd957eea 100644 --- a/src/Reader.cpp +++ b/src/Reader.cpp @@ -38,6 +38,14 @@ namespace pdal { +void Reader::readerProcessOptions(const Options& options) +{ + if (options.hasOption("filename")) + m_filename = options.getValueOrThrow("filename"); + if (options.hasOption("count")) + m_count = options.getValueOrThrow("count"); +} + boost::property_tree::ptree Reader::serializePipeline() const { diff --git a/src/ReaderIterator.cpp b/src/ReaderIterator.cpp deleted file mode 100644 index 52889d2601..0000000000 --- a/src/ReaderIterator.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com) -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#include -#include - - -namespace pdal -{ - -//--------------------------------------------------------------------------- -// -// ReaderSequentialIterator -// -//--------------------------------------------------------------------------- - -ReaderSequentialIterator::ReaderSequentialIterator(PointBuffer& buffer) - : StageSequentialIterator(buffer) -{} - - -ReaderSequentialIterator::~ReaderSequentialIterator() -{} - - -//--------------------------------------------------------------------------- -// -// RandomIterator -// -//--------------------------------------------------------------------------- - -ReaderRandomIterator::ReaderRandomIterator(PointBuffer& buffer) - : StageRandomIterator(buffer) -{} - - -ReaderRandomIterator::~ReaderRandomIterator() -{} - - -} // namespace pdal diff --git a/src/Stage.cpp b/src/Stage.cpp index 17b0a94ce2..22a6528637 100644 --- a/src/Stage.cpp +++ b/src/Stage.cpp @@ -165,6 +165,8 @@ void Stage::l_processOptions(const Options& options) // point. Maybe another stage might forward/set it later. } + // Process reader-specific options. + readerProcessOptions(options); // Process writer-specific options. writerProcessOptions(options); } diff --git a/src/StageIterator.cpp b/src/StageIterator.cpp deleted file mode 100644 index 82b573d2f6..0000000000 --- a/src/StageIterator.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com) -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#include - -#include // for std::min/max - -#include - -namespace pdal -{ - -static boost::uint32_t s_defaultChunkSize = 65536; - - -//--------------------------------------------------------------------------- -// -// StageIterator -// -//--------------------------------------------------------------------------- - -StageIterator::StageIterator(PointBuffer& buffer) -{ - (void)buffer; - Construct(); -} - - -StageIterator::StageIterator() -{ - Construct(); -} - - -void StageIterator::Construct() -{ - m_index = 0; - m_chunkSize = s_defaultChunkSize; - m_readBeginPerformed = false; - m_readBufferBeginPerformed = false; -} - -boost::uint64_t StageIterator::getIndex() const -{ - return m_index; -} - - -void StageIterator::setChunkSize(boost::uint32_t size) -{ - m_chunkSize = size; -} - - -boost::uint32_t StageIterator::getChunkSize() const -{ - return m_chunkSize; -} - - -point_count_t StageIterator::read(PointBuffer& buffer) -{ - readBegin(); - readBufferBegin(buffer); - point_count_t numRead = readBuffer(buffer); - readBufferEnd(buffer); - readEnd(); - - return numRead; -} - - -void StageIterator::readBegin() -{ - if (m_readBeginPerformed) - { - throw pdal_error("readBegin called without corresponding readEnd"); - } - - m_readBeginPerformed = false; - readBeginImpl(); - m_readBeginPerformed = true; -} - - -void StageIterator::readBufferBegin(PointBuffer& buffer) -{ - if (!m_readBeginPerformed) - { - throw pdal_error("readBufferBegin called without corresponding " - "readBegin"); - } - if (m_readBufferBeginPerformed) - { - throw pdal_error("readBufferBegin called without corresponding " - "readBufferEnd"); - } - - m_readBufferBeginPerformed = false; - readBufferBeginImpl(buffer); - m_readBufferBeginPerformed = true; -} - - -boost::uint32_t StageIterator::readBuffer(PointBuffer& buffer) -{ - if (!m_readBufferBeginPerformed) - { - throw pdal_error("readBuffer called without corresponding " - "readBufferBegin"); - } - - boost::uint32_t numRead = readBufferImpl(buffer); - m_index += numRead; - return numRead; -} - -void StageIterator::readBufferEnd(PointBuffer& buffer) -{ - if (!m_readBufferBeginPerformed) - { - throw pdal_error("readBufferEnd called without corresponding " - "readBufferBegin"); - } - - readBufferEndImpl(buffer); - m_readBufferBeginPerformed = false; -} - - -void StageIterator::readEnd() -{ - if (m_readBufferBeginPerformed) - { - throw pdal_error("readEnd called without corresponding readBufferEnd"); - } - - if (!m_readBeginPerformed) - { - throw pdal_error("readEnd called without corresponding readBegin"); - } - - readEndImpl(); - m_readBeginPerformed = false; -} - - -boost::uint64_t StageIterator::skip(boost::uint64_t count) -{ - uint32_t pos = m_index; - boost::uint64_t numSkipped = skipImpl(count); - m_index = pos + numSkipped; - return numSkipped; -} - - -//--------------------------------------------------------------------------- -// -// StageSequentialIterator -// -//--------------------------------------------------------------------------- - -StageSequentialIterator::StageSequentialIterator(PointBuffer& buffer) - : StageIterator(buffer) -{} - - -StageSequentialIterator::~StageSequentialIterator() -{} - - -bool StageSequentialIterator::atEnd() const -{ - return atEndImpl(); -} - -//--------------------------------------------------------------------------- -// -// StageRandomIterator -// -//--------------------------------------------------------------------------- - -StageRandomIterator::StageRandomIterator(PointBuffer& buffer) - : StageIterator(buffer) -{} - - -StageRandomIterator::~StageRandomIterator() -{} - - -boost::uint64_t StageRandomIterator::seek(boost::uint64_t position) -{ - m_index = seekImpl(position); - return m_index; -} - - -boost::uint64_t StageRandomIterator::skipImpl(boost::uint64_t numPts) -{ - uint64_t pos = m_index; - pos = seekImpl(pos + numPts); - return (pos - numPts); -} - -} // namespace pdal diff --git a/src/Writer.cpp b/src/Writer.cpp index 45bc365002..b19887cce9 100644 --- a/src/Writer.cpp +++ b/src/Writer.cpp @@ -35,7 +35,6 @@ #include #include -#include #include #include #include diff --git a/src/drivers/bpf/BpfReader.cpp b/src/drivers/bpf/BpfReader.cpp index 00533fe0cc..d54a3ca7d1 100644 --- a/src/drivers/bpf/BpfReader.cpp +++ b/src/drivers/bpf/BpfReader.cpp @@ -32,20 +32,23 @@ * OF SUCH DAMAGE. ****************************************************************************/ +#include + +#ifdef PDAL_HAVE_ZLIB +#include +#endif + #include -#include #include namespace pdal { -BpfReader::BpfReader(const Options& options) : Reader(options), - m_stream(options.getValueOrThrow("filename")) -{} - - -BpfReader::BpfReader(const std::string& filename) : m_stream(filename) -{} +void BpfReader::processOptions(const Options&) +{ + if (m_filename.empty()) + throw pdal_error("Can't read BPF file without filename."); +} // When the stage is intialized, the schema needs to be populated with the @@ -53,6 +56,7 @@ BpfReader::BpfReader(const std::string& filename) : m_stream(filename) // the dimensions in the PointBuffer. void BpfReader::initialize() { + m_stream.open(m_filename); // In order to know the dimensions we must read the file header. if (!m_header.read(m_stream)) return; @@ -119,17 +123,227 @@ bool BpfReader::readPolarData() return (bool)m_stream; } -StageSequentialIterator *BpfReader::createSequentialIterator() const + +void BpfReader::ready(PointContext ctx) +{ + m_index = 0; + m_start = m_stream.position(); + if (m_header.m_compression) + { +#ifdef PDAL_HAVE_ZLIB + m_deflateBuf.resize(numPoints() * m_dims.size() * sizeof(float)); + size_t index = 0; + size_t bytesRead = 0; + do + { + bytesRead = readBlock(m_deflateBuf, index); + index += bytesRead; + } while (bytesRead > 0 && index < m_deflateBuf.size()); + m_charbuf.initialize(m_deflateBuf.data(), m_deflateBuf.size(), m_start); + m_stream.pushStream(new std::istream(&m_charbuf)); +#else + throw "BPF compression required, but ZLIB is unavailable."; +#endif + } +} + + +void BpfReader::done(PointContext) { - return new BpfSeqIterator(m_dims, m_header.m_numPts, - m_header.m_pointFormat, m_header.m_compression, - const_cast(m_stream)); + delete m_stream.popStream(); } -StageRandomIterator * -BpfReader::createRandomIterator(PointBuffer& pb) const + +point_count_t BpfReader::read(PointBuffer& data, point_count_t count) { - return NULL; + switch (m_header.m_pointFormat) + { + case BpfFormat::PointMajor: + return readPointMajor(data, count); + case BpfFormat::DimMajor: + return readDimMajor(data, count); + case BpfFormat::ByteMajor: + return readByteMajor(data, count); + default: + break; + } + return 0; +} + + +size_t BpfReader::readBlock(std::vector& outBuf, size_t index) +{ +#ifdef PDAL_HAVE_ZLIB + boost::uint32_t finalBytes; + boost::uint32_t compressBytes; + + m_stream >> finalBytes; + m_stream >> compressBytes; + + std::vector in(compressBytes); + + // Fill the input bytes from the stream. + m_stream.get(in); + int ret = inflate(in.data(), compressBytes, + outBuf.data() + index, finalBytes); + return (ret ? 0 : finalBytes); +#else + throw pdal_error("BPF compression required, but ZLIB is unavailable"); +#endif +} + + +bool BpfReader::eof() +{ + return m_index >= numPoints(); +} + + +point_count_t BpfReader::readPointMajor(PointBuffer& data, point_count_t count) +{ + PointId nextId = data.size(); + PointId idx = m_index; + point_count_t numRead = 0; + seekPointMajor(idx); + while (numRead < count && idx < numPoints()) + { + for (size_t d = 0; d < m_dims.size(); ++d) + { + float f; + + m_stream >> f; + data.setField(m_dims[d].m_id, nextId, f + m_dims[d].m_offset); + } + idx++; + numRead++; + nextId++; + } + m_index = idx; + return numRead; +} + +point_count_t BpfReader::readDimMajor(PointBuffer& data, point_count_t count) +{ + PointId idx; + PointId startId = data.size(); + point_count_t numRead = 0; + for (size_t d = 0; d < m_dims.size(); ++d) + { + idx = m_index; + PointId nextId = startId; + numRead = 0; + seekDimMajor(d, idx); + for (; numRead < count && idx < numPoints(); idx++, numRead++, nextId++) + { + float f; + + m_stream >> f; + data.setField(m_dims[d].m_id, nextId, f + m_dims[d].m_offset); + } + } + m_index = idx; + return numRead; +} + +point_count_t BpfReader::readByteMajor(PointBuffer& data, point_count_t count) +{ + PointId idx; + PointId startId = data.size(); + point_count_t numRead = 0; + + // We need a temp buffer for the point data. + union uu + { + float f; + uint32_t u32; + }; + std::unique_ptr uArr( + new uu[std::min(count, numPoints() - m_index)]); + + for (size_t d = 0; d < m_dims.size(); ++d) + { + for (size_t b = 0; b < sizeof(float); ++b) + { + idx = m_index; + numRead = 0; + PointId nextId = startId; + seekByteMajor(d, b, idx); + + for (;numRead < count && idx < numPoints(); + idx++, numRead++, nextId++) + { + union uu& u = *(uArr.get() + numRead); + + if (b == 0) + u.u32 = 0; + uint8_t u8; + m_stream >> u8; + u.u32 |= ((uint32_t)u8 << (b * CHAR_BIT)); + if (b == 3) + { + u.f += m_dims[d].m_offset; + data.setField(m_dims[d].m_id, nextId, u.f); + } + } + } + } + m_index = idx; + return numRead; +} + + +void BpfReader::seekPointMajor(PointId ptIdx) +{ + std::streamoff offset = ptIdx * sizeof(float) * m_dims.size(); + m_stream.seek(m_start + offset); +} + + +void BpfReader::seekDimMajor(size_t dimIdx, PointId ptIdx) +{ + std::streamoff offset = ((sizeof(float) * dimIdx * numPoints()) + + (sizeof(float) * ptIdx)); + m_stream.seek(m_start + offset); +} + + +void BpfReader::seekByteMajor(size_t dimIdx, size_t byteIdx, PointId ptIdx) +{ + std::streamoff offset = + (dimIdx * numPoints() * sizeof(float)) + + (byteIdx * numPoints()) + + ptIdx; + m_stream.seek(m_start + offset); +} + + +#ifdef PDAL_HAVE_ZLIB +int BpfReader::inflate(char *buf, size_t insize, char *outbuf, size_t outsize) +{ + if (insize == 0) + return 0; + + int ret; + z_stream strm; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + if (inflateInit(&strm) != Z_OK) + return -2; + + strm.avail_in = insize; + strm.next_in = (unsigned char *)buf; + strm.avail_out = outsize; + strm.next_out = (unsigned char *)outbuf; + + ret = ::inflate(&strm, Z_NO_FLUSH); + (void)inflateEnd(&strm); + return ret == Z_STREAM_END ? 0 : -1; } +#endif -} //namespace +} //namespace pdal diff --git a/src/drivers/bpf/BpfSeqIterator.cpp b/src/drivers/bpf/BpfSeqIterator.cpp deleted file mode 100644 index aa6aa44ead..0000000000 --- a/src/drivers/bpf/BpfSeqIterator.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2014, Andrew Bell -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#include -#include - -#include -#include -#include -#include - -#ifdef PDAL_HAVE_ZLIB -#include -#endif - -namespace pdal -{ - -BpfSeqIterator::BpfSeqIterator(const BpfDimensionList& dims, - point_count_t numPoints, BpfFormat::Enum pointFormat, bool compression, - ILeStream& stream) : - m_dims(dims), m_numPoints(numPoints), m_pointFormat(pointFormat), - m_stream(stream), m_index(0), m_start(m_stream.position()) -{ - if (compression) - { -#ifdef PDAL_HAVE_ZLIB - m_deflateBuf.resize(m_numPoints * m_dims.size() * sizeof(float)); - size_t index = 0; - size_t bytesRead = 0; - do - { - bytesRead = readBlock(m_deflateBuf, index); - index += bytesRead; - } while (bytesRead > 0 && index < m_deflateBuf.size()); - m_charbuf.initialize(m_deflateBuf.data(), m_deflateBuf.size(), m_start); - m_stream.pushStream(new std::istream(&m_charbuf)); -#else - throw "BPF compression required, but ZLIB is unavailable."; -#endif - } -} - -BpfSeqIterator::~BpfSeqIterator() -{ - delete m_stream.popStream(); -} - -point_count_t BpfSeqIterator::readBufferImpl(PointBuffer& data) -{ - return read(data, std::numeric_limits::max()); -} - -point_count_t BpfSeqIterator::readImpl(PointBuffer& data, point_count_t count) -{ - return read(data, count); -} - -size_t BpfSeqIterator::readBlock(std::vector& outBuf, size_t index) -{ -#ifdef PDAL_HAVE_ZLIB - boost::uint32_t finalBytes; - boost::uint32_t compressBytes; - - m_stream >> finalBytes; - m_stream >> compressBytes; - - std::vector in(compressBytes); - - // Fill the input bytes from the stream. - m_stream.get(in); - int ret = inflate(in.data(), compressBytes, - outBuf.data() + index, finalBytes); - return (ret ? 0 : finalBytes); -#else - throw pdal_error("BPF compression required, but ZLIB is unavailable"); -#endif -} - -point_count_t BpfSeqIterator::read(PointBuffer& data, point_count_t count) -{ - switch (m_pointFormat) - { - case BpfFormat::PointMajor: - return readPointMajor(data, count); - case BpfFormat::DimMajor: - return readDimMajor(data, count); - case BpfFormat::ByteMajor: - return readByteMajor(data, count); - default: - break; - } - return 0; -} - -boost::uint64_t BpfSeqIterator::skipImpl(boost::uint64_t pointsToSkip) -{ - point_count_t lastIndex = m_index; - m_index += (point_count_t)pointsToSkip; - m_index = std::min(m_index, m_numPoints); - return std::min((point_count_t)pointsToSkip, m_index - lastIndex); -} - -bool BpfSeqIterator::atEndImpl() const -{ - return m_index >= m_numPoints; -} - -point_count_t BpfSeqIterator::readPointMajor(PointBuffer& data, - point_count_t count) -{ - PointId nextId = data.size(); - PointId idx = m_index; - point_count_t numRead = 0; - seekPointMajor(idx); - while (numRead < count && idx < m_numPoints) - { - for (size_t d = 0; d < m_dims.size(); ++d) - { - float f; - - m_stream >> f; - data.setField(m_dims[d].m_id, nextId, f + m_dims[d].m_offset); - } - idx++; - numRead++; - nextId++; - } - m_index = idx; - return numRead; -} - -point_count_t BpfSeqIterator::readDimMajor(PointBuffer& data, point_count_t count) -{ - PointId idx; - PointId startId = data.size(); - point_count_t numRead = 0; - for (size_t d = 0; d < m_dims.size(); ++d) - { - idx = m_index; - PointId nextId = startId; - numRead = 0; - seekDimMajor(d, idx); - for (; numRead < count && idx < m_numPoints; idx++, numRead++, nextId++) - { - float f; - - m_stream >> f; - data.setField(m_dims[d].m_id, nextId, f + m_dims[d].m_offset); - } - } - m_index = idx; - return numRead; -} - -point_count_t BpfSeqIterator::readByteMajor(PointBuffer& data, - point_count_t count) -{ - PointId idx; - PointId startId = data.size(); - point_count_t numRead = 0; - - // We need a temp buffer for the point data. - union uu - { - float f; - uint32_t u32; - }; - std::unique_ptr uArr( - new uu[std::min(count, m_numPoints - m_index)]); - - for (size_t d = 0; d < m_dims.size(); ++d) - { - for (size_t b = 0; b < sizeof(float); ++b) - { - idx = m_index; - numRead = 0; - PointId nextId = startId; - seekByteMajor(d, b, idx); - - for (;numRead < count && idx < m_numPoints; - idx++, numRead++, nextId++) - { - union uu& u = *(uArr.get() + numRead); - - if (b == 0) - u.u32 = 0; - uint8_t u8; - m_stream >> u8; - u.u32 |= ((uint32_t)u8 << (b * CHAR_BIT)); - if (b == 3) - { - u.f += m_dims[d].m_offset; - data.setField(m_dims[d].m_id, nextId, u.f); - } - } - } - } - m_index = idx; - return numRead; -} - -void BpfSeqIterator::seekPointMajor(uint32_t ptIdx) -{ - std::streamoff offset = ptIdx * sizeof(float) * m_dims.size(); - m_stream.seek(m_start + offset); -} - -void BpfSeqIterator::seekDimMajor(size_t dimIdx, uint32_t ptIdx) -{ - std::streamoff offset = ((sizeof(float) * dimIdx * m_numPoints) + - (sizeof(float) * ptIdx)); - m_stream.seek(m_start + offset); -} - -void BpfSeqIterator::seekByteMajor(size_t dimIdx, size_t byteIdx, uint32_t ptIdx) -{ - std::streamoff offset = - (dimIdx * m_numPoints * sizeof(float)) + - (byteIdx * m_numPoints) + - ptIdx; - m_stream.seek(m_start + offset); -} - -#ifdef PDAL_HAVE_ZLIB -int BpfSeqIterator::inflate(char *buf, size_t insize, char *outbuf, - size_t outsize) -{ - if (insize == 0) - return 0; - - int ret; - z_stream strm; - - /* allocate inflate state */ - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = 0; - strm.next_in = Z_NULL; - if (inflateInit(&strm) != Z_OK) - return -2; - - strm.avail_in = insize; - strm.next_in = (unsigned char *)buf; - strm.avail_out = outsize; - strm.next_out = (unsigned char *)outbuf; - - ret = ::inflate(&strm, Z_NO_FLUSH); - (void)inflateEnd(&strm); - return ret == Z_STREAM_END ? 0 : -1; -} -#endif - -} //namespace diff --git a/src/drivers/caris/CloudReader.cpp b/src/drivers/caris/CloudReader.cpp index 482f5c663b..4dfb85b188 100644 --- a/src/drivers/caris/CloudReader.cpp +++ b/src/drivers/caris/CloudReader.cpp @@ -25,8 +25,9 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ************************************************************************/ + +#include #include -#include #include "Utils.hpp" @@ -37,116 +38,60 @@ #endif #include -#include -#include -#include -#include -#include -#include #ifdef _MSC_VER # pragma warning(pop) - // decorated name length exceeded, name was truncated # pragma warning(disable : 4503) #endif +namespace pdal +{ namespace csar { -using namespace csar::utils; - namespace { - -//************************************************************************ -//! callback for logging messages -/*! -\param in_reader - \li CloudReader* to log to -\param in_message - \li message to log -*/ -//************************************************************************ -void logCallback(void* in_reader, const char* in_message) +void logCallback(void *in_reader, const char *in_message) { - CloudReader * reader = (CloudReader *)in_reader; + CloudReader *reader = (CloudReader *)in_reader; if (reader) - { - reader->log()->get(pdal::logINFO) << in_message << std::flush; - } + reader->log()->get(LogLevel::Info) << in_message << std::flush; } -} +} // anonymous namespace -//************************************************************************ -//! constructor -/*! -\param options - \li Reader options -*/ -//************************************************************************ -CloudReader::CloudReader( - const pdal::Options& options) - : pdal::Reader(options) -{ -} -//************************************************************************ -//! destructor -//************************************************************************ CloudReader::~CloudReader() { if (m_cloud) caris_cloud_release(m_cloud); } -//! \copydoc pdal::Reader::initialize -void CloudReader::initialize() + +point_count_t CloudReader::numPoints() { - pdal::Reader::initialize(); + return caris_cloud_num_points(m_cloud); +} + - int status = caris_cloud_open(getURI().c_str(), &m_cloud, &logCallback, this); +void CloudReader::initialize() +{ + int status = caris_cloud_open(getURI().c_str(), &m_cloud, + &logCallback, this); if (status) { std::string msg = caris_status_message(status, isDebug()); throw pdal::pdal_error(msg); } +} - assert(m_cloud); - - // bounds - { - double minMaxXYZ[2][3]; - caris_cloud_extents(m_cloud, - &minMaxXYZ[0][0], &minMaxXYZ[0][1], &minMaxXYZ[0][2], - &minMaxXYZ[1][0], &minMaxXYZ[1][1], &minMaxXYZ[1][2]); - - setBounds(pdal::Bounds( - minMaxXYZ[0][0], minMaxXYZ[0][1], minMaxXYZ[0][2], - minMaxXYZ[1][0], minMaxXYZ[1][1], minMaxXYZ[1][2] - )); - } - - setNumPoints(caris_cloud_num_points(m_cloud)); - -/** - if (const char* wktSR = caris_cloud_spatial_reference(m_cloud)) - setSpatialReference(pdal::SpatialReference(wktSR)); -**/ - - // Dimensions - pdal::Schema & schema = getSchemaRef(); - - // generate dimension UUIDs such that they are unique to the driver, but - // consistent accoss loads - boost::uuids::name_generator uuidGen( - boost::uuids::string_generator()( - "{5C668903-34CF-40d3-92C3-B8D9AB070902}")); +void CloudReader::addDimensions(PointContext ctx) +{ int numDims = 0; - caris_dimension const* dimArray = NULL; + const caris_dimension *dimArray = NULL; caris_cloud_dimensions(m_cloud, &dimArray, &numDims); // caris_dimesions may contain a tuple of numeric elements which need @@ -155,56 +100,130 @@ void CloudReader::initialize() { caris_dimension const& carisDim = dimArray[dimIndex]; - for (int tupleIndex = 0; tupleIndex < carisDim.tuple_length; ++tupleIndex) + for (int tupleIndex = 0; tupleIndex < carisDim.tuple_length; + ++tupleIndex) { - std::string name; - - if (carisDim.tuple_length == 1) + Dimension::Id::Enum dim = Dimension::Id::Unknown; + Dimension::Type::Enum inType = Dimension::Type::None; + std::string name = carisDim.name; + if (carisDim.tuple_length > 1) { - name = carisDim.name; - } - else - { - if (dimIndex == 0 - && carisDim.type == CARIS_TYPE_FLOAT64 - && carisDim.tuple_length == 3) + if (dimIndex == 0 && carisDim.type == CARIS_TYPE_FLOAT64 && + carisDim.tuple_length == 3) { - // position is always the first dim, name them X,Y,Z - char const* xyzStr[] = {"X", "Y", "Z"}; - name = xyzStr[tupleIndex]; + Dimension::Id::Enum xyz[] = + { Dimension::Id::X, + Dimension::Id::Y, + Dimension::Id::Z }; + inType = Dimension::Type::Double; + dim = xyz[tupleIndex]; } else - { - name = std::string(carisDim.name) - + "." + boost::lexical_cast(tupleIndex); - } + name += "." + boost::lexical_cast(tupleIndex); } - pdal::Dimension pdalDim( - name, - carisTypeToInterpretation(caris_type(carisDim.type)), - carisTypeToSize(caris_type(carisDim.type))); - pdalDim.setUUID(uuidGen(name)); - pdalDim.setNamespace(getName()); - m_dimInfo[pdalDim.getUUID()] = DimInfo(dimIndex, tupleIndex, &carisDim); - schema.appendDimension(pdalDim); + if (dim != Dimension::Id::Unknown) + { + inType = utils::carisTypeToPdal((caris_type)carisDim.type); + if (inType == Dimension::Type::None) + continue; + dim = ctx.registerOrAssignDim(name, inType); + } + m_dims[dim] = DimInfo(dimIndex, tupleIndex, inType, &carisDim); } } if (caris_cloud_status(m_cloud)) { - std::string msg = caris_status_message(caris_cloud_status(m_cloud), isDebug()); + std::string msg = caris_status_message(caris_cloud_status(m_cloud), + isDebug()); throw pdal::pdal_error(msg); } } +using namespace csar::utils; + +void CloudReader::ready(PointContext ctx) +{ + m_itr = caris_cloud_create_itr(m_cloud); + throwIfItrError(); +} + + +void CloudReader::done(PointContext ctx) +{ + if (m_itr) + caris_itr_release(m_itr); +} + + +point_count_t CloudReader::read(pdal::PointBuffer& io_buffer, point_count_t num) +{ + assert(m_itr); + + if (eof()) + return 0; + + // Determine the number of points availabe from the current iterator. + point_count_t numPoints = caris_itr_num_points(m_itr); + numPoints -= m_currentOffset; + + // We don't want any more points than requested. + num = std::min(numPoints, num); + + PointId startIdx = io_buffer.size(); + for (auto di = m_dims.begin(); di != m_dims.end(); ++di) + { + Dimension::Id::Enum dim = di->first; + DimInfo& dimInfo = di->second; + + int32_t numDimElements = 0; + const void *dimElements = caris_itr_read(m_itr, dimInfo.dimIndex, + &numDimElements); + throwIfItrError(); + assert((point_count_t)numDimElements == num); + + size_t elementSize = Dimension::size(dimInfo.type); + size_t srcStride = dimInfo.dimension->tuple_length * elementSize; + uint8_t *src = (uint8_t *)dimElements + + (m_currentOffset * srcStride) + + (elementSize * dimInfo.tupleIndex); + + PointId idx = startIdx; + for (size_t i = 0; i < num; ++i, ++idx, src += srcStride) + io_buffer.setField(dim, dimInfo.type, idx, (void *)src); + } + m_currentOffset += num; + + if ((point_count_t)m_currentOffset == numPoints) + { + m_currentOffset = 0; + caris_itr_next(m_itr); + } + + throwIfItrError(); + + return num; +} + + +bool CloudReader::eof() +{ + return (bool)caris_itr_done(m_itr); +} + -//! \copydoc pdal::Reader::createSequentialIterator -pdal::StageSequentialIterator* CloudReader::createSequentialIterator( - pdal::PointBuffer& in_buffer) const +//************************************************************************ +//! throw a pdal::pdal_error if an error has occured in the wrapped caris_itr +//************************************************************************ +void CloudReader::throwIfItrError() const { - assert(m_cloud); - return new CloudIterator(in_buffer, getCarisCloud()); + if (int status = caris_itr_status(m_itr)) + { + std::string msg = caris_status_message(status, isDebug()); + throw pdal::pdal_error(msg); + } } -} // namespace +} // namespace csar +} // namespace pdal diff --git a/src/drivers/caris/Utils.cpp b/src/drivers/caris/Utils.cpp index 382c628541..fcf30dbfa9 100644 --- a/src/drivers/caris/Utils.cpp +++ b/src/drivers/caris/Utils.cpp @@ -28,12 +28,13 @@ #include "Utils.hpp" -#include -#include -#include "boost_range_algorithm_count.hpp" +#include + #include #include +namespace pdal +{ namespace csar { namespace utils @@ -48,30 +49,35 @@ namespace utils \li pdal::dimension::Interpretation of \e in_type */ //************************************************************************ -pdal::dimension::Interpretation carisTypeToInterpretation(caris_type in_type) +Dimension::Type::Enum carisTypeToPdal(caris_type in_type) { - using namespace pdal::dimension; + using namespace Dimension; switch (in_type) { case CARIS_TYPE_FLOAT32: + return Type::Float; case CARIS_TYPE_FLOAT64: - return Float; + return Type::Double; case CARIS_TYPE_INT8: - return SignedByte; // or SignedInteger + return Type::Signed8; case CARIS_TYPE_INT16: + return Type::Signed16; case CARIS_TYPE_INT32: + return Type::Signed32; case CARIS_TYPE_INT64: - return SignedInteger; + return Type::Signed64; case CARIS_TYPE_UINT8: - return UnsignedByte; // or UnsignedInteger + return Type::Unsigned8; case CARIS_TYPE_UINT16: + return Type::Unsigned16; case CARIS_TYPE_UINT32: + return Type::Unsigned32; case CARIS_TYPE_UINT64: - return UnsignedInteger; + return Type::Unsigned64; default: assert(false && "Invalid caris_type"); - return Undefined; + return Type::None; } } @@ -84,6 +90,7 @@ pdal::dimension::Interpretation carisTypeToInterpretation(caris_type in_type) \li number of bytes of an element of type \e in_type */ //************************************************************************ +/** pdal::dimension::size_type carisTypeToSize(caris_type in_type) { using namespace pdal::dimension; @@ -109,6 +116,7 @@ pdal::dimension::size_type carisTypeToSize(caris_type in_type) return 0; } } +**/ //************************************************************************ //! convert a filesystem path to a URI @@ -139,9 +147,11 @@ std::string systemPathToURI(std::string const& in_path) std::string uri = "file://"; - BOOST_FOREACH(char c, path) + for (auto ci = path.begin(); ci != path.end(); ++ci) { - if (boost::range::count(validChars, c)) + char c = *ci; +// if (!boost::algorithm::find_first(validChars, c).empty()) + if (strchr(validChars, c)) { uri += c; } @@ -173,5 +183,6 @@ std::string systemPathToURI(std::string const& in_path) return uri; } -} -} +} // namespace utils; +} // namespace csar +} // namespace pdal diff --git a/src/drivers/caris/Utils.hpp b/src/drivers/caris/Utils.hpp index f0391a4762..f23885739a 100644 --- a/src/drivers/caris/Utils.hpp +++ b/src/drivers/caris/Utils.hpp @@ -38,17 +38,19 @@ #include #include -#include + +#include #ifdef _MSC_VER # pragma warning(pop) #endif +namespace pdal { namespace csar { namespace utils { -pdal::dimension::Interpretation carisTypeToInterpretation(caris_type in_type); -pdal::dimension::size_type carisTypeToSize(caris_type in_type); +pdal::Dimension::Type::Enum carisTypeToPdal(caris_type in_type); +//pdal::dimension::size_type carisTypeToSize(caris_type in_type); std::string systemPathToURI(std::string const& in_path); /// Lookup an item in a std::map @@ -70,6 +72,8 @@ boost::optional getOptionalCRef( return boost::none; } -}} // namespace +} // namespace utils +} // namespace csar +} // namespace pdal #endif diff --git a/src/drivers/caris/boost_range_algorithm_count.hpp b/src/drivers/caris/boost_range_algorithm_count.hpp deleted file mode 100644 index f9967b7418..0000000000 --- a/src/drivers/caris/boost_range_algorithm_count.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright Neil Groves 2009. Use, modification and -// distribution is subject to the Boost Software License, Version -// 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// -// For more information, see http://www.boost.org/libs/range/ -// -#ifndef BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED -#define BOOST_RANGE_ALGORITHM_COUNT_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - -namespace pdalboost{} namespace boost = pdalboost; namespace pdalboost{ - - namespace range - { - -/// \brief template function count -/// -/// range-based version of the count std algorithm -/// -/// \pre SinglePassRange is a model of the SinglePassRangeConcept -template< class SinglePassRange, class Value > -inline BOOST_DEDUCED_TYPENAME range_difference::type -count(SinglePassRange& rng, const Value& val) -{ - BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - return std::count(boost::begin(rng), boost::end(rng), val); -} - -/// \overload -template< class SinglePassRange, class Value > -inline BOOST_DEDUCED_TYPENAME range_difference::type -count(const SinglePassRange& rng, const Value& val) -{ - BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); - return std::count(boost::begin(rng), boost::end(rng), val); -} - - } // namespace range - using range::count; -} // namespace boost - -#endif // include guard diff --git a/src/drivers/caris/caris/caris_pc_wrapper.h b/src/drivers/caris/caris/caris_pc_wrapper.h index 1c7c08ba6f..7f5ab13b3a 100644 --- a/src/drivers/caris/caris/caris_pc_wrapper.h +++ b/src/drivers/caris/caris/caris_pc_wrapper.h @@ -41,6 +41,7 @@ #else #include #endif +#include #ifdef __cplusplus extern "C" { diff --git a/src/drivers/caris/pdal_csar.cpp b/src/drivers/caris/pdal_csar.cpp index 223fffe718..9cee51c8ce 100644 --- a/src/drivers/caris/pdal_csar.cpp +++ b/src/drivers/caris/pdal_csar.cpp @@ -56,7 +56,7 @@ namespace { //! CARIS CSAR file Point Cloud Reader -class FileCloudReader : public csar::CloudReader +class FileCloudReader : public pdal::csar::CloudReader { public: @@ -77,7 +77,7 @@ class FileCloudReader : public csar::CloudReader protected: virtual std::string getURI() const { - return csar::utils::systemPathToURI(m_filename); + return pdal::csar::utils::systemPathToURI(m_filename); } private: @@ -92,7 +92,7 @@ class FileCloudReader : public csar::CloudReader }; //! CARIS Database Point Cloud Reader -class DBCloudReader : public csar::CloudReader +class DBCloudReader : public pdal::csar::CloudReader { public: diff --git a/src/drivers/faux/Reader.cpp b/src/drivers/faux/Reader.cpp index f1537dacec..8d4a86d3a6 100644 --- a/src/drivers/faux/Reader.cpp +++ b/src/drivers/faux/Reader.cpp @@ -38,7 +38,6 @@ #include - namespace pdal { namespace drivers @@ -57,26 +56,36 @@ static Mode string2mode(const std::string& str) Reader::Reader(const Options& options) : pdal::Reader(options) -{} +{ + m_count = 0; +} void Reader::processOptions(const Options& options) { - m_bounds = options.getValueOrThrow>("bounds"); - m_numPoints = options.getValueOrThrow("num_points"); + Bounds bounds = options.getValueOrThrow>("bounds"); + const std::vector>& ranges = bounds.dimensions(); + m_minX = ranges[0].getMinimum(); + m_maxX = ranges[0].getMaximum(); + m_minY = ranges[1].getMinimum(); + m_maxY = ranges[1].getMaximum(); + m_minZ = ranges[2].getMinimum(); + m_maxZ = ranges[2].getMaximum(); + + // For backward compatibility. + if (m_count == 0) + m_count = options.getValueOrThrow("num_points"); m_mode = string2mode(options.getValueOrThrow("mode")); - // boost::lexical_cast, which is used by option.getValue<>, doesn't deal - // nicely with uint8_t. - // http://www.boost.org/doc/libs/1_56_0/doc/html/boost_lexical_cast/frequently_asked_questions.html - m_numberOfReturns = boost::numeric_cast( - options.getValueOrDefault("number_of_returns", 0)); + m_numReturns = options.getValueOrDefault("number_of_returns", 0); + if (m_numReturns > 10) + throw pdal_error("faux: number_of_returns option must be 10 or less."); } void Reader::addDimensions(PointContext ctx) { ctx.registerDims(getDefaultDimensions()); - if (m_numberOfReturns > 0) + if (m_numReturns > 0) { ctx.registerDim(Dimension::Id::ReturnNumber); ctx.registerDim(Dimension::Id::NumberOfReturns); @@ -96,49 +105,14 @@ Dimension::IdList Reader::getDefaultDimensions() } -Options Reader::getDefaultOptions() -{ - Options options; - return options; -} - - -pdal::StageSequentialIterator* Reader::createSequentialIterator() const -{ - return new FauxSeqIterator(m_bounds, m_mode, m_numPoints, - m_numberOfReturns, log()); -} - -} // namespace faux -} // namespace drivers - - -FauxSeqIterator::FauxSeqIterator(const Bounds& bounds, - drivers::faux::Mode mode, point_count_t numPoints, - uint8_t numberOfReturns, LogPtr log) : - m_time(0), m_mode(mode), m_numPoints(numPoints), - m_returnNumber(1), m_numberOfReturns(numberOfReturns), m_log(log) -{ - const std::vector>& ranges = bounds.dimensions(); - m_minX = ranges[0].getMinimum(); - m_maxX = ranges[0].getMaximum(); - m_minY = ranges[1].getMinimum(); - m_maxY = ranges[1].getMaximum(); - m_minZ = ranges[2].getMinimum(); - m_maxZ = ranges[2].getMaximum(); -} - - -point_count_t FauxSeqIterator::readImpl(PointBuffer& buf, point_count_t count) +point_count_t Reader::read(PointBuffer& buf, point_count_t count) { - using namespace pdal::drivers::faux; - const double numDeltas = (double)count - 1.0; const double delX = (m_maxX - m_minX) / numDeltas; const double delY = (m_maxY - m_minY) / numDeltas; const double delZ = (m_maxZ - m_minZ) / numDeltas; - m_log->get(LogLevel::Debug5) << "Reading a point buffer of " << + log()->get(LogLevel::Debug5) << "Reading a point buffer of " << count << " points." << std::endl; for (PointId idx = 0; idx < count; ++idx) @@ -169,15 +143,17 @@ point_count_t FauxSeqIterator::readImpl(PointBuffer& buf, point_count_t count) buf.setField(Dimension::Id::Y, idx, y); buf.setField(Dimension::Id::Z, idx, z); buf.setField(Dimension::Id::OffsetTime, idx, m_time++); - if (m_numberOfReturns > 0) + if (m_numReturns > 0) { - buf.setField(Dimension::Id::ReturnNumber, idx, m_returnNumber); - buf.setField(Dimension::Id::NumberOfReturns, idx, m_numberOfReturns); - m_returnNumber = (m_returnNumber % m_numberOfReturns) + 1; + buf.setField(Dimension::Id::ReturnNumber, idx, m_returnNum); + buf.setField(Dimension::Id::NumberOfReturns, idx, m_numReturns); + m_returnNum = (m_returnNum % m_numReturns) + 1; } } return count; } +} // namespace faux +} // namespace drivers } // namespace pdal diff --git a/src/drivers/icebridge/Reader.cpp b/src/drivers/icebridge/Reader.cpp index 5e064d0e0f..a74ffdeb73 100644 --- a/src/drivers/icebridge/Reader.cpp +++ b/src/drivers/icebridge/Reader.cpp @@ -94,49 +94,20 @@ Dimension::IdList Reader::getDefaultDimensions() } -void Reader::processOptions(const Options& options) -{ - m_filename = options.getOption("filename").getValue(); -} - - void Reader::addDimensions(PointContext ctx) { return ctx.registerDims(getDefaultDimensions()); } -StageSequentialIterator *Reader::createSequentialIterator() const -{ - return new iterators::sequential::IcebridgeSeqIter( - const_cast(&m_hdf5Handler)); -} - - void Reader::ready(PointContext ctx) { m_hdf5Handler.initialize(m_filename, hdf5Columns); + m_index = 0; } -void Reader::done(PointContext ctx) -{ - m_hdf5Handler.close(); -} - - -namespace iterators -{ -namespace sequential -{ - -point_count_t IcebridgeSeqIter::readBufferImpl(PointBuffer& buf) -{ - return readImpl(buf, (std::numeric_limits::max)()); -} - - -point_count_t IcebridgeSeqIter::readImpl(PointBuffer& buf, point_count_t count) +point_count_t Reader::read(PointBuffer& buf, point_count_t count) { //All data we read for icebridge is currently 4 bytes wide, so // just allocate once and forget it. @@ -144,13 +115,14 @@ point_count_t IcebridgeSeqIter::readImpl(PointBuffer& buf, point_count_t count) // in the icebridge handler? PointId startId = buf.size(); - point_count_t remaining = m_hdf5Handler->getNumPoints() - m_index; + point_count_t remaining = m_hdf5Handler.getNumPoints() - m_index; count = std::min(count, remaining); + std::unique_ptr rawData(new unsigned char[count * sizeof(float)]); //Not loving the position-linked data, but fine for now. - Dimension::IdList dims = Reader::getDefaultDimensions(); + Dimension::IdList dims = getDefaultDimensions(); auto di = dims.begin(); for (auto ci = hdf5Columns.begin(); ci != hdf5Columns.end(); ++ci, ++di) { @@ -160,9 +132,10 @@ point_count_t IcebridgeSeqIter::readImpl(PointBuffer& buf, point_count_t count) try { - m_hdf5Handler->getColumnEntries(rawData.get(), column.name, count, + m_hdf5Handler.getColumnEntries(rawData.get(), column.name, count, m_index); void *p = (void *)rawData.get(); + // This is ugly but avoids a test in a tight loop. if (column.predType == H5::PredType::NATIVE_FLOAT) { @@ -199,23 +172,17 @@ point_count_t IcebridgeSeqIter::readImpl(PointBuffer& buf, point_count_t count) } -uint64_t IcebridgeSeqIter::skipImpl(uint64_t count) +void Reader::done(PointContext ctx) { - const uint64_t skipped = std::min(count, - m_hdf5Handler->getNumPoints() - m_index); - m_index += skipped; - return skipped; + m_hdf5Handler.close(); } -bool IcebridgeSeqIter::atEndImpl() const +bool Reader::eof() { - return m_index >= m_hdf5Handler->getNumPoints(); + return m_index >= m_hdf5Handler.getNumPoints(); } -} // namespace sequential -} // namespace iterators - } // namespace icebridge } // namespace drivers } // namespace pdal diff --git a/src/drivers/las/LasHeaderReader.cpp b/src/drivers/las/LasHeaderReader.cpp index 392011d737..a5ad7fa112 100644 --- a/src/drivers/las/LasHeaderReader.cpp +++ b/src/drivers/las/LasHeaderReader.cpp @@ -1,11 +1,4 @@ /****************************************************************************** - * $Id$ - * - * Project: libLAS - http://liblas.org - A BSD library for LAS format data. - * Purpose: LAS header class - * Author: Mateusz Loskot, mateusz@loskot.net - * - ****************************************************************************** * Copyright (c) 2008, Mateusz Loskot * Copyright (c) 2008, Phil Vachon * @@ -47,7 +40,7 @@ #include #include #include -#include "ZipPoint.hpp" +#include #include #include @@ -62,12 +55,8 @@ namespace las LasHeaderReader::LasHeaderReader(LasHeader& header, std::istream& istream) - : m_header(header) - , m_istream(istream) - , m_numVLRs(0) -{ - return; -} + : m_header(header), m_istream(istream), m_numVLRs(0) +{} void LasHeaderReader::read(Reader& stage) @@ -115,7 +104,6 @@ void LasHeaderReader::read(Reader& stage) // 8. Version major Utils::read_n(n1, m_istream, sizeof(n1)); m_header.SetVersionMajor(n1); - // 9. Version minor Utils::read_n(n1, m_istream, sizeof(n1)); m_header.SetVersionMinor(n1); diff --git a/src/drivers/las/LasHeaderWriter.cpp b/src/drivers/las/LasHeaderWriter.cpp index 20fb412b3d..65b9935c41 100644 --- a/src/drivers/las/LasHeaderWriter.cpp +++ b/src/drivers/las/LasHeaderWriter.cpp @@ -1,11 +1,4 @@ /****************************************************************************** - * $Id$ - * - * Project: libLAS - http://liblas.org - A BSD library for LAS format data. - * Purpose: LAS header class - * Author: Mateusz Loskot, mateusz@loskot.net - * - ****************************************************************************** * Copyright (c) 2008, Mateusz Loskot * Copyright (c) 2008, Phil Vachon * @@ -42,13 +35,11 @@ #include "LasHeaderWriter.hpp" -#include "ZipPoint.hpp" - #include +#include #include #include - namespace pdal { namespace drivers @@ -56,7 +47,6 @@ namespace drivers namespace las { - LasHeaderWriter::LasHeaderWriter(LasHeader& header, std::ostream& ostream, boost::uint64_t firstPos) : m_header(header) , m_ostream(ostream) diff --git a/src/drivers/las/Reader.cpp b/src/drivers/las/Reader.cpp index 7cb4cb6054..7bc403d27d 100644 --- a/src/drivers/las/Reader.cpp +++ b/src/drivers/las/Reader.cpp @@ -37,19 +37,15 @@ #include #include -#ifdef PDAL_HAVE_LASZIP -#include -#endif - #include #include #include #include +#include #include #include "LasHeaderReader.hpp" #include #include -#include "ZipPoint.hpp" #include #ifdef PDAL_HAVE_GDAL @@ -70,14 +66,11 @@ namespace las { -Reader::Reader(const Options& options) - : pdal::Reader(options) -{} - - -Reader::Reader(const std::string& filename) - : pdal::Reader(Option("filename", filename)) -{} +Reader::~Reader() +{ + if (m_istream) + m_streamFactory->deallocate(*m_istream); +} void Reader::processOptions(const Options& options) @@ -91,13 +84,12 @@ void Reader::initialize() initialize(m_metadata); } + void Reader::initialize(MetadataNode& m) { m_streamFactory = createFactory(); - - std::istream& stream = m_streamFactory->allocate(); - - LasHeaderReader lasHeaderReader(m_lasHeader, stream); + m_istream = &(m_streamFactory->allocate()); + LasHeaderReader lasHeaderReader(m_lasHeader, *m_istream); try { lasHeaderReader.read(*this); @@ -114,9 +106,7 @@ void Reader::initialize(MetadataNode& m) << ". It does not have a las file signature."; throw std::invalid_argument(msg.str()); } - extractMetadata(m); - m_streamFactory->deallocate(stream); } @@ -128,18 +118,6 @@ Options Reader::getDefaultOptions() } -StreamFactory& Reader::getStreamFactory() const -{ - return *m_streamFactory; -} - - -pdal::StageSequentialIterator* Reader::createSequentialIterator() const -{ - return new drivers::las::iterators::sequential::Reader(*this); -} - - void Reader::extractMetadata(MetadataNode& m) { // If the user is already overriding this by setting it on the stage, we'll @@ -151,21 +129,19 @@ void Reader::extractMetadata(MetadataNode& m) m_lasHeader.getVLRs().constructSRS(new_srs); setSpatialReference(m, new_srs); } - LasHeader const& header = getLasHeader(); - - m.add("compressed", header.Compressed(), + m.add("compressed", m_lasHeader.Compressed(), "true if this LAS file is compressed"); m.add("dataformat_id", - static_cast(header.getPointFormat()), + static_cast(m_lasHeader.getPointFormat()), "The Point Format ID as specified in the LAS specification"); m.add("major_version", - static_cast(header.GetVersionMajor()), + static_cast(m_lasHeader.GetVersionMajor()), "The major LAS version for the file, always 1 for now"); m.add("minor_version", - static_cast(header.GetVersionMinor()), + static_cast(m_lasHeader.GetVersionMinor()), "The minor LAS version for the file"); m.add("filesource_id", - static_cast(header.GetFileSourceId()), + static_cast(m_lasHeader.GetFileSourceId()), "File Source ID (Flight Line Number if this file was derived from " "an original flight line): This field should be set to a value " "between 1 and 65,535, inclusive. A value of zero (0) is interpreted " @@ -176,7 +152,7 @@ void Reader::extractMetadata(MetadataNode& m) "result of merge and/or extract operations."); //Reserved is always 0, making this seem a bit silly. - boost::uint16_t reserved = header.GetReserved(); + boost::uint16_t reserved = m_lasHeader.GetReserved(); uint8_t *start = (uint8_t*)&reserved; std::vector raw_bytes; for (std::size_t i = 0 ; i < sizeof(uint16_t); ++i) @@ -190,7 +166,7 @@ void Reader::extractMetadata(MetadataNode& m) "is defined (this is the bit, that if set, would have the unsigned " "integer yield a value of 1)."); m.add("project_id", - header.GetProjectId(), "Project ID (GUID data): The four fields " + m_lasHeader.GetProjectId(), "Project ID (GUID data): The four fields " "that comprise a complete Globally Unique Identifier (GUID) are now " "reserved for use as a Project Identifier (Project ID). The field " "remains optional. The time of assignment of the Project ID is at " @@ -198,24 +174,24 @@ void Reader::extractMetadata(MetadataNode& m) "the same for all files that are associated with a unique project. " "By assigning a Project ID and using a File Source ID (defined above) " "every file within a project and every point within a file can be " "uniquely identified, globally."); - m.add("system_id", header.GetSystemId(false)); + m.add("system_id", m_lasHeader.GetSystemId(false)); m.add("software_id", - header.GetSoftwareId(false), "This information is ASCII data " + m_lasHeader.GetSoftwareId(false), "This information is ASCII data " "describing the generating software itself. This field provides a " "mechanism for specifying which generating software package and " "version was used during LAS file creation (e.g. \"TerraScan V-10.8\"," " \"REALM V-4.2\" and etc.)."); m.add("creation_doy", - static_cast(header.GetCreationDOY()), + static_cast(m_lasHeader.GetCreationDOY()), "Day, expressed as an unsigned short, on which this file was created. " "Day is computed as the Greenwich Mean Time (GMT) day. January 1 is " "considered day 1."); m.add("creation_year", - static_cast(header.GetCreationYear()), + static_cast(m_lasHeader.GetCreationYear()), "The year, expressed as a four digit number, in which the file was " "created."); m.add("header_size", - static_cast(header.GetHeaderSize()), + static_cast(m_lasHeader.GetHeaderSize()), "The size, in bytes, of the Public Header Block itself. In the event " "that the header is extended by a software application through the " "addition of data at the end of the header, the Header Size field " @@ -226,12 +202,12 @@ void Reader::extractMetadata(MetadataNode& m) "this data must be placed at the end of the structure and the Header " "Size must be updated to reflect the new size."); m.add("dataoffset", - static_cast(header.GetDataOffset()), + static_cast(m_lasHeader.GetDataOffset()), "The actual number of bytes from the beginning of the file to the " "first field of the first point record data field. This data offset " "must be updated if any software adds data from the Public Header " "Block or adds/removes data to/from the Variable Length Records."); - m.add("scale_x", header.GetScaleX(), + m.add("scale_x", m_lasHeader.GetScaleX(), "The scale factor fields contain a double floating point value that " "is used to scale the corresponding X, Y, and Z long values within " "the point records. The corresponding X, Y, and Z scale factor must " @@ -239,7 +215,7 @@ void Reader::extractMetadata(MetadataNode& m) "X, Y, or Z coordinate. For example, if the X, Y, and Z coordinates " "are intended to have two decimal point values, then each scale factor " "will contain the number 0.01."); - m.add("scale_y", header.GetScaleY(), + m.add("scale_y", m_lasHeader.GetScaleY(), "The scale factor fields contain a double floating point value that " "is used to scale the corresponding X, Y, and Z long values within " "the point records. The corresponding X, Y, and Z scale factor must " @@ -247,7 +223,7 @@ void Reader::extractMetadata(MetadataNode& m) "actual X, Y, or Z coordinate. For example, if the X, Y, and Z " "coordinates are intended to have two decimal point values, then each " "scale factor will contain the number 0.01."); - m.add("scale_z", header.GetScaleZ(), + m.add("scale_z", m_lasHeader.GetScaleZ(), "The scale factor fields contain a double floating point value that " "is used to scale the corresponding X, Y, and Z long values within " "the point records. The corresponding X, Y, and Z scale factor must " @@ -255,53 +231,54 @@ void Reader::extractMetadata(MetadataNode& m) "X, Y, or Z coordinate. For example, if the X, Y, and Z coordinates " "are intended to have two decimal point values, then each scale factor " "will contain the number 0.01."); - m.add("offset_x", header.GetOffsetX(), + m.add("offset_x", m_lasHeader.GetOffsetX(), "The offset fields should be used to set the overall offset for the " "point records. In general these numbers will be zero, but for " "certain cases the resolution of the point data may not be large " "enough for a given projection system. However, it should always be " "assumed that these numbers are used."); - m.add("offset_y", header.GetOffsetY(), + m.add("offset_y", m_lasHeader.GetOffsetY(), "The offset fields should be used to set the overall offset for the " "point records. In general these numbers will be zero, but for " "certain cases the resolution of the point data may not be large " "enough for a given projection system. However, it should always be " "assumed that these numbers are used."); - m.add("offset_z", header.GetOffsetZ(), + m.add("offset_z", m_lasHeader.GetOffsetZ(), "The offset fields should be used to set the overall offset for the " "point records. In general these numbers will be zero, but for certain " "cases the resolution of the point data may not be large enough for " "a given projection system. However, it should always be assumed that " "these numbers are used."); - m.add("minx", header.GetMinX(), + m.add("minx", m_lasHeader.GetMinX(), "The max and min data fields are the actual unscaled extents of the " "LAS point file data, specified in the coordinate system of the LAS " "data."); - m.add("miny", header.GetMinY(), + m.add("miny", m_lasHeader.GetMinY(), "The max and min data fields are the actual unscaled extents of the " "LAS point file data, specified in the coordinate system of the LAS " "data."); - m.add("minz", header.GetMinZ(), + m.add("minz", m_lasHeader.GetMinZ(), "The max and min data fields are the actual unscaled extents of the " "LAS point file data, specified in the coordinate system of the LAS " "data."); - m.add("maxx", header.GetMaxX(), + m.add("maxx", m_lasHeader.GetMaxX(), "The max and min data fields are the actual unscaled extents of the " "LAS point file data, specified in the coordinate system of the LAS " "data."); - m.add("maxy", header.GetMaxY(), + m.add("maxy", m_lasHeader.GetMaxY(), "The max and min data fields are the actual unscaled extents of the " "LAS point file data, specified in the coordinate system of the LAS " "data."); - m.add("maxz", header.GetMaxZ(), + m.add("maxz", m_lasHeader.GetMaxZ(), "The max and min data fields are the actual unscaled extents of the " "LAS point file data, specified in the coordinate system of the LAS " "data."); m.add("count", - header.GetPointRecordsCount(), "This field contains the total number " - "of point records within the file."); + m_lasHeader.GetPointRecordsCount(), "This field contains the total " + "number of point records within the file."); - std::vector const& vlrs = header.getVLRs().getAll(); + std::vector const& vlrs = + m_lasHeader.getVLRs().getAll(); for (std::vector::size_type t = 0; t < vlrs.size(); ++t) { @@ -350,8 +327,6 @@ void Reader::extractMetadata(MetadataNode& m) void Reader::addDimensions(PointContext ctx) { - const LasHeader& h = getLasHeader(); - using namespace Dimension; Id::Enum ids[] = { Id::X, Id::Y, Id::Z, Id::Intensity, Id::ReturnNumber, Id::NumberOfReturns, Id::ScanDirectionFlag, Id::EdgeOfFlightLine, @@ -359,104 +334,81 @@ void Reader::addDimensions(PointContext ctx) Id::Unknown }; ctx.registerDims(ids); - if (h.hasTime()) + if (m_lasHeader.hasTime()) ctx.registerDim(Id::GpsTime); - if (h.hasColor()) + if (m_lasHeader.hasColor()) { Id::Enum ids[] = { Id::Red, Id::Green, Id::Blue, Id::Unknown }; ctx.registerDims(ids); } } -namespace iterators -{ -Base::Base(pdal::drivers::las::Reader const& reader) - : m_bounds(3), m_reader(reader), - m_istream(m_reader.getStreamFactory().allocate()) , m_zipPoint(NULL), - m_unzipper(NULL) +void Reader::ready(PointContext ctx) { - m_istream.seekg(m_reader.getLasHeader().GetDataOffset()); + m_index = 0; + m_istream->seekg(m_lasHeader.GetDataOffset()); - if (m_reader.getLasHeader().Compressed()) + if (m_lasHeader.Compressed()) { #ifdef PDAL_HAVE_LASZIP - initialize(); -#else - throw pdal_error("LASzip is not enabled for this " - "pdal::drivers::las::IteratorBase!"); -#endif - } -} - - -Base::~Base() -{ -#ifdef PDAL_HAVE_LASZIP - m_zipPoint.reset(); - m_unzipper.reset(); -#endif - m_reader.getStreamFactory().deallocate(m_istream); -} - - -void Base::initialize() -{ -#ifdef PDAL_HAVE_LASZIP - if (!m_zipPoint) - { - PointFormat format = m_reader.getLasHeader().getPointFormat(); - boost::scoped_ptr z(new ZipPoint(format, - m_reader.getLasHeader(), true)); - m_zipPoint.swap(z); - } - - if (!m_unzipper) - { - boost::scoped_ptr z(new LASunzipper()); - m_unzipper.swap(z); + if (!m_zipPoint) + { + PointFormat format = m_lasHeader.getPointFormat(); + std::unique_ptr z(new ZipPoint(format, + m_lasHeader, true)); + m_zipPoint.swap(z); + } - m_istream.seekg(static_cast( - m_reader.getLasHeader().GetDataOffset()), std::ios::beg); - if (!m_unzipper->open(m_istream, m_zipPoint->GetZipper())) + if (!m_unzipper) { - std::ostringstream oss; - const char* err = m_unzipper->get_error(); - if (err==NULL) - err="(unknown error)"; - oss << "Failed to open LASzip stream: " << std::string(err); - throw pdal_error(oss.str()); + std::unique_ptr z(new LASunzipper()); + m_unzipper.swap(z); + + m_istream->seekg(static_cast( + m_lasHeader.GetDataOffset()), std::ios::beg); + if (!m_unzipper->open(*m_istream, m_zipPoint->GetZipper())) + { + std::ostringstream oss; + const char* err = m_unzipper->get_error(); + if (err == NULL) + err = "(unknown error)"; + oss << "Failed to open LASzip stream: " << std::string(err); + throw pdal_error(oss.str()); + } } - } +#else + throw pdal_error("LASzip is not enabled. Can't read LAZ data."); #endif + } } -point_count_t Base::processBuffer(PointBuffer& data, std::istream& stream, - point_count_t count, LASunzipper* unzipper, ZipPoint* zipPoint) + +point_count_t Reader::read(PointBuffer& data, point_count_t count) { - const LasHeader& h = m_reader.getLasHeader(); - size_t pointByteCount = h.getPointDataSize(); + size_t pointByteCount = m_lasHeader.getPointDataSize(); + count = std::min(count, getNumPoints() - m_index); PointId i = 0; - if (zipPoint) + if (m_zipPoint) { #ifdef PDAL_HAVE_LASZIP for (i = 0; i < count; i++) { - if (!unzipper->read(zipPoint->m_lz_point)) + if (!m_unzipper->read(m_zipPoint->m_lz_point)) { std::string error = "Error reading compressed point data: "; - const char* err = unzipper->get_error(); + const char* err = m_unzipper->get_error(); if (!err) err = "(unknown error)"; error += err; throw pdal_error(error); } - loadPoint(data, (char *)zipPoint->m_lz_point_data.get(), + loadPoint(data, (char *)m_zipPoint->m_lz_point_data.get(), pointByteCount); } #else - boost::ignore_unused_variable_warning(unzipper); + boost::ignore_unused_variable_warning(m_unzipper); throw pdal_error("LASzip is not enabled for this " "pdal::drivers::las::Reader::processBuffer"); #endif @@ -468,7 +420,7 @@ point_count_t Base::processBuffer(PointBuffer& data, std::istream& stream, { for (; i < count; ++i) { - stream.read(buf.data(), pointByteCount); + m_istream->read(buf.data(), pointByteCount); loadPoint(data, buf.data(), pointByteCount); } } @@ -477,21 +429,28 @@ point_count_t Base::processBuffer(PointBuffer& data, std::istream& stream, catch (pdal::invalid_stream&) {} } + m_index += i; return (point_count_t)i; } -void Base::loadPoint(PointBuffer& data, char *buf, size_t bufsize) +void Reader::loadPoint(PointBuffer& data, char *buf, size_t bufsize) { + // Turn a raw buffer (array of bytes) into a stream buf. Charbuf charstreambuf(buf, bufsize, 0); + + // Make an input stream based on the stream buf. std::istream stream(&charstreambuf); + + // Wrap the input stream with byte ordering. ILeStream istream(&stream); + PointId nextId = data.size(); int32_t xi, yi, zi; istream >> xi >> yi >> zi; - const LasHeader& h = m_reader.getLasHeader(); + const LasHeader& h = m_lasHeader; double x = xi * h.GetScaleX() + h.GetOffsetX(); double y = yi * h.GetScaleY() + h.GetOffsetY(); @@ -543,62 +502,14 @@ void Base::loadPoint(PointBuffer& data, char *buf, size_t bufsize) } -namespace sequential -{ - -Reader::Reader(pdal::drivers::las::Reader const& reader) : Base(reader) -{} - - -boost::uint64_t Reader::skipImpl(boost::uint64_t count) -{ - const LasHeader& h = m_reader.getLasHeader(); - -#ifdef PDAL_HAVE_LASZIP - if (m_unzipper) - { - const boost::uint32_t pos32 = - Utils::safeconvert64to32(getIndex() + count); - m_unzipper->seek(pos32); - } - else - { - std::streamoff delta = h.getPointDataSize(); - m_istream.seekg(delta * count, std::ios::cur); - } -#else - std::streamoff delta = h.getPointDataSize(); - m_istream.seekg(delta * count, std::ios::cur); -#endif - return count; -} - - -point_count_t Reader::readImpl(PointBuffer& data, point_count_t count) +void Reader::done(PointContext ctx) { - point_count_t numToRead = m_reader.getNumPoints() - getIndex(); #ifdef PDAL_HAVE_LASZIP - return processBuffer(data, m_istream, count, m_unzipper.get(), - m_zipPoint.get()); -#else - return processBuffer(data, m_istream, count, NULL, NULL); -#endif -} - -point_count_t Reader::readBufferImpl(PointBuffer& data) -{ - point_count_t numToRead = m_reader.getNumPoints() - getIndex(); -#ifdef PDAL_HAVE_LASZIP - return processBuffer(data, m_istream, numToRead, m_unzipper.get(), - m_zipPoint.get()); -#else - return processBuffer(data, m_istream, numToRead, NULL, NULL); + m_zipPoint.reset(); + m_unzipper.reset(); #endif } -} // sequential -} // iterators - } // namespace las } // namespace drivers } // namespace pdal diff --git a/src/drivers/las/Writer.cpp b/src/drivers/las/Writer.cpp index d1bb20b3ad..bb6dde4c67 100644 --- a/src/drivers/las/Writer.cpp +++ b/src/drivers/las/Writer.cpp @@ -37,15 +37,10 @@ #include #include +#include #include "LasHeaderWriter.hpp" -#include "ZipPoint.hpp" - -#ifdef PDAL_HAVE_LASZIP -#include -#endif - #include #include @@ -462,14 +457,14 @@ void Writer::ready(PointContext ctx) if (!m_zipPoint) { PointFormat format = m_lasHeader.getPointFormat(); - boost::scoped_ptr z(new ZipPoint(format, m_lasHeader, + std::unique_ptr z(new ZipPoint(format, m_lasHeader, false)); m_zipPoint.swap(z); } if (!m_zipper) { - boost::scoped_ptr z(new LASzipper()); + std::unique_ptr z(new LASzipper()); m_zipper.swap(z); bool stat(false); diff --git a/src/drivers/las/ZipPoint.cpp b/src/drivers/las/ZipPoint.cpp index c03b295665..fb3943573c 100644 --- a/src/drivers/las/ZipPoint.cpp +++ b/src/drivers/las/ZipPoint.cpp @@ -36,18 +36,14 @@ #ifdef PDAL_HAVE_LASZIP -#include "ZipPoint.hpp" - #include #include #include +#include #include -// laszip -#include - // std //#include //#include @@ -75,7 +71,7 @@ ZipPoint::ZipPoint(PointFormat format, const LasHeader& lasHeader, , m_lz_point(NULL) , m_lz_point_size(0) { - boost::scoped_ptr s(new LASzip()); + std::unique_ptr s(new LASzip()); m_zip.swap(s); const VariableLengthRecord* vlr = NULL; @@ -98,7 +94,8 @@ ZipPoint::ZipPoint(PointFormat format, const LasHeader& lasHeader, { std::ostringstream oss; const char* err = m_zip->get_error(); - if (err==NULL) err="(unknown error)"; + if (err == NULL) + err = "(unknown error)"; oss << "Error unpacking zip VLR data: " << std::string(err); throw pdal_error(oss.str()); } @@ -109,7 +106,8 @@ ZipPoint::ZipPoint(PointFormat format, const LasHeader& lasHeader, if (m_readMode) { std::ostringstream oss; - oss << "Unable to find LASzip VLR, but the file was opened in read mode!"; + oss << "Unable to find LASzip VLR, but the file was opened " + "in read mode!"; throw pdal_error(oss.str()); } @@ -117,24 +115,24 @@ ZipPoint::ZipPoint(PointFormat format, const LasHeader& lasHeader, { std::ostringstream oss; const char* err = m_zip->get_error(); - if (err==NULL) err="(unknown error)"; - oss << "Error setting up LASzip for format " << format <<": " << err; + if (err == NULL) + err = "(unknown error)"; + oss << "Error setting up LASzip for format " << format << ": " << + err; throw pdal_error(oss.str()); } } ConstructItems(); - return; } + ZipPoint::~ZipPoint() { - delete[] m_lz_point; - - return; } + void ZipPoint::ConstructItems() { // construct the object that will hold a laszip point @@ -190,13 +188,8 @@ VariableLengthRecord ZipPoint::ConstructVLR() const bool ZipPoint::IsZipVLR(const VariableLengthRecord& vlr) const { - if (laszip_userid == vlr.getUserId() && - laszip_recordid == vlr.getRecordId()) - { - return true; - } - - return false; + return (laszip_userid == vlr.getUserId() && + laszip_recordid == vlr.getRecordId()); } diff --git a/src/drivers/oci/OciReader.cpp b/src/drivers/oci/OciReader.cpp index 1fdef5f659..c5f6080e2a 100644 --- a/src/drivers/oci/OciReader.cpp +++ b/src/drivers/oci/OciReader.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #ifdef USE_PDAL_PLUGIN_OCI MAKE_READER_CREATOR(ociReader, pdal::drivers::oci::Reader) @@ -265,11 +264,195 @@ void OciReader::addDimensions(PointContext ctx) } -StageSequentialIterator* OciReader::createSequentialIterator() const +point_count_t OciReader::read(PointBuffer& buffer, point_count_t count) { - return new iterators::sequential::OciSeqIterator(m_stmt, m_block); + if (eof()) + return 0; + + point_count_t totalNumRead = 0; + while (totalNumRead < count) + { + if (m_block->numRemaining() == 0) + if (!readOci(m_stmt, m_block)) + return totalNumRead; + PointId bufBegin = buffer.size(); + + Orientation::Enum orientation = m_block->orientation(); + point_count_t numRead = 0; + if (m_block->orientation() == Orientation::DimensionMajor) + numRead = readDimMajor(buffer, m_block, count - totalNumRead); + else if (m_block->orientation() == Orientation::PointMajor) + numRead = readPointMajor(buffer, m_block, count - totalNumRead); + PointId bufEnd = bufBegin + numRead; + totalNumRead += numRead; + } + return totalNumRead; +} + + +point_count_t OciReader::readDimMajor(PointBuffer& buffer, BlockPtr block, + point_count_t numPts) +{ + point_count_t numRemaining = block->numRemaining(); + PointId startId = buffer.size(); + point_count_t blockRemaining; + point_count_t numRead = 0; + + schema::DimInfoList& dims = block->m_schema.m_dims; + for (auto di = dims.begin(); di != dims.end(); ++di) + { + schema::DimInfo& d = *di; + PointId nextId = startId; + char *pos = seekDimMajor(d, block); + blockRemaining = numRemaining; + numRead = 0; + while (numRead < numPts && blockRemaining > 0) + { + buffer.setField(d.m_id, d.m_type, nextId, pos); + pos += Dimension::size(d.m_type); + + if (d.m_id == Dimension::Id::X) + { + double v = buffer.getFieldAs(Dimension::Id::X, nextId); + v = v * block->xScale() + block->xOffset(); + buffer.setField(Dimension::Id::X, nextId, v); + } + + if (d.m_id == Dimension::Id::Y) + { + double v = buffer.getFieldAs(Dimension::Id::Y, nextId); + v = v * block->yScale() + block->yOffset(); + buffer.setField(Dimension::Id::Y, nextId, v); + } + + if (d.m_id == Dimension::Id::Z) + { + double v = buffer.getFieldAs(Dimension::Id::Z, nextId); + v = v * block->zScale() + block->zOffset(); + buffer.setField(Dimension::Id::Z, nextId, v); + } + + nextId++; + numRead++; + blockRemaining--; + } + } + block->setNumRemaining(blockRemaining); + return numRead; +} + + +point_count_t OciReader::readPointMajor(PointBuffer& buffer, + BlockPtr block, point_count_t numPts) +{ + size_t numRemaining = block->numRemaining(); + PointId nextId = buffer.size(); + point_count_t numRead = 0; + + + schema::DimInfoList& dims = block->m_schema.m_dims; + char *pos = seekPointMajor(block); + while (numRead < numPts && numRemaining > 0) + { + for (auto di = dims.begin(); di != dims.end(); ++di) + { + schema::DimInfo& d = *di; + buffer.setField(d.m_id, d.m_type, nextId, pos); + pos += Dimension::size(d.m_type); + } + + // Scale X, Y and Z + double v = buffer.getFieldAs(Dimension::Id::X, nextId); + v = v * block->xScale() + block->xOffset(); + buffer.setField(Dimension::Id::X, nextId, v); + + v = buffer.getFieldAs(Dimension::Id::Y, nextId); + v = v * block->yScale() + block->yOffset(); + buffer.setField(Dimension::Id::Y, nextId, v); + + v = buffer.getFieldAs(Dimension::Id::Z, nextId); + v = v * block->zScale() + block->zOffset(); + buffer.setField(Dimension::Id::Z, nextId, v); + + numRemaining--; + nextId++; + numRead++; + } + block->setNumRemaining(numRemaining); + return numRead; +} + + +char *OciReader::seekDimMajor(const schema::DimInfo& d, BlockPtr block) +{ + size_t size = 0; + schema::DimInfoList dims = block->m_schema.m_dims; + for (auto di = dims.begin(); di->m_id != d.m_id; ++di) + size += Dimension::size(di->m_type); + return block->data() + + (size * block->numPoints()) + + (Dimension::size(d.m_type) * block->numRead()); +} + + +char *OciReader::seekPointMajor(BlockPtr block) +{ + return block->data() + (block->numRead() * block->m_point_size); +} + + +// Read a block (set of points) from the database. +bool OciReader::readOci(Statement stmt, BlockPtr block) +{ + if (!block->fetched()) + { + if (!stmt->Fetch()) + { + m_atEnd = true; + return false; + } + block->setFetched(); + } + // Read the points from the blob in the row. + readBlob(stmt, block); + schema::XMLSchema *s = findSchema(stmt, block); + block->update(s); + block->clearFetched(); + return true; +} + + +void OciReader::readBlob(Statement stmt, BlockPtr block) +{ + uint32_t amountRead = 0; + uint32_t blobLength = stmt->GetBlobLength(block->locator); + + if (block->chunk.size() < blobLength) + block->chunk.resize(blobLength); + + if (!stmt->ReadBlob(block->locator, (void*)(block->chunk.data()), + block->chunk.size() , &amountRead)) + throw pdal_error("Did not read all blob data!"); +} + + +// All of the schemas should be the same with regard to actual dimension +// name, order, etc, but each cloud may have its own scaling for X, Y and Z. +// Store it away so that it can be applied later if necessary. +schema::XMLSchema* OciReader::findSchema(Statement stmt, BlockPtr block) +{ + int32_t cloudId = stmt->GetInteger(&block->pc->pc_id); + auto si = m_schemas.find(cloudId); + if (si == m_schemas.end()) + { + schema::XMLSchema s = fetchSchema(stmt, block); + auto i = m_schemas.insert(std::make_pair(cloudId, s)); + si = i.first; + } + return &(si->second); } } // namespace oci } // namespace drivers } // namespace pdal + diff --git a/src/drivers/oci/OciSeqIterator.cpp b/src/drivers/oci/OciSeqIterator.cpp deleted file mode 100644 index f5cd1cf055..0000000000 --- a/src/drivers/oci/OciSeqIterator.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2014, Hobu Inc., hobu.inc@gmail.com -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#include -#include -#include -#include - -#ifdef USE_PDAL_PLUGIN_OCI -MAKE_READER_CREATOR(ociReader, pdal::drivers::oci::Reader) -CREATE_READER_PLUGIN(oci, pdal::drivers::oci::Reader) -#endif - - -namespace pdal -{ -namespace drivers -{ -namespace oci -{ - - -namespace iterators -{ -namespace sequential -{ - - -void OciSeqIterator::readBlob(Statement stmt, BlockPtr block) -{ - boost::uint32_t amountRead = 0; - boost::uint32_t blobLength = stmt->GetBlobLength(block->locator); - - if (block->chunk.size() < blobLength) - block->chunk.resize(blobLength); - - if (!stmt->ReadBlob(block->locator, (void*)(block->chunk.data()), - block->chunk.size() , &amountRead)) - throw pdal_error("Did not read all blob data!"); -} - - -point_count_t OciSeqIterator::read(PointBuffer& buffer, BlockPtr block, - point_count_t numPts) -{ - Orientation::Enum orientation = block->orientation(); - if (block->orientation() == Orientation::DimensionMajor) - return readDimMajor(buffer, block, numPts); - else if (block->orientation() == Orientation::PointMajor) - return readPointMajor(buffer, block, numPts); - throw pdal_error("Unsupported orientation."); -} - - -point_count_t OciSeqIterator::readDimMajor(PointBuffer& buffer, BlockPtr block, - point_count_t numPts) -{ - point_count_t numRemaining = block->numRemaining(); - PointId startId = buffer.size(); - point_count_t blockRemaining; - point_count_t numRead = 0; - - schema::DimInfoList& dims = block->m_schema.m_dims; - for (auto di = dims.begin(); di != dims.end(); ++di) - { - schema::DimInfo& d = *di; - PointId nextId = startId; - char *pos = seekDimMajor(d, block); - blockRemaining = numRemaining; - numRead = 0; - while (numRead < numPts && blockRemaining > 0) - { - buffer.setField(d.m_id, d.m_type, nextId, pos); - pos += Dimension::size(d.m_type); - - if (d.m_id == Dimension::Id::X) - { - double v = buffer.getFieldAs(Dimension::Id::X, nextId); - v = v * block->xScale() + block->xOffset(); - buffer.setField(Dimension::Id::X, nextId, v); - } - - if (d.m_id == Dimension::Id::Y) - { - double v = buffer.getFieldAs(Dimension::Id::Y, nextId); - v = v * block->yScale() + block->yOffset(); - buffer.setField(Dimension::Id::Y, nextId, v); - } - - if (d.m_id == Dimension::Id::Z) - { - double v = buffer.getFieldAs(Dimension::Id::Z, nextId); - v = v * block->zScale() + block->zOffset(); - buffer.setField(Dimension::Id::Z, nextId, v); - } - - nextId++; - numRead++; - blockRemaining--; - } - } - block->setNumRemaining(blockRemaining); - return numRead; -} - - -point_count_t OciSeqIterator::readPointMajor(PointBuffer& buffer, - BlockPtr block, point_count_t numPts) -{ - size_t numRemaining = block->numRemaining(); - PointId nextId = buffer.size(); - point_count_t numRead = 0; - - - schema::DimInfoList& dims = block->m_schema.m_dims; - char *pos = seekPointMajor(block); - while (numRead < numPts && numRemaining > 0) - { - for (auto di = dims.begin(); di != dims.end(); ++di) - { - schema::DimInfo& d = *di; - buffer.setField(d.m_id, d.m_type, nextId, pos); - pos += Dimension::size(d.m_type); - } - - // Scale X, Y and Z - double v = buffer.getFieldAs(Dimension::Id::X, nextId); - v = v * block->xScale() + block->xOffset(); - buffer.setField(Dimension::Id::X, nextId, v); - - v = buffer.getFieldAs(Dimension::Id::Y, nextId); - v = v * block->yScale() + block->yOffset(); - buffer.setField(Dimension::Id::Y, nextId, v); - - v = buffer.getFieldAs(Dimension::Id::Z, nextId); - v = v * block->zScale() + block->zOffset(); - buffer.setField(Dimension::Id::Z, nextId, v); - - numRemaining--; - nextId++; - numRead++; - } - block->setNumRemaining(numRemaining); - return numRead; -} - - -char *OciSeqIterator::seekDimMajor(const schema::DimInfo& d, BlockPtr block) -{ - size_t size = 0; - schema::DimInfoList dims = block->m_schema.m_dims; - for (auto di = dims.begin(); di->m_id != d.m_id; ++di) - size += Dimension::size(di->m_type); - return block->data() + - (size * block->numPoints()) + - (Dimension::size(d.m_type) * block->numRead()); -} - - -char *OciSeqIterator::seekPointMajor(BlockPtr block) -{ - return block->data() + (block->numRead() * block->m_point_size); -} - - -point_count_t OciSeqIterator::readImpl(PointBuffer& buffer, point_count_t count) -{ - if (atEndImpl()) - return 0; - - point_count_t totalNumRead = 0; - while (totalNumRead < count) - { - if (m_block->numRemaining() == 0) - if (!readOci(m_stmt, m_block)) - return totalNumRead; - PointId bufBegin = buffer.size(); - point_count_t numRead = read(buffer, m_block, count - totalNumRead); - PointId bufEnd = bufBegin + numRead; - totalNumRead += numRead; - } - return totalNumRead; -} - - -uint64_t OciSeqIterator::skipImpl(uint64_t count) -{ - BlockPtr block = m_block; - - boost::uint64_t initialCount = count; - while (count) - { - point_count_t numRem = block->numRemaining(); - point_count_t blockCount = std::min((point_count_t)count, numRem); - block->setNumRemaining(numRem - blockCount); - count -= blockCount; - if (count > 0) - if (!readOci(m_stmt, m_block)) - break; - } - return initialCount - count; -} - - -// Read a block (set of points) from the database. -bool OciSeqIterator::readOci(Statement stmt, BlockPtr block) -{ - if (!block->fetched()) - { - if (!stmt->Fetch()) - { - m_atEnd = true; - return false; - } - block->setFetched(); - } - // Read the points from the blob in the row. - readBlob(stmt, block); - schema::XMLSchema *s = findSchema(stmt, block); - block->update(s); - block->clearFetched(); - return true; -} - - -// All of the schemas should be the same with regard to actual dimension -// name, order, etc, but each cloud may have its own scaling for X, Y and Z. -// Store it away so that it can be applied later if necessary. -schema::XMLSchema* OciSeqIterator::findSchema(Statement stmt, BlockPtr block) -{ - int32_t cloudId = stmt->GetInteger(&block->pc->pc_id); - auto si = m_schemas.find(cloudId); - if (si == m_schemas.end()) - { - schema::XMLSchema s = fetchSchema(stmt, block); - auto i = m_schemas.insert(std::make_pair(cloudId, s)); - si = i.first; - } - return &(si->second); -} - - -pdal::Bounds OciSeqIterator::getBounds(Statement stmt, BlockPtr block) -{ - double xmin, ymin, xmax, ymax; - - stmt->GetElement(&(block->blk_extent->sdo_ordinates), 0, &xmin); - stmt->GetElement(&(block->blk_extent->sdo_ordinates), 1, &ymin); - stmt->GetElement(&(block->blk_extent->sdo_ordinates), 2, &xmax); - stmt->GetElement(&(block->blk_extent->sdo_ordinates), 3, &ymax); - return pdal::Bounds(xmin, ymin, xmax, ymax); -} - -} // namespace sequential -} // namespace iterators - -} // namespace oci -} // namespace drivers -} // namespace pdal diff --git a/src/drivers/pcd/Reader.cpp b/src/drivers/pcd/Reader.cpp index 21f7d23bc7..639ac1752c 100644 --- a/src/drivers/pcd/Reader.cpp +++ b/src/drivers/pcd/Reader.cpp @@ -50,7 +50,6 @@ namespace drivers namespace pcd { - void PcdReader::ready(PointContext ctx) { pcl::PCLPointCloud2 cloud; @@ -60,53 +59,25 @@ void PcdReader::ready(PointContext ctx) } -Options PcdReader::getDefaultOptions() -{ - Options options; - return options; -} - - void PcdReader::addDimensions(PointContext ctx) { ctx.registerDims(getDefaultDimensions()); } -void PcdReader::processOptions(const Options& options) -{ - m_filename = options.getOption("filename").getValue(); -} - - -StageSequentialIterator* PcdReader::createSequentialIterator() const -{ - return new iterators::sequential::PcdSeqIterator(getDefaultDimensions(), m_filename); -} - -namespace iterators -{ -namespace sequential -{ - -point_count_t PcdSeqIterator::readImpl(PointBuffer& data, std::string filename) +point_count_t PcdReader::read(PointBuffer& data, point_count_t count) { pcl::PointCloud::Ptr cloud(new pcl::PointCloud); pcl::PCDReader r; - r.read(filename, *cloud); + r.read(m_filename, *cloud); - pdal::PCDtoPDAL(*cloud, data); + PCDtoPDAL(*cloud, data); - point_count_t numPoints = cloud->points.size(); - - return numPoints; + return cloud->points.size(); } -} // sequential -} // iterators - -} -} -} // namespaces +} // namespace pcd +} // namespace drivers +} // namespace pdal diff --git a/src/drivers/pgpointcloud/PgIterator.cpp b/src/drivers/pgpointcloud/PgIterator.cpp deleted file mode 100644 index 4bc65b3700..0000000000 --- a/src/drivers/pgpointcloud/PgIterator.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2012, Howard Butler, hobu.inc@gmail.com -* Copyright (c) 2013, Paul Ramsey, pramsey@cleverelephant.ca -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#include -#include -#include - -namespace pdal -{ -namespace drivers -{ -namespace pgpointcloud -{ - -namespace iterators -{ -namespace sequential -{ - -PgIterator::PgIterator(const PgReader& reader, const schema::DimInfoList& dims) - : m_reader(reader) - , m_at_end(false) - , m_cursor(false) - , m_session(NULL) - , m_dims(dims) - , m_point_size(0) - , m_cur_row(0) - , m_cur_nrows(0) - , m_cur_result(NULL) - , m_patch(new Patch) -{ - m_session = pg_connect(reader.connString()); - - m_point_size = 0; - for (auto di = m_dims.begin(); di != m_dims.end(); ++di) - m_point_size += Dimension::size(di->m_type); -} - -PgIterator::~PgIterator() -{ - if (m_session) - PQfinish(m_session); - if (m_cur_result) - PQclear(m_cur_result); -} - - -uint64_t PgIterator::skipImpl(uint64_t count) -{ - uint64_t initialCount = count; - while (count) - { - point_count_t numRem = m_patch->remaining; - point_count_t blockCount = std::min((point_count_t)count, numRem); - m_patch->remaining = (numRem - blockCount); - count -= blockCount; - if (count > 0) - if (!NextBuffer()) - break; - } - return initialCount - count; -} - - -bool PgIterator::atEndImpl() const -{ - m_reader.log()->get(LogLevel::Debug) << "atEndImpl called" << std::endl; - return m_at_end; -} - - -bool PgIterator::CursorSetup() -{ - std::ostringstream oss; - oss << "DECLARE cur CURSOR FOR " << m_reader.getDataQuery(); - pg_begin(m_session); - pg_execute(m_session, oss.str()); - m_cursor = true; - - m_reader.log()->get(LogLevel::Debug) << "SQL cursor prepared: " << - oss.str() << std::endl; - return true; -} - - -bool PgIterator::CursorTeardown() -{ - pg_execute(m_session, "CLOSE cur"); - pg_commit(m_session); - m_cursor = false; - m_reader.log()->get(LogLevel::Debug) << "SQL cursor closed." << - std::endl; - return true; -} - - -point_count_t PgIterator::readPgPatch(PointBuffer& buffer, point_count_t numPts) -{ - point_count_t numRemaining = m_patch->remaining; - PointId nextId = buffer.size(); - point_count_t numRead = 0; - - size_t offset = ((m_patch->count - m_patch->remaining) * m_point_size); - uint8_t *pos = &(m_patch->binary.front()) + offset; - while (numRead < numPts && numRemaining > 0) - { - for (auto di = m_dims.begin(); di != m_dims.end(); ++di) - { - schema::DimInfo& d = *di; - buffer.setField(d.m_id, d.m_type, nextId, pos); - pos += Dimension::size(d.m_type); - } - numRemaining--; - nextId++; - numRead++; - } - m_patch->remaining = numRemaining; - return numRead; -} - - -bool PgIterator::NextBuffer() -{ - if (! m_cursor) - CursorSetup(); - - if (m_cur_row >= m_cur_nrows || ! m_cur_result) - { - static std::string fetch = "FETCH 2 FROM cur"; - if (m_cur_result) - PQclear(m_cur_result); - m_cur_result = pg_query_result(m_session, fetch); - bool logOutput = (m_reader.log()->getLevel() > LogLevel::Debug3); - if (logOutput) - m_reader.log()->get(LogLevel::Debug3) << "SQL: " << - fetch << std::endl; - if ((PQresultStatus(m_cur_result) != PGRES_TUPLES_OK) || - (PQntuples(m_cur_result) == 0)) - { - PQclear(m_cur_result); - m_cur_result = NULL; - CursorTeardown(); - return false; - } - - m_cur_row = 0; - m_cur_nrows = PQntuples(m_cur_result); - } - m_patch->hex = PQgetvalue(m_cur_result, m_cur_row, 0); - m_patch->count = atoi(PQgetvalue(m_cur_result, m_cur_row, 1)); - m_patch->remaining = m_patch->count; - m_patch->update_binary(); - - m_cur_row++; - return true; -} - -point_count_t PgIterator::readImpl(PointBuffer& buffer, point_count_t count) -{ - if (atEndImpl()) - return 0; - - m_reader.log()->get(LogLevel::Debug) << "readBufferImpl called with " - "PointBuffer filled to " << buffer.size() << " points" << - std::endl; - - // First time through, create the SQL statement, allocate holding pens - // and fire it off! - if (! m_cursor) - CursorSetup(); - - point_count_t totalNumRead = 0; - while (totalNumRead < count) - { - if (m_patch->remaining == 0) - if (!NextBuffer()) - return totalNumRead; - PointId bufBegin = buffer.size(); - point_count_t numRead = readPgPatch(buffer, count - totalNumRead); - PointId bufEnd = bufBegin + numRead; - totalNumRead += numRead; - } - return totalNumRead; -} - -} // namespace sequential -} // namespace iterators - -} // namespace pgpointcloud -} // namespace drivers -} // namespace pdal diff --git a/src/drivers/pgpointcloud/PgReader.cpp b/src/drivers/pgpointcloud/PgReader.cpp index 0d3581f70e..e211a66143 100644 --- a/src/drivers/pgpointcloud/PgReader.cpp +++ b/src/drivers/pgpointcloud/PgReader.cpp @@ -59,6 +59,7 @@ PgReader::PgReader(const Options& options) PgReader::~PgReader() { + //ABELL - Do bad things if we don't do this? Already in done(). if (m_session) PQfinish(m_session); } @@ -101,17 +102,7 @@ void PgReader::processOptions(const Options& options) } -void PgReader::ready(PointContext ctx) -{ - // Database connection - m_session = pg_connect(m_connection); - - if (getSpatialReference().empty()) - setSpatialReference(fetchSpatialReference()); -} - - -uint64_t PgReader::getNumPoints() const +point_count_t PgReader::getNumPoints() const { if (m_cached_point_count) return m_cached_point_count; @@ -131,6 +122,7 @@ uint64_t PgReader::getNumPoints() const { throw pdal_error("unable to get point count"); } + m_cached_point_count = atoi(PQgetvalue(result, 0, 0)); m_cached_max_points = atoi(PQgetvalue(result, 0, 1)); PQclear(result); @@ -156,7 +148,7 @@ std::string PgReader::getDataQuery() const } -uint64_t PgReader::getMaxPoints() const +point_count_t PgReader::getMaxPoints() const { if (m_cached_point_count == 0) getNumPoints(); // Fills m_cached_max_points. @@ -256,11 +248,142 @@ pdal::SpatialReference PgReader::fetchSpatialReference() const } -pdal::StageSequentialIterator* PgReader::createSequentialIterator() const +void PgReader::ready(PointContext ctx) +{ + m_atEnd = false; + m_cur_row = 0; + m_cur_nrows = 0; + m_cur_result = NULL; + + m_session = pg_connect(m_connection); + + if (getSpatialReference().empty()) + setSpatialReference(fetchSpatialReference()); + + m_point_size = 0; + schema::DimInfoList& dims = m_schema.m_dims; + for (auto di = dims.begin(); di != dims.end(); ++di) + m_point_size += Dimension::size(di->m_type); + + CursorSetup(); +} + + +void PgReader::done(PointContext ctx) +{ + CursorTeardown(); + if (m_session) + PQfinish(m_session); + m_session = NULL; + if (m_cur_result) + PQclear(m_cur_result); +} + + +void PgReader::CursorSetup() { - return new iterators::sequential::PgIterator(*this, m_schema.m_dims); + std::ostringstream oss; + oss << "DECLARE cur CURSOR FOR " << getDataQuery(); + pg_begin(m_session); + pg_execute(m_session, oss.str()); + + log()->get(LogLevel::Debug) << "SQL cursor prepared: " << + oss.str() << std::endl; +} + + +void PgReader::CursorTeardown() +{ + pg_execute(m_session, "CLOSE cur"); + pg_commit(m_session); + log()->get(LogLevel::Debug) << "SQL cursor closed." << std::endl; +} + + +point_count_t PgReader::readPgPatch(PointBuffer& buffer, point_count_t numPts) +{ + point_count_t numRemaining = m_patch.remaining; + PointId nextId = buffer.size(); + point_count_t numRead = 0; + + size_t offset = ((m_patch.count - m_patch.remaining) * m_point_size); + uint8_t *pos = &(m_patch.binary.front()) + offset; + + schema::DimInfoList& dims = m_schema.m_dims; + while (numRead < numPts && numRemaining > 0) + { + for (auto di = dims.begin(); di != dims.end(); ++di) + { + schema::DimInfo& d = *di; + buffer.setField(d.m_id, d.m_type, nextId, pos); + pos += Dimension::size(d.m_type); + } + numRemaining--; + nextId++; + numRead++; + } + m_patch.remaining = numRemaining; + return numRead; +} + + +bool PgReader::NextBuffer() +{ + if (m_cur_row >= m_cur_nrows || !m_cur_result) + { + static std::string fetch = "FETCH 2 FROM cur"; + if (m_cur_result) + PQclear(m_cur_result); + m_cur_result = pg_query_result(m_session, fetch); + bool logOutput = (log()->getLevel() > LogLevel::Debug3); + if (logOutput) + log()->get(LogLevel::Debug3) << "SQL: " << fetch << std::endl; + if ((PQresultStatus(m_cur_result) != PGRES_TUPLES_OK) || + (PQntuples(m_cur_result) == 0)) + { + PQclear(m_cur_result); + m_cur_result = NULL; + m_atEnd = true; + return false; + } + + m_cur_row = 0; + m_cur_nrows = PQntuples(m_cur_result); + } + m_patch.hex = PQgetvalue(m_cur_result, m_cur_row, 0); + m_patch.count = atoi(PQgetvalue(m_cur_result, m_cur_row, 1)); + m_patch.remaining = m_patch.count; + m_patch.update_binary(); + + m_cur_row++; + return true; +} + + +point_count_t PgReader::read(PointBuffer& buffer, point_count_t count) +{ + if (eof()) + return 0; + + log()->get(LogLevel::Debug) << "readBufferImpl called with " + "PointBuffer filled to " << buffer.size() << " points" << + std::endl; + + point_count_t totalNumRead = 0; + while (totalNumRead < count) + { + if (m_patch.remaining == 0) + if (!NextBuffer()) + return totalNumRead; + PointId bufBegin = buffer.size(); + point_count_t numRead = readPgPatch(buffer, count - totalNumRead); + PointId bufEnd = bufBegin + numRead; + totalNumRead += numRead; + } + return totalNumRead; } } // pgpointcloud } // drivers } // pdal + diff --git a/src/drivers/qfit/Reader.cpp b/src/drivers/qfit/Reader.cpp index 348d4814a4..015a7a7ef0 100644 --- a/src/drivers/qfit/Reader.cpp +++ b/src/drivers/qfit/Reader.cpp @@ -202,7 +202,7 @@ void Reader::initialize() } str->seekg(0); - boost::int32_t int4(0); + int32_t int4(0); Utils::read_n(int4, *str, sizeof(int4)); @@ -277,7 +277,6 @@ Options Reader::getDefaultOptions() void Reader::processOptions(const Options& ops) { - m_filename = ops.getOption("filename").getValue(); m_flip_x = ops.getValueOrDefault("flip_coordinates", true); m_scale_z = ops.getValueOrDefault("scale_z", 0.001); } @@ -327,27 +326,30 @@ void Reader::ready(PointContext ctx) "inconsistent with point size."; throw qfit_error(msg.str()); } + m_index = 0; + m_istream = FileUtils::openFile(m_filename); + m_istream->seekg(getPointDataOffset()); } -point_count_t Reader::processBuffer(PointBuffer& data, std::istream& stream, - point_count_t count) const +point_count_t Reader::read(PointBuffer& data, point_count_t count) { - if (!stream.good()) + if (!m_istream->good()) { - throw pdal_error("QFIT Reader::processBuffer stream is no good!"); + throw pdal_error("QFIT file stream is no good!"); } - if (stream.eof()) + if (m_istream->eof()) { - throw pdal_error("QFIT Reader::processBuffer stream is eof!"); + throw pdal_error("QFIT file stream is eof!"); } + count = std::min(m_numPoints - m_index, count); uint8_t *buf = new uint8_t[m_size]; PointId nextId = data.size(); point_count_t numRead = 0; while (count--) { - Utils::read_n(buf, stream, m_size); + Utils::read_n(buf, *m_istream, m_size); uint8_t* p = buf; // always read the base fields @@ -450,18 +452,14 @@ point_count_t Reader::processBuffer(PointBuffer& data, std::istream& stream, int32_t gpstime = Utils::read_field(p); numRead++; + nextId++; } delete[] buf; + m_index += numRead; return numRead; } -pdal::StageSequentialIterator* -Reader::createSequentialIterator(PointBuffer& buffer) const -{ - return new iterators::sequential::Reader(*this); -} - Dimension::IdList Reader::getDefaultDimensions() { @@ -487,40 +485,12 @@ Dimension::IdList Reader::getDefaultDimensions() } -namespace iterators -{ -namespace sequential -{ - -Reader::Reader(const pdal::drivers::qfit::Reader& reader) : m_reader(reader) -{ - m_istream = FileUtils::openFile(m_reader.m_filename); - m_istream->seekg(m_reader.getPointDataOffset()); -} - - -Reader::~Reader() +void Reader::done(PointContext ctx) { FileUtils::closeFile(m_istream); } - -uint64_t Reader::skipImpl(boost::uint64_t count) -{ - m_istream->seekg(m_reader.getPointDataSize() * count, std::ios::cur); - return count; -} - - -point_count_t Reader::readBufferImpl(PointBuffer& data) -{ - point_count_t numToRead = m_reader.getNumPoints() - getIndex(); - return m_reader.processBuffer(data, *m_istream, numToRead); -} - -} // sequential -} // iterators - } // namespace qfit } // namespace drivers } // namespace pdal + diff --git a/src/drivers/sbet/Reader.cpp b/src/drivers/sbet/Reader.cpp index f7ba181bb4..58e9efeb3e 100644 --- a/src/drivers/sbet/Reader.cpp +++ b/src/drivers/sbet/Reader.cpp @@ -48,12 +48,6 @@ Options SbetReader::getDefaultOptions() } -void SbetReader::processOptions(const Options& options) -{ - m_filename = options.getOption("filename").getValue(); -} - - void SbetReader::addDimensions(PointContext ctx) { ctx.registerDims(getDefaultDimensions()); @@ -67,34 +61,24 @@ void SbetReader::ready(PointContext ctx) if (fileSize % pointSize != 0) throw pdal_error("invalid sbet file size"); m_numPts = fileSize / pointSize; + m_index = 0; m_stream.reset(new ILeStream(m_filename)); } -StageSequentialIterator* SbetReader::createSequentialIterator() const -{ - return new iterators::sequential::SbetSeqIterator(getDefaultDimensions(), - m_numPts, *m_stream); -} - - -namespace iterators -{ -namespace sequential -{ - -point_count_t SbetSeqIterator::readImpl(PointBuffer& buf, point_count_t numPts) +point_count_t SbetReader::read(PointBuffer& buf, point_count_t count) { PointId nextId = buf.size(); PointId idx = m_index; point_count_t numRead = 0; seek(idx); - while (numRead < numPts && idx < m_numPts) + Dimension::IdList dims = getDefaultDimensions(); + while (numRead < count && idx < m_numPts) { - for (auto di = m_dims.begin(); di != m_dims.end(); ++di) + for (auto di = dims.begin(); di != dims.end(); ++di) { double d; - m_stream >> d; + *m_stream >> d; Dimension::Id::Enum dim = *di; buf.setField(dim, nextId, d); } @@ -107,29 +91,17 @@ point_count_t SbetSeqIterator::readImpl(PointBuffer& buf, point_count_t numPts) } -uint64_t SbetSeqIterator::skipImpl(uint64_t pointsToSkip) -{ - uint32_t lastIndex = (uint32_t)m_index; - uint64_t newIndex = m_index + pointsToSkip; - m_index = (uint32_t)std::min((uint64_t)m_numPts, newIndex); - return std::min(pointsToSkip, m_index - lastIndex); -} - - -bool SbetSeqIterator::atEndImpl() const +bool SbetReader::eof() { return m_index >= m_numPts; } -void SbetSeqIterator::seek(PointId idx) +void SbetReader::seek(PointId idx) { - m_stream.seek(idx * sizeof(double) * m_dims.size()); + m_stream->seek(idx * sizeof(double) * getDefaultDimensions().size()); } -} // namespace sequential -} // namespace iterators - } // namespace sbet } // namespace drivers } // namespace pdal diff --git a/src/drivers/sqlite/SQLiteIterator.cpp b/src/drivers/sqlite/SQLiteIterator.cpp deleted file mode 100644 index 6eff65414b..0000000000 --- a/src/drivers/sqlite/SQLiteIterator.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2014, Howard Butler, howard@hobu.co -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following -* conditions are met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the -* names of its contributors may be used to endorse or promote -* products derived from this software without specific prior -* written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -* OF SUCH DAMAGE. -****************************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace pdal -{ -namespace drivers -{ -namespace sqlite -{ - - -namespace iterators -{ -namespace sequential -{ - -SQLiteIterator::SQLiteIterator(const pdal::drivers::sqlite::SQLiteReader& reader, PatchPtr patch ) - : m_reader(reader) - , m_at_end(false) - , b_doneQuery(false) - , m_patch(patch) -{ - - pdal::Options const& options = reader.getOptions(); - std::string const& connection = options.getValueOrThrow("connection"); - - m_reader.log()->get(LogLevel::Debug) << "Connection: '" << connection << "'" << std::endl; - m_session = std::unique_ptr(new SQLite(connection, m_reader.log())); - m_session->connect(false); // don't connect in write mode - - - schema::DimInfoList dims = patch->m_schema.m_dims; - for (auto di = dims.begin(); di != dims.end(); ++di) - m_point_size += Dimension::size(di->m_type); -} - -bool SQLiteIterator::doQuery() -{ - pdal::Options const& options = m_reader.getOptions(); - std::string const& query = options.getValueOrThrow("query"); - m_session->query(query); - return true; -} - -void SQLiteIterator::validateQuery() const -{ - std::set reqFields; - reqFields.insert("POINTS"); - reqFields.insert("SCHEMA"); - reqFields.insert("NUM_POINTS"); - reqFields.insert("CLOUD"); - - for (auto r = reqFields.begin(); r != reqFields.end(); ++r) - { - auto p = m_session->columns().find(*r); - if (p == m_session->columns().end()) - { - std::ostringstream oss; - oss << "Unable to find required column name '" << *r << "'"; - throw pdal_error(oss.str()); - } - } -} - - -bool SQLiteIterator::NextBuffer() -{ - return m_session->next(); -} - -point_count_t SQLiteIterator::readPatch(PointBuffer& buffer, point_count_t numPts) -{ - - const row* r = m_session->get(); - if (!r) - throw pdal_error("readPatch with no data in session!"); - std::map const& columns = m_session->columns(); - - // Availability of positions already validated - int32_t position = columns.find("POINTS")->second; - auto bytes = (*r)[position].blobBuf; - size_t size = (*r)[position].blobLen; - position = columns.find("NUM_POINTS")->second; - int32_t count = boost::lexical_cast((*r)[position].data); - m_reader.log()->get(LogLevel::Debug4) << "fetched patch with " << count - << " points and " << size << " bytes bytesize: " << size << std::endl; - m_patch->remaining = count; - m_patch->count = count; - m_patch->bytes = bytes; - m_patch->byte_size = size; - - point_count_t numRemaining = m_patch->remaining; - PointId nextId = buffer.size(); - point_count_t numRead = 0; - - size_t offset = ((m_patch->count - m_patch->remaining) * m_point_size); - uint8_t *pos = &(m_patch->bytes.front()) + offset; - - schema::DimInfoList& dims = m_patch->m_schema.m_dims; - while (numRead < numPts && numRemaining > 0) - { - for (auto di = dims.begin(); di != dims.end(); ++di) - { - schema::DimInfo& d = *di; - buffer.setField(d.m_id, d.m_type, nextId, pos); - pos += Dimension::size(d.m_type); - } - - // Scale X, Y and Z - // double v = buffer.getFieldAs(Dimension::Id::X, nextId); - // v = v * m_patch->xScale() + m_patch->xOffset(); - // buffer.setField(Dimension::Id::X, nextId, v); - // - // v = buffer.getFieldAs(Dimension::Id::Y, nextId); - // v = v * m_patch->yScale() + m_patch->yOffset(); - // buffer.setField(Dimension::Id::Y, nextId, v); - // - // v = buffer.getFieldAs(Dimension::Id::Z, nextId); - // v = v * m_patch->zScale() + m_patch->zOffset(); - // buffer.setField(Dimension::Id::Z, nextId, v); - - numRemaining--; - nextId++; - numRead++; - } - - m_patch->remaining = numRemaining; - - - return numRead; -} - - -point_count_t SQLiteIterator::readImpl(PointBuffer& buffer, point_count_t count) -{ - if (atEndImpl()) - return 0; - - m_reader.log()->get(LogLevel::Debug4) << "readBufferImpl called with " - "PointBuffer filled to " << buffer.size() << " points" << - std::endl; - - point_count_t totalNumRead = 0; - - if (! b_doneQuery) - { - // read first patch - doQuery(); - validateQuery(); - b_doneQuery = true; - totalNumRead = readPatch(buffer, count); - } - int patch_count(0); - while (totalNumRead < count) - { - if (m_patch->remaining == 0) - { - if (!NextBuffer()) - { - return totalNumRead; - } - } - PointId bufBegin = buffer.size(); - point_count_t numRead = readPatch(buffer, count - totalNumRead); - PointId bufEnd = bufBegin + numRead; - totalNumRead += numRead; - patch_count++; - - } - - return totalNumRead; - -} - -boost::uint64_t SQLiteIterator::skipImpl(boost::uint64_t count) -{ - boost::uint64_t initialCount = count; - while (count) - { - point_count_t numRem = m_patch->remaining; - point_count_t blockCount = std::min((point_count_t)count, numRem); - m_patch->remaining = (numRem - blockCount); - count -= blockCount; - if (count > 0) - if (! NextBuffer()) - break; - } - return initialCount - count; -} - - -bool SQLiteIterator::atEndImpl() const -{ - return m_at_end; -} - - -} -} // iterators::sequential:: - -} -} -} // namespace pdal::driver::sqlite diff --git a/src/drivers/sqlite/SQLiteReader.cpp b/src/drivers/sqlite/SQLiteReader.cpp index 5ade08167c..2904473b18 100644 --- a/src/drivers/sqlite/SQLiteReader.cpp +++ b/src/drivers/sqlite/SQLiteReader.cpp @@ -33,21 +33,7 @@ ****************************************************************************/ #include -#include #include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include #ifdef USE_PDAL_PLUGIN_SOCI MAKE_READER_CREATOR(sqliteReader, pdal::drivers::sqlite::Reader) @@ -62,21 +48,21 @@ namespace drivers namespace sqlite { - -SQLiteReader::SQLiteReader(const Options& options) - : pdal::Reader(options) +SQLiteReader::SQLiteReader(const Options& options) : pdal::Reader(options) {} void SQLiteReader::initialize() { try { - log()->get(LogLevel::Debug) << "Connection: '" << m_connection << "'" << std::endl; + log()->get(LogLevel::Debug) << "Connection: '" << m_connection << "'" << + std::endl; m_session = std::unique_ptr(new SQLite(m_connection, log())); m_session->connect(false); // don't connect in write mode log()->get(LogLevel::Debug) << "Connected to database" << std::endl; bool bHaveSpatialite = m_session->doesTableExist("geometry_columns"); - log()->get(LogLevel::Debug) << "Have spatialite?: " << bHaveSpatialite << std::endl; + log()->get(LogLevel::Debug) << "Have spatialite?: " << + bHaveSpatialite << std::endl; m_session->spatialite(); if (!bHaveSpatialite) @@ -106,7 +92,6 @@ void SQLiteReader::initialize() } m_patch = PatchPtr(new Patch()); - } @@ -173,7 +158,6 @@ void SQLiteReader::processOptions(const Options& options) } - void SQLiteReader::validateQuery() const { std::set reqFields; @@ -194,6 +178,7 @@ void SQLiteReader::validateQuery() const } } + void SQLiteReader::addDimensions(PointContext ctx) { log()->get(LogLevel::Debug) << "Fetching schema object" << std::endl; @@ -218,15 +203,129 @@ void SQLiteReader::addDimensions(PointContext ctx) } -pdal::StageSequentialIterator* -SQLiteReader::createSequentialIterator() const +void SQLiteReader::ready(PointContext ctx) +{ + m_at_end = false; + b_doneQuery = false; + + m_session.reset(new SQLite(m_connection, log())); + m_session->connect(false); // don't connect in write mode + + schema::DimInfoList dims = m_patch->m_schema.m_dims; + m_point_size = 0; + for (auto di = dims.begin(); di != dims.end(); ++di) + m_point_size += Dimension::size(di->m_type); +} + + +bool SQLiteReader::NextBuffer() { - return new pdal::drivers::sqlite::iterators::sequential::SQLiteIterator(*this, m_patch); + return m_session->next(); } +point_count_t SQLiteReader::readPatch(PointBuffer& buffer, point_count_t numPts) +{ + const row* r = m_session->get(); + if (!r) + throw pdal_error("readPatch with no data in session!"); + std::map const& columns = m_session->columns(); + + // Availability of positions already validated + int32_t position = columns.find("POINTS")->second; + auto bytes = (*r)[position].blobBuf; + size_t size = (*r)[position].blobLen; + position = columns.find("NUM_POINTS")->second; + int32_t count = boost::lexical_cast((*r)[position].data); + log()->get(LogLevel::Debug4) << "fetched patch with " << count << + " points and " << size << " bytes bytesize: " << size << std::endl; + m_patch->remaining = count; + m_patch->count = count; + m_patch->bytes = bytes; + m_patch->byte_size = size; + + point_count_t numRemaining = m_patch->remaining; + PointId nextId = buffer.size(); + point_count_t numRead = 0; + size_t offset = ((m_patch->count - m_patch->remaining) * m_point_size); + uint8_t *pos = &(m_patch->bytes.front()) + offset; + schema::DimInfoList& dims = m_patch->m_schema.m_dims; + while (numRead < numPts && numRemaining > 0) + { + for (auto di = dims.begin(); di != dims.end(); ++di) + { + schema::DimInfo& d = *di; + buffer.setField(d.m_id, d.m_type, nextId, pos); + pos += Dimension::size(d.m_type); + } + + // Scale X, Y and Z + // double v = buffer.getFieldAs(Dimension::Id::X, nextId); + // v = v * m_patch->xScale() + m_patch->xOffset(); + // buffer.setField(Dimension::Id::X, nextId, v); + // + // v = buffer.getFieldAs(Dimension::Id::Y, nextId); + // v = v * m_patch->yScale() + m_patch->yOffset(); + // buffer.setField(Dimension::Id::Y, nextId, v); + // + // v = buffer.getFieldAs(Dimension::Id::Z, nextId); + // v = v * m_patch->zScale() + m_patch->zOffset(); + // buffer.setField(Dimension::Id::Z, nextId, v); + + numRemaining--; + nextId++; + numRead++; + } + + m_patch->remaining = numRemaining; + + return numRead; } + + +point_count_t SQLiteReader::read(PointBuffer& buffer, point_count_t count) +{ + if (eof()) + return 0; + + log()->get(LogLevel::Debug4) << "readBufferImpl called with " + "PointBuffer filled to " << buffer.size() << " points" << + std::endl; + + point_count_t totalNumRead = 0; + if (! b_doneQuery) + { + // read first patch + m_session->query(m_query); + validateQuery(); + b_doneQuery = true; + totalNumRead = readPatch(buffer, count); + } + + int patch_count(0); + while (totalNumRead < count) + { + if (m_patch->remaining == 0) + { + if (!NextBuffer()) + { + m_at_end = true; + return totalNumRead; + } + } + PointId bufBegin = buffer.size(); + point_count_t numRead = readPatch(buffer, count - totalNumRead); + PointId bufEnd = bufBegin + numRead; + totalNumRead += numRead; + patch_count++; + } + + return totalNumRead; + } -} // namespace pdal::driver::sqlite + +} // namespace sqlite +} // namespace drivers +} // namespace pdal diff --git a/src/drivers/terrasolid/Reader.cpp b/src/drivers/terrasolid/Reader.cpp index 5afe691b0a..45fafa2feb 100644 --- a/src/drivers/terrasolid/Reader.cpp +++ b/src/drivers/terrasolid/Reader.cpp @@ -45,17 +45,9 @@ namespace drivers namespace terrasolid { -Reader::Reader(const Options& options) - : pdal::Reader(options) - , m_format(TERRASOLID_Format_Unknown) - , m_haveColor(false) - , m_haveTime(false) +void Reader::initialize() { - std::string filename= getFileName(); - - std::istream* stream = FileUtils::openFile(filename); - - stream->seekg(0); + std::istream* stream = FileUtils::openFile(m_filename); TerraSolidHeaderPtr h(new TerraSolidHeader); m_header.swap(h); @@ -69,24 +61,15 @@ Reader::Reader(const Options& options) m_haveTime = (m_header->Time != 0); m_format = static_cast(m_header->HdrVersion); - if (!((m_format==TERRASOLID_Format_1) || (m_format == TERRASOLID_Format_2))) + if ((m_format != TERRASOLID_Format_1) && (m_format != TERRASOLID_Format_2)) { std::ostringstream oss; oss << "Version was '" << m_format << "', not '" << TERRASOLID_Format_1 << "' or '" << TERRASOLID_Format_2 << "'"; throw terrasolid_error(oss.str()); - } - m_size = 0; - m_offset = 56; - delete stream; -} - - -void Reader::initialize() -{ log()->get(LogLevel::Debug) << "TerraSolid Reader::initialize format: " << m_format << std::endl; log()->get(LogLevel::Debug) << "OrgX: " << m_header->OrgX << std::endl; @@ -101,20 +84,6 @@ void Reader::initialize() } -Options Reader::getDefaultOptions() -{ - Options options; - Option filename("filename", "", "file to read from"); - return options; -} - - -std::string Reader::getFileName() const -{ - return getOptions().getValueOrThrow("filename"); -} - - void Reader::addDimensions(PointContext ctx) { m_size = 0; @@ -152,19 +121,45 @@ void Reader::addDimensions(PointContext ctx) } -uint32_t Reader::processBuffer(PointBuffer& data, std::istream& stream, - uint64_t numPointsLeft) const +Dimension::IdList Reader::getDefaultDimensions() { - uint32_t baseTime; + using namespace Dimension; - // we must not read more points than are left in the file - uint32_t numPoints = - (uint32_t)std::min((uint64_t)data.size(), numPointsLeft); + IdList dims; - const int pointByteCount = getPointDataSize(); + dims.push_back(Id::Classification); + dims.push_back(Id::PointSourceId); + dims.push_back(Id::ReturnNumber); + dims.push_back(Id::Flag); + dims.push_back(Id::Mark); + dims.push_back(Id::Intensity); + dims.push_back(Id::X); + dims.push_back(Id::Y); + dims.push_back(Id::Z); + dims.push_back(Id::Red); + dims.push_back(Id::Green); + dims.push_back(Id::Blue); + dims.push_back(Id::Alpha); + dims.push_back(Id::OffsetTime); + return dims; +} - uint8_t *buf = new uint8_t[pointByteCount * numPoints]; - Utils::read_n(buf, stream, pointByteCount * numPoints); + +void Reader::ready(PointContext ctx) +{ + m_istream = FileUtils::openFile(m_filename); + // Skip to the beginning of points. + m_istream->seekg(56); + m_index = 0; +} + + +point_count_t Reader::read(PointBuffer& data, point_count_t count) +{ + count = std::min(count, getNumPoints() - m_index); + + uint8_t *buf = new uint8_t[m_size * count]; + Utils::read_n(buf, *m_istream, m_size * count); //See https://www.terrasolid.com/download/tscan.pdf // This spec is awful, but it's something. @@ -173,224 +168,112 @@ uint32_t Reader::processBuffer(PointBuffer& data, std::istream& stream, // says. // Also modified the fetch of time/color based on header flag (rather // than just not write the data into the buffer). - for (PointId pointIndex = 0; pointIndex < numPoints; pointIndex++) + PointId nextId = data.size(); + while (!eof()) { - uint8_t* p = buf + pointByteCount * pointIndex; + uint8_t* p = buf + m_size * m_index; if (m_format == TERRASOLID_Format_1) { uint8_t classification = Utils::read_field(p); - data.setField(Dimension::Id::Classification, pointIndex, + data.setField(Dimension::Id::Classification, nextId, classification); uint8_t flight_line = Utils::read_field(p); - data.setField(Dimension::Id::PointSourceId, pointIndex, + data.setField(Dimension::Id::PointSourceId, nextId, flight_line); uint16_t echo_int = Utils::read_field(p); - data.setField(Dimension::Id::ReturnNumber, pointIndex, echo_int); + data.setField(Dimension::Id::ReturnNumber, nextId, echo_int); int32_t x = Utils::read_field(p); - data.setField(Dimension::Id::X, pointIndex, + data.setField(Dimension::Id::X, nextId, (x - m_header->OrgX) / m_header->Units); int32_t y = Utils::read_field(p); - data.setField(Dimension::Id::Y, pointIndex, + data.setField(Dimension::Id::Y, nextId, (y - m_header->OrgY) / m_header->Units); int32_t z = Utils::read_field(p); - data.setField(Dimension::Id::Z, pointIndex, + data.setField(Dimension::Id::Z, nextId, (z - m_header->OrgZ) / m_header->Units); } if (m_format == TERRASOLID_Format_2) { int32_t x = Utils::read_field(p); - data.setField(Dimension::Id::X, pointIndex, + data.setField(Dimension::Id::X, nextId, (x - m_header->OrgX) / m_header->Units); int32_t y = Utils::read_field(p); - data.setField(Dimension::Id::Y, pointIndex, + data.setField(Dimension::Id::Y, nextId, (y - m_header->OrgY) / m_header->Units); int32_t z = Utils::read_field(p); - data.setField(Dimension::Id::Z, pointIndex, + data.setField(Dimension::Id::Z, nextId, (z - m_header->OrgZ) / m_header->Units); uint8_t classification = Utils::read_field(p); - data.setField(Dimension::Id::Classification, pointIndex, + data.setField(Dimension::Id::Classification, nextId, classification); uint8_t return_number = Utils::read_field(p); - data.setField(Dimension::Id::ReturnNumber, pointIndex, + data.setField(Dimension::Id::ReturnNumber, nextId, return_number); uint8_t flag = Utils::read_field(p); - data.setField(Dimension::Id::Flag, pointIndex, flag); + data.setField(Dimension::Id::Flag, nextId, flag); boost::uint8_t mark = Utils::read_field(p); - data.setField(Dimension::Id::Mark, pointIndex, mark); + data.setField(Dimension::Id::Mark, nextId, mark); uint16_t flight_line = Utils::read_field(p); - data.setField(Dimension::Id::PointSourceId, pointIndex, + data.setField(Dimension::Id::PointSourceId, nextId, flight_line); uint16_t intensity = Utils::read_field(p); - data.setField(Dimension::Id::Intensity, pointIndex, intensity); + data.setField(Dimension::Id::Intensity, nextId, intensity); } if (m_haveTime) { uint32_t t = Utils::read_field(p); - if (pointIndex == 0) - baseTime = t; - t = baseTime - t; //Offset from the beginning of the file. + if (m_index == 0) + m_baseTime = t; + t -= m_baseTime; //Offset from the beginning of the read. //instead of GPS week. t /= 5; //5000ths of a second to milliseconds - data.setField(Dimension::Id::OffsetTime, pointIndex, t); + data.setField(Dimension::Id::OffsetTime, nextId, t); } if (m_haveColor) { uint8_t red = Utils::read_field(p); - data.setField(Dimension::Id::Red, pointIndex, red); + data.setField(Dimension::Id::Red, nextId, red); uint8_t green = Utils::read_field(p); - data.setField(Dimension::Id::Green, pointIndex, green); + data.setField(Dimension::Id::Green, nextId, green); uint8_t blue = Utils::read_field(p); - data.setField(Dimension::Id::Blue, pointIndex, blue); + data.setField(Dimension::Id::Blue, nextId, blue); uint8_t alpha = Utils::read_field(p); - data.setField(Dimension::Id::Alpha, pointIndex, alpha); + data.setField(Dimension::Id::Alpha, nextId, alpha); } + nextId++; } delete[] buf; - return numPoints; -} - -pdal::StageSequentialIterator* -Reader::createSequentialIterator(PointBuffer& buffer) const -{ - return new pdal::drivers::terrasolid::iterators::sequential::Reader( - *this, buffer); -} - - -pdal::StageRandomIterator* Reader::createRandomIterator(PointBuffer& buffer) const -{ - return new pdal::drivers::terrasolid::iterators::random::Reader( - *this, buffer); -} - -Dimension::IdList Reader::getDefaultDimensions() -{ - using namespace Dimension; - - IdList dims; - - dims.push_back(Id::Classification); - dims.push_back(Id::PointSourceId); - dims.push_back(Id::ReturnNumber); - dims.push_back(Id::Flag); - dims.push_back(Id::Mark); - dims.push_back(Id::Intensity); - dims.push_back(Id::X); - dims.push_back(Id::Y); - dims.push_back(Id::Z); - dims.push_back(Id::Red); - dims.push_back(Id::Green); - dims.push_back(Id::Blue); - dims.push_back(Id::Alpha); - dims.push_back(Id::OffsetTime); - return dims; -} - - -namespace iterators -{ - -namespace sequential -{ - - -Reader::Reader(const terrasolid::Reader& reader, PointBuffer& buffer) - : pdal::ReaderSequentialIterator(buffer), m_reader(reader) -{ - m_istream = FileUtils::openFile(m_reader.getFileName()); - m_istream->seekg(m_reader.getPointDataOffset()); -} - - -Reader::~Reader() -{ - FileUtils::closeFile(m_istream); - return; -} - - -boost::uint64_t Reader::skipImpl(boost::uint64_t count) -{ - m_istream->seekg(m_reader.getPointDataSize() * count, std::ios::cur); return count; } -bool Reader::atEndImpl() const -{ - return getIndex() >= m_reader.getNumPoints(); -} - - -point_count_t Reader::readBufferImpl(PointBuffer& data) -{ - point_count_t numToRead = m_reader.getNumPoints() - getIndex(); - return m_reader.processBuffer(data, *m_istream, numToRead); -} - - -} // sequential - -namespace random -{ - - - -Reader::Reader(const terrasolid::Reader& reader, PointBuffer& buffer) - : pdal::ReaderRandomIterator(buffer), m_reader(reader) -{ - m_istream = FileUtils::openFile(m_reader.getFileName()); - m_istream->seekg(m_reader.getPointDataOffset()); -} - - -Reader::~Reader() +void Reader::done(PointContext ctx) { FileUtils::closeFile(m_istream); - return; } - -boost::uint64_t Reader::seekImpl(boost::uint64_t count) -{ - - m_istream->seekg(m_reader.getPointDataSize() * count + m_reader.getPointDataOffset(), std::ios::cur); - - return count; -} - - -point_count_t Reader::readBufferImpl(PointBuffer& data) -{ - point_count_t numToRead = m_reader.getNumPoints() - getIndex(); - return m_reader.processBuffer(data, *m_istream, numToRead); -} - -} // random -} // iterators - } // namespace terrasolid } // namespace drivers } // namespace pdal diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index a594c47082..57ee2973af 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -35,7 +35,7 @@ SET(PDAL_UNITTEST_TEST_SRC OptionsTest.cpp PipelineManagerTest.cpp PointBufferTest.cpp -# drivers/qfit/QFITReaderTest.cpp + drivers/qfit/QFITReaderTest.cpp RangeTest.cpp filters/ReprojectionFilterTest.cpp drivers/sbet/SbetReaderTest.cpp diff --git a/test/unit/SpatialReferenceTest.cpp b/test/unit/SpatialReferenceTest.cpp index 09d9cd5e1a..c7b69d6cf2 100644 --- a/test/unit/SpatialReferenceTest.cpp +++ b/test/unit/SpatialReferenceTest.cpp @@ -134,7 +134,9 @@ BOOST_AUTO_TEST_CASE(test_read_srs) PointContext ctx; - las::Reader reader(Support::datapath("utm17.las")); + Options ops; + ops.add("filename", Support::datapath("utm17.las")); + las::Reader reader(ops); reader.prepare(ctx); const pdal::SpatialReference& ref = reader.getSpatialReference(); @@ -263,7 +265,9 @@ BOOST_AUTO_TEST_CASE(test_vertical_datums) PointContext ctx; // Write a very simple file with our SRS and one point. - las::Reader reader(Support::datapath("1.2-with-color.las")); + Options ops1; + ops1.add("filename", Support::datapath("1.2-with-color.las")); + las::Reader reader(ops1); std::ostream* ofs = pdal::FileUtils::createFile(tmpfile); { @@ -282,7 +286,9 @@ BOOST_AUTO_TEST_CASE(test_vertical_datums) // Reopen and check contents. { PointContext ctx; - las::Reader reader(tmpfile); + Options ops; + ops.add("filename", tmpfile); + las::Reader reader(ops); reader.prepare(ctx); const SpatialReference ref2 = reader.getSpatialReference(); @@ -340,7 +346,9 @@ BOOST_AUTO_TEST_CASE(test_writing_vlr) pdal::FileUtils::deleteFile(tmpfile); PointContext ctx; - las::Reader readerx(Support::datapath("1.2-with-color.las")); + Options ops; + ops.add("filename", Support::datapath("1.2-with-color.las")); + las::Reader readerx(ops); std::ostream* ofs = pdal::FileUtils::createFile(tmpfile); { const boost::uint64_t numPoints = readerx.getNumPoints(); @@ -358,7 +366,9 @@ BOOST_AUTO_TEST_CASE(test_writing_vlr) // Reopen and check contents. { PointContext ctx; - las::Reader reader(tmpfile); + Options ops; + ops.add("filename", tmpfile); + las::Reader reader(ops); reader.prepare(ctx); SpatialReference result_ref = reader.getSpatialReference(); diff --git a/test/unit/Support.cpp b/test/unit/Support.cpp index fa896fe226..a8ace09380 100644 --- a/test/unit/Support.cpp +++ b/test/unit/Support.cpp @@ -43,7 +43,6 @@ #include #include -#include #include #include #include diff --git a/test/unit/XMLSchemaTest.cpp b/test/unit/XMLSchemaTest.cpp index 914a2317f8..eecd264c66 100644 --- a/test/unit/XMLSchemaTest.cpp +++ b/test/unit/XMLSchemaTest.cpp @@ -41,12 +41,8 @@ #include #include - #include - #include - -#include #include #include "Support.hpp" diff --git a/test/unit/apps/pc2pcTest.cpp b/test/unit/apps/pc2pcTest.cpp index df70af01b3..dc68d7c29b 100644 --- a/test/unit/apps/pc2pcTest.cpp +++ b/test/unit/apps/pc2pcTest.cpp @@ -96,9 +96,10 @@ static bool fileIsCompressed(const std::string& name) { PointContext ctx; - drivers::las::Reader reader(name); + Options ops; + ops.add("filename", name); + drivers::las::Reader reader(ops); reader.prepare(ctx); - return reader.getLasHeader().Compressed(); } @@ -107,7 +108,9 @@ static bool fileHasSrs(const std::string& name) { PointContext ctx; - drivers::las::Reader reader(name); + Options ops; + ops.add("filename", name); + drivers::las::Reader reader(ops); reader.prepare(ctx); return !reader.getSpatialReference().empty(); } diff --git a/test/unit/drivers/bpf/BPFTest.cpp b/test/unit/drivers/bpf/BPFTest.cpp index 699d6b9088..9dea71eac4 100644 --- a/test/unit/drivers/bpf/BPFTest.cpp +++ b/test/unit/drivers/bpf/BPFTest.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include "Support.hpp" @@ -54,13 +53,18 @@ void test_file_type(const std::string& filename) PointContext context; - pdal::BpfReader reader(Support::datapath(filename)); + Options ops; + + ops.add("filename", Support::datapath(filename)); + ops.add("count", 506); + BpfReader reader(ops); + reader.prepare(context); - - PointBuffer data(context); - StageSequentialIterator *it = reader.createSequentialIterator(); - boost::uint32_t numRead = it->read(data, 3); - BOOST_CHECK(numRead = 3); + PointBufferSet pbSet = reader.execute(context); + + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 506); struct PtData { @@ -75,43 +79,29 @@ void test_file_type(const std::string& filename) for (int i = 0; i < 3; ++i) { - float x = data.getFieldAs(Dimension::Id::X, i); - float y = data.getFieldAs(Dimension::Id::Y, i); - float z = data.getFieldAs(Dimension::Id::Z, i); + float x = buf->getFieldAs(Dimension::Id::X, i); + float y = buf->getFieldAs(Dimension::Id::Y, i); + float z = buf->getFieldAs(Dimension::Id::Z, i); BOOST_CHECK_CLOSE(x, pts2[i].x, 0.001); BOOST_CHECK_CLOSE(y, pts2[i].y, 0.001); BOOST_CHECK_CLOSE(z, pts2[i].z, 0.001); } - // Should be positioned at point 3. - // Skip by 500, which should put us at 503. - - it->skip(500); - PointBuffer data2(context); - numRead = it->read(data2, 3); - BOOST_CHECK(numRead = 3); PtData pts[3] = { {494915.25, 4878096.5, 128.220001}, {494917.062, 4878124.5, 128.539993}, {494920.781, 4877914.5, 127.43} }; - for (int i = 0; i < 3; ++i) + for (int i = 503; i < 3; ++i) { - float x = data2.getFieldAs(Dimension::Id::X, i); - float y = data2.getFieldAs(Dimension::Id::Y, i); - float z = data2.getFieldAs(Dimension::Id::Z, i); + float x = buf->getFieldAs(Dimension::Id::X, i); + float y = buf->getFieldAs(Dimension::Id::Y, i); + float z = buf->getFieldAs(Dimension::Id::Z, i); BOOST_CHECK_CLOSE(x, pts[i].x, 0.001); BOOST_CHECK_CLOSE(y, pts[i].y, 0.001); BOOST_CHECK_CLOSE(z, pts[i].z, 0.001); } - - // We should now be at 506. Skip too far. Check that we've skipped - // to the end. - uint32_t numSkipped = it->skip(2000); - BOOST_CHECK(numSkipped == 559); - - delete it; } } //namespace diff --git a/test/unit/drivers/faux/FauxReaderTest.cpp b/test/unit/drivers/faux/FauxReaderTest.cpp index 216bc286b3..a4ac3fe154 100644 --- a/test/unit/drivers/faux/FauxReaderTest.cpp +++ b/test/unit/drivers/faux/FauxReaderTest.cpp @@ -36,73 +36,65 @@ #include #include + BOOST_AUTO_TEST_SUITE(FauxReaderTest) +using namespace pdal; + BOOST_AUTO_TEST_CASE(test_constant_mode_sequential_iter) { - using namespace pdal; - Options ops; Bounds bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0); ops.add("bounds", bounds); - ops.add("num_points", 1000); + ops.add("count", 750); ops.add("mode", "constant"); drivers::faux::Reader reader(ops); PointContext ctx; reader.prepare(ctx); BOOST_CHECK_EQUAL(reader.getDescription(), "Faux Reader"); - - PointBuffer buf(ctx); - StageSequentialIterator* iter = reader.createSequentialIterator(); - point_count_t numRead = iter->read(buf, 750); - - BOOST_CHECK_EQUAL(numRead, 750u); - - for (point_count_t i = 0; i < numRead; i++) + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 750); + for (point_count_t i = 0; i < buf->size(); i++) { - double x = buf.getFieldAs(Dimension::Id::X, i); - double y = buf.getFieldAs(Dimension::Id::Y, i); - double z = buf.getFieldAs(Dimension::Id::Z, i); - uint64_t t = buf.getFieldAs(Dimension::Id::OffsetTime, i); + double x = buf->getFieldAs(Dimension::Id::X, i); + double y = buf->getFieldAs(Dimension::Id::Y, i); + double z = buf->getFieldAs(Dimension::Id::Z, i); + uint64_t t = buf->getFieldAs(Dimension::Id::OffsetTime, i); BOOST_CHECK_CLOSE(x, 1.0, 0.00001); BOOST_CHECK_CLOSE(y, 2.0, 0.00001); BOOST_CHECK_CLOSE(z, 3.0, 0.00001); BOOST_CHECK_EQUAL(t, i); } - - delete iter; } BOOST_AUTO_TEST_CASE(test_random_mode) { - using namespace pdal; - Bounds bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0); Options ops; ops.add("bounds", bounds); - ops.add("num_points", 1000); + ops.add("count", 750); ops.add("mode", "constant"); drivers::faux::Reader reader(ops); PointContext ctx; reader.prepare(ctx); + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 750); - PointBuffer buf(ctx); - StageSequentialIterator* iter = reader.createSequentialIterator(); - point_count_t numRead = iter->read(buf, 750); - - BOOST_CHECK_EQUAL(numRead, 750u); - - for (point_count_t i = 0; i < numRead; ++i) + for (point_count_t i = 0; i < buf->size(); ++i) { - double x = buf.getFieldAs(Dimension::Id::X, i); - double y = buf.getFieldAs(Dimension::Id::Y, i); - double z = buf.getFieldAs(Dimension::Id::Z, i); - uint64_t t = buf.getFieldAs(Dimension::Id::OffsetTime, i); + double x = buf->getFieldAs(Dimension::Id::X, i); + double y = buf->getFieldAs(Dimension::Id::Y, i); + double z = buf->getFieldAs(Dimension::Id::Z, i); + uint64_t t = buf->getFieldAs(Dimension::Id::OffsetTime, i); BOOST_CHECK_GE(x, 1.0); BOOST_CHECK_LE(x, 101.0); @@ -115,7 +107,6 @@ BOOST_AUTO_TEST_CASE(test_random_mode) BOOST_CHECK_EQUAL(t, i); } - delete iter; } @@ -126,29 +117,27 @@ BOOST_AUTO_TEST_CASE(test_ramp_mode_1) Bounds bounds(0, 0, 0, 4, 4, 4); Options ops; ops.add("bounds", bounds); - ops.add("num_points", 2); + ops.add("count", 2); ops.add("mode", "ramp"); + drivers::faux::Reader reader(ops); PointContext ctx; reader.prepare(ctx); + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 2); - PointBuffer buf(ctx); - - StageSequentialIterator* iter = reader.createSequentialIterator(); - point_count_t numRead = iter->read(buf, 2); - - BOOST_CHECK_EQUAL(numRead, 2u); + double x0 = buf->getFieldAs(Dimension::Id::X, 0); + double y0 = buf->getFieldAs(Dimension::Id::Y, 0); + double z0 = buf->getFieldAs(Dimension::Id::Z, 0); + uint64_t t0 = buf->getFieldAs(Dimension::Id::OffsetTime, 0); - double x0 = buf.getFieldAs(Dimension::Id::X, 0); - double y0 = buf.getFieldAs(Dimension::Id::Y, 0); - double z0 = buf.getFieldAs(Dimension::Id::Z, 0); - uint64_t t0 = buf.getFieldAs(Dimension::Id::OffsetTime, 0); - - double x1 = buf.getFieldAs(Dimension::Id::X, 1); - double y1 = buf.getFieldAs(Dimension::Id::Y, 1); - double z1 = buf.getFieldAs(Dimension::Id::Z, 1); - uint64_t t1 = buf.getFieldAs(Dimension::Id::OffsetTime, 1); + double x1 = buf->getFieldAs(Dimension::Id::X, 1); + double y1 = buf->getFieldAs(Dimension::Id::Y, 1); + double z1 = buf->getFieldAs(Dimension::Id::Z, 1); + uint64_t t1 = buf->getFieldAs(Dimension::Id::OffsetTime, 1); BOOST_CHECK_CLOSE(x0, 0.0, 0.00001); BOOST_CHECK_CLOSE(y0, 0.0, 0.00001); @@ -159,8 +148,6 @@ BOOST_AUTO_TEST_CASE(test_ramp_mode_1) BOOST_CHECK_CLOSE(y1, 4.0, 0.00001); BOOST_CHECK_CLOSE(z1, 4.0, 0.00001); BOOST_CHECK_EQUAL(t1, 1u); - - delete iter; } @@ -171,38 +158,33 @@ BOOST_AUTO_TEST_CASE(test_ramp_mode_2) Bounds bounds(1.0, 2.0, 3.0, 101.0, 152.0, 203.0); Options ops; ops.add("bounds", bounds); - ops.add("num_points", 750); + ops.add("count", 750); ops.add("mode", "ramp"); drivers::faux::Reader reader(ops); PointContext ctx; reader.prepare(ctx); - - PointBuffer buf(ctx); - - StageSequentialIterator* iter = reader.createSequentialIterator(); - point_count_t numRead = iter->read(buf, 750); - - BOOST_CHECK_EQUAL(numRead,750u); + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 750); double delX = (101.0 - 1.0) / (750.0 - 1.0); double delY = (152.0 - 2.0) / (750.0 - 1.0); double delZ = (203.0 - 3.0) / (750.0 - 1.0); - for (point_count_t i = 0; i < numRead; ++i) + for (point_count_t i = 0; i < buf->size(); ++i) { - double x = buf.getFieldAs(Dimension::Id::X, i); - double y = buf.getFieldAs(Dimension::Id::Y, i); - double z = buf.getFieldAs(Dimension::Id::Z, i); - uint64_t t = buf.getFieldAs(Dimension::Id::OffsetTime, i); + double x = buf->getFieldAs(Dimension::Id::X, i); + double y = buf->getFieldAs(Dimension::Id::Y, i); + double z = buf->getFieldAs(Dimension::Id::Z, i); + uint64_t t = buf->getFieldAs(Dimension::Id::OffsetTime, i); BOOST_CHECK_CLOSE(x, 1.0 + delX * i, 0.00001); BOOST_CHECK_CLOSE(y, 2.0 + delY * i, 0.00001); BOOST_CHECK_CLOSE(z, 3.0 + delZ * i, 0.00001); BOOST_CHECK_EQUAL(t, i); } - - delete iter; } @@ -214,29 +196,28 @@ BOOST_AUTO_TEST_CASE(test_return_number) Bounds bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0); ops.add("bounds", bounds); - ops.add("num_points", 100); + ops.add("count", 100); ops.add("mode", "constant"); ops.add("number_of_returns", 9); drivers::faux::Reader reader(ops); PointContext ctx; reader.prepare(ctx); + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 100); - PointBuffer buf(ctx); - StageSequentialIterator* iter = reader.createSequentialIterator(); - point_count_t numRead = iter->read(buf, 100); - - for (point_count_t i = 0; i < numRead; i++) + for (point_count_t i = 0; i < buf->size(); i++) { - uint8_t returnNumber = buf.getFieldAs(Dimension::Id::ReturnNumber, i); - uint8_t numberOfReturns = buf.getFieldAs(Dimension::Id::NumberOfReturns, i); + uint8_t returnNumber = buf->getFieldAs( + Dimension::Id::ReturnNumber, i); + uint8_t numberOfReturns = + buf->getFieldAs(Dimension::Id::NumberOfReturns, i); BOOST_CHECK_EQUAL(returnNumber, (i % 9) + 1); BOOST_CHECK_EQUAL(numberOfReturns, 9); } - - delete iter; } - BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit/drivers/icebridge/IcebridgeReaderTest.cpp b/test/unit/drivers/icebridge/IcebridgeReaderTest.cpp index 57af3d7004..af38f73e9c 100644 --- a/test/unit/drivers/icebridge/IcebridgeReaderTest.cpp +++ b/test/unit/drivers/icebridge/IcebridgeReaderTest.cpp @@ -138,43 +138,6 @@ BOOST_AUTO_TEST_CASE(testRead) 0.0); // relTime } -BOOST_AUTO_TEST_CASE(testSkip) -{ - Option filename("filename", getFilePath(), ""); - Options options(filename); - - drivers::icebridge::Reader reader(options); - - PointContext ctx; - reader.prepare(ctx); - - StageTester::ready(&reader, ctx); - - PointBuffer data(ctx); - std::unique_ptr it( - reader.createSequentialIterator()); - - it->skip(1); - it->read(data, 1); - StageTester::done(&reader, ctx); - - checkPoint( - data, - 0, - 141437548, // time - 82.605287, // latitude - 301.404862, // longitude - 18.688, // elevation - 2642, // xmtSig - 173, // rcvSig - 52.006, // azimuth - -4.376, // pitch - 0.609, // roll - 2.9, // gpsPdop - 17.0, // pulseWidth - 0.0); // relTime -} - BOOST_AUTO_TEST_CASE(testPipeline) { PipelineManager manager; @@ -184,7 +147,7 @@ BOOST_AUTO_TEST_CASE(testPipeline) reader.readPipeline(Support::datapath("icebridge/pipeline.xml")); BOOST_CHECK(isWriter); - const uint64_t numPoints = manager.execute(); + point_count_t numPoints = manager.execute(); BOOST_CHECK_EQUAL(numPoints, 2); FileUtils::deleteFile(Support::datapath("icebridge/outfile.txt")); } diff --git a/test/unit/drivers/las/LasReaderTest.cpp b/test/unit/drivers/las/LasReaderTest.cpp index b8918240c7..3dcb121e09 100644 --- a/test/unit/drivers/las/LasReaderTest.cpp +++ b/test/unit/drivers/las/LasReaderTest.cpp @@ -35,7 +35,6 @@ #include #include -#include #include #include #include "Support.hpp" @@ -90,204 +89,48 @@ BOOST_AUTO_TEST_CASE(test_sequential) { PointContext ctx; - pdal::drivers::las::Reader reader(Support::datapath("1.2-with-color.las")); - BOOST_CHECK(reader.getDescription() == "Las Reader"); - reader.prepare(ctx); - pdal::StageSequentialIterator* iter = reader.createSequentialIterator(); - - { - PointBuffer data(ctx); - point_count_t numRead = iter->read(data, 3); - BOOST_CHECK(numRead == 3); - - Support::check_p0_p1_p2(data); - } - - // Can we seek it? Yes, we can! - iter->skip(97); - { - PointBuffer data(ctx); - BOOST_CHECK(iter->getIndex() == 100); - point_count_t numRead = iter->read(data, 3); - BOOST_CHECK(numRead == 3); - - Support::check_p100_p101_p102(data); - } - delete iter; -} - + Options ops1; + ops1.add("filename", Support::datapath("1.2-with-color.las")); + ops1.add("count", 103); + drivers::las::Reader reader(ops1); -BOOST_AUTO_TEST_CASE(test_two_iters) -{ - PointContext ctx; - pdal::drivers::las::Reader reader(Support::datapath("1.2-with-color.las")); BOOST_CHECK(reader.getDescription() == "Las Reader"); reader.prepare(ctx); - - BOOST_CHECK(reader.getNumPoints() == 1065); - { - pdal::StageSequentialIterator* iter = reader.createSequentialIterator(); - BOOST_CHECK(iter->getIndex() == 0); - - PointBuffer data(ctx); - point_count_t numRead = iter->read(data, 1065); - BOOST_CHECK(numRead == 1065); - BOOST_CHECK(iter->getIndex() == 1065); - - Support::check_p0_p1_p2(data); - - delete iter; - } + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + Support::check_p0_p1_p2(*buf); + PointBufferPtr buf2 = buf->makeNew(); + buf2->appendPoint(*buf, 100); + buf2->appendPoint(*buf, 101); + buf2->appendPoint(*buf, 102); + Support::check_p100_p101_p102(*buf2); } -BOOST_AUTO_TEST_CASE(test_simultaneous_iters) +static void test_a_format(const std::string& file, uint8_t majorVersion, + uint8_t minorVersion, int pointFormat, + double xref, double yref, double zref, double tref, uint16_t rref, + uint16_t gref, uint16_t bref) { PointContext ctx; - pdal::drivers::las::Reader reader(Support::datapath("1.2-with-color.las")); - BOOST_CHECK_EQUAL(reader.getDescription(), "Las Reader"); - reader.prepare(ctx); - - BOOST_CHECK_EQUAL(reader.getNumPoints(), 1065); - BOOST_CHECK_EQUAL(355 * 3, 1065); - - point_count_t numRead; - - pdal::StageSequentialIterator* iterS1 = reader.createSequentialIterator(); - BOOST_CHECK_EQUAL(iterS1->getIndex(), 0); - - pdal::StageSequentialIterator* iterS2 = reader.createSequentialIterator(); - BOOST_CHECK_EQUAL(iterS2->getIndex(), 0); - - /** - pdal::StageRandomIterator* iterR1 = reader.createRandomIterator(data); - BOOST_CHECK_EQUAL(iterR1->getIndex(), 0); - - pdal::StageRandomIterator* iterR2 = reader.createRandomIterator(data); - BOOST_CHECK_EQUAL(iterR2->getIndex(), 0); - **/ - - { - PointBuffer data(ctx); - numRead = iterS1->read(data, 355); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterS1->getIndex(), 355); - - Support::check_p0_p1_p2(data); - } - - { - iterS2->skip(355); - - PointBuffer data(ctx); - numRead = iterS2->read(data, 355); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterS2->getIndex(), 710); - - Support::check_p355_p356_p357(data); - } - - /** - { - iterR1->seek(355); - numRead = iterR1->read(data); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterR1->getIndex(), 710); - - Support::check_p355_p356_p357(data); - } - - { - iterR2->seek(0); - numRead = iterR2->read(data); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterR2->getIndex(), 355); - - Support::check_p0_p1_p2(data); - } -**/ - - { - PointBuffer data(ctx); - iterS1->skip(355); - numRead = iterS1->read(data, 355); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterS1->getIndex(), 1065); - - Support::check_p710_p711_p712(data); - } - - { - PointBuffer data(ctx); - iterS2->skip(0); - numRead = iterS2->read(data, 355); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterS2->getIndex(), 1065); - - Support::check_p710_p711_p712(data); - } - -/** - { - iterR1->seek(355); - numRead = iterR1->read(data); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterR1->getIndex(), 710); - - Support::check_p355_p356_p357(data); - } - - { - iterR2->seek(710); - numRead = iterR2->read(data); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterR2->getIndex(), 1065); - - Support::check_p710_p711_p712(data); - } - - { - iterR1->seek(0); - numRead = iterR1->read(data); - BOOST_CHECK_EQUAL(numRead, 355); - BOOST_CHECK_EQUAL(iterR1->getIndex(), 355); - - Support::check_p0_p1_p2(data); - } -**/ - - delete iterS1; - delete iterS2; -/** - delete iterR1; - delete iterR2; -**/ -} - -static void test_a_format(const std::string& file, boost::uint8_t majorVersion, boost::uint8_t minorVersion, int pointFormat, - double xref, double yref, double zref, double tref, boost::uint16_t rref, boost::uint16_t gref, boost::uint16_t bref) -{ - PointContext ctx; - - pdal::drivers::las::Reader reader(Support::datapath(file)); + Options ops1; + ops1.add("filename", Support::datapath(file)); + ops1.add("count", 1); + drivers::las::Reader reader(ops1); reader.prepare(ctx); BOOST_CHECK_EQUAL(reader.getLasHeader().getPointFormat(), pointFormat); BOOST_CHECK_EQUAL(reader.getLasHeader().GetVersionMajor(), majorVersion); BOOST_CHECK_EQUAL(reader.getLasHeader().GetVersionMinor(), minorVersion); - pdal::StageSequentialIterator* iter = reader.createSequentialIterator(); - - { - PointBuffer data(ctx); - point_count_t numRead = iter->read(data, 1); - BOOST_CHECK_EQUAL(numRead, 1); - - Support::check_pN(data, 0, xref, yref, zref, tref, rref, gref, bref); - } + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 1); - delete iter; + Support::check_pN(*buf, 0, xref, yref, zref, tref, rref, gref, bref); } BOOST_AUTO_TEST_CASE(test_different_formats) @@ -309,47 +152,22 @@ BOOST_AUTO_TEST_CASE(test_vlr) { PointContext ctx; - pdal::drivers::las::Reader reader(Support::datapath("lots_of_vlr.las")); + Options ops1; + ops1.add("filename", Support::datapath("lots_of_vlr.las")); + drivers::las::Reader reader(ops1); reader.prepare(ctx); BOOST_CHECK_EQUAL(reader.getLasHeader().getVLRs().getAll().size(), 390); } -BOOST_AUTO_TEST_CASE(test_no_xyz) -{ - PointContext ctx; - - // Wipe off the XYZ dimensions and see if we can - // still read LAS data #123 - pdal::drivers::las::Reader reader(Support::datapath("1.2-with-color.las")); - BOOST_CHECK(reader.getDescription() == "Las Reader"); - reader.prepare(ctx); - - pdal::StageSequentialIterator* iter = reader.createSequentialIterator(); - - PointBuffer data(ctx); - point_count_t numRead = iter->read(data, 3); - BOOST_CHECK(numRead == 3); - - delete iter; -} - - -BOOST_AUTO_TEST_CASE(testFilenameConstructorSetOption) -{ - pdal::drivers::las::Reader reader(Support::datapath("1.2-with-color.las")); - BOOST_CHECK_EQUAL( - reader.getOptions().getValueOrDefault("filename", ""), - Support::datapath("1.2-with-color.las")); -} - - BOOST_AUTO_TEST_CASE(testInvalidFileSignature) { PointContext ctx; - pdal::drivers::las::Reader reader( - Support::datapath("1.2-with-color.las.wkt")); + + Options ops1; + ops1.add("filename", Support::datapath("1.2-with-color.las.wkt")); + pdal::drivers::las::Reader reader(ops1); try { reader.prepare(ctx); @@ -363,5 +181,4 @@ BOOST_AUTO_TEST_CASE(testInvalidFileSignature) BOOST_FAIL("reader.initialize() did not throw std::invalid_argument"); } - BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit/drivers/nitf/NitfReaderTest.cpp b/test/unit/drivers/nitf/NitfReaderTest.cpp index 482435dd02..a2a5308b94 100644 --- a/test/unit/drivers/nitf/NitfReaderTest.cpp +++ b/test/unit/drivers/nitf/NitfReaderTest.cpp @@ -61,16 +61,17 @@ BOOST_AUTO_TEST_SUITE(NitfReaderTest) BOOST_AUTO_TEST_CASE(test_one) { - pdal::Option nitf_opt("filename", - Support::datapath("nitf/autzen-utm10.ntf")); - pdal::Options nitf_opts; - nitf_opts.add(nitf_opt); + Options nitf_opts; + nitf_opts.add("filename", Support::datapath("nitf/autzen-utm10.ntf")); + nitf_opts.add("count", 750); PointContext ctx; - pdal::drivers::nitf::NitfReader nitf_reader(nitf_opts); + drivers::nitf::NitfReader nitf_reader(nitf_opts); nitf_reader.prepare(ctx); - + PointBufferSet pbSet = nitf_reader.execute(ctx); BOOST_CHECK_EQUAL(nitf_reader.getDescription(), "NITF Reader"); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); // check metadata //ABELL @@ -82,60 +83,44 @@ BOOST_AUTO_TEST_CASE(test_one) } **/ - PointBuffer nitf_data(ctx); - - StageSequentialIterator* nitf_iter = - nitf_reader.createSequentialIterator(); - const uint32_t nitf_numRead = nitf_iter->read(nitf_data, 750); - // // read LAS // - pdal::Option las_opt("filename", - Support::datapath("nitf/autzen-utm10.las")); pdal::Options las_opts; - las_opts.add(las_opt); + las_opts.add("count", 750); + las_opts.add("filename", Support::datapath("nitf/autzen-utm10.las")); PointContext ctx2; - pdal::drivers::las::Reader las_reader(las_opts); + drivers::las::Reader las_reader(las_opts); las_reader.prepare(ctx2); - - PointBuffer las_data(ctx2); - - StageSequentialIterator* las_iter = - las_reader.createSequentialIterator(); - const uint32_t las_numRead = las_iter->read(las_data, 750); + PointBufferSet pbSet2 = las_reader.execute(ctx2); + BOOST_CHECK_EQUAL(pbSet2.size(), 1); + PointBufferPtr buf2 = *pbSet.begin(); + // // // compare the two buffers // - BOOST_CHECK_EQUAL(las_numRead, nitf_numRead); + BOOST_CHECK_EQUAL(buf->size(), buf2->size()); - for (uint32_t i = 0; i < las_numRead; i++) + for (PointId i = 0; i < buf2->size(); i++) { - int32_t nitf_x = nitf_data.getFieldAs(Dimension::Id::X, i); - int32_t nitf_y = nitf_data.getFieldAs(Dimension::Id::Y, i); - int32_t nitf_z = nitf_data.getFieldAs(Dimension::Id::Z, i); + int32_t nitf_x = buf->getFieldAs(Dimension::Id::X, i); + int32_t nitf_y = buf->getFieldAs(Dimension::Id::Y, i); + int32_t nitf_z = buf->getFieldAs(Dimension::Id::Z, i); - int32_t las_x = las_data.getFieldAs(Dimension::Id::X, i); - int32_t las_y = las_data.getFieldAs(Dimension::Id::Y, i); - int32_t las_z = las_data.getFieldAs(Dimension::Id::Z, i); + int32_t las_x = buf2->getFieldAs(Dimension::Id::X, i); + int32_t las_y = buf2->getFieldAs(Dimension::Id::Y, i); + int32_t las_z = buf2->getFieldAs(Dimension::Id::Z, i); BOOST_CHECK_EQUAL(nitf_x, las_x); BOOST_CHECK_EQUAL(nitf_y, las_y); BOOST_CHECK_EQUAL(nitf_z, las_z); } - - delete nitf_iter; - delete las_iter; } BOOST_AUTO_TEST_CASE(test_chipper) { - // - // read NITF - // - pdal::Option option("filename", Support::datapath("nitf/chipper.xml")); pdal::Options options(option); diff --git a/test/unit/drivers/oci/OCITest.cpp b/test/unit/drivers/oci/OCITest.cpp index 5961dde74c..b96c98a903 100644 --- a/test/unit/drivers/oci/OCITest.cpp +++ b/test/unit/drivers/oci/OCITest.cpp @@ -51,7 +51,6 @@ #include #include -#include #include "Support.hpp" #include "TestConfig.hpp" @@ -379,22 +378,15 @@ BOOST_AUTO_TEST_CASE(read_unprojected_data) pdal::drivers::oci::OciReader reader(options); PointContext ctx; reader.prepare(ctx); + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 1065); - pdal::PointBuffer data(ctx); - pdal::StageSequentialIterator* iter = reader.createSequentialIterator(); - - uint32_t numRead = iter->read(data); - - BOOST_CHECK_EQUAL(numRead, 1065u); - BOOST_CHECK_EQUAL(data.size(), 1065u); - - // checkUnProjectedPoints(data); - - // compareAgainstSourceBuffer(data, Support::datapath("autzen-utm-chipped-25.las")); - compareAgainstSourceBuffer(data, Support::datapath("autzen-utm.las")); + // checkUnProjectedPoints(*buf); - delete iter; - + // compareAgainstSourceBuffer(*buf, Support::datapath("autzen-utm-chipped-25.las")); + compareAgainstSourceBuffer(*buf, Support::datapath("autzen-utm.las")); } diff --git a/test/unit/drivers/qfit/QFITReaderTest.cpp b/test/unit/drivers/qfit/QFITReaderTest.cpp index 3210c8effd..83412df0d2 100644 --- a/test/unit/drivers/qfit/QFITReaderTest.cpp +++ b/test/unit/drivers/qfit/QFITReaderTest.cpp @@ -33,15 +33,10 @@ ****************************************************************************/ #include -#include -#include #include #include #include -#include -#include -#include #include "Support.hpp" #include @@ -61,131 +56,68 @@ BOOST_AUTO_TEST_SUITE(QFITReaderTest) void Check_Point(const pdal::PointBuffer& data, std::size_t index, double xref, double yref, double zref, - boost::int32_t tref) + int32_t tref) { - const ::pdal::Schema& schema = data.getSchema(); - - Dimension const& dimX = schema.getDimension("X"); - Dimension const& dimY = schema.getDimension("Y"); - Dimension const& dimZ = schema.getDimension("Z"); - Dimension const& dimTime = schema.getDimension("Time"); - - - boost::int32_t x = data.getField(dimX, index); - boost::int32_t y = data.getField(dimY, index); - boost::int32_t z = data.getField(dimZ, index); - boost::int32_t t = data.getField(dimTime, index); - - double x0 = dimX.applyScaling(x); - double y0 = dimY.applyScaling(y); - double z0 = dimZ.applyScaling(z); - - Compare(x0, xref); - Compare(y0, yref); - Compare(z0, zref); + double x = data.getFieldAs(Dimension::Id::X, index); + double y = data.getFieldAs(Dimension::Id::Y, index); + double z = data.getFieldAs(Dimension::Id::Z, index); + int32_t t = data.getFieldAs(Dimension::Id::OffsetTime, index); + + Compare(x, xref); + Compare(y, yref); + Compare(z, zref); BOOST_CHECK_EQUAL(t, tref); } BOOST_AUTO_TEST_CASE(test_10_word) { - pdal::Options options; - // std::string filename = Support::datapath("20050903_231839.qi"); + Options options; - pdal::Option filename("filename", Support::datapath("qfit/10-word.qi"), + options.add("filename", Support::datapath("qfit/10-word.qi"), "Input filename for reader to use"); - Option flip_coordinates("flip_coordinates", false, + options.add("flip_coordinates", false, "Flip coordinates from 0-360 to -180-180"); - Option scale_z("scale_z", 0.001f, "Z scale from mm to m"); + options.add("scale_z", 0.001f, "Z scale from mm to m"); + options.add("count", 3); - options.add(scale_z); - options.add(flip_coordinates); - options.add(filename); - pdal::drivers::qfit::Reader reader(options); + drivers::qfit::Reader reader(options); BOOST_CHECK(reader.getDescription() == "QFIT Reader"); BOOST_CHECK_EQUAL(reader.getName(), "drivers.qfit.reader"); - reader.prepare(); - - const Schema& schema = reader.getSchema(); - PointBuffer data(schema, 3); + PointContext ctx; + reader.prepare(ctx); + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 3); - pdal::StageSequentialIterator* iter = reader.createSequentialIterator(data); - - { - boost::uint32_t numRead = iter->read(data); - BOOST_CHECK_EQUAL(numRead,3u); - } - - delete iter; - - Check_Point(data, 0, 221.826822, 59.205160, 32.0900, 0); - Check_Point(data, 1, 221.826740, 59.205161, 32.0190, 0); - Check_Point(data, 2, 221.826658, 59.205164, 32.0000, 0); + Check_Point(*buf, 0, 221.826822, 59.205160, 32.0900, 0); + Check_Point(*buf, 1, 221.826740, 59.205161, 32.0190, 0); + Check_Point(*buf, 2, 221.826658, 59.205164, 32.0000, 0); } BOOST_AUTO_TEST_CASE(test_14_word) { - pdal::Options options; + Options options; - pdal::Option filename("filename", Support::datapath("qfit/14-word.qi"), + options.add("filename", Support::datapath("qfit/14-word.qi"), "Input filename for reader to use"); - options.add(filename); - Option flip_coordinates("flip_coordinates", false, + options.add("flip_coordinates", false, "Flip coordinates from 0-360 to -180-180"); - Option scale_z("scale_z", 0.001f, "Z scale from mm to m"); - - options.add(scale_z); - options.add(flip_coordinates); - - pdal::drivers::qfit::Reader reader(options); - reader.prepare(); - - const Schema& schema = reader.getSchema(); - - PointBuffer data(schema, 3); - - pdal::StageSequentialIterator* iter = reader.createSequentialIterator(data); - - { - boost::uint32_t numRead = iter->read(data); - BOOST_CHECK_EQUAL(numRead,3u); - } - - delete iter; - - Check_Point(data, 0, 244.306337, 35.623317, 1056.830000000, 903); - Check_Point(data, 1, 244.306260, 35.623280, 1056.409000000, 903); - Check_Point(data, 2, 244.306204, 35.623257, 1056.483000000, 903); + options.add("scale_z", 0.001f, "Z scale from mm to m"); + options.add("count", 3); + + PointContext ctx; + drivers::qfit::Reader reader(options); + reader.prepare(ctx); + PointBufferSet pbSet = reader.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); + BOOST_CHECK_EQUAL(buf->size(), 3); + + Check_Point(*buf, 0, 244.306337, 35.623317, 1056.830000000, 903); + Check_Point(*buf, 1, 244.306260, 35.623280, 1056.409000000, 903); + Check_Point(*buf, 2, 244.306204, 35.623257, 1056.483000000, 903); } -//ABELL - Perhaps this test should go away as it seems to have lots -// of issues. -BOOST_AUTO_TEST_CASE(test_pipeline) -{ - PipelineManager manager; - PipelineReader reader(manager); - - bool isWriter = reader.readPipeline(Support::datapath("qfit/pipeline.xml")); - BOOST_CHECK_EQUAL(isWriter, true); - - // this test doesn't work with the current OSGeo4W (it requires a - // newer PROJ) -#ifndef PDAL_PLATFORM_WIN32 - try - { - const boost::uint64_t np = manager.execute(); - BOOST_CHECK_EQUAL(np, 10314u); - } - catch (std::runtime_error) - { - //ABELL - //This pipeline tries to stuff a qfit file into a las. The qfit - //has 32 bit input for scan angle rank, but las has only 8. - } - - FileUtils::deleteFile(Support::datapath("qfit/qfit-foo.las")); -#endif -} - - BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit/drivers/sbet/SbetReaderTest.cpp b/test/unit/drivers/sbet/SbetReaderTest.cpp index 101da54b95..3e0c76f12d 100644 --- a/test/unit/drivers/sbet/SbetReaderTest.cpp +++ b/test/unit/drivers/sbet/SbetReaderTest.cpp @@ -117,35 +117,6 @@ BOOST_AUTO_TEST_CASE(testRead) 7.179027672314571e-02); } -BOOST_AUTO_TEST_CASE(testSkip) -{ - Option filename("filename", Support::datapath("sbet/2-points.sbet"), ""); - Options options(filename); - drivers::sbet::SbetReader reader(options); - - PointContext ctx; - PointBuffer buf(ctx); - reader.prepare(ctx); - - StageTester::ready(&reader, ctx); - StageSequentialIterator* iter = reader.createSequentialIterator(); - iter->skip(1); - iter->read(buf, 1); - StageTester::done(&reader, ctx); - - delete iter; - - checkPoint(ctx, buf, 0, 1.516310078318641e+05, 5.680211834722869e-01, - -2.041654392034053e+00, 1.077151424357507e+02, - -2.336228229691271e+00, -3.324663118952635e-01, - -3.022948961008987e-02, -2.813856631423094e-02, - -2.425215669392169e-02, 3.047131105236811e+00, - -2.198416007932108e-02, 8.397590491636475e-01, - 3.252165276637165e-01, -1.558883225990844e-01, - 8.379685112283802e-04, 7.372886784718076e-03, - 7.179027672314571e-02); -} - BOOST_AUTO_TEST_CASE(testBadFile) { Option filename("filename", Support::datapath("sbet/badfile.sbet"), ""); @@ -162,7 +133,7 @@ BOOST_AUTO_TEST_CASE(testPipeline) PipelineReader reader(manager); reader.readPipeline(Support::datapath("sbet/pipeline.xml")); - const boost::uint64_t numPoints = manager.execute(); + point_count_t numPoints = manager.execute(); BOOST_CHECK_EQUAL(numPoints, 2); FileUtils::deleteFile(Support::datapath("sbet/outfile.txt")); } diff --git a/test/unit/drivers/terrasolid/TerraSolidReaderTest.cpp b/test/unit/drivers/terrasolid/TerraSolidReaderTest.cpp index 68d8954f1c..abe32dfe02 100644 --- a/test/unit/drivers/terrasolid/TerraSolidReaderTest.cpp +++ b/test/unit/drivers/terrasolid/TerraSolidReaderTest.cpp @@ -35,7 +35,6 @@ #include #include -#include #include #include #include diff --git a/test/unit/filters/ChipperTest.cpp b/test/unit/filters/ChipperTest.cpp index b4de84f4ce..33d98ca021 100644 --- a/test/unit/filters/ChipperTest.cpp +++ b/test/unit/filters/ChipperTest.cpp @@ -56,7 +56,9 @@ BOOST_AUTO_TEST_CASE(test_construction) { PointContext ctx; - pdal::drivers::las::Reader reader(Support::datapath("1.2-with-color.las")); + Options ops1; + ops1.add("filename", Support::datapath("1.2-with-color.las")); + drivers::las::Reader reader(ops1); { // need to scope the writer, so that's it dtor can use the stream diff --git a/test/unit/filters/ColorizationFilterTest.cpp b/test/unit/filters/ColorizationFilterTest.cpp index b0e06a84cc..00c7999017 100644 --- a/test/unit/filters/ColorizationFilterTest.cpp +++ b/test/unit/filters/ColorizationFilterTest.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include "Support.hpp" @@ -53,7 +52,9 @@ BOOST_AUTO_TEST_CASE(ColorizationFilterTest_test_1) { using namespace pdal; - drivers::las::Reader reader(Support::datapath("autzen-point-format-3.las")); + Options ops1; + ops1.add("filename", Support::datapath("autzen-point-format-3.las")); + drivers::las::Reader reader(ops1); Options options; @@ -94,20 +95,15 @@ BOOST_AUTO_TEST_CASE(ColorizationFilterTest_test_1) filter.setInput(&reader); PointContext ctx; - PointBuffer buffer(ctx); filter.prepare(ctx); + PointBufferSet pbSet = filter.execute(ctx); + BOOST_CHECK_EQUAL(pbSet.size(), 1); + PointBufferPtr buf = *pbSet.begin(); - StageSequentialIterator *iter = reader.createSequentialIterator(); - uint32_t numRead = iter->read(buffer, 1); - - FilterTester::ready(&filter, ctx); - FilterTester::filter(&filter, buffer); - FilterTester::done(&filter, ctx); - - uint16_t r = buffer.getFieldAs(Dimension::Id::Red, 0); - uint16_t g = buffer.getFieldAs(Dimension::Id::Green, 0); - uint16_t b = buffer.getFieldAs(Dimension::Id::Blue, 0); + uint16_t r = buf->getFieldAs(Dimension::Id::Red, 0); + uint16_t g = buf->getFieldAs(Dimension::Id::Green, 0); + uint16_t b = buf->getFieldAs(Dimension::Id::Blue, 0); BOOST_CHECK_EQUAL(r, 210u); BOOST_CHECK_EQUAL(g, 205u); diff --git a/test/unit/filters/CropFilterTest.cpp b/test/unit/filters/CropFilterTest.cpp index f173e4b4f1..b4f5b19c1e 100644 --- a/test/unit/filters/CropFilterTest.cpp +++ b/test/unit/filters/CropFilterTest.cpp @@ -42,7 +42,6 @@ #include #include #include -#include #include "Support.hpp" #include "../StageTester.hpp" @@ -115,7 +114,9 @@ BOOST_AUTO_TEST_CASE(test_crop_polygon) using namespace pdal; #ifdef PDAL_HAVE_GEOS - drivers::las::Reader reader(Support::datapath("1.2-with-color.las")); + Options ops1; + ops1.add("filename", Support::datapath("1.2-with-color.las")); + drivers::las::Reader reader(ops1); Options options; Option debug("debug", true, ""); diff --git a/test/unit/filters/DecimationFilterTest.cpp b/test/unit/filters/DecimationFilterTest.cpp index 9df7f82b3f..424c328518 100644 --- a/test/unit/filters/DecimationFilterTest.cpp +++ b/test/unit/filters/DecimationFilterTest.cpp @@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(DecimationFilterTest_test1) Options ops; ops.add("bounds", srcBounds); ops.add("mode", "random"); - ops.add("num_points", 1000); + ops.add("num_points", 30); drivers::faux::Reader reader(ops); Options decimationOps; @@ -61,18 +61,11 @@ BOOST_AUTO_TEST_CASE(DecimationFilterTest_test1) BOOST_CHECK(filter.getDescription() == "Decimation Filter"); PointContext ctx; - PointBufferPtr buf(new PointBuffer(ctx)); filter.prepare(ctx); - - StageSequentialIterator* iter = reader.createSequentialIterator(); - point_count_t numRead = iter->read(*buf, 30); - - BOOST_CHECK_EQUAL(numRead, 30); - - PointBufferSet pbSet = FilterTester::run(&filter, buf); + PointBufferSet pbSet = filter.execute(ctx); BOOST_CHECK_EQUAL(pbSet.size(), 1); - buf = *pbSet.begin(); + PointBufferPtr buf = *pbSet.begin(); BOOST_CHECK_EQUAL(buf->size(), 3); uint64_t t0 = buf->getFieldAs(Dimension::Id::OffsetTime, 0); @@ -82,55 +75,6 @@ BOOST_AUTO_TEST_CASE(DecimationFilterTest_test1) BOOST_CHECK_EQUAL(t0, 0); BOOST_CHECK_EQUAL(t1, 10); BOOST_CHECK_EQUAL(t2, 20); - - delete iter; -} - - -BOOST_AUTO_TEST_CASE(DecimationFilterTest_test_random) -{ - Bounds srcBounds(0.0, 0.0, 0.0, 100.0, 100.0, 100.0); - Options ops; - ops.add("bounds", srcBounds); - ops.add("num_points", 1000); - ops.add("mode", "random"); - - drivers::faux::Reader reader(ops); - - Options decimationOps; - decimationOps.add("step", 10); - decimationOps.add("offset", 1); - Option debug("debug", true, ""); - Option verbose("verbose", 9, ""); - // opts.add(debug); - // opts.add(verbose); - filters::Decimation filter(decimationOps); - filter.setInput(&reader); - BOOST_CHECK(filter.getDescription() == "Decimation Filter"); - - PointContext ctx; - PointBufferPtr buf(new PointBuffer(ctx)); - filter.prepare(ctx); - - StageSequentialIterator* iter = reader.createSequentialIterator(); - iter->skip(7); - point_count_t numRead = iter->read(*buf, 50); - - BOOST_CHECK(numRead == 50); - - PointBufferSet pbSet = FilterTester::run(&filter, buf); - BOOST_CHECK_EQUAL(pbSet.size(), 1); - buf = *pbSet.begin(); - - uint64_t t0 = buf->getFieldAs(Dimension::Id::OffsetTime, 0); - uint64_t t1 = buf->getFieldAs(Dimension::Id::OffsetTime, 1); - uint64_t t2 = buf->getFieldAs(Dimension::Id::OffsetTime, 2); - - BOOST_CHECK_EQUAL(t0, 8); - BOOST_CHECK_EQUAL(t1, 18); - BOOST_CHECK_EQUAL(t2, 28); - - delete iter; } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit/filters/HexbinFilterTest.cpp b/test/unit/filters/HexbinFilterTest.cpp index 603d76e2af..6024e468bb 100644 --- a/test/unit/filters/HexbinFilterTest.cpp +++ b/test/unit/filters/HexbinFilterTest.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include "Support.hpp" diff --git a/test/unit/filters/InPlaceReprojectionFilterTest.cpp b/test/unit/filters/InPlaceReprojectionFilterTest.cpp index 580a3a79ad..67f32fc39c 100644 --- a/test/unit/filters/InPlaceReprojectionFilterTest.cpp +++ b/test/unit/filters/InPlaceReprojectionFilterTest.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include diff --git a/test/unit/filters/ReprojectionFilterTest.cpp b/test/unit/filters/ReprojectionFilterTest.cpp index 495c88db6a..619b5804a3 100644 --- a/test/unit/filters/ReprojectionFilterTest.cpp +++ b/test/unit/filters/ReprojectionFilterTest.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include "Support.hpp" @@ -73,7 +72,9 @@ BOOST_AUTO_TEST_CASE(ReprojectionFilterTest_test_1) { const SpatialReference out_ref(epsg4326_wkt); - drivers::las::Reader reader(Support::datapath("utm15.las")); + Options ops1; + ops1.add("filename", Support::datapath("utm15.las")); + drivers::las::Reader reader(ops1); Options options; Option debug("debug", true, ""); diff --git a/test/unit/filters/SplitterTest.cpp b/test/unit/filters/SplitterTest.cpp index 7c34ab5c13..ab2f5eb06a 100644 --- a/test/unit/filters/SplitterTest.cpp +++ b/test/unit/filters/SplitterTest.cpp @@ -47,7 +47,9 @@ BOOST_AUTO_TEST_SUITE(SplitterTest) BOOST_AUTO_TEST_CASE(test_tile_filter) { // create the reader - drivers::las::Reader r(Support::datapath("1.2-with-color.las")); + Options ops1; + ops1.add("filename", Support::datapath("1.2-with-color.las")); + drivers::las::Reader r(ops1); Options o; Option length("length", 1000, "length"); diff --git a/test/unit/filters/StatsFilterTest.cpp b/test/unit/filters/StatsFilterTest.cpp index d10355866e..508fae3eec 100644 --- a/test/unit/filters/StatsFilterTest.cpp +++ b/test/unit/filters/StatsFilterTest.cpp @@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(StatsFilterTest_test1) Bounds bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0); Options ops; ops.add("bounds", bounds); - ops.add("num_points", 1000); + ops.add("count", 1000); ops.add("mode", "constant"); drivers::faux::Reader reader(ops); @@ -62,17 +62,7 @@ BOOST_AUTO_TEST_CASE(StatsFilterTest_test1) PointContext ctx; filter.prepare(ctx); - - PointBuffer buf(ctx); - - std::unique_ptr - iter(reader.createSequentialIterator()); - boost::uint32_t numRead = iter->read(buf, 1000); - BOOST_CHECK_EQUAL(numRead, 1000u); - - FilterTester::ready(&filter, ctx); - FilterTester::filter(&filter, buf); - FilterTester::done(&filter, ctx); + filter.execute(ctx); const filters::stats::Summary& statsX = filter.getStats(Dimension::Id::X); const filters::stats::Summary& statsY = filter.getStats(Dimension::Id::Y);