Example #1
0
// Test that data from three input views gets written to separate output files.
TEST(LasWriterTest, flex)
{
    std::array<std::string, 3> outname =
        {{ "test_1.las", "test_2.las", "test_3.las" }};

    Options readerOps;
    readerOps.add("filename", Support::datapath("las/simple.las"));

    PointTable table;

    LasReader reader;
    reader.setOptions(readerOps);

    reader.prepare(table);
    PointViewSet views = reader.execute(table);
    PointViewPtr v = *(views.begin());

    PointViewPtr v1(new PointView(table));
    PointViewPtr v2(new PointView(table));
    PointViewPtr v3(new PointView(table));

    std::vector<PointViewPtr> vs;
    vs.push_back(v1);
    vs.push_back(v2);
    vs.push_back(v3);

    for (PointId i = 0; i < v->size(); ++i)
        vs[i % 3]->appendPoint(*v, i);

    for (size_t i = 0; i < outname.size(); ++i)
        FileUtils::deleteFile(Support::temppath(outname[i]));

    BufferReader reader2;
    reader2.addView(v1);
    reader2.addView(v2);
    reader2.addView(v3);

    Options writerOps;
    writerOps.add("filename", Support::temppath("test_#.las"));

    LasWriter writer;
    writer.setOptions(writerOps);
    writer.setInput(reader2);

    writer.prepare(table);
    writer.execute(table);

    for (size_t i = 0; i < outname.size(); ++i)
    {
        std::string filename = Support::temppath(outname[i]);
        EXPECT_TRUE(FileUtils::fileExists(filename));

        Options ops;
        ops.add("filename", filename);

        LasReader r;
        r.setOptions(ops);
        EXPECT_EQ(r.preview().m_pointCount, 355u);
    }
}
Example #2
0
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)
{
    PointTable table;

    Options ops1;
    ops1.add("filename", Support::datapath(file));
    ops1.add("count", 1);
    LasReader reader;
    reader.setOptions(ops1);
    reader.prepare(table);

    EXPECT_EQ(reader.header().pointFormat(), pointFormat);
    EXPECT_EQ(reader.header().versionMajor(), majorVersion);
    EXPECT_EQ(reader.header().versionMinor(), minorVersion);

    PointViewSet viewSet = reader.execute(table);
    EXPECT_EQ(viewSet.size(), 1u);
    PointViewPtr view = *viewSet.begin();
    EXPECT_EQ(view->size(), 1u);

    Support::check_pN(*view, 0, xref, yref, zref, tref, rref, gref, bref);
}
Example #3
0
TEST(LasReaderTest, IgnoreVLRs)
{
    PointTable table;

    Options readOps;
    readOps.add("filename", Support::datapath("las/lots_of_vlr.las"));
    readOps.add("ignore_vlr", "Merrick");
    LasReader reader;
    reader.setOptions(readOps);

    reader.prepare(table);
    PointViewSet viewSet = reader.execute(table);

    // First two VLRs are SRS info, the other 388 would be
    // Merrick ones that we want to ignore/remove
    MetadataNode root = reader.getMetadata();
    for (size_t i = 2; i < 390; ++i)
    {
        std::string name("vlr_");
        name += std::to_string(i);
        MetadataNode m = root.findChild(name);
        EXPECT_FALSE(!m.empty()) << "No node " << i;
        m = m.findChild("data");
        EXPECT_FALSE(!m.empty()) << "No value for node " << i;
    }

}
Example #4
0
// LAZ files are normally written in chunks of 50,000, so a file of size
// 110,000 ensures we read some whole chunks and a partial.
TEST(LasReaderTest, lazperf)
{
    Options ops1;
    ops1.add("filename", Support::datapath("laz/autzen_trim.laz"));
    ops1.add("compression", "lazperf");

    LasReader lazReader;
    lazReader.setOptions(ops1);

    PointTable t1;
    lazReader.prepare(t1);
    PointViewSet pbSet = lazReader.execute(t1);
    EXPECT_EQ(pbSet.size(), 1UL);
    PointViewPtr view1 = *pbSet.begin();
    EXPECT_EQ(view1->size(), (point_count_t)110000);

    Options ops2;
    ops2.add("filename", Support::datapath("las/autzen_trim.las"));

    LasReader lasReader;
    lasReader.setOptions(ops2);

    PointTable t2;
    lasReader.prepare(t2);
    pbSet = lasReader.execute(t2);
    EXPECT_EQ(pbSet.size(), 1UL);
    PointViewPtr view2 = *pbSet.begin();
    EXPECT_EQ(view2->size(), (point_count_t)110000);

    DimTypeList dims = view1->dimTypes();
    size_t pointSize = view1->pointSize();
    EXPECT_EQ(view1->pointSize(), view2->pointSize());
    // Validate some point data.
    std::unique_ptr<char> buf1(new char[pointSize]);
    std::unique_ptr<char> buf2(new char[pointSize]);
    for (PointId i = 0; i < 110000; i += 100)
    {
       view1->getPackedPoint(dims, i, buf1.get());
       view2->getPackedPoint(dims, i, buf2.get());
       EXPECT_EQ(memcmp(buf1.get(), buf2.get(), pointSize), 0);
    }
}
Example #5
0
TEST(LasWriterTest, all_extra_dims)
{
    Options readerOps;

    readerOps.add("filename", Support::datapath("bpf/simple-extra.bpf"));
    BpfReader reader;
    reader.setOptions(readerOps);

    FileUtils::deleteFile(Support::temppath("simple.las"));

    Options writerOps;
    writerOps.add("extra_dims", "all");
    writerOps.add("filename", Support::temppath("simple.las"));
    writerOps.add("minor_version", 4);
    LasWriter writer;
    writer.setInput(reader);
    writer.setOptions(writerOps);

    PointTable table;
    writer.prepare(table);
    writer.execute(table);

    Options ops;
    ops.add("filename", Support::temppath("simple.las"));

    LasReader r;
    r.setOptions(ops);

    PointTable t2;
    r.prepare(t2);
    Dimension::Id foo = t2.layout()->findDim("Foo");
    Dimension::Id bar = t2.layout()->findDim("Bar");
    Dimension::Id baz = t2.layout()->findDim("Baz");

    PointViewSet s = r.execute(t2);
    EXPECT_EQ(s.size(), 1u);
    PointViewPtr v = *s.begin();

    // We test for floats instead of doubles because when X, Y and Z
    // get written, they are written scaled, which loses precision.  The
    // foo, bar and baz values are written as full-precision doubles.
    for (PointId i = 0; i < v->size(); ++i)
    {
        using namespace Dimension;

        ASSERT_FLOAT_EQ(v->getFieldAs<float>(Id::X, i),
            v->getFieldAs<float>(foo, i));
        ASSERT_FLOAT_EQ(v->getFieldAs<float>(Id::Y, i),
            v->getFieldAs<float>(bar, i));
        ASSERT_FLOAT_EQ(v->getFieldAs<float>(Id::Z, i),
            v->getFieldAs<float>(baz, i));
    }
}
Example #6
0
// Compare the source LAS file with the extracted OCI data.
// Candidate is the OCI reader's view.
void compare(const PointViewPtr candidate, std::string filename)
{
    Options options;
    Option fn("filename", filename);
    options.add(fn);

    PointTable table;

    LasReader reader;
    reader.setOptions(options);

    reader.prepare(table);
    PointViewSet viewSet = reader.execute(table);

    EXPECT_EQ(viewSet.size(), 1u);
    PointViewPtr source = *viewSet.begin();

    EXPECT_EQ(source->size(), candidate->size());
    PointId limit = std::min(source->size(), candidate->size());

    for (PointId i = 0; i < limit; ++i)
    {
        using namespace Dimension;

        int32_t sx = source->getFieldAs<int32_t>(Id::X, i);
        int32_t sy = source->getFieldAs<int32_t>(Id::Y, i);
        int32_t sz = source->getFieldAs<int32_t>(Id::Z, i);
        uint16_t sintensity = source->getFieldAs<uint16_t>(Id::Intensity, i);
        uint16_t sred = source->getFieldAs<uint16_t>(Id::Red, i);
        uint16_t sgreen = source->getFieldAs<uint16_t>(Id::Green, i);
        uint16_t sblue = source->getFieldAs<uint16_t>(Id::Blue, i);

        int32_t cx = candidate->getFieldAs<int32_t>(Id::X, i);
        int32_t cy = candidate->getFieldAs<int32_t>(Id::Y, i);
        int32_t cz = candidate->getFieldAs<int32_t>(Id::Z, i);
        uint16_t cintensity = candidate->getFieldAs<uint16_t>(Id::Intensity, i);
        uint16_t cred = candidate->getFieldAs<uint16_t>(Id::Red, i);
        uint16_t cgreen = candidate->getFieldAs<uint16_t>(Id::Green, i);
        uint16_t cblue = candidate->getFieldAs<uint16_t>(Id::Blue, 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);
    }
}
Example #7
0
// The header of 1.2-with-color-clipped says that it has 1065 points,
// but it really only has 1064.
TEST(LasReaderTest, LasHeaderIncorrentPointcount)
{
    PointTable table;

    Options readOps;
    readOps.add("filename", Support::datapath("las/1.2-with-color-clipped.las"));
    LasReader reader;
    reader.setOptions(readOps);

    reader.prepare(table);
    PointViewSet viewSet = reader.execute(table);
    PointViewPtr view = *viewSet.begin();

    EXPECT_EQ(1064u, view->size());
}
Example #8
0
TEST(LasWriterTest, auto_offset)
{
    using namespace Dimension;

    const std::string FILENAME(Support::temppath("offset_test.las"));
    PointTable table;

    table.layout()->registerDim(Id::X);

    BufferReader bufferReader;

    PointViewPtr view(new PointView(table));
    view->setField(Id::X, 0, 125000.00);
    view->setField(Id::X, 1, 74529.00);
    view->setField(Id::X, 2, 523523.02);
    bufferReader.addView(view);

    Options writerOps;
    writerOps.add("filename", FILENAME);
    writerOps.add("offset_x", "auto");
    writerOps.add("scale_x", "auto");

    LasWriter writer;
    writer.setOptions(writerOps);
    writer.setInput(bufferReader);

    writer.prepare(table);
    writer.execute(table);

    Options readerOps;
    readerOps.add("filename", FILENAME);

    PointTable readTable;

    LasReader reader;
    reader.setOptions(readerOps);

    reader.prepare(readTable);
    EXPECT_DOUBLE_EQ(74529.00, reader.header().offsetX());
    PointViewSet viewSet = reader.execute(readTable);
    EXPECT_EQ(viewSet.size(), 1u);
    view = *viewSet.begin();
    EXPECT_EQ(view->size(), 3u);
    EXPECT_NEAR(125000.00, view->getFieldAs<double>(Id::X, 0), .0001);
    EXPECT_NEAR(74529.00, view->getFieldAs<double>(Id::X, 1), .0001);
    EXPECT_NEAR(523523.02, view->getFieldAs<double>(Id::X, 2), .0001);
    FileUtils::deleteFile(FILENAME);
}
Example #9
0
TEST(LasReaderTest, EmptyGeotiffVlr)
{
    PointTable table;

    Options readOps;
    readOps.add("filename", Support::datapath("las/1.2-empty-geotiff-vlrs.las"));
    LasReader reader;
    reader.setOptions(readOps);

    reader.prepare(table);
    PointViewSet viewSet = reader.execute(table);
    PointViewPtr view = *viewSet.begin();

    EXPECT_EQ(43u, view->size());

}
Example #10
0
TEST(LasWriterTest, forwardvlr)
{
    Options readerOps1;

    readerOps1.add("filename", Support::datapath("las/lots_of_vlr.las"));
    LasReader r1;
    r1.addOptions(readerOps1);

    std::string testfile = Support::temppath("tmp.las");
    FileUtils::deleteFile(testfile);

    Options writerOps;
    writerOps.add("forward", "vlr");
    writerOps.add("filename", testfile);

    LasWriter w;
    w.setInput(r1);
    w.addOptions(writerOps);

    PointTable t;

    w.prepare(t);
    w.execute(t);

    Options readerOps;
    readerOps.add("filename", testfile);

    LasReader r;

    r.setOptions(readerOps);

    PointTable t2;

    r.prepare(t2);
    r.execute(t2);

    MetadataNode forward = t2.privateMetadata("lasforward");

    auto pred = [](MetadataNode temp)
        { return Utils::startsWith(temp.name(), "vlr_"); };
    MetadataNodeList nodes = forward.findChildren(pred);
    EXPECT_EQ(nodes.size(), 388UL);
}
Example #11
0
TEST(LasReaderTest, test_vlr)
{
    PointTable table;

    Options ops1;
    ops1.add("filename", Support::datapath("las/lots_of_vlr.las"));
    LasReader reader;
    reader.setOptions(ops1);
    reader.prepare(table);
    reader.execute(table);

    MetadataNode root = reader.getMetadata();
    for (size_t i = 0; i < 390; ++i)
    {
        std::string name("vlr_");
        name += std::to_string(i);
        MetadataNode m = root.findChild(name);
        EXPECT_TRUE(!m.value().empty()) << "No node " << i;
    }
}
Example #12
0
TEST(LasReaderTest, callback)
{
    PointTable table;
    point_count_t count = 0;

    Options ops;
    ops.add("filename", Support::datapath("las/simple.las"));

    Reader::PointReadFunc cb = [&count](PointView& view, PointId id)
    {
        count++;
    };
    LasReader reader;
    reader.setOptions(ops);
    reader.setReadCb(cb);

    reader.prepare(table);
    reader.execute(table);
    EXPECT_EQ(count, (point_count_t)1065);
}
Example #13
0
TEST(LasReaderTest, test_sequential)
{
    PointTable table;

    Options ops1;
    ops1.add("filename", Support::datapath("las/1.2-with-color.las"));
    ops1.add("count", 103);
    LasReader reader;
    reader.setOptions(ops1);

    reader.prepare(table);
    PointViewSet viewSet = reader.execute(table);
    EXPECT_EQ(viewSet.size(), 1u);
    PointViewPtr view = *viewSet.begin();
    Support::check_p0_p1_p2(*view);
    PointViewPtr view2 = view->makeNew();
    view2->appendPoint(*view, 100);
    view2->appendPoint(*view, 101);
    view2->appendPoint(*view, 102);
    Support::check_p100_p101_p102(*view2);
}
Example #14
0
TEST(LasReaderTest, test_sequential)
{
    PointContext ctx;

    Options ops1;
    ops1.add("filename", Support::datapath("las/1.2-with-color.las"));
    ops1.add("count", 103);
    LasReader reader;
    reader.setOptions(ops1);

    reader.prepare(ctx);
    PointBufferSet pbSet = reader.execute(ctx);
    EXPECT_EQ(pbSet.size(), 1u);
    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);
}
Example #15
0
TEST(LasWriterTest, fix1063_1064_1065)
{
    std::string outfile = Support::temppath("out.las");
    std::string infile = Support::datapath("las/test1_4.las");

    FileUtils::deleteFile(outfile);


    std::string cmd = "pdal translate --writers.las.forward=all "
        "--writers.las.a_srs=\"EPSG:4326\" " + infile + " " + outfile;
    std::string output;
    Utils::run_shell_command(Support::binpath(cmd), output);

    Options o;
    o.add("filename", outfile);

    LasReader r;
    r.setOptions(o);

    PointTable t;
    r.prepare(t);
    PointViewSet s = r.execute(t);
    EXPECT_EQ(s.size(), 1u);
    PointViewPtr v = *s.begin();
    EXPECT_EQ(v->size(), 1000u);

    // https://github.com/PDAL/PDAL/issues/1063
    for (PointId idx = 0; idx < v->size(); ++idx)
        EXPECT_EQ(8, v->getFieldAs<int>(Dimension::Id::ClassFlags, idx));

    // https://github.com/PDAL/PDAL/issues/1064
    MetadataNode m = r.getMetadata();
    m = m.findChild("global_encoding");
    EXPECT_EQ(17, m.value<int>());

    // https://github.com/PDAL/PDAL/issues/1065
    SpatialReference ref = v->spatialReference();
    std::string wkt = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]]";
    EXPECT_EQ(ref.getWKT(), wkt);
}
Example #16
0
void compareTextLas(const std::string& textFilename,
    const std::string& lasFilename)
{
    TextReader t;
    Options to;
    to.add("filename", textFilename);
    t.setOptions(to);

    LasReader l;
    Options lo;
    lo.add("filename", lasFilename);
    l.setOptions(lo);
    
    PointTable tt;
    t.prepare(tt);
    PointViewSet ts = t.execute(tt);
    EXPECT_EQ(ts.size(), 1U);
    PointViewPtr tv = *ts.begin();

    PointTable lt;
    l.prepare(lt);
    PointViewSet ls = l.execute(lt);
    EXPECT_EQ(ls.size(), 1U);
    PointViewPtr lv = *ls.begin();

    EXPECT_EQ(tv->size(), lv->size());

    // Validate some point data.
    for (PointId i = 0; i < lv->size(); ++i)
    {
       EXPECT_DOUBLE_EQ(tv->getFieldAs<double>(Dimension::Id::X, i),
           lv->getFieldAs<double>(Dimension::Id::X, i));
       EXPECT_DOUBLE_EQ(tv->getFieldAs<double>(Dimension::Id::Y, i),
           lv->getFieldAs<double>(Dimension::Id::Y, i));
       EXPECT_DOUBLE_EQ(tv->getFieldAs<double>(Dimension::Id::Z, i),
           lv->getFieldAs<double>(Dimension::Id::Z, i));
    }
}
Example #17
0
// Make sure that we can translate this special test data to 1.4, dataformat 6.
TEST(LasWriterTest, issue2320)
{
    std::string outfile(Support::temppath("2320.laz"));

    {
        LasReader r;
        Options ro;
        ro.add("filename", Support::datapath("las/wontcompress3.las"));
        r.setOptions(ro);

        LasWriter w;
        Options wo;
        wo.add("minor_version", 4);
        wo.add("dataformat_id", 6);
        wo.add("filename", outfile);
        w.setOptions(wo);
        w.setInput(r);

        PointTable t;
        w.prepare(t);
        w.execute(t);
    }

    // Check that we can read.
    {
        LasReader r;
        Options ro;
        ro.add("filename", outfile);
        r.setOptions(ro);

        PointTable t;
        r.prepare(t);
        PointViewSet s = r.execute(t);
        EXPECT_EQ(s.size(), 1U);
        PointViewPtr v = *s.begin();
        EXPECT_EQ(v->size(), 1000U);
    }
}
Example #18
0
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;

    Options ops1;
    ops1.add("filename", Support::datapath(file));
    ops1.add("count", 1);
    LasReader reader;
    reader.setOptions(ops1);
    reader.prepare(ctx);

    EXPECT_EQ(reader.header().pointFormat(), pointFormat);
    EXPECT_EQ(reader.header().versionMajor(), majorVersion);
    EXPECT_EQ(reader.header().versionMinor(), minorVersion);

    PointBufferSet pbSet = reader.execute(ctx);
    EXPECT_EQ(pbSet.size(), 1u);
    PointBufferPtr buf = *pbSet.begin();
    EXPECT_EQ(buf->size(), 1u);

    Support::check_pN(*buf, 0, xref, yref, zref, tref, rref, gref, bref);
}
Example #19
0
TEST(LasWriterTest, flex_vlr)
{
    std::array<std::string, 3> outname =
        {{ "test_1.laz", "test_2.laz", "test_3.laz" }};

    Options readerOps;
    readerOps.add("filename", Support::datapath("las/simple.las"));

    PointTable table;

    LasReader reader;
    reader.setOptions(readerOps);

    reader.prepare(table);
    PointViewSet views = reader.execute(table);
    PointViewPtr v = *(views.begin());

    PointViewPtr v1(new PointView(table));
    PointViewPtr v2(new PointView(table));
    PointViewPtr v3(new PointView(table));

    std::vector<PointViewPtr> vs;
    vs.push_back(v1);
    vs.push_back(v2);
    vs.push_back(v3);

    for (PointId i = 0; i < v->size(); ++i)
        vs[i % 3]->appendPoint(*v, i);

    for (size_t i = 0; i < outname.size(); ++i)
        FileUtils::deleteFile(Support::temppath(outname[i]));

    BufferReader reader2;
    reader2.addView(v1);
    reader2.addView(v2);
    reader2.addView(v3);

    Options writerOps;
    writerOps.add("filename", Support::temppath("test_#.laz"));
    writerOps.add("pdal_metadata", true);

    LasWriter writer;
    writer.setOptions(writerOps);
    writer.setInput(reader2);

    writer.prepare(table);
    writer.execute(table);

    // Make sure that the files have the same three VLRs.
    for (size_t i = 0; i < outname.size(); ++i)
    {
        std::string filename = Support::temppath(outname[i]);
        EXPECT_TRUE(FileUtils::fileExists(filename));

        Options ops;
        ops.add("filename", filename);

        LasReader r;
        r.setOptions(ops);

        PointTable t;
        r.prepare(t);
        r.execute(t);
        const VlrList& vlrs = r.header().vlrs();
        EXPECT_EQ(vlrs.size(), 3U);
        EXPECT_NE(r.header().findVlr("laszip encoded", 22204), nullptr);
        EXPECT_NE(r.header().findVlr("PDAL", 12), nullptr);
        EXPECT_NE(r.header().findVlr("PDAL", 13), nullptr);
    }
}
Example #20
0
// Merge a couple of 1.4 LAS files with point formats 1 and 6.  Write the
// output with version 3.  Verify that you get point format 3 (default),
// LAS 1.3 output and other header data forwarded.
TEST(LasWriterTest, forward)
{
    Options readerOps1;

    readerOps1.add("filename", Support::datapath("las/4_1.las"));

    Options readerOps2;

    readerOps2.add("filename", Support::datapath("las/4_6.las"));

    LasReader r1;
    r1.addOptions(readerOps1);

    LasReader r2;
    r2.addOptions(readerOps2);

    StageFactory sf;
    Stage *m = sf.createStage("filters.merge");
    m->setInput(r1);
    m->setInput(r2);

    std::string testfile = Support::temppath("tmp.las");
    FileUtils::deleteFile(testfile);

    Options writerOps;
    writerOps.add("forward", "header");
    writerOps.add("minor_version", 3);
    writerOps.add("filename", testfile);

    LasWriter w;
    w.setInput(*m);
    w.addOptions(writerOps);

    PointTable t;

    w.prepare(t);
    w.execute(t);

    Options readerOps;
    readerOps.add("filename", testfile);

    LasReader r;

    r.setOptions(readerOps);

    PointTable t2;

    r.prepare(t2);
    r.execute(t2);

    MetadataNode n1 = r.getMetadata();
    EXPECT_EQ(n1.findChild("major_version").value<uint8_t>(), 1);
    EXPECT_EQ(n1.findChild("minor_version").value<uint8_t>(), 3);
    EXPECT_EQ(n1.findChild("dataformat_id").value<uint8_t>(), 3);
    EXPECT_EQ(n1.findChild("filesource_id").value<uint8_t>(), 0);
    // Global encoding doesn't match because 4_1.las has a bad value, so we
    // get the default.
    EXPECT_EQ(n1.findChild("global_encoding").value<uint16_t>(), 0);
    EXPECT_EQ(n1.findChild("project_id").value<Uuid>(), Uuid());
    EXPECT_EQ(n1.findChild("system_id").value(), "");
    EXPECT_EQ(n1.findChild("software_id").value(), "TerraScan");
    EXPECT_EQ(n1.findChild("creation_doy").value<uint16_t>(), 142);
    EXPECT_EQ(n1.findChild("creation_year").value<uint16_t>(), 2014);
}
Example #21
0
// Identical to above, but writes each input view to a separate output file.
TEST(LasWriterTest, auto_offset2)
{
    using namespace Dimension;

    const std::string outname(Support::temppath("offset_test#.las"));
    const std::string inname1(Support::temppath("offset_test1.las"));
    const std::string inname2(Support::temppath("offset_test2.las"));
    PointTable table;

    table.layout()->registerDims({Id::X, Id::Y, Id::Z});

    BufferReader bufferReader;

    PointViewPtr view(new PointView(table));
    view->setField(Id::X, 0, 125000.00);
    view->setField(Id::X, 1, 74529.00);
    view->setField(Id::X, 2, 1000000.02);
    view->setField(Id::Y, 0, 0);
    view->setField(Id::Y, 1, 1);
    view->setField(Id::Y, 2, 2);
    view->setField(Id::Z, 0, -123);
    view->setField(Id::Z, 1, 456.78);
    view->setField(Id::Z, 2, 945.23);
    bufferReader.addView(view);

    view.reset(new PointView(table));
    view->setField(Id::X, 0, 25.00);
    view->setField(Id::X, 1, 74529.00);
    view->setField(Id::X, 2, 534252.35);
    view->setField(Id::Y, 0, 3);
    view->setField(Id::Y, 1, 4);
    view->setField(Id::Y, 2, 5);
    view->setField(Id::Z, 0, 1.5);
    view->setField(Id::Z, 1, 2147483524);
    view->setField(Id::Z, 2, 745.23);
    bufferReader.addView(view);

    Options writerOps;
    writerOps.add("filename", outname);
    writerOps.add("offset_x", "auto");
    writerOps.add("scale_x", "auto");
    writerOps.add("offset_z", "auto");
    writerOps.add("scale_z", "auto");

    LasWriter writer;
    writer.setOptions(writerOps);
    writer.setInput(bufferReader);

    writer.prepare(table);
    writer.execute(table);

    {
        Options readerOps;
        readerOps.add("filename", inname1);
        PointTable readTable;

        LasReader reader;
        reader.setOptions(readerOps);

        reader.prepare(readTable);
        EXPECT_DOUBLE_EQ(74529.00, reader.header().offsetX());
        EXPECT_DOUBLE_EQ(0, reader.header().offsetY());
        EXPECT_DOUBLE_EQ(-123, reader.header().offsetZ());

        EXPECT_NEAR(4.30956e-4, reader.header().scaleX(), 1e-4);
        EXPECT_DOUBLE_EQ(.01, reader.header().scaleY());
        // (max - min) are chosen to yield std::numeric_limits<int>::max();
        EXPECT_NEAR(4.9743e-7, reader.header().scaleZ(), 1e-7);

        PointViewSet viewSet = reader.execute(readTable);
        EXPECT_EQ(viewSet.size(), 1u);
        view = *viewSet.begin();
        EXPECT_EQ(view->size(), 3u);
        EXPECT_NEAR(125000.00, view->getFieldAs<double>(Id::X, 0), .001);
        EXPECT_NEAR(74529.00, view->getFieldAs<double>(Id::X, 1), .001);
        EXPECT_NEAR(1000000.02, view->getFieldAs<double>(Id::X, 2), .0001);
    }

    {
        Options readerOps;
        readerOps.add("filename", inname2);
        PointTable readTable;

        LasReader reader;
        reader.setOptions(readerOps);

        reader.prepare(readTable);
        EXPECT_DOUBLE_EQ(25.0, reader.header().offsetX());
        EXPECT_DOUBLE_EQ(0, reader.header().offsetY());
        EXPECT_DOUBLE_EQ(1.5, reader.header().offsetZ());

        EXPECT_NEAR(2.4876e-4, reader.header().scaleX(), 1e-7);
        EXPECT_DOUBLE_EQ(.01, reader.header().scaleY());
        EXPECT_NEAR(.99999, reader.header().scaleZ(), 1e-5);

        PointViewSet viewSet = reader.execute(readTable);
        EXPECT_EQ(viewSet.size(), 1u);
        view = *viewSet.begin();
        EXPECT_EQ(view->size(), 3u);
        EXPECT_NEAR(25.00, view->getFieldAs<double>(Id::X, 0), .0001);
        EXPECT_NEAR(74529.00, view->getFieldAs<double>(Id::X, 1), .001);
        EXPECT_NEAR(534252.35, view->getFieldAs<double>(Id::X, 2), .0001);
    }

    FileUtils::deleteFile(inname1);
    FileUtils::deleteFile(inname2);
}
Example #22
0
// Test that stage options passed via --stage.<tagname>.<option> work.
TEST(json, stagetags)
{
    auto checkValue = [](const std::string filename, double value)
    {
        Options o;
        o.add("filename", filename);
        LasReader r;
        r.setOptions(o);

        PointTable t;
        r.prepare(t);
        PointViewSet s = r.execute(t);
        EXPECT_EQ(s.size(), 1u);
        PointViewPtr v = *s.begin();

        for (PointId i = 0; i < v->size(); ++i)
            EXPECT_DOUBLE_EQ(value,
                v->getFieldAs<double>(Dimension::Id::Z, i));

        FileUtils::deleteFile(filename);
    };

    std::string outFilename(Support::temppath("assigned.las"));
    std::string base(appName() + " " +
        Support::configuredpath("pipeline/options.json"));
    std::string output;
    int stat;

    stat = Utils::run_shell_command(base, output);
    EXPECT_EQ(stat, 0);
    checkValue(outFilename, 25);

    stat = Utils::run_shell_command(base +
        " --filters.assign.assignment=Z[:]=101",
        output);
    EXPECT_EQ(stat, 0);
    checkValue(outFilename, 101);

    stat = Utils::run_shell_command(base +
        " --stage.assigner.assignment=Z[:]=1987",
        output);
    EXPECT_EQ(stat, 0);
    checkValue(outFilename, 1987);

    // Make sure that tag options override stage options.
    stat = Utils::run_shell_command(base +
        " --filters.assign.assignment=Z[:]=25 "
        "--stage.assigner.assignment=Z[:]=555", output);
    EXPECT_EQ(stat, 0);
    checkValue(outFilename, 555);
    stat = Utils::run_shell_command(base +
        " --stage.assigner.assignment=Z[:]=555 "
        "--filters.assign.assignment=Z[:]=25 ", output);
    EXPECT_EQ(stat, 0);
    checkValue(outFilename, 555);

    // Check that bad tag fails.
    stat = Utils::run_shell_command(base +
        " --stage.foobar.assignment=Z[:]=1987",
        output);
    EXPECT_NE(stat, 0);

    // Check that bad option name fails.
    stat = Utils::run_shell_command(base +
        " --stage.assigner.blah=Z[:]=1987",
        output);
    EXPECT_NE(stat, 0);

    // Check that multiply specified option fails.
    stat = Utils::run_shell_command(base +
        " --stage.reader.compression=laszip "
        "--stage.reader.compression=lazperf", output);
    EXPECT_NE(stat, 0);
}
Example #23
0
TEST(LasReaderTest, extraBytes)
{
    PointTable table;
    PointLayoutPtr layout(table.layout());

    Options readOps;
    readOps.add("filename", Support::datapath("las/extrabytes.las"));
    LasReader reader;
    reader.setOptions(readOps);

    reader.prepare(table);

    DimTypeList dimTypes = layout->dimTypes();
    EXPECT_EQ(dimTypes.size(), (size_t)24);

    Dimension::Id color0 = layout->findProprietaryDim("Colors0");
    EXPECT_EQ(layout->dimType(color0), Dimension::Type::Unsigned16);
    Dimension::Id color1 = layout->findProprietaryDim("Colors1");
    EXPECT_EQ(layout->dimType(color1), Dimension::Type::Unsigned16);
    Dimension::Id color2 = layout->findProprietaryDim("Colors2");
    EXPECT_EQ(layout->dimType(color2), Dimension::Type::Unsigned16);

    Dimension::Id flag0 = layout->findProprietaryDim("Flags0");
    EXPECT_EQ(layout->dimType(flag0), Dimension::Type::Signed8);
    Dimension::Id flag1 = layout->findProprietaryDim("Flags1");
    EXPECT_EQ(layout->dimType(flag1), Dimension::Type::Signed8);

    Dimension::Id time2 = layout->findDim("Time");
    EXPECT_EQ(layout->dimType(time2), Dimension::Type::Unsigned64);

    PointViewSet viewSet = reader.execute(table);
    EXPECT_EQ(viewSet.size(), (size_t)1);
    PointViewPtr view = *viewSet.begin();

    Dimension::Id red = layout->findDim("Red");
    Dimension::Id green = layout->findDim("Green");
    Dimension::Id blue = layout->findDim("Blue");

    Dimension::Id returnNum = layout->findDim("ReturnNumber");
    Dimension::Id numReturns = layout->findDim("NumberOfReturns");

    Dimension::Id intensity = layout->findDim("Intensity");
    Dimension::Id time = layout->findDim("GpsTime");

    for (PointId idx = 0; idx < view->size(); ++idx)
    {
        ASSERT_EQ(view->getFieldAs<uint16_t>(red, idx),
            view->getFieldAs<uint16_t>(color0, idx));
        ASSERT_EQ(view->getFieldAs<uint16_t>(green, idx),
            view->getFieldAs<uint16_t>(color1, idx));
        ASSERT_EQ(view->getFieldAs<uint16_t>(blue, idx),
            view->getFieldAs<uint16_t>(color2, idx));

        ASSERT_EQ(view->getFieldAs<uint16_t>(flag0, idx),
            view->getFieldAs<uint16_t>(returnNum, idx));
        ASSERT_EQ(view->getFieldAs<uint16_t>(flag1, idx),
            view->getFieldAs<uint16_t>(numReturns, idx));

        // Time was written truncated rather than rounded.
        ASSERT_NEAR(view->getFieldAs<double>(time, idx),
            view->getFieldAs<double>(time2, idx), 1.0);
    }
}
Example #24
0
void streamTest(const std::string src, const std::string compression)
{
    Options ops1;
    ops1.add("filename", src);
    ops1.add("compression", compression);

    LasReader lasReader;
    lasReader.setOptions(ops1);

    PointTable t;
    lasReader.prepare(t);
    PointViewSet s = lasReader.execute(t);
    PointViewPtr p = *s.begin();

    class Checker : public Filter
    {
    public:
        std::string getName() const
            { return "checker"; }
        Checker(PointViewPtr v) : m_cnt(0), m_view(v),
            m_bulkBuf(v->pointSize()), m_buf(v->pointSize()),
            m_dims(v->dimTypes())
            {}
    private:
        point_count_t m_cnt;
        PointViewPtr m_view;
        std::vector<char> m_bulkBuf;
        std::vector<char> m_buf;
        DimTypeList m_dims;

        bool processOne(PointRef& point)
        {
            PointRef bulkPoint = m_view->point(m_cnt);

            bulkPoint.getPackedData(m_dims, m_bulkBuf.data());
            point.getPackedData(m_dims, m_buf.data());
            EXPECT_EQ(memcmp(m_buf.data(), m_bulkBuf.data(),
                m_view->pointSize()), 0);
            m_cnt++;
            return true;
        }

        void done(PointTableRef)
        {
            EXPECT_EQ(m_cnt, 110000u);
        }
    };

    Options ops2;
    ops2.add("filename", Support::datapath("las/autzen_trim.las"));

    LasReader lazReader;
    lazReader.setOptions(ops2);

    Checker c(p);
    c.setInput(lazReader);

    FixedPointTable fixed(100);
    c.prepare(fixed);
    c.execute(fixed);
}
Example #25
0
TEST(Compression, Simple)
{
    const std::string file(Support::datapath("las/1.2-with-color.las"));

    const pdal::Option opt_filename("filename", file);
    pdal::Options opts;
    opts.add(opt_filename);

    LasReader reader;
    reader.setOptions(opts);

    PointTable table;
    PointLayoutPtr layout(table.layout());

    reader.prepare(table);
    PointViewSet viewSet = reader.execute(table);
    PointViewPtr view = *viewSet.begin();

    EXPECT_EQ(layout->pointSize(), 52U);

    std::vector<unsigned char> rawBuf;
    LazPerfBuf b(rawBuf);

    DimTypeList dimTypes = layout->dimTypes();
    LazPerfCompressor<LazPerfBuf> compressor(b, dimTypes);

    std::vector<char> tmpbuf(compressor.pointSize());
    for (PointId idx = 0; idx < view->size(); ++idx)
    {
        view->getPackedPoint(dimTypes, idx, tmpbuf.data());
        compressor.compress(tmpbuf.data(), compressor.pointSize());
    }
    compressor.done();

    EXPECT_EQ(view->size() * compressor.pointSize(), (size_t)55380);
    EXPECT_EQ(rawBuf.size(), (size_t)30945);

    LazPerfBuf b2(rawBuf);

    LazPerfDecompressor<LazPerfBuf> decompressor(b2, dimTypes);

    size_t outbufSize = decompressor.pointSize() * view->size();
    std::vector<char> outbuf(outbufSize);
    decompressor.decompress(outbuf.data(), outbufSize);

    PointViewPtr otherView(new PointView(table));

    char *pos = outbuf.data();
    for (PointId nextId = 0; nextId < 11; nextId++)
    {
        otherView->setPackedPoint(dimTypes, nextId, pos);
        pos += decompressor.pointSize();
    }
    EXPECT_EQ(otherView->size(), 11U);
    EXPECT_EQ(getBytes(otherView).size(), (size_t)(52 * 11));

    uint16_t r = otherView->getFieldAs<uint16_t>(Dimension::Id::Red, 10);
    EXPECT_EQ(r, 64U);
    int32_t x = otherView->getFieldAs<int32_t>(Dimension::Id::X, 10);
    EXPECT_EQ(x, 636038);
    double xd = otherView->getFieldAs<double>(Dimension::Id::X, 10);
    EXPECT_FLOAT_EQ(xd, 636037.53);
    int32_t y = otherView->getFieldAs<int32_t>(Dimension::Id::Y, 10);
    EXPECT_EQ(y, 849338);
}
Example #26
0
TEST(Compression, simple)
{
    const std::string file(Support::datapath("las/1.2-with-color.las"));

    const pdal::Option opt_filename("filename", file);
    pdal::Options opts;
    opts.add(opt_filename);

    LasReader reader;
    reader.setOptions(opts);

    PointTable table;
    PointLayoutPtr layout(table.layout());

    reader.prepare(table);
    PointViewSet viewSet = reader.execute(table);
    PointViewPtr view = *viewSet.begin();

    EXPECT_EQ(layout->pointSize(), 52U);

    std::vector<unsigned char> rawBuf;

    DimTypeList dimTypes = layout->dimTypes();
    auto cb = [&rawBuf](char *buf, size_t bufsize)
    {
        unsigned char *ubuf = reinterpret_cast<unsigned char *>(buf);
        rawBuf.insert(rawBuf.end(), ubuf, ubuf + bufsize);
    };

    LazPerfCompressor compressor(cb, dimTypes);

    std::vector<char> tmpbuf(layout->pointSize());
    for (PointId idx = 0; idx < view->size(); ++idx)
    {
        view->getPackedPoint(dimTypes, idx, tmpbuf.data());
        compressor.compress(tmpbuf.data(), layout->pointSize());
    }
    compressor.done();

    EXPECT_EQ(view->size() * layout->pointSize(), (size_t)55380);
    EXPECT_EQ(rawBuf.size(), (size_t)30945);

    PointViewPtr otherView(new PointView(table));
    PointId nextId(0);
    auto cb2 = [&otherView, &dimTypes, &nextId](char *buf, size_t bufsize)
    {

        otherView->setPackedPoint(dimTypes, nextId, buf);
        nextId++;
    };

    LazPerfDecompressor(cb2, dimTypes, view->size()).
        decompress(reinterpret_cast<const char *>(rawBuf.data()),
            rawBuf.size());

    EXPECT_EQ(otherView->size(), 1065U);
    EXPECT_EQ(getBytes(otherView).size(), (size_t)(52 * 1065));

    uint16_t r = otherView->getFieldAs<uint16_t>(Dimension::Id::Red, 10);
    EXPECT_EQ(r, 64U);
    int32_t x = otherView->getFieldAs<int32_t>(Dimension::Id::X, 10);
    EXPECT_EQ(x, 636038);
    double xd = otherView->getFieldAs<double>(Dimension::Id::X, 10);
    EXPECT_FLOAT_EQ(xd, 636037.53);
    int32_t y = otherView->getFieldAs<int32_t>(Dimension::Id::Y, 10);
    EXPECT_EQ(y, 849338);
}
Example #27
0
TEST(PointTable, userView)
{
    class UserTable : public PointTable
    {
    private:
        double m_x;
        double m_y;
        double m_z;

    public:
        PointId addPoint()
            { return 0; }
        char *getPoint(PointId idx)
            { return NULL; }
        void setField(const Dimension::Detail *d, PointId idx, const void *value)
        {
            if (d->id() == Dimension::Id::X)
               m_x = *(const double *)value;
            else if (d->id() == Dimension::Id::Y)
               m_y = *(const double *)value;
            else if (d->id() == Dimension::Id::Z)
               m_z = *(const double *)value;
        }
        void getField(const Dimension::Detail *d, PointId idx, void *value)
        {
            if (d->id() == Dimension::Id::X)
               *(double *)value = m_x;
            else if (d->id() == Dimension::Id::Y)
               *(double *)value = m_y;
            else if (d->id() == Dimension::Id::Z)
               *(double *)value = m_z;
        }
    };

    LasReader reader;

    Options opts;
    opts.add("filename", Support::datapath("las/simple.las"));
    opts.add("count", 100);

    reader.setOptions(opts);

    PointTable defTable;
    reader.prepare(defTable);
    PointViewSet viewSet = reader.execute(defTable);
    PointViewPtr defView = *viewSet.begin();

    bool called(false);
    auto readCb = [defView, &called](PointView& customView, PointId id)
    {
        called = true;
        double xDef = defView->getFieldAs<double>(Dimension::Id::X, id);
        double yDef = defView->getFieldAs<double>(Dimension::Id::Y, id);
        double zDef = defView->getFieldAs<double>(Dimension::Id::Z, id);

        double x = customView.getFieldAs<double>(Dimension::Id::X, id);
        double y = customView.getFieldAs<double>(Dimension::Id::Y, id);
        double z = customView.getFieldAs<double>(Dimension::Id::Z, id);

        EXPECT_FLOAT_EQ(xDef, x);
        EXPECT_FLOAT_EQ(yDef, y);
        EXPECT_FLOAT_EQ(zDef, z);
    };

    reader.setReadCb(readCb);
    UserTable table;

    reader.prepare(table);
    reader.execute(table);
    EXPECT_TRUE(called);
}