diff --git a/point_io.cpp b/point_io.cpp index 3394e18..be1ec8e 100644 --- a/point_io.cpp +++ b/point_io.cpp @@ -314,6 +314,40 @@ PointSet *fastPlyReadPointSet(const std::string &filename) { return r; } +#ifdef WITH_PDAL +template +bool pdalReadLasMeta(pdal::MetadataNode &lasforward, std::string name, T &val) { + pdal::MetadataNode m = lasforward.findChild(name); + if (m.valid()) { + val = m.value(); + return true; + } else { + return false; + } +} + +void pdalReadLasScaleOffset(pdal::PointTable *table, PointSet *pSet) { + pdal::MetadataNode lasforward; + lasforward = table->privateMetadata("lasforward"); + if (!lasforward.valid()) + return; + bool success = true; + pSet->scales = std::make_unique>(); + success &= pdalReadLasMeta(lasforward, "scale_x", pSet->scales->at(0)); + success &= pdalReadLasMeta(lasforward, "scale_y", pSet->scales->at(1)); + success &= pdalReadLasMeta(lasforward, "scale_z", pSet->scales->at(2)); + if (!success) + pSet->scales = nullptr; + success = true; + pSet->offsets = std::make_unique>(); + success &= pdalReadLasMeta(lasforward, "offset_x", pSet->offsets->at(0)); + success &= pdalReadLasMeta(lasforward, "offset_y", pSet->offsets->at(1)); + success &= pdalReadLasMeta(lasforward, "offset_z", pSet->offsets->at(2)); + if (!success) + pSet->offsets = nullptr; +} +#endif + PointSet *pdalReadPointSet(const std::string &filename) { #ifdef WITH_PDAL std::string labelDimension; @@ -336,6 +370,10 @@ PointSet *pdalReadPointSet(const std::string &filename) { s->prepare(*table); const pdal::PointViewSet pvSet = s->execute(*table); + if (driver == "readers.las") { + pdalReadLasScaleOffset(table, r); + } + r->pointView = *pvSet.begin(); const pdal::PointViewPtr pView = r->pointView; @@ -492,6 +530,18 @@ void pdalSavePointSet(PointSet &pSet, const std::string &filename) { pdal::Stage *s = factory.createStage(driver); pdal::Options opts; opts.add("filename", filename); + if (driver == "writers.las") { + if (pSet.scales != nullptr) { + opts.add("scale_x", pSet.scales->at(0)); + opts.add("scale_y", pSet.scales->at(1)); + opts.add("scale_z", pSet.scales->at(2)); + } + if (pSet.offsets != nullptr) { + opts.add("offset_x", pSet.offsets->at(0)); + opts.add("offset_y", pSet.offsets->at(1)); + opts.add("offset_z", pSet.offsets->at(2)); + } + } s->setOptions(opts); s->setInput(reader); diff --git a/point_io.hpp b/point_io.hpp index 241988c..812cf19 100644 --- a/point_io.hpp +++ b/point_io.hpp @@ -40,6 +40,8 @@ struct PointSet { #ifdef WITH_PDAL pdal::PointViewPtr pointView = nullptr; + std::unique_ptr> scales = nullptr; + std::unique_ptr> offsets = nullptr; #endif template