示例#1
0
TEST(LasWriterTest, srs)
{
    Options readerOps;
    readerOps.add("filename", Support::datapath("las/utm15.las"));

    LasReader reader;
    reader.setOptions(readerOps);

    Options writerOps;
    writerOps.add("filename", Support::temppath("out.las"));
    LasWriter writer;
    writer.setInput(reader);
    writer.setOptions(writerOps);

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

    LasTester tester;
    SpatialReference srs = tester.srs(writer);
    EXPECT_EQ(srs, SpatialReference("EPSG:26915"));
}
示例#2
0
TEST(LasWriterTest, pdal_metadata)
{
    PointTable table;

    std::string infile(Support::datapath("las/1.2-with-color.las"));
    std::string outfile(Support::temppath("simple.las"));

    // remove file from earlier run, if needed
    FileUtils::deleteFile(outfile);

    Options readerOpts;
    readerOpts.add("filename", infile);

    Options writerOpts;
    writerOpts.add("pdal_metadata", true);
    writerOpts.add("filename", outfile);

    LasReader reader;
    reader.setOptions(readerOpts);

    LasWriter writer;
    writer.setOptions(writerOpts);
    writer.setInput(reader);
    writer.prepare(table);
    writer.execute(table);

    PointTable t2;
    Options readerOpts2;
    readerOpts2.add("filename", outfile);
    LasReader reader2;
    reader2.setOptions(readerOpts2);

    reader2.prepare(t2);
    reader2.execute(t2);

    EXPECT_EQ(reader2.getMetadata().children("pdal_metadata").size(), 1UL);
    EXPECT_EQ(reader2.getMetadata().children("pdal_pipeline").size(), 1UL);

}
示例#3
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);
    }
}
示例#4
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);
    }
}
示例#5
0
// This is the same test as the above, but for a 1.4-specific point format.
// 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(LasWriterTest, laszip1_4)
{
    Options readerOps;
    std::string baseFilename = Support::datapath("las/autzen_trim_7.las");
    readerOps.add("filename", baseFilename);

    LasReader lazReader;
    lazReader.setOptions(readerOps);

    std::string testfile(Support::temppath("temp.laz"));

    FileUtils::deleteFile(testfile);

    Options writerOps;
    writerOps.add("filename", testfile);
    writerOps.add("dataformat_id", 7);
    writerOps.add("minor_version", 4);

    LasWriter lazWriter;
    lazWriter.setOptions(writerOps);
    lazWriter.setInput(lazReader);

    PointTable t;
    lazWriter.prepare(t);
    lazWriter.execute(t);

    // Now test the points were properly written.  Use laszip.
    Options ops1;
    ops1.add("filename", testfile);

    LasReader r1;
    r1.setOptions(ops1);

    PointTable t1;
    r1.prepare(t1);
    PointViewSet set1 = r1.execute(t1);
    PointViewPtr view1 = *set1.begin();

    Options ops2;
    ops2.add("filename", baseFilename);

    LasReader r2;
    r2.setOptions(ops2);

    PointTable t2;
    r2.prepare(t2);
    PointViewSet set2 = r2.execute(t2);
    PointViewPtr view2 = *set2.begin();

    EXPECT_EQ(view1->size(), view2->size());
    EXPECT_EQ(view1->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 idx = 0; idx < view1->size(); idx++)
    {
       view1->getPackedPoint(dims, idx, buf1.get());
       view2->getPackedPoint(dims, idx, buf2.get());
       char *b1 = buf1.get();
       char *b2 = buf2.get();
       // Uncomment this to figure out the exact byte at which things are
       // broken.
       /**
       for (size_t i = 0; i < pointSize; ++i)
       {
           if (*b1++ != *b2++)
           {
               {
                   size_t s = 0;
                   for (auto di = dims.begin(); di != dims.end(); ++di)
                   {
                       std::cerr << "Dim " << view1->dimName(di->m_id) <<
                           " at " << s << "!\n";
                       s += Dimension::size(di->m_type);
                   }
               }
               throw pdal_error("Mismatch at byte = " + to_string(i) + "!");
           }
       }
       **/
       EXPECT_EQ(memcmp(buf1.get(), buf2.get(), pointSize), 0);
    }
}
示例#6
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(LasWriterTest, laszip)
{
    Options readerOps;
    readerOps.add("filename", Support::datapath("las/autzen_trim.las"));

    LasReader lazReader;
    lazReader.setOptions(readerOps);

    std::string testfile(Support::temppath("temp.laz"));

    FileUtils::deleteFile(testfile);

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

    LasWriter lazWriter;
    lazWriter.setOptions(writerOps);
    lazWriter.setInput(lazReader);

    PointTable t;
    lazWriter.prepare(t);
    lazWriter.execute(t);

    // Now test the points were properly written.  Use laszip.
    Options ops1;
    ops1.add("filename", testfile);

    LasReader r1;
    r1.setOptions(ops1);

    PointTable t1;
    r1.prepare(t1);
    PointViewSet set1 = r1.execute(t1);
    PointViewPtr view1 = *set1.begin();

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

    LasReader r2;
    r2.setOptions(ops2);

    PointTable t2;
    r2.prepare(t2);
    PointViewSet set2 = r2.execute(t2);
    PointViewPtr view2 = *set2.begin();

    EXPECT_EQ(view1->size(), view2->size());
    EXPECT_EQ(view1->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 < view1->size(); i += 100)
    {
       view1->getPackedPoint(dims, i, buf1.get());
       view2->getPackedPoint(dims, i, buf2.get());
       EXPECT_EQ(memcmp(buf1.get(), buf2.get(), pointSize), 0);
    }
}
示例#7
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);
}
示例#8
0
TEST(LasWriterTest, extra_dims)
{
    Options readerOps;

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

    Options writerOps;
    writerOps.add("extra_dims", "Red=int32, Blue = int16, Green = int32_t");
    writerOps.add("filename", Support::temppath("simple.las"));
    LasWriter writer;
    writer.setInput(reader);
    writer.setOptions(writerOps);

    PointTable table;
    writer.prepare(table);
    PointViewSet viewSet = writer.execute(table);

    LasTester tester;
    LasHeader *header = tester.header(writer);
    EXPECT_EQ(header->pointLen(), header->basePointLen() + 10);
    PointViewPtr pb = *viewSet.begin();

    uint16_t colors[][3] = {
        { 68, 77, 88 },
        { 92, 100, 110 },
        { 79, 87, 87 },
        { 100, 102, 116 },
        { 162, 114, 145 },
        { 163, 137, 155 },
        { 154, 131, 144 },
        { 104, 111, 126 },
        { 164, 136, 156 },
        { 72, 87, 82 },
        { 117, 117, 136 }
    };

    Options reader2Ops;
    reader2Ops.add("filename", Support::temppath("simple.las"));
    reader2Ops.add("extra_dims", "R1 =int32, B1= int16 ,G1=int32_t");

    LasReader reader2;
    reader2.setOptions(reader2Ops);

    PointTable readTable;
    reader2.prepare(readTable);
    viewSet = reader2.execute(readTable);
    pb = *viewSet.begin();
    Dimension::Id r1 = readTable.layout()->findDim("R1");
    EXPECT_TRUE(r1 != Dimension::Id::Unknown);
    Dimension::Id b1 = readTable.layout()->findDim("B1");
    EXPECT_TRUE(b1 != Dimension::Id::Unknown);
    Dimension::Id g1 = readTable.layout()->findDim("G1");
    EXPECT_TRUE(g1 != Dimension::Id::Unknown);
    EXPECT_EQ(pb->size(), (size_t)1065);
    size_t j = 0;
    for (PointId i = 0; i < pb->size(); i += 100)
    {
        EXPECT_EQ(pb->getFieldAs<int16_t>(r1, i), colors[j][0]);
        EXPECT_EQ(pb->getFieldAs<int16_t>(g1, i), colors[j][1]);
        EXPECT_EQ(pb->getFieldAs<int16_t>(b1, i), colors[j][2]);
        j++;
    }
}
示例#9
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);
}