From 71c61db3e6a7eb0164b113f338980ec791c7e45f Mon Sep 17 00:00:00 2001 From: Howard Butler Date: Mon, 29 Apr 2019 15:25:04 -0500 Subject: [PATCH 1/3] fix build for MrSiD SDK #2460 (#2478) --- plugins/mrsid/CMakeLists.txt | 4 ++++ plugins/mrsid/io/MrsidReader.cpp | 32 +++++++++++++++++++++++++++++++- plugins/mrsid/io/MrsidReader.hpp | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/plugins/mrsid/CMakeLists.txt b/plugins/mrsid/CMakeLists.txt index 46c4a1856d..3b8092b9b7 100644 --- a/plugins/mrsid/CMakeLists.txt +++ b/plugins/mrsid/CMakeLists.txt @@ -12,6 +12,7 @@ if (MRSID_FOUND) ${MRSID_LIBRARY} INCLUDES ${PDAL_IO_DIR} + ${NLOHMANN_INCLUDE_DIR} ${MRSID_INCLUDE_DIR} ) target_compile_definitions(${reader_libname} PRIVATE -DHAVE_MRSID=1) @@ -24,6 +25,9 @@ if (MRSID_FOUND) ${reader_libname} INCLUDES ${PDAL_IO_DIR} + ${NLOHMANN_INCLUDE_DIR} + ${MRSID_INCLUDE_DIR} + ) endif() else() diff --git a/plugins/mrsid/io/MrsidReader.cpp b/plugins/mrsid/io/MrsidReader.cpp index c48dc2612d..c9c1642847 100644 --- a/plugins/mrsid/io/MrsidReader.cpp +++ b/plugins/mrsid/io/MrsidReader.cpp @@ -210,7 +210,16 @@ void MrsidReader::LayoutToPointInfo(const PointLayout &layout, LizardTech::Point if (Utils::iequals(name, "Classification")) name = CHANNEL_NAME_ClassId; if (Utils::iequals(name, "ScanAngleRank")) name = CHANNEL_NAME_ScanAngle; if (Utils::iequals(name, "ScanDirectionFlag")) name = CHANNEL_NAME_ScanDir; +#ifdef CHANNEL_NAME_GPSTime if (Utils::iequals(name, "GpsTime")) name = CHANNEL_NAME_GPSTime; +#endif +#ifdef CHANNEL_NAME_GPSTime_Week + if (Utils::iequals(name, "GpsTime")) name = CHANNEL_NAME_GPSTime_Week; +#endif +#ifdef CHANNEL_NAME_GPSTime_Adjusted + //FIXME: We should account for header metadata if we have it + if (Utils::iequals(name, "GpsTime")) name = CHANNEL_NAME_GPSTime_Adjusted; +#endif if (Utils::iequals(name, "PointSourceId")) name = CHANNEL_NAME_SourceId; if (Utils::iequals(name, "ReturnNumber")) name = CHANNEL_NAME_ReturnNum; if (Utils::iequals(name, "NumberOfReturns")) name = CHANNEL_NAME_NumReturns; @@ -307,13 +316,34 @@ point_count_t MrsidReader::read(PointViewPtr view, point_count_t count) pointIndex, getData(points, CHANNEL_NAME_Z, pointIndex)); } - } else if (Utils::iequals(name, "GpsTime") && + } +#ifdef CHANNEL_NAME_GPSTime + else if (Utils::iequals(name, "GpsTime") && m_pointInfo.hasChannel(CHANNEL_NAME_GPSTime)) { view->setField( d, pointIndex, getData(points, CHANNEL_NAME_GPSTime, pointIndex)); } +#endif +#ifdef CHANNEL_NAME_GPSTime_Week + else if (Utils::iequals(name, "GpsTime") && + m_pointInfo.hasChannel(CHANNEL_NAME_GPSTime_Week)) + { + view->setField( d, + pointIndex, + getData(points, CHANNEL_NAME_GPSTime_Week, pointIndex)); + } +#endif +#ifdef CHANNEL_NAME_GPSTime_Adjusted + else if (Utils::iequals(name, "GpsTime") && + m_pointInfo.hasChannel(CHANNEL_NAME_GPSTime_Week)) + { + view->setField( d, + pointIndex, + getData(points, CHANNEL_NAME_GPSTime_Adjusted, pointIndex)); + } +#endif else if (Utils::iequals(name, "Intensity") && m_pointInfo.hasChannel(CHANNEL_NAME_Intensity)) { diff --git a/plugins/mrsid/io/MrsidReader.hpp b/plugins/mrsid/io/MrsidReader.hpp index e1f62b1625..865689288e 100644 --- a/plugins/mrsid/io/MrsidReader.hpp +++ b/plugins/mrsid/io/MrsidReader.hpp @@ -35,7 +35,7 @@ #pragma once #include -#include +#include #include #include From 73ed303cfeb3d91763ff6916882906fa90ce4353 Mon Sep 17 00:00:00 2001 From: Andrew Bell Date: Wed, 1 May 2019 10:37:52 -0400 Subject: [PATCH 2/3] Properly initialize member variables when a new PointView is processed. (#2481) --- filters/ChipperFilter.cpp | 20 +-- scripts/docker/alpine/Dockerfile.dependencies | 3 +- test/unit/filters/ChipperTest.cpp | 134 ++++-------------- 3 files changed, 36 insertions(+), 121 deletions(-) diff --git a/filters/ChipperFilter.cpp b/filters/ChipperFilter.cpp index d10e7c4bb9..0f7fcb890e 100644 --- a/filters/ChipperFilter.cpp +++ b/filters/ChipperFilter.cpp @@ -91,6 +91,15 @@ PointViewSet ChipperFilter::run(PointViewPtr view) return m_outViews; m_inView = view; + m_partitions.resize(0); + m_xvec.resize(0); + m_yvec.resize(0); + m_spare.resize(view->size()); + m_outViews.clear(); + + m_xvec.reserve(view->size()); + m_yvec.reserve(view->size()); + load(*view.get(), m_xvec, m_yvec, m_spare); partition(m_xvec.size()); decideSplit(m_xvec, m_yvec, m_spare, 0, m_partitions.size() - 1); @@ -101,13 +110,6 @@ PointViewSet ChipperFilter::run(PointViewPtr view) void ChipperFilter::load(PointView& view, ChipRefList& xvec, ChipRefList& yvec, ChipRefList& spare) { - point_count_t idx; - std::vector::iterator it; - - xvec.reserve(view.size()); - yvec.reserve(view.size()); - spare.resize(view.size()); - for (PointId i = 0; i < view.size(); ++i) { ChipPtRef xref; @@ -127,7 +129,7 @@ void ChipperFilter::load(PointView& view, ChipRefList& xvec, ChipRefList& yvec, std::stable_sort(xvec.begin(), xvec.end()); for (size_t i = 0; i < xvec.size(); ++i) { - idx = xvec[i].m_ptindex; + point_count_t idx = xvec[i].m_ptindex; yvec[idx].m_oindex = i; } @@ -140,8 +142,6 @@ void ChipperFilter::load(PointView& view, ChipRefList& xvec, ChipRefList& yvec, } - - #ifdef _WIN32 inline long lround(double d) { diff --git a/scripts/docker/alpine/Dockerfile.dependencies b/scripts/docker/alpine/Dockerfile.dependencies index 0e9bd9cc5c..fc21fb9d02 100644 --- a/scripts/docker/alpine/Dockerfile.dependencies +++ b/scripts/docker/alpine/Dockerfile.dependencies @@ -1,4 +1,4 @@ -FROM alpine:3.8 +FROM alpine:3.9 # # Nitro looks for unistd.h in the wrong place. @@ -52,6 +52,7 @@ RUN \ postgresql-dev \ sqlite-dev \ libcrypto1.1@edgemain \ + xerces-c@edgetesting \ libspatialite-dev@edgetesting \ gdal-dev@edgetesting \ libgeotiff-dev@edgetesting \ diff --git a/test/unit/filters/ChipperTest.cpp b/test/unit/filters/ChipperTest.cpp index 772bafc829..38bb6d1a35 100644 --- a/test/unit/filters/ChipperTest.cpp +++ b/test/unit/filters/ChipperTest.cpp @@ -103,6 +103,30 @@ TEST(ChipperTest, test_construction) } +// Test that the chipper runs with multiple inputs. +TEST(ChipperTest, issue_2479) +{ + PointTable table; + PointViewPtr view(new PointView(table)); + + LasReader r1; + LasReader r2; + Options rOpts; + + rOpts.add("filename", Support::datapath("las/autzen_trim.las")); + r1.setOptions(rOpts); + r2.setOptions(rOpts); + + ChipperFilter chipper; + chipper.setInput(r1); + chipper.setInput(r2); + + chipper.prepare(table); + PointViewSet viewSet = chipper.execute(table); + + EXPECT_EQ(viewSet.size(), 44u); +} + // Make sure things don't crash if the point buffer is empty. TEST(ChipperTest, empty_buffer) { @@ -120,113 +144,3 @@ TEST(ChipperTest, empty_buffer) EXPECT_EQ(viewSet.size(), 0u); } -//ABELL -/** -TEST(ChipperTest, test_ordering) -{ - std::string candidate_filename(Support::datapath("autzen-utm.las")); - std::string source_filename(Support::datapath("autzen-utm-chipped-25.las")); - - Options options; - Option filename("filename", source_filename, ""); - options.add(filename); - - Option capacity("capacity", 25); - options.add(capacity); - - LasReader candidate_reader(options); - std::shared_ptr chipper(new ChipperFilter)(options); - chipper->setInput(&candidate_reader); - chipper->prepare(); - - Option& query = options.getOptionByRef("filename"); - query.setValue(source_filename); - - LasReader source_reader(options); - source_reader.prepare(); - - EXPECT_EQ(chipper->getNumPoints(), source_reader.getNumPoints()); - - PointView candidate(chipper->getSchema(), chipper->getNumPoints()); - PointView patch(chipper->getSchema(), chipper->getNumPoints()); - - StageSequentialIterator* iter_c = chipper->createSequentialIterator(patch); - uint64_t numRead(0); - - while (true) - { - numRead = iter_c->read(patch); - if (! numRead) - break; - candidate.copyPointsFast(candidate.getNumPoints(), 0, patch, patch.getNumPoints()); - candidate.setNumPoints(candidate.getNumPoints() + patch.getNumPoints()); - } - EXPECT_EQ(candidate.getNumPoints(), chipper->getNumPoints()); - - PointView source(source_reader.getSchema(), source_reader.getNumPoints()); - - StageSequentialIterator* iter_s = source_reader.createSequentialIterator(source); - numRead = iter_s->read(source); - EXPECT_EQ(numRead, source_reader.getNumPoints()); - - - - Schema const& cs = candidate.getSchema(); - Schema const& ss = source.getSchema(); - - Dimension const& sdimX = ss.getDimension("X"); - Dimension const& sdimY = ss.getDimension("Y"); - Dimension const& sdimZ = ss.getDimension("Z"); - Dimension const& sdimIntensity = ss.getDimension("Intensity"); - Dimension const& sdimRed = ss.getDimension("Red"); - Dimension const& sdimGreen = ss.getDimension("Green"); - Dimension const& sdimBlue = ss.getDimension("Blue"); - - Dimension const& cdimX = cs.getDimension("X"); - Dimension const& cdimY = cs.getDimension("Y"); - Dimension const& cdimZ = cs.getDimension("Z"); - Dimension const& cdimIntensity = cs.getDimension("Intensity"); - Dimension const& cdimRed = cs.getDimension("Red"); - Dimension const& cdimGreen = cs.getDimension("Green"); - Dimension const& cdimBlue = cs.getDimension("Blue"); - // - // int X[] = { 49405730, 49413382, 49402110, 494192890, 49418622, 49403411 }; - // int Y[] = { 487743335, 487743982, 487743983, 487744219, 487744254, 487745019 }; - // int Z[] = { 13063, 13044, 13046, 13050, 13049, 13066 }; - // int I[] = { 134, 75, 153, 93, 67, 167 }; - // int R[] = { 142, 152, 146, 104, 113, 163 }; - // int G[] = { 102, 108, 104, 96, 97, 118 }; - // int B[] = { 137, 134, 140, 120, 123, 150 }; - // - for (unsigned i = 0; i < candidate.getNumPoints(); ++i) - { - int32_t sx = source.getField(sdimX, i); - int32_t sy = source.getField(sdimY, i); - int32_t sz = source.getField(sdimZ, i); - uint16_t sintensity = source.getField(sdimIntensity, i); - uint16_t sred = source.getField(sdimRed, i); - uint16_t sgreen = source.getField(sdimGreen, i); - uint16_t sblue = source.getField(sdimBlue, i); - - int32_t cx = candidate.getField(cdimX, i); - int32_t cy = candidate.getField(cdimY, i); - int32_t cz = candidate.getField(cdimZ, i); - uint16_t cintensity = candidate.getField(cdimIntensity, i); - uint16_t cred = candidate.getField(cdimRed, i); - uint16_t cgreen = candidate.getField(cdimGreen, i); - uint16_t cblue = candidate.getField(cdimBlue, i); - - - EXPECT_EQ(sx, cx); - EXPECT_EQ(sy, cy); - EXPECT_EQ(sz, cz); - EXPECT_EQ(sintensity, cintensity); - EXPECT_EQ(sred, cred); - EXPECT_EQ(sgreen, cgreen); - EXPECT_EQ(sblue, cblue); - } - delete iter_c; - delete iter_s; - -} -**/ From b7576970d91c8a8a07d9e05a68926d68ba589454 Mon Sep 17 00:00:00 2001 From: Andrew Bell Date: Wed, 1 May 2019 11:52:39 -0400 Subject: [PATCH 3/3] Revert split of Box/Bounds. (#2484) --- filters/CropFilter.cpp | 2 +- io/EptReader.hpp | 2 +- io/GDALWriter.hpp | 2 +- io/LasHeader.hpp | 2 +- io/private/EptSupport.hpp | 2 +- pdal/Bounds.cpp | 123 ----------------------- pdal/Bounds.hpp | 74 -------------- pdal/EigenUtils.cpp | 2 +- pdal/GDALUtils.hpp | 2 +- pdal/Metadata.cpp | 2 +- pdal/Metadata.hpp | 2 +- pdal/PDALUtils.hpp | 2 +- pdal/QuadIndex.hpp | 2 +- pdal/QuickInfo.hpp | 2 +- pdal/util/{Box.cpp => Bounds.cpp} | 72 ++++++++++++- pdal/util/{Box.hpp => Bounds.hpp} | 32 ++++++ pdal/util/CMakeLists.txt | 2 +- plugins/greyhound/io/GreyhoundCommon.cpp | 2 +- plugins/i3s/io/EsriReader.hpp | 2 +- plugins/mrsid/io/MrsidReader.hpp | 2 +- plugins/nitf/io/NitfFileWriter.hpp | 2 +- test/unit/BoundsTest.cpp | 2 +- tools/lasdump/Header.hpp | 2 +- 23 files changed, 122 insertions(+), 217 deletions(-) delete mode 100644 pdal/Bounds.cpp delete mode 100644 pdal/Bounds.hpp rename pdal/util/{Box.cpp => Bounds.cpp} (83%) rename pdal/util/{Box.hpp => Bounds.hpp} (96%) diff --git a/filters/CropFilter.cpp b/filters/CropFilter.cpp index b1ccc3e246..bbca489122 100644 --- a/filters/CropFilter.cpp +++ b/filters/CropFilter.cpp @@ -34,11 +34,11 @@ #include "CropFilter.hpp" -#include #include #include #include #include +#include #include #include "private/Point.hpp" diff --git a/io/EptReader.hpp b/io/EptReader.hpp index 3b56e0f247..0807951884 100644 --- a/io/EptReader.hpp +++ b/io/EptReader.hpp @@ -41,9 +41,9 @@ #include #include -#include #include #include +#include #include diff --git a/io/GDALWriter.hpp b/io/GDALWriter.hpp index 2f0e8e7f44..4660777911 100644 --- a/io/GDALWriter.hpp +++ b/io/GDALWriter.hpp @@ -34,10 +34,10 @@ #include -#include #include #include #include +#include #include namespace pdal diff --git a/io/LasHeader.hpp b/io/LasHeader.hpp index a1a9fd5d96..3001e79064 100644 --- a/io/LasHeader.hpp +++ b/io/LasHeader.hpp @@ -40,7 +40,7 @@ #include #include -#include +#include #include #include #include diff --git a/io/private/EptSupport.hpp b/io/private/EptSupport.hpp index a353ec3c66..81b1183f5d 100644 --- a/io/private/EptSupport.hpp +++ b/io/private/EptSupport.hpp @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #include diff --git a/pdal/Bounds.cpp b/pdal/Bounds.cpp deleted file mode 100644 index 4baa7d8ebc..0000000000 --- a/pdal/Bounds.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2019, Hobu Inc. (info@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. 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 -{ - -const double LOWEST = (std::numeric_limits::lowest)(); -const double HIGHEST = (std::numeric_limits::max)(); - -} - -namespace pdal -{ - -Bounds::Bounds(const BOX3D& box) : m_box(box) -{} - - -Bounds::Bounds(const BOX2D& box) : m_box(box) -{ - m_box.minz = HIGHEST; - m_box.maxz = LOWEST; -} - - -// We don't allow implicit conversion from a BOX2D to BOX3D. Use the explicit -// BOX3D ctor that takes a BOX2D if that's what you want. -BOX3D Bounds::to3d() const -{ - if (!is3d()) - return BOX3D(); - return m_box; -} - - -BOX2D Bounds::to2d() const -{ - return m_box.to2d(); -} - - -bool Bounds::is3d() const -{ - return (m_box.minz != HIGHEST || m_box.maxz != LOWEST); -} - - -void Bounds::set(const BOX3D& box) -{ - m_box = box; -} - - -void Bounds::set(const BOX2D& box) -{ - m_box = BOX3D(box); - m_box.minz = HIGHEST; - m_box.maxz = LOWEST; -} - -std::istream& operator>>(std::istream& in, Bounds& bounds) -{ - std::streampos start = in.tellg(); - BOX3D b3d; - in >> b3d; - if (in.fail()) - { - in.clear(); - in.seekg(start); - BOX2D b2d; - in >> b2d; - if (!in.fail()) - bounds.set(b2d); - } - else - bounds.set(b3d); - return in; -} - -std::ostream& operator<<(std::ostream& out, const Bounds& bounds) -{ - if (bounds.is3d()) - out << bounds.to3d(); - else - out << bounds.to2d(); - return out; -} - -} // namespace pdal diff --git a/pdal/Bounds.hpp b/pdal/Bounds.hpp deleted file mode 100644 index ba46aa13db..0000000000 --- a/pdal/Bounds.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/****************************************************************************** -* Copyright (c) 2019, Hobu Inc. (info@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. 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 - -namespace pdal -{ - -/** - Wrapper for BOX3D and BOX2D to allow extraction as either. Typically used - to facilitate streaming either a BOX2D or BOX3D -*/ -class PDAL_DLL Bounds -{ -public: - Bounds() - {} - - explicit Bounds(const BOX3D& box); - explicit Bounds(const BOX2D& box); - - BOX3D to3d() const; - BOX2D to2d() const; - bool is3d() const; - - friend PDAL_DLL std::istream& operator >> (std::istream& in, - Bounds& bounds); - friend PDAL_DLL std::ostream& operator << (std::ostream& out, - const Bounds& bounds); - -private: - BOX3D m_box; - - void set(const BOX3D& box); - void set(const BOX2D& box); -}; - -PDAL_DLL std::istream& operator >> (std::istream& in, Bounds& bounds); -PDAL_DLL std::ostream& operator << (std::ostream& in, const Bounds& bounds); - -} // namespace pdal - diff --git a/pdal/EigenUtils.cpp b/pdal/EigenUtils.cpp index 01636dfda5..989ec7e511 100644 --- a/pdal/EigenUtils.cpp +++ b/pdal/EigenUtils.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/pdal/GDALUtils.hpp b/pdal/GDALUtils.hpp index 7393b34516..e1a2394030 100644 --- a/pdal/GDALUtils.hpp +++ b/pdal/GDALUtils.hpp @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include diff --git a/pdal/Metadata.cpp b/pdal/Metadata.cpp index a83b41b3fd..5c54b06c1e 100644 --- a/pdal/Metadata.cpp +++ b/pdal/Metadata.cpp @@ -34,7 +34,7 @@ #include #include -#include +#include namespace pdal { diff --git a/pdal/Metadata.hpp b/pdal/Metadata.hpp index e412f41609..9f09a3cd54 100644 --- a/pdal/Metadata.hpp +++ b/pdal/Metadata.hpp @@ -36,7 +36,7 @@ #include -#include +#include #include #include diff --git a/pdal/PDALUtils.hpp b/pdal/PDALUtils.hpp index 213100c5e1..ae9b1284a7 100644 --- a/pdal/PDALUtils.hpp +++ b/pdal/PDALUtils.hpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/pdal/QuadIndex.hpp b/pdal/QuadIndex.hpp index 2c983e236d..f7cc4bf446 100644 --- a/pdal/QuadIndex.hpp +++ b/pdal/QuadIndex.hpp @@ -38,7 +38,7 @@ #include #include -#include +#include namespace pdal { diff --git a/pdal/QuickInfo.hpp b/pdal/QuickInfo.hpp index 7bffe64e8a..e969f0b59b 100644 --- a/pdal/QuickInfo.hpp +++ b/pdal/QuickInfo.hpp @@ -36,7 +36,7 @@ #include -#include +#include #include namespace pdal diff --git a/pdal/util/Box.cpp b/pdal/util/Bounds.cpp similarity index 83% rename from pdal/util/Box.cpp rename to pdal/util/Bounds.cpp index 50861cbe09..c7e38e260e 100644 --- a/pdal/util/Box.cpp +++ b/pdal/util/Bounds.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include namespace { @@ -171,6 +171,48 @@ const BOX3D& BOX3D::getDefaultSpatialExtent() return v; } +Bounds::Bounds(const BOX3D& box) : m_box(box) +{} + + +Bounds::Bounds(const BOX2D& box) : m_box(box) +{ + m_box.minz = HIGHEST; + m_box.maxz = LOWEST; +} + +// We don't allow implicit conversion from a BOX2D to BOX3D. Use the explicit +// BOX3D ctor that takes a BOX2D if that's what you want. +BOX3D Bounds::to3d() const +{ + if (!is3d()) + return BOX3D(); + return m_box; +} + +BOX2D Bounds::to2d() const +{ + return m_box.to2d(); +} + +bool Bounds::is3d() const +{ + return (m_box.minz != HIGHEST || m_box.maxz != LOWEST); +} + + +void Bounds::set(const BOX3D& box) +{ + m_box = box; +} + + +void Bounds::set(const BOX2D& box) +{ + m_box = BOX3D(box); + m_box.minz = HIGHEST; + m_box.maxz = LOWEST; +} std::istream& operator>>(std::istream& istr, BOX2D& bounds) { @@ -279,4 +321,32 @@ std::istream& operator>>(std::istream& istr, BOX3D& bounds) return istr; } +std::istream& operator>>(std::istream& in, Bounds& bounds) +{ + std::streampos start = in.tellg(); + BOX3D b3d; + in >> b3d; + if (in.fail()) + { + in.clear(); + in.seekg(start); + BOX2D b2d; + in >> b2d; + if (!in.fail()) + bounds.set(b2d); + } + else + bounds.set(b3d); + return in; +} + +std::ostream& operator<<(std::ostream& out, const Bounds& bounds) +{ + if (bounds.is3d()) + out << bounds.to3d(); + else + out << bounds.to2d(); + return out; +} + } // namespace pdal diff --git a/pdal/util/Box.hpp b/pdal/util/Bounds.hpp similarity index 96% rename from pdal/util/Box.hpp rename to pdal/util/Bounds.hpp index c67f33a7cb..605b86e9db 100644 --- a/pdal/util/Box.hpp +++ b/pdal/util/Bounds.hpp @@ -575,6 +575,35 @@ class PDAL_DLL BOX3D : private BOX2D static const BOX3D& getDefaultSpatialExtent(); }; +/** + Wrapper for BOX3D and BOX2D to allow extraction as either. Typically used + to facilitate streaming either a BOX2D or BOX3D +*/ +class PDAL_DLL Bounds +{ +public: + Bounds() + {} + + explicit Bounds(const BOX3D& box); + explicit Bounds(const BOX2D& box); + + BOX3D to3d() const; + BOX2D to2d() const; + bool is3d() const; + + friend PDAL_DLL std::istream& operator >> (std::istream& in, + Bounds& bounds); + friend PDAL_DLL std::ostream& operator << (std::ostream& out, + const Bounds& bounds); + +private: + BOX3D m_box; + + void set(const BOX3D& box); + void set(const BOX2D& box); +}; + /** Write a 2D bounds box to a stream in a format used by PDAL options. @@ -640,4 +669,7 @@ extern PDAL_DLL std::istream& operator>>(std::istream& istr, BOX2D& bounds); */ extern PDAL_DLL std::istream& operator>>(std::istream& istr, BOX3D& bounds); +PDAL_DLL std::istream& operator >> (std::istream& in, Bounds& bounds); +PDAL_DLL std::ostream& operator << (std::ostream& in, const Bounds& bounds); + } // namespace pdal diff --git a/pdal/util/CMakeLists.txt b/pdal/util/CMakeLists.txt index bb36998a92..37e4a0ba92 100644 --- a/pdal/util/CMakeLists.txt +++ b/pdal/util/CMakeLists.txt @@ -20,7 +20,7 @@ else() endif() set(PDAL_UTIL_SOURCES - "${PDAL_UTIL_DIR}/Box.cpp" + "${PDAL_UTIL_DIR}/Bounds.cpp" "${PDAL_UTIL_DIR}/Charbuf.cpp" "${PDAL_UTIL_DIR}/FileUtils.cpp" "${PDAL_UTIL_DIR}/Georeference.cpp" diff --git a/plugins/greyhound/io/GreyhoundCommon.cpp b/plugins/greyhound/io/GreyhoundCommon.cpp index 910885adcb..599e9b2bbf 100644 --- a/plugins/greyhound/io/GreyhoundCommon.cpp +++ b/plugins/greyhound/io/GreyhoundCommon.cpp @@ -38,8 +38,8 @@ #include #include -#include #include +#include namespace pdal { diff --git a/plugins/i3s/io/EsriReader.hpp b/plugins/i3s/io/EsriReader.hpp index 41f848657d..19e50ab891 100644 --- a/plugins/i3s/io/EsriReader.hpp +++ b/plugins/i3s/io/EsriReader.hpp @@ -40,8 +40,8 @@ #include -#include #include +#include #include namespace pdal diff --git a/plugins/mrsid/io/MrsidReader.hpp b/plugins/mrsid/io/MrsidReader.hpp index 865689288e..e1f62b1625 100644 --- a/plugins/mrsid/io/MrsidReader.hpp +++ b/plugins/mrsid/io/MrsidReader.hpp @@ -35,7 +35,7 @@ #pragma once #include -#include +#include #include #include diff --git a/plugins/nitf/io/NitfFileWriter.hpp b/plugins/nitf/io/NitfFileWriter.hpp index 59f237df66..81280c17b3 100644 --- a/plugins/nitf/io/NitfFileWriter.hpp +++ b/plugins/nitf/io/NitfFileWriter.hpp @@ -35,7 +35,7 @@ #pragma once #include -#include +#include #include #include diff --git a/test/unit/BoundsTest.cpp b/test/unit/BoundsTest.cpp index 6b04aa64ad..5e1e117173 100644 --- a/test/unit/BoundsTest.cpp +++ b/test/unit/BoundsTest.cpp @@ -33,8 +33,8 @@ ****************************************************************************/ #include -#include #include +#include using namespace pdal; diff --git a/tools/lasdump/Header.hpp b/tools/lasdump/Header.hpp index af068f82ca..31c7a94b1f 100644 --- a/tools/lasdump/Header.hpp +++ b/tools/lasdump/Header.hpp @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include