Skip to content

Commit

Permalink
Allow update of metadata nodes (#2220)
Browse files Browse the repository at this point in the history
* Use proper logic for multiple crop regions.
Close #2198

* Set SRS if it hasn't been overridden by an option.
Close #2194

* Add addOrUpdate support for generic MetadataNode.
Add test support.
Fix description setting error.
  • Loading branch information
abellgithub committed Oct 9, 2018
1 parent ffd563a commit 8c84b04
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 11 deletions.
30 changes: 28 additions & 2 deletions pdal/Metadata.hpp
Expand Up @@ -120,6 +120,18 @@ class PDAL_DLL MetadataNodeImpl
return node;
}

MetadataNodeImplPtr replace(MetadataNodeImplPtr node)
{
auto ni = m_subnodes.find(node->m_name);
if (ni == m_subnodes.end())
return MetadataNodeImplPtr();
MetadataImplList& l = ni->second;
if (l.size() != 1)
return MetadataNodeImplPtr();
l.front() = node;
return node;
}

bool operator == (const MetadataNodeImpl& m) const
{
if (m_name != m.m_name || m_descrip != m.m_descrip ||
Expand Down Expand Up @@ -483,8 +495,9 @@ class PDAL_DLL MetadataNode

if (l.empty())
return add(lname, value);
MetadataNodeImplPtr impl = *l.begin();
MetadataNodeImplPtr impl(new MetadataNodeImpl(lname));
impl->setValue(value);
l.front() = impl;
return MetadataNode(impl);
}

Expand All @@ -493,7 +506,20 @@ class PDAL_DLL MetadataNode
const std::string& descrip)
{
MetadataNode m = addOrUpdate(lname, value);
m_impl->m_descrip = descrip;
m.m_impl->m_descrip = descrip;
return m;
}

MetadataNode addOrUpdate(MetadataNode& n)
{
if (m_impl->nodeType(n.name()) == MetadataType::Array)
throw pdal_error("Can't call addOrUpdate() on subnode list.");

MetadataNode m;
if (m_impl->subnodes(n.name()).empty())
m = add(n);
else
m = MetadataNode(m_impl->replace(n.m_impl));
return m;
}

Expand Down
50 changes: 41 additions & 9 deletions test/unit/MetadataTest.cpp
Expand Up @@ -275,15 +275,6 @@ TEST(MetadataTest, find_child_string)
EXPECT_EQ(n.value(), "220");
}

/**
TEST(MetadataTest, sanitize)
{
MetadataNode top(" Test;semicolon:colon space'apostrophe\"quote:");
EXPECT_EQ(top.name(),
"_Test_semicolon_colon_space_apostrophe_quote_");
}
**/

// Make sure that we handle double-precision values to 10 decimal places.
TEST(MetadataTest, test_float)
{
Expand Down Expand Up @@ -327,3 +318,44 @@ TEST(MetadataTest, infnan)
n2 = n.add("value2", d);
EXPECT_EQ(n2.jsonValue(), "\"-Infinity\"");
}

// Test the addOrUpdate functions.
TEST(MetadataTest, update)
{
MetadataNode root("root");

EXPECT_EQ(false, root.hasChildren());
root.addOrUpdate("test", 21);
EXPECT_EQ(1U, root.children().size());
root.addOrUpdate("test", 22, "description");
EXPECT_EQ(1U, root.children().size());
MetadataNodeList l = root.children();
MetadataNode n = l.front();
EXPECT_EQ("test", n.name());
EXPECT_EQ("description", n.description());
EXPECT_EQ(22, n.value<int>());

MetadataNode root2("root2");
MetadataNode child("child");
child.add("subchild1", 1);
child.add("subchild2", 2);
root2.add(child);

MetadataNode child2("child");
child2.add("subchild3", 3);
child2.add("subchild4", 4);
child2.add("subchild5", 5);
root2.addOrUpdate(child2);

l = root2.children();
EXPECT_EQ(l.size(), 1U);
MetadataNode c = l.front();
l = c.children();
EXPECT_EQ(l.size(), 3U);
EXPECT_EQ(l[0].value<int>(), 3);
EXPECT_EQ(l[1].value<int>(), 4);
EXPECT_EQ(l[2].value<int>(), 5);

root2.add(c);
EXPECT_THROW(root2.addOrUpdate(c), pdal_error);
}

0 comments on commit 8c84b04

Please sign in to comment.