From 3d24b67146ddd126d277b9dd3b1a55aba800db37 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Thu, 17 Nov 2016 16:05:28 +0100 Subject: [PATCH] Fix #157 --- src/ifcconvert/XmlSerializer.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp index 48d41f3d89..68fa283f89 100644 --- a/src/ifcconvert/XmlSerializer.cpp +++ b/src/ifcconvert/XmlSerializer.cpp @@ -39,8 +39,30 @@ std::map argument_name_map; // Format an IFC attribute and maybe returns as string. Only literal scalar // values are converted. Things like entity instances and lists are omitted. -boost::optional format_attribute(const Argument* argument, IfcUtil::ArgumentType argument_type) { +boost::optional format_attribute(const Argument* argument, IfcUtil::ArgumentType argument_type, const std::string& argument_name) { boost::optional value; + + // Hard-code lat-lon as it represents an array + // of integers best emitted as a single decimal + if (argument_name == "IfcSite.RefLatitude" || + argument_name == "IfcSite.RefLongitude") + { + std::vector angle = *argument; + double deg; + if (angle.size() >= 3) { + deg = angle[0] + angle[1] / 60. + angle[2] / 3600.; + int prec = 8; + if (angle.size() == 4) { + deg += angle[3] / (1000000. * 3600.); + prec = 14; + } + std::stringstream stream; + stream << std::setprecision(prec) << deg; + value = stream.str(); + } + return value; + } + switch(argument_type) { case IfcUtil::Argument_BOOL: { const bool b = *argument; @@ -66,7 +88,7 @@ boost::optional format_attribute(const Argument* argument, IfcUtil: IfcUtil::IfcBaseClass* e = *argument; if (Type::IsSimple(e->type())) { IfcUtil::IfcBaseType* f = (IfcUtil::IfcBaseType*) e; - value = format_attribute(f->getArgument(0), f->getArgumentType(0)); + value = format_attribute(f->getArgument(0), f->getArgumentType(0), argument_name); } else if (e->is(IfcSchema::Type::IfcSIUnit) || e->is(IfcSchema::Type::IfcConversionBasedUnit)) { // Some string concatenation to have a unit name as a XML attribute. @@ -122,9 +144,10 @@ ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& child, pt } const IfcUtil::ArgumentType argument_type = instance->getArgumentType(i); + const std::string qualified_name = IfcSchema::Type::ToString(instance->type()) + "." + argument_name; boost::optional value; try { - value = format_attribute(argument, argument_type); + value = format_attribute(argument, argument_type, qualified_name); } catch (...) {} if (value) {