PointViewSet Stage::execute(PointTableRef table) { //printf("called %s\n", this->classname()); log()->setLevel(LogLevel::Enum::Debug); std::string cn(this->classname()); log()->setLeader(cn + " Stage::execute"); log()->get(LogLevel::Debug) << "Called by class " << std::endl; table.layout()->finalize(); PointViewSet views; if (m_inputs.empty()) { log()->get(LogLevel::Debug) << "if block, class" << std::endl; views.insert(PointViewPtr(new PointView(table))); } else { for (size_t i = 0; i < m_inputs.size(); ++i) { log()->get(LogLevel::Debug) << "block, class" << "input number "<< i << std::endl; log()->get(LogLevel::Debug) << "if block, class" << std::endl; Stage *prev = m_inputs[i]; PointViewSet temp = prev->execute(table); views.insert(temp.begin(), temp.end()); } } PointViewSet outViews; std::vector<StageRunnerPtr> runners; ready(table); for (auto const& it : views) { log()->get(LogLevel::Debug) << "run, class" << std::endl; StageRunnerPtr runner(new StageRunner(this, it)); runners.push_back(runner); runner->run(); } for (auto const& it : runners) { log()->get(LogLevel::Debug) << "wait, class" << std::endl; StageRunnerPtr runner(it); PointViewSet temp = runner->wait(); outViews.insert(temp.begin(), temp.end()); } l_done(table); done(table); return outViews; }
TEST(PointViewTest, order) { PointTable table; const size_t COUNT(1000); std::array<PointViewPtr, COUNT> views; std::random_device dev; std::mt19937 generator(dev()); for (size_t i = 0; i < COUNT; ++i) views[i] = PointViewPtr(new PointView(table)); std::shuffle(views.begin(), views.end(), generator); PointViewSet set; for (size_t i = 0; i < COUNT; ++i) set.insert(views[i]); PointViewSet::iterator pi; for (auto si = set.begin(); si != set.end(); ++si) { if (si != set.begin()) EXPECT_TRUE((*pi)->id() < (*si)->id()); pi = si; } }
void PointView::calculateBounds(const PointViewSet& set, BOX3D& output) { for (auto iter = set.begin(); iter != set.end(); ++iter) { PointViewPtr buf = *iter; buf->calculateBounds(output); } }
TEST(ChipperTest, test_construction) { PointTable table; Options ops1; std::string filename(Support::datapath("las/1.2-with-color.las")); ops1.add("filename", filename); LasReader reader; reader.setOptions(ops1); { // need to scope the writer, so that's it dtor can use the stream Options options; Option capacity("capacity", 15, "capacity"); options.add(capacity); ChipperFilter chipper; chipper.setInput(reader); chipper.setOptions(options); chipper.prepare(table); PointViewSet viewSet = chipper.execute(table); EXPECT_EQ(viewSet.size(), 71u); std::vector<PointViewPtr> views; for (auto it = viewSet.begin(); it != viewSet.end(); ++it) views.push_back(*it); auto sorter = [](PointViewPtr p1, PointViewPtr p2) { //This is super inefficient, but we're doing tests. BOX3D b1 = p1->calculateBounds(); BOX3D b2 = p2->calculateBounds(); return b1.minx < b2.minx ? true : b1.minx > b2.minx ? false : b1.miny < b2.miny; }; std::sort(views.begin(), views.end(), sorter); auto view = views[2]; auto bounds = view->calculateBounds(); EXPECT_NEAR(bounds.minx, 635674.05, 0.05); EXPECT_NEAR(bounds.maxx, 635993.93, 0.05); EXPECT_NEAR(bounds.miny, 848992.45, 0.05); EXPECT_NEAR(bounds.maxy, 849427.07, 0.05); for (size_t i = 0; i < views.size(); ++i) EXPECT_EQ(views[i]->size(), 15u); } }
TEST(SplitterTest, test_buffer) { Options readerOptions; readerOptions.add("filename", Support::datapath("las/1.2-with-color.las")); LasReader reader; reader.setOptions(readerOptions); Options splitterOptions; splitterOptions.add("length", 1000); splitterOptions.add("buffer", 20); SplitterFilter splitter; splitter.setOptions(splitterOptions); splitter.setInput(reader); PointTable table; splitter.prepare(table); PointViewSet viewSet = splitter.execute(table); std::vector<PointViewPtr> views; std::map<PointViewPtr, BOX2D> bounds; for (auto it = viewSet.begin(); it != viewSet.end(); ++it) { BOX2D b; PointViewPtr v = *it; v->calculateBounds(b); EXPECT_TRUE(b.maxx - b.minx <= 1040); EXPECT_TRUE(b.maxy - b.miny <= 1040); bounds[v] = b; views.push_back(v); } auto sorter = [&bounds](PointViewPtr p1, PointViewPtr p2) { BOX2D b1 = bounds[p1]; BOX2D b2 = bounds[p2]; return b1.minx < b2.minx ? true : b1.minx > b2.minx ? false : b1.miny < b2.miny; }; std::sort(views.begin(), views.end(), sorter); EXPECT_EQ(views.size(), 24u); size_t counts[] = {26, 26, 3, 28, 27, 13, 14, 65, 80, 47, 80, 89, 94, 77, 5, 79, 65, 34, 63, 67, 74, 69, 36, 5}; size_t i = 0; for (PointViewPtr view : views) EXPECT_EQ(view->size(), counts[i++]); }
cpd::Matrix CpdKernel::readFile(const std::string& filename) { Stage& reader = makeReader(filename, ""); PointTable table; PointViewSet viewSet; if (!m_bounds.empty()) { Options boundsOptions; boundsOptions.add("bounds", m_bounds); Stage& crop = makeFilter("filters.crop", reader); crop.setOptions(boundsOptions); crop.prepare(table); viewSet = crop.execute(table); } else { reader.prepare(table); viewSet = reader.execute(table); } cpd::Matrix matrix(0, 3); for (auto it = viewSet.begin(); it != viewSet.end(); ++it) { PointViewPtr view = *it; point_count_t rowidx; if (matrix.rows() == 0) { rowidx = 0; matrix.resize(view->size(), 3); } else { rowidx = matrix.rows(); matrix.conservativeResize(matrix.rows() + view->size(), 3); } for (point_count_t bufidx = 0; bufidx < view->size(); ++bufidx, ++rowidx) { matrix(rowidx, 0) = view->getFieldAs<double>(Dimension::Id::X, bufidx); matrix(rowidx, 1) = view->getFieldAs<double>(Dimension::Id::Y, bufidx); matrix(rowidx, 2) = view->getFieldAs<double>(Dimension::Id::Z, bufidx); } } return matrix; }
TEST(SplitterTest, test_tile_filter) { StageFactory f; // create the reader Options ops1; ops1.add("filename", Support::datapath("las/1.2-with-color.las")); LasReader r; r.setOptions(ops1); Options o; Option length("length", 1000); o.add(length); // create the tile filter and prepare SplitterFilter s; s.setOptions(o); s.setInput(r); PointTable table; s.prepare(table); PointViewSet viewSet = s.execute(table); std::vector<PointViewPtr> views; std::map<PointViewPtr, BOX2D> bounds; for (auto it = viewSet.begin(); it != viewSet.end(); ++it) { BOX2D b; PointViewPtr v = *it; v->calculateBounds(b); EXPECT_TRUE(b.maxx - b.minx <= 1000); EXPECT_TRUE(b.maxy - b.miny <= 1000); for (auto& p : bounds) EXPECT_FALSE(p.second.overlaps(b)); bounds[v] = b; views.push_back(v); } auto sorter = [&bounds](PointViewPtr p1, PointViewPtr p2) { BOX2D b1 = bounds[p1]; BOX2D b2 = bounds[p2]; return b1.minx < b2.minx ? true : b1.minx > b2.minx ? false : b1.miny < b2.miny; }; std::sort(views.begin(), views.end(), sorter); EXPECT_EQ(views.size(), 24u); size_t counts[] = {24, 25, 2, 26, 27, 10, 82, 68, 43, 57, 7, 71, 73, 61, 33, 84, 74, 4, 59, 70, 67, 34, 60, 4 }; for (size_t i = 0; i < views.size(); ++i) { PointViewPtr view = views[i]; EXPECT_EQ(view->size(), counts[i]); } }
PointViewSet Stage::execute(PointTableRef table) { table.finalize(); PointViewSet views; // If the inputs are empty, we're a reader. if (m_inputs.empty()) { views.insert(PointViewPtr(new PointView(table))); } else { for (size_t i = 0; i < m_inputs.size(); ++i) { Stage *prev = m_inputs[i]; PointViewSet temp = prev->execute(table); views.insert(temp.begin(), temp.end()); } } PointViewSet outViews; std::vector<StageRunnerPtr> runners; // Put the spatial references from the views onto the table. // The table's spatial references are only valid as long as the stage // is running. // ABELL - Should we clear the references once the stage run has // completed? Wondering if that would break something where a // writer wants to check a table's SRS. SpatialReference srs; table.clearSpatialReferences(); for (auto const& it : views) table.addSpatialReference(it->spatialReference()); // Do the ready operation and then start running all the views // through the stage. ready(table); for (auto const& it : views) { StageRunnerPtr runner(new StageRunner(this, it)); runners.push_back(runner); runner->run(); } // As the stages complete (synchronously at this time), propagate the // spatial reference and merge the output views. srs = getSpatialReference(); for (auto const& it : runners) { StageRunnerPtr runner(it); PointViewSet temp = runner->wait(); // If our stage has a spatial reference, the view takes it on once // the stage has been run. if (!srs.empty()) for (PointViewPtr v : temp) v->setSpatialReference(srs); outViews.insert(temp.begin(), temp.end()); } done(table); return outViews; }