MetadataNode findChild(std::string s) const { auto splitString = [](std::string& s) -> std::string { std::string val; size_t pos = s.find(':'); if (pos == std::string::npos) { val = s; s.clear(); } else { val = s.substr(0, pos); s = (pos == s.size() - 1) ? "" : s.substr(pos + 1); } return val; }; if (s.empty()) return *this; std::string lname = splitString(s); auto nodes = children(lname); for (auto ai = nodes.begin(); ai != nodes.end(); ++ai) { MetadataNode& n = *ai; MetadataNode child = n.findChild(s); if (!child.empty()) return child; } return MetadataNode(); }
MetadataNode addList(const std::string& name, const T& value, const std::string& descrip = std::string()) { MetadataNodeImplPtr impl = m_impl->addList(name); impl->setValue(value); impl->m_descrip = descrip; return MetadataNode(impl); }
MetadataNode addWithType(const std::string& name, const std::string& value, const std::string& type, const std::string& descrip) { MetadataNodeImplPtr impl = m_impl->add(name); impl->m_type = type; impl->m_value = value; impl->m_descrip = descrip; return MetadataNode(impl); }
MetadataNode addListEncoded(const std::string& name, const unsigned char *buf, size_t size, const std::string& descrip = std::string()) { MetadataNodeImplPtr impl = m_impl->addList(name); impl->setValue(Utils::base64_encode(buf, size)); impl->m_type = "base64Binary"; impl->m_descrip = descrip; return MetadataNode(impl); }
MetadataNode findChild(PREDICATE p) const { auto nodes = children(); for (auto ai = nodes.begin(); ai != nodes.end(); ++ai) { MetadataNode& n = *ai; if (p(n)) return n; } return MetadataNode(); }
MetadataNode addOrUpdate(const std::string& lname, const T& value) { if (m_impl->nodeType(lname) == MetadataType::Array) throw pdal_error("Can't call addOrUpdate() on subnode list."); MetadataImplList& l = m_impl->subnodes(lname); if (l.empty()) return add(lname, value); MetadataNodeImplPtr impl = *l.begin(); impl->setValue(value); return MetadataNode(impl); }
MetadataNode find(PREDICATE p) const { if (p(*this)) return *this; auto nodes = children(); for (auto ai = nodes.begin(); ai != nodes.end(); ++ai) { MetadataNode n = ai->find(p); if (!n.empty()) return n; } return MetadataNode(); }
MetadataNodeList children(const std::string& name) const { MetadataNodeList outnodes; auto si = m_impl->m_subnodes.find(name); if (si != m_impl->m_subnodes.end()) { const MetadataImplList& l = si->second; for (auto li = l.begin(); li != l.end(); ++li) outnodes.push_back(MetadataNode(*li)); } return outnodes; }
MetadataNodeList children() const { MetadataNodeList outnodes; const MetadataSubnodes& nodes = m_impl->m_subnodes; for (auto si = nodes.begin(); si != nodes.end(); ++si) { const MetadataImplList& l = si->second; for (auto li = l.begin(); li != l.end(); ++li) outnodes.push_back(MetadataNode(*li)); } return outnodes; }
bool XMLSchema::load(xmlDocPtr doc) { xmlNode* root = xmlDocGetRootElement(doc); // print_element_names(root); if (!Utils::iequals((const char*)root->name, "PointCloudSchema")) { std::cerr << "First node of document was not named 'PointCloudSchema'"; return false; } const unsigned SENTINEL_POS = 100000; unsigned missingPos = SENTINEL_POS + 1; xmlNode* dimension = root->children; pdal::Metadata metadata; for (xmlNode *dimension = root->children; dimension; dimension = dimension->next) { // Read off orientation setting if (std::string((const char*)dimension->name) == "orientation") { xmlChar* n = xmlNodeListGetString(doc, dimension->children, 1); if (!n) { std::cerr << "Unable to fetch orientation.\n"; return false; } std::string orientation = std::string((const char*)n); xmlFree(n); if (Utils::iequals(orientation, "dimension")) m_orientation = Orientation::DimensionMajor; else m_orientation = Orientation::PointMajor; continue; } if (std::string((const char*)dimension->name) == "metadata") { m_metadata = MetadataNode("root"); if (!loadMetadata(dimension, m_metadata)) return false; continue; } if (dimension->type != XML_ELEMENT_NODE || !Utils::iequals((const char*)dimension->name, "dimension")) continue; XMLDim dim; dim.m_position = SENTINEL_POS; for (xmlNode *properties = dimension->children; properties; properties = properties->next) { if (properties->type != XML_ELEMENT_NODE) continue; std::string propName = (const char *)properties->name; propName = Utils::tolower(propName); if (propName == "name") { xmlChar *n = xmlNodeListGetString(doc, properties->children, 1); if (!n) { std::cerr << "Unable to fetch name from XML node."; return false; } dim.m_name = remapOldNames(std::string((const char*)n)); xmlFree(n); } if (propName == "description") { xmlChar* n = xmlNodeListGetString(doc, properties->children, 1); if (!n) { std::cerr << "Unable to fetch description.\n"; return false; } dim.m_description = std::string((const char*)n); xmlFree(n); } if (propName == "interpretation") { xmlChar* n = xmlNodeListGetString(doc, properties->children, 1); if (!n) { std::cerr << "Unable to fetch interpretation.\n"; return false; } dim.m_dimType.m_type = Dimension::type((const char*)n); xmlFree(n); } if (propName == "minimum") { xmlChar* n = xmlGetProp(properties, (const xmlChar*) "value"); if (!n) { return false; std::cerr << "Unable to fetch minimum value.\n"; } dim.m_min = std::atof((const char*)n); xmlFree(n); } if (propName == "maximum") { xmlChar* n = xmlGetProp(properties, (const xmlChar*) "value"); if (!n) { std::cerr << "Unable to fetch maximum value.\n"; return false; } dim.m_max = std::atof((const char*)n); xmlFree(n); } if (propName == "position") { xmlChar* n = xmlNodeListGetString(doc, properties->children, 1); if (!n) { std::cerr << "Unable to fetch position value.\n"; return false; } dim.m_position = std::atoi((const char*)n); xmlFree(n); } if (propName == "offset") { xmlChar* n = xmlNodeListGetString(doc, properties->children, 1); if (!n) { std::cerr << "Unable to fetch offset value!"; return false; } dim.m_dimType.m_xform.m_offset.set((const char*)n); xmlFree(n); } if (propName == "scale") { xmlChar* n = xmlNodeListGetString(doc, properties->children, 1); if (!n) { std::cerr << "Unable to fetch scale value!"; return false; } dim.m_dimType.m_xform.m_scale.set((const char*)n); xmlFree(n); } } // If we don't have a position, set it to some value larger than all // previous values. if (dim.m_position == SENTINEL_POS) dim.m_position = missingPos++; m_dims.push_back(dim); } std::sort(m_dims.begin(), m_dims.end()); // Renumber dimension positions to be 1..N for (unsigned pos = 0; pos < m_dims.size(); pos++) m_dims[pos].m_position = pos + 1; return true; }
MetadataNode addList(MetadataNode node) { return MetadataNode(m_impl->addList(node.m_impl)); }
MetadataNode addList(const std::string& name) { return MetadataNode(m_impl->addList(name)); }