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); }
int SplitKernel::execute() { PointTable table; Options readerOpts; readerOpts.add("filename", m_inputFile); readerOpts.add("debug", isDebug()); readerOpts.add("verbose", getVerboseLevel()); Stage& reader = makeReader(m_inputFile); reader.setOptions(readerOpts); std::unique_ptr<Stage> f; StageFactory factory; Options filterOpts; if (m_length) { f.reset(factory.createStage("filters.splitter")); filterOpts.add("length", m_length); filterOpts.add("origin_x", m_xOrigin); filterOpts.add("origin_y", m_yOrigin); } else { f.reset(factory.createStage("filters.chipper")); filterOpts.add("capacity", m_capacity); } f->setInput(reader); f->setOptions(filterOpts); f->prepare(table); PointViewSet pvSet = f->execute(table); int filenum = 1; for (auto& pvp : pvSet) { BufferReader reader; reader.addView(pvp); std::string filename = makeFilename(m_outputFile, filenum++); Stage& writer = makeWriter(filename, reader); writer.prepare(table); writer.execute(table); } return 0; }
TEST(ComputeRangeFilterTest, compute) { using namespace Dimension; PointTable table; PointLayoutPtr layout(table.layout()); layout->registerDim(Id::X); layout->registerDim(Id::Y); layout->registerDim(Id::Z); Id pn = layout->registerOrAssignDim("Pixel Number", Type::Double); Id fn = layout->registerOrAssignDim("Frame Number", Type::Double); PointViewPtr view(new PointView(table)); BufferReader r; r.addView(view); ComputeRangeFilter crop; crop.setInput(r); crop.prepare(table); view->setField(Id::X, 0, 0.0); view->setField(Id::Y, 0, 0.0); view->setField(Id::Z, 0, 0.0); view->setField(pn, 0, 0.0); view->setField(fn, 0, 0.0); view->setField(Id::X, 1, 0.0); view->setField(Id::Y, 1, 3.0); view->setField(Id::Z, 1, 4.0); view->setField(pn, 1, -5.0); view->setField(fn, 1, 0.0); PointViewSet s = crop.execute(table); EXPECT_EQ(1u, s.size()); Id range = layout->findDim("Range"); EXPECT_NE(Id::Unknown, range); PointViewPtr out = *s.begin(); EXPECT_EQ(2u, out->size()); EXPECT_EQ(5.0, out->getFieldAs<double>(range, 0)); EXPECT_EQ(0.0, out->getFieldAs<double>(range, 1)); }
int SortKernel::execute() { Stage& readerStage = makeReader(m_inputFile, ""); // go ahead and prepare/execute on reader stage only to grab input // PointViewSet, this makes the input PointView available to both the // processing pipeline and the visualizer PointTable table; readerStage.prepare(table); PointViewSet viewSetIn = readerStage.execute(table); // the input PointViewSet will be used to populate a BufferReader that is // consumed by the processing pipeline PointViewPtr inView = *viewSetIn.begin(); BufferReader bufferReader; bufferReader.addView(inView); Stage& sortStage = makeFilter("filters.mortonorder", bufferReader); Stage& writer = makeWriter(m_outputFile, sortStage, ""); Options writerOptions; if (m_bCompress) writerOptions.add("compression", true); if (m_bForwardMetadata) writerOptions.add("forward_metadata", true); writer.addOptions(writerOptions); writer.prepare(table); // process the data, grabbing the PointViewSet for visualization of the PointViewSet viewSetOut = writer.execute(table); if (isVisualize()) visualize(*viewSetOut.begin()); return 0; }
int SplitKernel::execute() { PointTable table; Stage& reader = makeReader(m_inputFile, m_driverOverride); Options filterOpts; std::string driver = (m_length ? "filters.splitter" : "filters.chipper"); if (m_length) { filterOpts.add("length", m_length); filterOpts.add("origin_x", m_xOrigin); filterOpts.add("origin_y", m_yOrigin); } else { filterOpts.add("capacity", m_capacity); } Stage& f = makeFilter(driver, reader, filterOpts); f.prepare(table); PointViewSet pvSet = f.execute(table); int filenum = 1; for (auto& pvp : pvSet) { BufferReader reader; reader.addView(pvp); std::string filename = makeFilename(m_outputFile, filenum++); Stage& writer = makeWriter(filename, reader, ""); writer.prepare(table); writer.execute(table); } return 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); }
int CpdKernel::execute() { PointTable tableX; PointTable tableY; cpd::Matrix X = readFile(m_filex); cpd::Matrix Y = readFile(m_filey); if (X.rows() == 0 || Y.rows() == 0) { throw pdal_error("No points to process."); } cpd::Matrix result; if (m_method == "rigid") { cpd::Rigid rigid; rigid .set_tolerance(m_tolerance) .set_max_iterations(m_max_it) .set_outlier_weight(m_outliers); rigid .no_reflections(m_no_reflections) .allow_scaling(m_allow_scaling); if (m_sigma2 > 0) { result = rigid.compute(X, Y, m_sigma2).points; } else { result = rigid.compute(X, Y).points; } } else if (m_method == "nonrigid") { cpd::Nonrigid nonrigid; nonrigid .set_tolerance(m_tolerance) .set_max_iterations(m_max_it) .set_outlier_weight(m_outliers); nonrigid .set_beta(m_beta) .set_lambda(m_lambda); if (m_sigma2 > 0) { result = nonrigid.compute(X, Y, m_sigma2).points; } else { result = nonrigid.compute(X, Y).points; } } else { std::stringstream ss; ss << "Invalid cpd method: " << m_method << std::endl; throw pdal_error(ss.str()); } PointTable outTable; PointLayoutPtr outLayout(outTable.layout()); outLayout->registerDim(Dimension::Id::X); outLayout->registerDim(Dimension::Id::Y); outLayout->registerDim(Dimension::Id::Z); outLayout->registerDim(Dimension::Id::XVelocity); outLayout->registerDim(Dimension::Id::YVelocity); outLayout->registerDim(Dimension::Id::ZVelocity); PointViewPtr outView(new PointView(outTable)); size_t M = Y.rows(); for (size_t i = 0; i < M; ++i) { outView->setField<double>(Dimension::Id::X, i, result(i, 0)); outView->setField<double>(Dimension::Id::Y, i, result(i, 1)); outView->setField<double>(Dimension::Id::Z, i, result(i, 2)); outView->setField<double>(Dimension::Id::XVelocity, i, Y(i, 0) - result(i, 0)); outView->setField<double>(Dimension::Id::YVelocity, i, Y(i, 1) - result(i, 1)); outView->setField<double>(Dimension::Id::ZVelocity, i, Y(i, 2) - result(i, 2)); } BufferReader reader; reader.addView(outView); Options writerOpts; if (StageFactory::inferReaderDriver(m_output) == "writers.text") { writerOpts.add("order", "X,Y,Z,XVelocity,YVelocity,ZVelocity"); writerOpts.add("keep_unspecified", false); } Stage& writer = makeWriter(m_output, reader, "", writerOpts); writer.prepare(outTable); writer.execute(outTable); return 0; }
int SortKernel::execute() { PointTable table; Options readerOptions; readerOptions.add("filename", m_inputFile); readerOptions.add("debug", isDebug()); readerOptions.add("verbose", getVerboseLevel()); Stage& readerStage = makeReader(readerOptions); // go ahead and prepare/execute on reader stage only to grab input // PointViewSet, this makes the input PointView available to both the // processing pipeline and the visualizer readerStage.prepare(table); PointViewSet viewSetIn = readerStage.execute(table); // the input PointViewSet will be used to populate a BufferReader that is // consumed by the processing pipeline PointViewPtr inView = *viewSetIn.begin(); BufferReader bufferReader; bufferReader.setOptions(readerOptions); bufferReader.addView(inView); Options sortOptions; sortOptions.add<bool>("debug", isDebug()); sortOptions.add<uint32_t>("verbose", getVerboseLevel()); StageFactory f; Stage& sortStage = ownStage(f.createStage("filters.mortonorder")); sortStage.setInput(bufferReader); sortStage.setOptions(sortOptions); Options writerOptions; writerOptions.add("filename", m_outputFile); setCommonOptions(writerOptions); if (m_bCompress) writerOptions.add("compression", true); if (m_bForwardMetadata) writerOptions.add("forward_metadata", true); std::vector<std::string> cmd = getProgressShellCommand(); UserCallback *callback = cmd.size() ? (UserCallback *)new ShellScriptCallback(cmd) : (UserCallback *)new HeartbeatCallback(); Stage& writer = makeWriter(m_outputFile, sortStage); // Some options are inferred by makeWriter based on filename // (compression, driver type, etc). writer.setOptions(writerOptions + writer.getOptions()); writer.setUserCallback(callback); for (const auto& pi : getExtraStageOptions()) { std::string name = pi.first; Options options = pi.second; //ABELL - Huh? std::vector<Stage *> stages = writer.findStage(name); for (const auto& s : stages) { Options opts = s->getOptions(); for (const auto& o : options.getOptions()) opts.add(o); s->setOptions(opts); } } writer.prepare(table); // process the data, grabbing the PointViewSet for visualization of the PointViewSet viewSetOut = writer.execute(table); if (isVisualize()) visualize(*viewSetOut.begin()); return 0; }
TEST(CropFilterTest, multibounds) { using namespace Dimension; PointTable table; table.layout()->registerDim(Id::X); table.layout()->registerDim(Id::Y); table.layout()->registerDim(Id::Z); PointViewPtr view(new PointView(table)); view->setField(Id::X, 0, 2); view->setField(Id::Y, 0, 2); view->setField(Id::X, 1, 4); view->setField(Id::Y, 1, 2); view->setField(Id::X, 2, 6); view->setField(Id::Y, 2, 2); view->setField(Id::X, 3, 8); view->setField(Id::Y, 3, 2); view->setField(Id::X, 4, 10); view->setField(Id::Y, 4, 2); view->setField(Id::X, 5, 12); view->setField(Id::Y, 5, 2); BufferReader r; r.addView(view); CropFilter crop; Options o; o.add("bounds", "([1, 3], [1, 3])"); o.add("bounds", "([5, 7], [1, 3])"); o.add("polygon", "POLYGON ((9 1, 11 1, 11 3, 9 3, 9 1))"); crop.setInput(r); crop.setOptions(o); crop.prepare(table); PointViewSet s = crop.execute(table); // Make sure we get three views, one with the point 2, 2, one with the // point 6, 2 and one with 10,2. EXPECT_EQ(s.size(), 3u); static int total_cnt = 0; for (auto v : s) { int cnt = 0; EXPECT_EQ(v->size(), 1u); double x = v->getFieldAs<double>(Dimension::Id::X, 0); double y = v->getFieldAs<double>(Dimension::Id::Y, 0); if (x == 2 && y == 2) cnt = 1; if (x == 6 && y == 2) cnt = 2; if (x == 10 && y == 2) cnt = 4; EXPECT_TRUE(cnt > 0); total_cnt += cnt; } EXPECT_EQ(total_cnt, 7); }