TEST(CropFilterTest, test_crop) { BOX3D srcBounds(0.0, 0.0, 0.0, 10.0, 100.0, 1000.0); Options opts; opts.add("bounds", srcBounds); opts.add("num_points", 1000); opts.add("mode", "ramp"); FauxReader reader; reader.setOptions(opts); // crop the window to 1/3rd the size in each dimension BOX2D dstBounds(3.33333, 33.33333, 6.66666, 66.66666); Options cropOpts; cropOpts.add("bounds", dstBounds); CropFilter filter; filter.setOptions(cropOpts); filter.setInput(reader); Options statOpts; StatsFilter stats; stats.setOptions(statOpts); stats.setInput(filter); PointTable table; stats.prepare(table); PointViewSet viewSet = stats.execute(table); EXPECT_EQ(viewSet.size(), 1u); PointViewPtr buf = *viewSet.begin(); const stats::Summary& statsX = stats.getStats(Dimension::Id::X); const stats::Summary& statsY = stats.getStats(Dimension::Id::Y); const stats::Summary& statsZ = stats.getStats(Dimension::Id::Z); EXPECT_EQ(buf->size(), 333u); const double minX = statsX.minimum(); const double minY = statsY.minimum(); const double minZ = statsZ.minimum(); const double maxX = statsX.maximum(); const double maxY = statsY.maximum(); const double maxZ = statsZ.maximum(); const double avgX = statsX.average(); const double avgY = statsY.average(); const double avgZ = statsZ.average(); const double delX = 10.0 / 999.0 * 100.0; const double delY = 100.0 / 999.0 * 100.0; const double delZ = 1000.0 / 999.0 * 100.0; EXPECT_NEAR(minX, 3.33333, delX); EXPECT_NEAR(minY, 33.33333, delY); EXPECT_NEAR(minZ, 333.33333, delZ); EXPECT_NEAR(maxX, 6.66666, delX); EXPECT_NEAR(maxY, 66.66666, delY); EXPECT_NEAR(maxZ, 666.66666, delZ); EXPECT_NEAR(avgX, 5.00000, delX); EXPECT_NEAR(avgY, 50.00000, delY); EXPECT_NEAR(avgZ, 500.00000, delZ); }
TEST(OptionsTest, conditional) { CropFilter s; Options ops; ops.add("foo", "foo"); ops.add("bar", "bar"); ops.add("baz", "baz"); s.setOptions(ops); Options condOps; condOps.add("foo", "lose"); condOps.add("bar", "lose"); condOps.add("baz", "lose"); condOps.add("foot", "win"); condOps.add("barf", "win"); condOps.add("bazel", "win"); s.addConditionalOptions(condOps); ops = s.getOptions(); EXPECT_EQ(ops.size(), 6u); EXPECT_EQ(ops.getValueOrDefault("foo", std::string()), "foo"); EXPECT_EQ(ops.getValueOrDefault("bar", std::string()), "bar"); EXPECT_EQ(ops.getValueOrDefault("baz", std::string()), "baz"); EXPECT_EQ(ops.getValueOrDefault("foot", std::string()), "win"); EXPECT_EQ(ops.getValueOrDefault("barf", std::string()), "win"); EXPECT_EQ(ops.getValueOrDefault("bazel", std::string()), "win"); }
TEST(OptionsTest, test_static_options) { Options ops; FauxReader reader; reader.setOptions(ops); CropFilter crop; crop.setOptions(ops); crop.setInput(reader); auto opts = crop.getDefaultOptions(); EXPECT_EQ(opts.getOptions().size(), 4u); EXPECT_TRUE(opts.hasOption("bounds")); EXPECT_TRUE(opts.hasOption("inside")); EXPECT_TRUE(opts.hasOption("polygon")); EXPECT_FALSE(opts.hasOption("metes")); }
TEST(CropFilterTest, test_crop_polygon_reprojection) { Options options; options.add("spatialreference", Support::datapath("autzen/autzen-srs.wkt")); options.add("out_srs", "EPSG:4326"); options.add("x_dim", std::string("readers.las.X")); options.add("y_dim", std::string("readers.las.Y")); options.add("z_dim", std::string("readers.las.Z")); options.add("scale_x", 0.0000001f); options.add("scale_y", 0.0000001f); options.add("filename", Support::datapath("las/1.2-with-color.las")); std::istream* wkt_stream = FileUtils::openFile( Support::datapath("autzen/autzen-selection-dd.wkt")); std::stringstream strbuf; strbuf << wkt_stream->rdbuf(); std::string wkt(strbuf.str()); Option polygon("polygon", wkt); options.add(polygon); LasReader reader; reader.setOptions(options); ReprojectionFilter reprojection; reprojection.setOptions(options); reprojection.setInput(reader); CropFilter crop; crop.setOptions(options); crop.setInput(reprojection); PointTable table; PointViewPtr view(new PointView(table)); crop.prepare(table); PointViewSet viewSet = crop.execute(table); EXPECT_EQ(viewSet.size(), 1u); view = *viewSet.begin(); EXPECT_EQ(view->size(), 47u); FileUtils::closeFile(wkt_stream); }
TEST(OptionsTest, conditional) { CropFilter s; Options ops; ops.add("foo", "foo"); ops.add("bar", "bar"); ops.add("baz", "baz"); s.setOptions(ops); Options condOps; condOps.add("foo", "lose"); condOps.add("bar", "lose"); condOps.add("baz", "lose"); condOps.add("foot", "win"); condOps.add("barf", "win"); condOps.add("bazel", "win"); s.addConditionalOptions(condOps); EXPECT_EQ(s.getOptions().getOptions().size(), 6U); }
TEST(CropFilterTest, test_crop_polygon) { #ifdef PDAL_HAVE_GEOS Options ops1; ops1.add("filename", Support::datapath("las/1.2-with-color.las")); LasReader reader; reader.setOptions(ops1); Options options; Option debug("debug", true, ""); Option verbose("verbose", 9, ""); std::istream* wkt_stream = FileUtils::openFile(Support::datapath("autzen/autzen-selection.wkt")); std::stringstream strbuf; strbuf << wkt_stream->rdbuf(); std::string wkt(strbuf.str()); Option polygon("polygon", wkt, ""); options.add(polygon); CropFilter crop; crop.setInput(reader); crop.setOptions(options); PointTable table; crop.prepare(table); PointViewSet viewSet = crop.execute(table); EXPECT_EQ(viewSet.size(), 1u); PointViewPtr view = *viewSet.begin(); EXPECT_EQ(view->size(), 47u); FileUtils::closeFile(wkt_stream); #endif }
TEST(RialtoWriterTest, testRandom) { static const int K = 1000; static const int M = 1000 * K; static const int NUM_POINTS = 100 * K; static const int NUM_QUERIES = 100; const std::string filename(Support::temppath("rialto3.gpkg")); FileUtils::deleteFile(filename); RialtoTest::Data* actualData; const uint32_t maxLevel = 5; // make a test database { PointTable table; PointViewPtr inputView(new PointView(table)); actualData = RialtoTest::randomDataInit(table, inputView, NUM_POINTS); RialtoTest::createDatabase(table, inputView, filename, maxLevel); } // now read from it { LogPtr log(new Log("rialtowritertest", "stdout")); PointViewSet views; PointViewPtr view; RialtoReader reader; Options options; options.add("filename", filename); //options.add("verbose", LogLevel::Debug); reader.setOptions(options); for (int i=0; i<NUM_QUERIES; i++) { double minx = Utils::random(-179.9, 179.9); double maxx = Utils::random(-179.9, 179.9); if (minx > maxx) std::swap(minx, maxx); double miny = Utils::random(-89.9, 89.9); double maxy = Utils::random(-89.9, 89.9); if (miny > maxy) std::swap(miny, maxy); const double minz = -999999.0; const double maxz = 999999.0; BOX3D bounds(minx, miny, minz, maxx, maxy, maxz); options.remove("bounds"); options.add("bounds", bounds); reader.setOptions(options); CropFilter crop; Options co; co.add("bounds", bounds); crop.setInput(reader); crop.setOptions(co); PointTable table; crop.prepare(table); views = crop.execute(table); EXPECT_EQ(views.size(), 1u); view = *(views.begin()); uint32_t c = view->size(); //RialtoTest::verifyPointsInBounds(view, minx, miny, maxx, maxy); uint32_t expected = RialtoTest::countPointsInBounds(actualData, NUM_POINTS, minx, miny, maxx, maxy); EXPECT_EQ(expected, view->size()); } } delete[] actualData; FileUtils::deleteFile(filename); }
TEST(CropFilterTest, stream) { using namespace Dimension; FixedPointTable table(2); table.layout()->registerDim(Id::X); table.layout()->registerDim(Id::Y); table.layout()->registerDim(Id::Z); class StreamReader : public Reader { public: std::string getName() const { return "readers.stream"; } bool processOne(PointRef& point) { static int i = 0; if (i == 0) { point.setField(Id::X, 2); point.setField(Id::Y, 2); } else if (i == 1) { point.setField(Id::X, 6); point.setField(Id::Y, 2); } else if (i == 2) { point.setField(Id::X, 8); point.setField(Id::Y, 2); } else if (i == 3) { point.setField(Id::X, 10); point.setField(Id::Y, 2); } else if (i == 4) { point.setField(Id::X, 12); point.setField(Id::Y, 2); } else return false; i++; return true; } }; StreamReader r; 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); auto cb = [](PointRef& point) { static int i = 0; if (i == 0) { EXPECT_EQ(point.getFieldAs<int>(Id::X), 2); EXPECT_EQ(point.getFieldAs<int>(Id::Y), 2); } if (i == 1) { EXPECT_EQ(point.getFieldAs<int>(Id::X), 6); EXPECT_EQ(point.getFieldAs<int>(Id::Y), 2); } if (i == 2) { EXPECT_EQ(point.getFieldAs<int>(Id::X), 10); EXPECT_EQ(point.getFieldAs<int>(Id::Y), 2); } else return false; i++; return true; }; StreamCallbackFilter f; f.setCallback(cb); f.setInput(crop); f.prepare(table); f.execute(table); }
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); }
TEST(CropFilterTest, test_crop_polygon_reprojection) { #ifdef PDAL_HAVE_GEOS Options options; Option in_srs("spatialreference",Support::datapath("autzen/autzen-srs.wkt"), "Input SRS"); Option out_srs("out_srs","EPSG:4326", "Output SRS to reproject to"); Option x_dim("x_dim", std::string("readers.las.X"), "Dimension name to use for 'X' data"); Option y_dim("y_dim", std::string("readers.las.Y"), "Dimension name to use for 'Y' data"); Option z_dim("z_dim", std::string("readers.las.Z"), "Dimension name to use for 'Z' data"); Option x_scale("scale_x", 0.0000001f, "Scale for output X data " "in the case when 'X' dimension data are to be scaled. Defaults " "to '1.0'. If not set, the Dimensions's scale will be used"); Option y_scale("scale_y", 0.0000001f, "Scale for output Y data " "in the case when 'Y' dimension data are to be scaled. Defaults " "to '1.0'. If not set, the Dimensions's scale will be used"); Option filename("filename", Support::datapath("las/1.2-with-color.las")); Option debug("debug", true, ""); Option verbose("verbose", 9, ""); // options.add(debug); // options.add(verbose); options.add(in_srs); options.add(out_srs); options.add(x_dim); options.add(y_dim); options.add(z_dim); options.add(x_scale); options.add(y_scale); options.add(filename); std::istream* wkt_stream = FileUtils::openFile( Support::datapath("autzen/autzen-selection-dd.wkt")); std::stringstream strbuf; strbuf << wkt_stream->rdbuf(); std::string wkt(strbuf.str()); Option polygon("polygon", wkt, ""); options.add(polygon); LasReader reader; reader.setOptions(options); ReprojectionFilter reprojection; reprojection.setOptions(options); reprojection.setInput(reader); CropFilter crop; crop.setOptions(options); crop.setInput(reprojection); PointTable table; PointViewPtr view(new PointView(table)); crop.prepare(table); PointViewSet viewSet = crop.execute(table); EXPECT_EQ(viewSet.size(), 1u); view = *viewSet.begin(); EXPECT_EQ(view->size(), 47u); FileUtils::closeFile(wkt_stream); #endif }