From 9a89861b4be54d56924207eac10384ce7c383707 Mon Sep 17 00:00:00 2001 From: Andrew Bell Date: Mon, 29 Dec 2014 09:10:10 -0600 Subject: [PATCH] Changes to support preview of stages and general stats filter changes. --- filters/stats/StatsFilter.cpp | 1 - include/pdal/Metadata.hpp | 64 +++++--- include/pdal/PDALUtils.hpp | 35 ++--- kernels/KernelSupport.cpp | 5 +- kernels/KernelSupport.hpp | 2 +- kernels/info/InfoKernel.cpp | 276 ++++++++++------------------------ kernels/info/InfoKernel.hpp | 18 ++- src/Stage.cpp | 8 +- test/unit/PointBufferTest.cpp | 37 +++-- 9 files changed, 175 insertions(+), 271 deletions(-) diff --git a/filters/stats/StatsFilter.cpp b/filters/stats/StatsFilter.cpp index 7b855884d0..fd1963f912 100644 --- a/filters/stats/StatsFilter.cpp +++ b/filters/stats/StatsFilter.cpp @@ -125,7 +125,6 @@ void StatsFilter::ready(PointContext ctx) void StatsFilter::extractMetadata(PointContext ctx) { - uint32_t position(0); for (auto di = m_stats.begin(); di != m_stats.end(); ++di) diff --git a/include/pdal/Metadata.hpp b/include/pdal/Metadata.hpp index 56352e74c4..c919bd91fe 100644 --- a/include/pdal/Metadata.hpp +++ b/include/pdal/Metadata.hpp @@ -46,7 +46,7 @@ #include #include #include - +#include namespace { @@ -96,7 +96,7 @@ class MetadataNodeImpl private: MetadataNodeImpl(const std::string& name) : m_kind(MetadataType::Instance) { - m_name = sanitize(name); + m_name = sanitize(name); } MetadataNodeImpl() : m_kind(MetadataType::Instance) @@ -264,8 +264,7 @@ inline void MetadataNodeImpl::setValue(const double& d) } template <> -inline void MetadataNodeImpl::setValue( - const SpatialReference& ref) +inline void MetadataNodeImpl::setValue(const SpatialReference& ref) { std::ostringstream oss; oss << ref; @@ -274,7 +273,7 @@ inline void MetadataNodeImpl::setValue( } template <> -inline void MetadataNodeImpl::setValue(const BOX3D& b) +inline void MetadataNodeImpl::setValue(const BOX3D& b) { std::ostringstream oss; oss << b; @@ -283,64 +282,84 @@ inline void MetadataNodeImpl::setValue(const BOX3D& b) } template <> -inline void MetadataNodeImpl::setValue(const uint8_t& u) +inline void MetadataNodeImpl::setValue(const unsigned char& u) { m_type = "nonNegativeInteger"; m_value = boost::lexical_cast((unsigned)u); } template <> -inline void MetadataNodeImpl::setValue(const uint16_t& u) +inline void MetadataNodeImpl::setValue(const unsigned short& u) +{ + m_type = "nonNegativeInteger"; + m_value = boost::lexical_cast(u); +} + +template <> +inline void MetadataNodeImpl::setValue(const unsigned int& u) { m_type = "nonNegativeInteger"; m_value = boost::lexical_cast(u); } template <> -inline void MetadataNodeImpl::setValue(const uint32_t& u) +inline void MetadataNodeImpl::setValue(const unsigned long& u) { m_type = "nonNegativeInteger"; m_value = boost::lexical_cast(u); } template <> -inline void MetadataNodeImpl::setValue(const uint64_t& u) +inline void MetadataNodeImpl::setValue(const unsigned long long& u) { m_type = "nonNegativeInteger"; m_value = boost::lexical_cast(u); } template <> -inline void MetadataNodeImpl::setValue(const int8_t& i) +inline void MetadataNodeImpl::setValue(const char& i) { m_type = "integer"; m_value = boost::lexical_cast((int)i); } template <> -inline void MetadataNodeImpl::setValue(const int16_t& i) +inline void MetadataNodeImpl::setValue(const signed char& i) { m_type = "integer"; - m_value = boost::lexical_cast(i); + m_value = boost::lexical_cast((int)i); } template <> -inline void MetadataNodeImpl::setValue(const int32_t& i) +inline void MetadataNodeImpl::setValue(const short& s) { m_type = "integer"; - m_value = boost::lexical_cast(i); + m_value = boost::lexical_cast(s); } template <> -inline void MetadataNodeImpl::setValue(const int64_t& i) +inline void MetadataNodeImpl::setValue(const int& i) { m_type = "integer"; m_value = boost::lexical_cast(i); } template <> -inline void MetadataNodeImpl::setValue( - const boost::uuids::uuid& u) +inline void MetadataNodeImpl::setValue(const long& l) +{ + m_type = "integer"; + m_value = boost::lexical_cast(l); +} + +template <> +inline void MetadataNodeImpl::setValue(const long long& l) +{ + m_type = "integer"; + m_value = boost::lexical_cast(l); +} + +template <> +inline void MetadataNodeImpl::setValue(const boost::uuids::uuid& u) { std::ostringstream oss; oss << u; @@ -370,6 +389,14 @@ class PDAL_DLL MetadataNode MetadataNode addList(const std::string& name) { return MetadataNode(m_impl->addList(name)); } + MetadataNode clone(const std::string& name) + { + MetadataNode node; + node.m_impl.reset(new MetadataNodeImpl(*m_impl)); + node.m_impl->m_name = name; + return node; + } + MetadataNode add(MetadataNode node) { return MetadataNode(m_impl->add(node.m_impl)); } @@ -624,9 +651,6 @@ class Metadata MetadataNode m_root; MetadataNode m_private; std::string m_name; - - MetadataNode privateNode() const - { return m_private; } }; typedef std::shared_ptr MetadataPtr; diff --git a/include/pdal/PDALUtils.hpp b/include/pdal/PDALUtils.hpp index 3d9565b92a..11d4024ac5 100644 --- a/include/pdal/PDALUtils.hpp +++ b/include/pdal/PDALUtils.hpp @@ -34,6 +34,7 @@ #pragma once +#include #include #include #include @@ -41,7 +42,6 @@ #include #include #include -#include #include namespace pdal @@ -87,24 +87,21 @@ inline ptree toPTree(MetadataNode const& node) } -inline ptree toPTree(PointContextRef ctx) +inline MetadataNode toMetadata(PointContextRef ctx) { - ptree tree; - ptree dimsTree; + MetadataNode root; for (const auto& id : ctx.dims()) { - ptree dim; - dim.put("name", ctx.dimName(id)); + MetadataNode dim("dimensions"); + dim.add("name", ctx.dimName(id)); Dimension::Type::Enum t = ctx.dimType(id); - dim.put("type", Dimension::toName(Dimension::base(t))); - dim.put("size", ctx.dimSize(id)); - dimsTree.push_back(std::make_pair("", dim)); + dim.add("type", Dimension::toName(Dimension::base(t))); + dim.add("size", ctx.dimSize(id)); + root.addList(dim); } - tree.add_child("dimensions", dimsTree); - - return tree; + return root; } @@ -124,27 +121,23 @@ inline ptree toPTree(PointContextRef ctx) \endverbatim */ -inline ptree toPTree(const PointBuffer& buffer) +inline MetadataNode toMetadata(const PointBuffer& buffer) { - - ptree tree; + MetadataNode node; const Dimension::IdList& dims = buffer.dims(); for (PointId idx = 0; idx < buffer.size(); idx++) { - std::string pointstring = boost::lexical_cast(idx) + "."; - + MetadataNode pointnode = node.add(std::to_string(idx)); for (auto di = dims.begin(); di != dims.end(); ++di) { - std::string key = pointstring + Dimension::name(*di); double v = buffer.getFieldAs(*di, idx); - std::string value = boost::lexical_cast(v); - tree.add(key, value); + pointnode.add(Dimension::name(*di), v); } } - return tree; + return node; } /// Outputs a string-based boost::property_tree::ptree representation diff --git a/kernels/KernelSupport.cpp b/kernels/KernelSupport.cpp index e6ad21d9db..716f64d9fd 100644 --- a/kernels/KernelSupport.cpp +++ b/kernels/KernelSupport.cpp @@ -44,10 +44,8 @@ namespace pdal { -PipelineManager* KernelSupport::makePipeline(pdal::Options& options) +PipelineManager* KernelSupport::makePipeline(const std::string& inputFile) { - std::string inputFile = options.getValueOrThrow("filename"); - if (!pdal::FileUtils::fileExists(inputFile)) throw app_runtime_error("file not found: " + inputFile); @@ -67,6 +65,7 @@ PipelineManager* KernelSupport::makePipeline(pdal::Options& options) { StageFactory factory; std::string driver = factory.inferReaderDriver(inputFile); + if (driver.empty()) throw app_runtime_error("Cannot determine input file type of " + inputFile); diff --git a/kernels/KernelSupport.hpp b/kernels/KernelSupport.hpp index cd234ae465..f2d6010531 100644 --- a/kernels/KernelSupport.hpp +++ b/kernels/KernelSupport.hpp @@ -73,7 +73,7 @@ class PDAL_DLL KernelSupport // makes a writer, from just the filename and some other // options (and the input stage) static Writer* makeWriter(const std::string& filename, Stage *stage); - static PipelineManager* makePipeline(Options& options); + static PipelineManager* makePipeline(const std::string& filename); private: KernelSupport& operator=(const KernelSupport&); // not implemented diff --git a/kernels/info/InfoKernel.cpp b/kernels/info/InfoKernel.cpp index 02ac29cdc4..4f1b445447 100644 --- a/kernels/info/InfoKernel.cpp +++ b/kernels/info/InfoKernel.cpp @@ -50,13 +50,12 @@ InfoKernel::InfoKernel() , m_showSchema(false) , m_showStage(false) , m_showMetadata(false) - , m_showSDOPCMetadata(false) , m_computeBoundary(false) , m_useXML(false) , m_useJSON(false) , m_useRST(false) - , m_QueryDistance(0.0) , m_showSummary(false) + , m_statsStage(NULL) {} @@ -66,17 +65,16 @@ void InfoKernel::validateSwitches() m_showStats || m_showSchema || m_showMetadata || - m_showSDOPCMetadata || m_computeBoundary || m_showStage || m_showSummary || m_QueryPoint.size() > 0 || m_pointIndexes.size() > 0; + if (!got_something) { m_showStats = true; m_showSchema = true; - } } @@ -102,7 +100,6 @@ void InfoKernel::addSwitches() ("point,p", po::value(&m_pointIndexes), "point to dump") ("query", po::value< std::string>(&m_QueryPoint), "A 2d or 3d point query point") - ("distance", po::value< double>(&m_QueryDistance), "A query distance") ("stats", po::value(&m_showStats)->zero_tokens()->implicit_value(true), "dump stats on all points (reads entire dataset)") @@ -110,17 +107,13 @@ void InfoKernel::addSwitches() po::value(&m_computeBoundary)->zero_tokens()->implicit_value(true), "compute a hexagonal hull/boundary of dataset") ("dimensions", po::value(&m_Dimensions), - "dump stats on all points (reads entire dataset)") + "dimensions on which to compute statistics") ("schema", po::value(&m_showSchema)->zero_tokens()->implicit_value(true), "dump the schema") ("metadata,m", po::value(&m_showMetadata)->zero_tokens()->implicit_value(true), "dump the metadata") - ("sdo_pc", - po::value(&m_showSDOPCMetadata)->zero_tokens()-> - implicit_value(true), - "dump the SDO_PC Oracle Metadata") ("stage,r", po::value(&m_showStage)->zero_tokens()->implicit_value(true), "dump the stage info") @@ -161,11 +154,10 @@ uint32_t parseInt(const string& s) } -void addRange(const string& begin, const string& end, - vector& points) +void addRange(const string& begin, const string& end, vector& points) { - uint32_t low = parseInt(begin); - uint32_t high = parseInt(end); + PointId low = parseInt(begin); + PointId high = parseInt(end); if (low > high) throw app_runtime_error(string("Range invalid: ") + begin + "-" + end); while (low <= high) @@ -173,9 +165,9 @@ void addRange(const string& begin, const string& end, } -vector getListOfPoints(std::string p) +vector getListOfPoints(std::string p) { - vector output; + vector output; //Remove whitespace from string with awful remove/erase idiom. p.erase(remove_if(p.begin(), p.end(), ::isspace), p.end()); @@ -196,11 +188,13 @@ vector getListOfPoints(std::string p) } //namespace -void InfoKernel::dumpPoints(PointBufferPtr buf) const +MetadataNode InfoKernel::dumpPoints(PointBufferPtr buf) const { + MetadataNode root; PointBufferPtr outbuf = buf->makeNew(); - std::vector points = getListOfPoints(m_pointIndexes); + // Stick points in a buffer. + std::vector points = getListOfPoints(m_pointIndexes); for (size_t i = 0; i < points.size(); ++i) { PointId id = (PointId)points[i]; @@ -208,181 +202,82 @@ void InfoKernel::dumpPoints(PointBufferPtr buf) const outbuf->appendPoint(*buf, id); } - boost::property_tree::ptree buffer_tree = pdal::utils::toPTree(*outbuf); + MetadataNode tree = utils::toMetadata(*outbuf); + std::string prefix("point "); for (size_t i = 0; i < outbuf->size(); ++i) { - std::string name = (std::string)"point " + - boost::lexical_cast(points[i]); - std::string key = boost::lexical_cast(i); - m_tree->add_child(name, buffer_tree.get_child(key)); - } -} - - -void InfoKernel::dumpStats() -{ - PipelineWriter* writer = NULL; - - if (m_pipelineFile.size() > 0) - writer = new pdal::PipelineWriter(*m_manager); - - MetadataNode statsNode("stats"); - - statsNode.add(m_manager->getMetadata()); - - boost::property_tree::ptree stats; - std::stringstream strm; - strm << statsNode.toJSON(); - boost::property_tree::read_json(strm, stats); - m_tree->add_child("stats", stats); - - if (m_pipelineFile.size() > 0) - writer->writePipeline(m_pipelineFile); - delete writer; -} - - -// return a ptree containing min/max for X,Y,Z, -// based on the stats filter metadata -static boost::property_tree::ptree getSummaryBounds(MetadataNode root) -{ - boost::property_tree::ptree pt; - - if (root.empty()) return pt; - - MetadataNode m = root.findChild("filters.stats"); - if (m.empty()) return pt; - - std::vector ms = m.children("statistic"); - for (auto dataNode: ms) - { - if (dataNode.empty()) continue; - - MetadataNode nameNode = dataNode.findChild("name"); - if (nameNode.empty()) continue; - - const std::string& name = nameNode.value(); - if (name=="X" || name=="Y" || name=="Z") - { - MetadataNode minNode = dataNode.findChild("minimum"); - MetadataNode maxNode = dataNode.findChild("maximum"); - if (minNode.empty()) continue; - if (maxNode.empty()) continue; - - boost::property_tree::ptree stats; - stats.put("min", minNode.value()); - stats.put("max", maxNode.value()); - pt.add_child(name, stats); - } + MetadataNode n = tree.findChild(std::to_string(i)); + root.add(n.clone(prefix + std::to_string(points[i]))); } - - return pt; + return root; } -// return a ptree containing list of dimensions -// based on the stats filter metadata -static boost::property_tree::ptree getSummaryDimensions(MetadataNode root) +MetadataNode InfoKernel::dumpSummary() { - boost::property_tree::ptree pt; - - if (root.empty()) return pt; - - MetadataNode m = root.findChild("filters.stats"); - if (m.empty()) return pt; - - std::vector ms = m.children("statistic"); - for (auto dataNode: ms) - { - if (dataNode.empty()) continue; - - MetadataNode nameNode = dataNode.findChild("name"); - if (nameNode.empty()) continue; - - const std::string& name = nameNode.value(); - boost::property_tree::ptree item; - pt.put(name, ""); - //pt.add_child("dim", item); - } - - return pt; -} - - -void InfoKernel::dumpSummary(PointContext ctx, PointBufferPtr buf) -{ - Stage* stage = m_manager->getStage(); - assert(stage->getName() == "filters.stats"); - - MetadataNode metaNode = m_manager->getMetadata(); - + QuickInfo qi = m_reader->preview(); + + MetadataNode summary("summary"); + summary.add("num_points", qi.m_pointCount); + summary.add("spatial_reference", qi.m_srs.getWKT()); + MetadataNode bounds = summary.add("bounds"); + MetadataNode x = bounds.add("X"); + x.add("min", qi.m_bounds.minx); + x.add("max", qi.m_bounds.maxx); + MetadataNode y = bounds.add("Y"); + y.add("min", qi.m_bounds.miny); + y.add("max", qi.m_bounds.maxy); + MetadataNode z = bounds.add("Z"); + z.add("min", qi.m_bounds.minz); + z.add("max", qi.m_bounds.maxz); + + std::string dims; + auto di = qi.m_dimNames.begin(); + while (di != qi.m_dimNames.end()) { - boost::property_tree::ptree pt; - pt.put("NumPoints", buf->size()); - pt.put("NumDimensions", ctx.dims().size()); - pt.put("WKT", ctx.spatialRef().getWKT()); - m_tree->add_child("Summary", pt); - } - - { - boost::property_tree::ptree pt = getSummaryBounds(metaNode); - m_tree->add_child("Bounds", pt); - } - - { - boost::property_tree::ptree pt = getSummaryDimensions(metaNode); - m_tree->add_child("Dimensions", pt); + dims += *di; + ++di; + if (di != qi.m_dimNames.end()) + dims += ", "; } + summary.add("dimensions", dims); + return summary; } void InfoKernel::dump(PointContext ctx, PointBufferPtr buf) { if (m_showStats) - { - dumpStats(); - } + m_statsStage->getMetadata(); + + if (m_pipelineFile.size() > 0) + PipelineWriter(*m_manager).writePipeline(m_pipelineFile); if (m_pointIndexes.size()) - { dumpPoints(buf); - } if (m_showSchema) - { - boost::property_tree::ptree dims(pdal::utils::toPTree(ctx)); - m_tree->add_child("schema", dims); - } - - if (m_showSDOPCMetadata) - { - boost::property_tree::ptree metadata = - m_manager->getStage()->serializePipeline(); - - boost::property_tree::ptree output; - m_tree->add_child("stage", output); - } + MetadataNode root = utils::toMetadata(ctx); if (m_QueryPoint.size()) - { dumpQuery(buf); - } if (m_showSummary) - { - dumpSummary(ctx, buf); - } + dumpSummary(); + + if (m_computeBoundary) + m_hexbinStage->getMetadata(); } -void InfoKernel::dumpQuery(PointBufferPtr buf) const +MetadataNode InfoKernel::dumpQuery(PointBufferPtr buf) const { -#define SEPARATORS ",| " - boost::char_separator sep(SEPARATORS); - tokenizer tokens(m_QueryPoint, sep); + auto seps = [](char c){ return (c == ',' || c == '|' || c == ' '); }; + + std::vector tokens = Utils::split2(m_QueryPoint, seps); std::vector values; - for (tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t) - values.push_back(boost::lexical_cast(*t)); + for (auto ti = tokens.begin(); ti != tokens.end(); ++ti) + values.push_back(boost::lexical_cast(*ti)); if (values.size() != 2 && values.size() != 3) throw app_runtime_error("--points must be two or three values"); @@ -401,20 +296,10 @@ void InfoKernel::dumpQuery(PointBufferPtr buf) const for (auto i = ids.begin(); i != ids.end(); ++i) outbuf->appendPoint(*buf, *i); - boost::property_tree::ptree tree = pdal::utils::toPTree(*outbuf); - m_tree->add_child("point", tree); + return utils::toMetadata(*outbuf); } -void InfoKernel::dumpSDO_PCMetadata(PointContext ctx, const Stage& stage) const -{ - std::ostream& ostr = std::cout; - // std::string xml = pdal::Schema::to_xml(*ctx.schema(), stage.getMetadata()); - // ostr << xml; -} - - - void InfoKernel::dumpMetadata(PointContext ctx, const Stage& stage) const { boost::property_tree::ptree tree = stage.serializePipeline(); @@ -432,56 +317,51 @@ void InfoKernel::dumpMetadata(PointContext ctx, const Stage& stage) const int InfoKernel::execute() { Options readerOptions; - { - if (m_usestdin) - m_inputFile = "STDIN"; - readerOptions.add("filename", m_inputFile); - readerOptions.add("debug", isDebug()); - readerOptions.add("verbose", getVerboseLevel()); - } + bool preview = true; + + std::string filename = m_usestdin ? std::string("STDIN") : m_inputFile; + readerOptions.add("filename", filename); m_manager = std::unique_ptr( - KernelSupport::makePipeline(readerOptions)); + KernelSupport::makePipeline(filename)); + m_reader = static_cast(m_manager->getStage()); + Stage *stage = m_reader; if (m_Dimensions.size()) m_options.add("dimensions", m_Dimensions, "List of dimensions"); Options options = m_options + readerOptions; - - Stage* stage = m_manager->getStage(); - stage->setOptions(options); - if (m_showStats || m_showSummary) + m_reader->setOptions(options); + if (m_showStats) { - if (m_showSummary) - { - // we need exact dimensions for the bbox, so we need to visit - // all the points, alas - options.add("num_points", 0); - } - stage = m_manager->addFilter("filters.stats", stage); - stage->setOptions(options); + m_statsStage = m_manager->addFilter("filters.stats", stage); + m_statsStage->setOptions(options); + stage = m_statsStage; + preview = false; } if (m_computeBoundary) { - stage = m_manager->addFilter("filters.hexbin", stage); + m_hexbinStage = m_manager->addFilter("filters.hexbin", stage); stage->setOptions(options); + stage = m_hexbinStage; + preview = false; } - m_tree = std::unique_ptr( - new boost::property_tree::ptree); - std::ostream& ostr = std::cout; m_manager->execute(); PointBufferSet pbSet = m_manager->buffers(); assert(pbSet.size() == 1); dump(m_manager->context(), *pbSet.begin()); +//ABELL +/** if (m_useXML) write_xml(ostr, *m_tree); else if (m_useRST) pdal::utils::reST::write_rst(ostr, *m_tree); else write_json(ostr, *m_tree); +**/ return 0; } diff --git a/kernels/info/InfoKernel.hpp b/kernels/info/InfoKernel.hpp index e4506d487c..919814ec55 100644 --- a/kernels/info/InfoKernel.hpp +++ b/kernels/info/InfoKernel.hpp @@ -34,8 +34,9 @@ #pragma once -#include #include "Kernel.hpp" + +#include #include #include @@ -71,10 +72,11 @@ class PDAL_DLL InfoKernel : public Kernel void dump(PointContext ctx, PointBufferPtr buf); - void dumpPoints(PointBufferPtr buf) const; - void dumpStats(); - void dumpSummary(PointContext ctx, PointBufferPtr buf); - void dumpQuery(PointBufferPtr buf) const; + MetadataNode dumpPoints(PointBufferPtr buf) const; + MetadataNode dumpStats() const; + void dumpPipeline() const; + MetadataNode dumpSummary(); + MetadataNode dumpQuery(PointBufferPtr buf) const; void dumpMetadata(PointContext ctx, const Stage&) const; void dumpSDO_PCMetadata(PointContext ctx, Stage const&) const; @@ -96,7 +98,11 @@ class PDAL_DLL InfoKernel : public Kernel std::string m_pipelineFile; bool m_showSummary; - std::unique_ptr m_tree; + Stage *m_statsStage; + Stage *m_hexbinStage; + Reader *m_reader; + + MetadataNode m_tree; std::unique_ptr m_manager; }; diff --git a/src/Stage.cpp b/src/Stage.cpp index f6822f4f3f..a222496ee5 100644 --- a/src/Stage.cpp +++ b/src/Stage.cpp @@ -193,8 +193,12 @@ void Stage::setSpatialReference(MetadataNode& m, MetadataNode spatialNode = m.findChild(pred); if (spatialNode.empty()) { - m.add("spatialreference", spatialRef.getWKT(SpatialReference::eHorizontalOnly, false), "SRS of this stage"); - m.add("comp_spatialreference", spatialRef.getWKT(SpatialReference::eCompoundOK, false), "SRS of this stage"); + m.add("spatialreference", + spatialRef.getWKT(SpatialReference::eHorizontalOnly, false), + "SRS of this stage"); + m.add("comp_spatialreference", + spatialRef.getWKT(SpatialReference::eCompoundOK, false), + "SRS of this stage"); } } diff --git a/test/unit/PointBufferTest.cpp b/test/unit/PointBufferTest.cpp index e71d141849..0dacedd56a 100644 --- a/test/unit/PointBufferTest.cpp +++ b/test/unit/PointBufferTest.cpp @@ -41,10 +41,11 @@ #include #include #include +#include "Support.hpp" using namespace pdal; -PointBuffer* makeTestBuffer(PointContext ctx) +PointBuffer* makeTestBuffer(PointContext ctx, point_count_t cnt = 17) { ctx.registerDim(Dimension::Id::Classification); ctx.registerDim(Dimension::Id::X); @@ -53,7 +54,7 @@ PointBuffer* makeTestBuffer(PointContext ctx) PointBuffer* data = new PointBuffer(ctx); // write the data into the buffer - for (uint32_t i = 0; i < 17; i++) + for (PointId i = 0; i < cnt; i++) { const uint8_t x = (uint8_t)(i + 1); const int32_t y = i * 10; @@ -63,23 +64,23 @@ PointBuffer* makeTestBuffer(PointContext ctx) data->setField(Dimension::Id::X, i, y); data->setField(Dimension::Id::Y, i, z); } - EXPECT_EQ(data->size(), 17u); + EXPECT_EQ(data->size(), cnt); return data; } -static void verifyTestBuffer(const PointBuffer& data) +static void verifyTestBuffer(const PointBuffer& data, point_count_t cnt = 17) { // read the data back out - for (int i = 0; i < 17; i++) + for (PointId i = 0; i < cnt; i++) { - const uint8_t x = data.getFieldAs( + uint8_t x = data.getFieldAs( Dimension::Id::Classification, i); - const int32_t y = data.getFieldAs(Dimension::Id::X, i); - const double z = data.getFieldAs(Dimension::Id::Y, i); + int32_t y = data.getFieldAs(Dimension::Id::X, i); + double z = data.getFieldAs(Dimension::Id::Y, i); - EXPECT_EQ(x, i + 1u); - EXPECT_EQ(y, i * 10); + EXPECT_EQ(x, (uint8_t)(i + 1)); + EXPECT_EQ(y, (int32_t)(i * 10)); EXPECT_TRUE(Utils::compare_approx(z, static_cast(i) * 100.0, (std::numeric_limits::min)())); } @@ -218,21 +219,19 @@ TEST(PointBufferTest, assignment) } -TEST(PointBufferTest, ptree) +TEST(PointBufferTest, metadata) { PointContext ctx; - PointBuffer* data = makeTestBuffer(ctx); + PointBuffer* data = makeTestBuffer(ctx, 2); std::stringstream ss1(std::stringstream::in | std::stringstream::out); - boost::property_tree::ptree tree = utils::toPTree(*data); + MetadataNode tree = utils::toMetadata(*data); delete data; - boost::property_tree::write_xml(ss1, tree); - std::string out1 = ss1.str(); - std::string xml_header = "\n"; - std::string ref = xml_header + "<0>001<1>101002"; - - EXPECT_EQ(ref, out1.substr(0, ref.length())); + std::ifstream str1(Support::datapath("pointbuffer/metadata.txt")); + std::string json = tree.toJSON(); + std::istringstream str2(tree.toJSON()); + EXPECT_TRUE(Support::compare_text_files(str1, str2)); }