diff --git a/include/pdal/PointView.hpp b/include/pdal/PointView.hpp index 3e002cb03a..6cad1b5533 100644 --- a/include/pdal/PointView.hpp +++ b/include/pdal/PointView.hpp @@ -56,17 +56,18 @@ namespace plang class BufferedInvocation; } +struct PointViewLess; class PointView; class PointViewIter; typedef std::shared_ptr PointViewPtr; -typedef std::set PointViewSet; +typedef std::set PointViewSet; class PDAL_DLL PointView { friend class plang::BufferedInvocation; friend class PointRef; - friend bool operator < (const PointViewPtr& p1, const PointViewPtr& p2); + friend struct PointViewLess; public: PointView(PointTableRef pointTable) : m_pointTable(pointTable), m_size(0), m_id(0) @@ -81,6 +82,9 @@ class PDAL_DLL PointView PointViewIter begin(); PointViewIter end(); + int id() const + { return m_id; } + point_count_t size() const { return m_size; } @@ -263,9 +267,11 @@ class PDAL_DLL PointView { m_temps.push(id); } }; -inline bool operator < (const PointViewPtr& p1, const PointViewPtr& p2) - { return p1->m_id < p2->m_id; } - +struct PointViewLess +{ + bool operator () (const PointViewPtr& p1, const PointViewPtr& p2) const + { return p1->m_id < p2->m_id; } +}; template T PointView::getFieldInternal(Dimension::Id::Enum dim, PointId id) const diff --git a/plugins/nitf/io/NitfWriter.cpp b/plugins/nitf/io/NitfWriter.cpp index c33c843a9c..2020f07713 100644 --- a/plugins/nitf/io/NitfWriter.cpp +++ b/plugins/nitf/io/NitfWriter.cpp @@ -229,11 +229,25 @@ void NitfWriter::done(PointTableRef table) BOX3D bounds = reprojectBoxToDD(table.spatialRef(), m_bounds); + //NITF decimal degree values for corner coordinates only has a + // precision of 3 after the decimal. This may cause an invalid + // polygon due to rounding errors with a small tile. Therefore + // instead of rounding min values will use the floor value and + // max values will use the ceiling values. + bounds.minx = (floor(bounds.minx * 1000)) / 1000.0; + bounds.miny = (floor(bounds.miny * 1000)) / 1000.0; + bounds.maxx = (ceil(bounds.maxx * 1000)) / 1000.0; + bounds.maxy = (ceil(bounds.maxy * 1000)) / 1000.0; + double corners[4][2]; - corners[0][0] = bounds.maxy; corners[0][1] = bounds.minx; - corners[1][0] = bounds.maxy; corners[1][1] = bounds.maxx; - corners[2][0] = bounds.miny; corners[2][1] = bounds.maxx; - corners[3][0] = bounds.miny; corners[3][1] = bounds.minx; + corners[0][0] = bounds.maxy; + corners[0][1] = bounds.minx; + corners[1][0] = bounds.maxy; + corners[1][1] = bounds.maxx; + corners[2][0] = bounds.miny; + corners[2][1] = bounds.maxx; + corners[3][0] = bounds.miny; + corners[3][1] = bounds.minx; subheader.setCornersFromLatLons(NRT_CORNERS_DECIMAL, corners); subheader.getImageSecurityClass().set(m_imgSecurityClass); diff --git a/plugins/oci/test/OCITest.cpp b/plugins/oci/test/OCITest.cpp index 37e14d392d..4345967059 100644 --- a/plugins/oci/test/OCITest.cpp +++ b/plugins/oci/test/OCITest.cpp @@ -90,17 +90,22 @@ Options getOCIOptions() class SplitFilter : public Filter { public: + SplitFilter(point_count_t viewSize = 100) : m_viewSize(viewSize) + {} + virtual std::string getName() const { return "split_filter"; } private: + point_count_t m_viewSize; + virtual PointViewSet run(PointViewPtr view) { PointViewSet out; PointViewPtr v = view->makeNew(); for (PointId i = 0; i < view->size(); ++i) { - if (i && (i % 100 == 0)) + if (i && (i % m_viewSize == 0)) { out.insert(v); v = v->makeNew(); @@ -182,6 +187,51 @@ class OCITest : public testing::Test }; +/** +TEST_F(OCITest, throughput) +{ + Options options; + + options.add("capacity", 10000); + options.add("connection", std::string(TestConfig::g_oracle_connection)); + options.add("block_table_name", "PDAL_TEST_BLOCKS"); + options.add("base_table_name", "PDAL_TEST_BASE"); + options.add("cloud_column_name", "CLOUD"); + options.add("srid", 26910); + options.add("disable_cloud_trigger", true); + options.add("store_dimensional_orientation", false); + options.add("filename", "/Volumes/acbell-lidar1/big.ntf"); + + { + options.add("offset_x", "auto"); + options.add("offset_y", "auto"); + options.add("offset_z", "auto"); + options.add("scale_x", 1e-6); + options.add("scale_y", 1e-6); + options.add("scale_z", 1e-6); + } + //if (compression) + options.add("compression", true); + + PointTable table; + + StageFactory f; + std::unique_ptr reader(f.createStage("readers.nitf")); + reader->setOptions(options); + + SplitFilter split(10000); + split.setInput(*reader); + + std::unique_ptr writer(f.createStage("writers.oci")); + EXPECT_TRUE(writer.get()); + writer->setOptions(options); + writer->setInput(split); + + writer->prepare(table); + writer->execute(table); +} +***/ + void writeData(Orientation::Enum orient, bool scaling, bool compression = false) { @@ -197,7 +247,6 @@ void writeData(Orientation::Enum orient, bool scaling, bool compression = false) options.add("disable_cloud_trigger", true); options.add("store_dimensional_orientation", orient == Orientation::DimensionMajor); - options.add("filename", Support::datapath("autzen/autzen-utm.las")); if (scaling) { options.add("offset_x", "auto"); @@ -212,9 +261,12 @@ void writeData(Orientation::Enum orient, bool scaling, bool compression = false) PointTable table; + Options readerOps; + readerOps.add("filename", Support::datapath("autzen/autzen-utm.las")); + StageFactory f; LasReader reader; - reader.setOptions(options); + reader.setOptions(readerOps); SplitFilter split; split.setInput(reader); @@ -348,161 +400,3 @@ TEST_F(OCITest, point_major_scaled) readData(); } - -// TEST_F(OCITest, read_view_reproj) -// { -// if (!ShouldRunTest()) return; -// -// WriteDefaultData(); -// -// std::ostringstream oss; -// -// oss << "SELECT l.\"OBJ_ID\", l.\"BLK_ID\", l.\"BLK_EXTENT\", l.\"BLK_DOMAIN\"," -// " l.\"PCBLK_MIN_RES\", l.\"PCBLK_MAX_RES\", l.\"NUM_POINTS\"," -// " l.\"NUM_UNSORTED_POINTS\", l.\"PT_SORT_DIM\", l.\"POINTS\", b.cloud " -// "FROM PDAL_TEST_BLOCKS l, PDAL_TEST_BASE b " -// "WHERE b.id=1 and l.obj_id = b.id " -// "ORDER BY l.obj_id "; -// Options options = getOCIOptions(); -// Option& query = options.getOptionByRef("query"); -// query.setValue(oss.str()); -// -// Option& out_srs = options.getOptionByRef("out_srs"); -// out_srs.setValue("EPSG:26910"); -// -// Option& x_scale = options.getOptionByRef("scale_x"); -// x_scale.setValue(0.01); -// -// Option& y_scale = options.getOptionByRef("scale_y"); -// y_scale.setValue(0.01); -// -// // Option& offset_x = options.getOptionByRef("offset_x"); -// // offset_x.setValue( -123.0749695f); -// // offset_x.setValue( 0.0f); -// -// // Option& offset_y = options.getOptionByRef("offset_y"); -// // offset_y.setValue( 44.0500086f); -// // offset_y.setValue( 0.0f); -// -// -// Option x_dim("x_dim", std::string("readers.oci.X"), "Dimension name to use for 'X' data"); -// Option y_dim("y_dim", std::string("readers.oci.Y"), "Dimension name to use for 'Y' data"); -// Option z_dim("z_dim", std::string("readers.oci.Z"), "Dimension name to use for 'Z' data"); -// -// options.add(x_dim); -// options.add(y_dim); -// options.add(z_dim); -// -// Option& debug = options.getOptionByRef("debug"); -// debug.setValue( "true"); -// -// OciReader reader_reader(options); -// // filters::InPlaceReprojection reproj(reader_reader, options); -// reader_reader.prepare(); -// -// PointViewPtr data(reader_reader.getSchema(), chunk_size+30); -// StageSequentialIterator* iter = reader_reader.createSequentialIterator(data); -// -// uint32_t numRead(0); -// -// numRead = iter->read(data); -// -// EXPECT_EQ(numRead, chunk_size+30u); -// EXPECT_EQ(view->getNumPoints(), chunk_size+30u); -// -// checkPoints(data); -// -// delete iter; -// -// } - -// -// TEST_F(OCITest, read_all) -// { -// if (!ShouldRunTest()) return; -// -// WriteDefaultData(); -// WriteDefaultData(); -// -// std::ostringstream oss; -// -// oss << "SELECT CLOUD FROM PDAL_TEST_BASE"; -// Options options = getOCIOptions(); -// Option& query = options.getOptionByRef("query"); -// query.setValue(oss.str()); -// OciReader reader_reader(options); -// reader_reader.prepare(); -// -// PointViewPtr data(reader_reader.getSchema(), 2500); -// std::unique_ptr iter(reader_reader.createSequentialIterator(data)); -// -// -// uint32_t numRead = iter->read(data); -// -// EXPECT_EQ(numRead, 2130u); -// -// Schema const& schema = view->getSchema(); -// Dimension const& dimX = schema.getDimension("X"); -// Dimension const& dimY = schema.getDimension("Y"); -// Dimension const& dimZ = schema.getDimension("Z"); -// Dimension const& dimIntensity = schema.getDimension("Intensity"); -// Dimension const& dimRed = schema.getDimension("Red"); -// -// int32_t x = view->getFieldAs(dimX, 0); -// int32_t y = view->getFieldAs(dimY, 0); -// int32_t z = view->getFieldAs(dimZ, 0); -// uint16_t intensity = view->getFieldAs(dimIntensity, 6); -// uint16_t red = view->getFieldAs(dimRed, 6); -// -// EXPECT_EQ(x, -1250367506); -// EXPECT_EQ(y, 492519663); -// EXPECT_EQ(z, 12931); -// EXPECT_EQ(intensity, 67); -// EXPECT_EQ(red, 113); -// -// } -// - -// TEST_F(OCITest, read_view) -// { -// if (!ShouldRunTest()) return; -// -// WriteDefaultData(); -// -// std::ostringstream oss; -// -// oss << "SELECT l.\"OBJ_ID\", l.\"BLK_ID\", l.\"BLK_EXTENT\", l.\"BLK_DOMAIN\"," -// " l.\"PCBLK_MIN_RES\", l.\"PCBLK_MAX_RES\", l.\"NUM_POINTS\"," -// " l.\"NUM_UNSORTED_POINTS\", l.\"PT_SORT_DIM\", l.\"POINTS\", b.cloud " -// "FROM PDAL_TEST_BLOCKS l, PDAL_TEST_BASE b " -// "WHERE b.id=1 and l.obj_id = b.id " -// "ORDER BY l.obj_id "; -// Options options = getOCIOptions(); -// Option& query = options.getOptionByRef("query"); -// query.setValue(oss.str()); -// OciReader reader_reader(options); -// reader_reader.prepare(); -// -// PointViewPtr data(reader_reader.getSchema(), chunk_size+30); -// std::unique_ptr iter(reader_reader.createSequentialIterator(data)); -// -// -// uint32_t numTotal(0); -// uint32_t numRead(0); -// -// PointViewPtr data3(reader_reader.getSchema(), 100); -// numRead = iter->read(data3); -// EXPECT_EQ(numRead, 100u); -// numTotal = numRead + numTotal; -// -// while (numRead !=0) -// { -// numRead = iter->read(data3); -// numTotal = numRead + numTotal; -// -// } -// -// EXPECT_EQ(numRead, 0u); -// EXPECT_EQ(numTotal, 1065u); -// -// } diff --git a/test/unit/PointViewTest.cpp b/test/unit/PointViewTest.cpp index 7484e6457e..462fb9980b 100644 --- a/test/unit/PointViewTest.cpp +++ b/test/unit/PointViewTest.cpp @@ -416,33 +416,29 @@ TEST(PointViewTest, calcBounds) check_bounds(box_bs, 0.0, 3.0, 0.0, 3.0, 0.0, 3.0); } -/** -TEST(PointViewTest, sort) +TEST(PointViewTest, order) { PointTable table; - PointView view(table); - const PointId NUM_PTS = 10000; - - auto cmp = [](const PointRef& p1, const PointRef& p2) - { - return p1.compare(Dimension::Id::X, p2); - }; - table->layout()->registerDim(Dimension::Id::X); + const size_t COUNT(1000); + std::array views; - std::default_random_engine generator; - std::uniform_real_distribution dist(0.0, 10000.0); - for (PointId i = 0; i < NUM_PTS; ++i) - view.setField(Dimension::Id::X, i, dist(generator)); + 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); - std::sort(view.begin(), view.end(), cmp); + PointViewSet set; + for (size_t i = 0; i < COUNT; ++i) + set.insert(views[i]); - for (PointId i = 1; i < NUM_PTS; ++i) + PointViewSet::iterator pi; + for (auto si = set.begin(); si != set.end(); ++si) { - double d1 = view.getFieldAs(Dimension::Id::X, i - 1); - double d2 = view.getFieldAs(Dimension::Id::X, i); - EXPECT_TRUE(d1 <= d2); + if (si != set.begin()) + EXPECT_TRUE((*pi)->id() < (*si)->id()); + pi = si; } } -**/ -