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); }
// Make sure that spatialreference works for random readers TEST(json, issue_2159) { class XReader : public Reader { std::string getName() const { return "readers.x"; } virtual void addDimensions(PointLayoutPtr layout) { using namespace Dimension; layout->registerDims( { Id::X, Id::Y, Id::Z } ); } virtual point_count_t read(PointViewPtr v, point_count_t count) { using namespace Dimension; for (PointId idx = 0; idx < count; ++idx) { v->setField(Id::X, idx, idx); v->setField(Id::Y, idx, 10 * idx); v->setField(Id::Z, idx, 1.152); } return count; } }; XReader xr; Options rOpts; rOpts.add("count", "1000"); rOpts.add("spatialreference", "EPSG:4326"); xr.setOptions(rOpts); StatsFilter f; f.setInput(xr); PointTable t; f.prepare(t); PointViewSet s = f.execute(t); PointViewPtr v = *(s.begin()); SpatialReference srs = v->spatialReference(); EXPECT_EQ(srs, SpatialReference("EPSG:4326")); }
TEST(Stats, dimset) { BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0); Options ops; ops.add("bounds", bounds); ops.add("count", 1000); ops.add("mode", "constant"); StageFactory f; std::unique_ptr<Stage> reader(f.createStage("readers.faux")); EXPECT_TRUE(reader.get()); reader->setOptions(ops); Options filterOps; filterOps.add("dimensions", " , X, Z "); StatsFilter filter; filter.setInput(*reader); filter.setOptions(filterOps); EXPECT_EQ(filter.getName(), "filters.stats"); PointTable table; filter.prepare(table); filter.execute(table); const stats::Summary& statsX = filter.getStats(Dimension::Id::X); EXPECT_THROW(filter.getStats(Dimension::Id::Y), pdal_error); const stats::Summary& statsZ = filter.getStats(Dimension::Id::Z); EXPECT_EQ(statsX.count(), 1000u); EXPECT_EQ(statsZ.count(), 1000u); EXPECT_FLOAT_EQ(statsX.minimum(), 1.0); EXPECT_FLOAT_EQ(statsZ.minimum(), 3.0); EXPECT_FLOAT_EQ(statsX.maximum(), 1.0); EXPECT_FLOAT_EQ(statsZ.maximum(), 3.0); EXPECT_FLOAT_EQ(statsX.average(), 1.0); EXPECT_FLOAT_EQ(statsZ.average(), 3.0); }
TEST(Stats, metadata) { BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0); Options ops; ops.add("bounds", bounds); ops.add("count", 1000); ops.add("mode", "constant"); StageFactory f; std::unique_ptr<Stage> reader(f.createStage("readers.faux")); EXPECT_TRUE(reader.get()); reader->setOptions(ops); Options filterOps; filterOps.add("dimensions", " , X, Z "); StatsFilter filter; filter.setInput(*reader); filter.setOptions(filterOps); PointTable table; filter.prepare(table); filter.execute(table); MetadataNode m = filter.getMetadata(); std::vector<MetadataNode> children = m.children("statistic"); auto findNode = [](MetadataNode m, const std::string name, const std::string val) { auto findNameVal = [name, val](MetadataNode m) { return (m.name() == name && m.value() == val); }; return m.find(findNameVal); }; for (auto mi = children.begin(); mi != children.end(); ++mi) { if (findNode(*mi, "name", "X").valid()) { EXPECT_DOUBLE_EQ(mi->findChild("average").value<double>(), 1.0); EXPECT_DOUBLE_EQ(mi->findChild("minimum").value<double>(), 1.0); EXPECT_DOUBLE_EQ(mi->findChild("maximum").value<double>(), 1.0); EXPECT_DOUBLE_EQ(mi->findChild("count").value<double>(), 1000.0); } if (findNode(*mi, "name", "Z").valid()) { EXPECT_DOUBLE_EQ(mi->findChild("average").value<double>(), 3.0); EXPECT_DOUBLE_EQ(mi->findChild("minimum").value<double>(), 3.0); EXPECT_DOUBLE_EQ(mi->findChild("maximum").value<double>(), 3.0); EXPECT_DOUBLE_EQ(mi->findChild("count").value<double>(), 1000.0); } } }
TEST(Stats, stream) { BOX3D bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0); Options ops; ops.add("bounds", bounds); ops.add("count", 1000); ops.add("mode", "constant"); StageFactory f; Stage* reader(f.createStage("readers.faux")); EXPECT_TRUE(reader); reader->setOptions(ops); StatsFilter filter; filter.setInput(*reader); EXPECT_EQ(filter.getName(), "filters.stats"); FixedPointTable table(100); filter.prepare(table); filter.execute(table); const stats::Summary& statsX = filter.getStats(Dimension::Id::X); const stats::Summary& statsY = filter.getStats(Dimension::Id::Y); const stats::Summary& statsZ = filter.getStats(Dimension::Id::Z); EXPECT_EQ(statsX.count(), 1000u); EXPECT_EQ(statsY.count(), 1000u); EXPECT_EQ(statsZ.count(), 1000u); EXPECT_FLOAT_EQ(statsX.minimum(), 1.0); EXPECT_FLOAT_EQ(statsY.minimum(), 2.0); EXPECT_FLOAT_EQ(statsZ.minimum(), 3.0); EXPECT_FLOAT_EQ(statsX.maximum(), 1.0); EXPECT_FLOAT_EQ(statsY.maximum(), 2.0); EXPECT_FLOAT_EQ(statsZ.maximum(), 3.0); EXPECT_FLOAT_EQ(statsX.average(), 1.0); EXPECT_FLOAT_EQ(statsY.average(), 2.0); EXPECT_FLOAT_EQ(statsZ.average(), 3.0); }
{ BOX3D bounds(1.0, 0.0, 0.0, 10.0, 100.0, 1000.0); Options ops; ops.add("bounds", bounds); ops.add("count", 10); ops.add("mode", "ramp"); FauxReader reader; reader.setOptions(ops); Options filterOps; filterOps.add("dimensions", "X, Y, Z"); filterOps.add("enumerate", "X"); filterOps.add("count", "Y"); StatsFilter filter; filter.setInput(reader); filter.setOptions(filterOps); PointTable table; filter.prepare(table); filter.execute(table); const stats::Summary& statsX = filter.getStats(Dimension::Id::X); const stats::Summary::EnumMap& values = statsX.values(); EXPECT_EQ(values.size(), 10U); double d = 1.0; for (auto& v : values) { EXPECT_DOUBLE_EQ(d, v.first); d += 1.0;