diff --git a/app/build.cpp b/app/build.cpp index f264c4d1..47312623 100644 --- a/app/build.cpp +++ b/app/build.cpp @@ -179,9 +179,12 @@ void Build::addArgs() m_ap.add( "--laz_14", - "Write LAZ 1.4 content encoding (default: false)" - "logging (default: 10).", - [this](json j) { m_json["laz_14"] = extract(j); }); + "Write LAZ 1.4 content encoding (default: false)", + [this](json j) + { + checkEmpty(j); + m_json["laz_14"] = true; + }); addArbiter(); } diff --git a/entwine/io/laszip.cpp b/entwine/io/laszip.cpp index 4d88d2f1..f554147d 100644 --- a/entwine/io/laszip.cpp +++ b/entwine/io/laszip.cpp @@ -45,22 +45,31 @@ void Laszip::write( reader.addView(view); // See https://www.pdal.io/stages/writers.las.html - const uint64_t timeMask(contains(metadata.schema, "GpsTime") ? 1 : 0); - const uint64_t colorMask(contains(metadata.schema, "Red") ? 2 : 0); + const bool hasColor = contains(metadata.schema, "Red"); pdal::Options options; options.add("filename", localDir + localFile); if (metadata.internal.laz_14) + { + const bool hasNir = contains(metadata.schema, "Infrared"); + int pdrf = hasColor ? 7 : 6; + if (hasNir) pdrf = 8; options.add("minor_version", 4); + options.add("dataformat_id", pdrf); + } else + { + const uint64_t timeMask(contains(metadata.schema, "GpsTime") ? 1 : 0); + const uint64_t colorMask(hasColor ? 2 : 0); options.add("minor_version", 2); + options.add("dataformat_id", timeMask | colorMask); + } options.add("extra_dims", "all"); options.add("software_id", "Entwine " + currentEntwineVersion().toString()); - options.add("dataformat_id", timeMask | colorMask); const auto so = getScaleOffset(metadata.schema); if (!so) throw std::runtime_error("Scale/offset is required for laszip"); diff --git a/entwine/util/config.cpp b/entwine/util/config.cpp index 172252df..9843204a 100644 --- a/entwine/util/config.cpp +++ b/entwine/util/config.cpp @@ -37,7 +37,8 @@ BuildParameters getBuildParameters(const json& j) getSleepCount(j), getProgressInterval(j), getHierarchyStep(j), - getVerbose(j)); + getVerbose(j), + j.value("laz_14", false)); } } // unnamed namespace diff --git a/test/unit/build.cpp b/test/unit/build.cpp index 94415384..ac158e69 100644 --- a/test/unit/build.cpp +++ b/test/unit/build.cpp @@ -120,7 +120,6 @@ TEST(build, laszip14) { run({ { "input", test::dataPath() + "ellipsoid14.laz" } }); const json ept = checkEpt(); - // By default, since this is laszip input, our output will be laszip. EXPECT_EQ(ept.at("dataType").get(), "laszip"); const auto stuff = execute(); @@ -133,10 +132,9 @@ TEST(build, withflags) { run({ { "input", test::dataPath() + "ellipsoid14.laz" } }); const json ept = checkEpt(); - // By default, since this is laszip input, our output will be laszip. EXPECT_EQ(ept.at("dataType").get(), "laszip"); - const auto stuff = execute({ outDir + "ept-data/0-0-0-0.laz" }); + const auto stuff = execute(); auto& view = stuff->view; ASSERT_TRUE(view); @@ -147,6 +145,26 @@ TEST(build, withflags) } } +TEST(build, laz14Output) +{ + run({ + { "input", test::dataPath() + "ellipsoid-class33.laz" }, + { "laz_14", true }, + }); + const json ept = checkEpt(); + EXPECT_EQ(ept.at("dataType").get(), "laszip"); + + const auto stuff = execute(); + + auto& view = stuff->view; + ASSERT_TRUE(view); + checkData(*view); + for (const auto pr : *view) + { + ASSERT_EQ(pr.getFieldAs(pdal::Dimension::Id::Classification), 33); + } +} + TEST(build, failedWrite) { struct FailIo : public io::Laszip @@ -175,21 +193,6 @@ TEST(build, failedWrite) ASSERT_ANY_THROW(builder::run(builder, config)); } -TEST(build, laz14) -{ - run({ - { "input", test::dataPath() + "ellipsoid.laz" }, - { "laz_14", "true" } - }); - const json ept = checkEpt(); - EXPECT_EQ(ept.at("dataType").get(), "laszip"); - - const auto stuff = execute(); - auto& view = stuff->view; - ASSERT_TRUE(view); - checkData(*view); -} - TEST(build, binary) { run({