[xsd-users] CityGML deserialization - CityModel generation

Adrian Victor Manoliu victor.manoliu at yahoo.com
Tue Feb 22 04:14:06 EST 2011



Greetings everyone,


I'm currently working on a CityGML (de)serializer - I need C++ classes for 
certain corresponding objects - and I'm having some trouble with
generating the root object itself. I don't know how familiar everyone here is 
with CityGML, but here's a description of the situation:

I've used the CodeSynthesis version of xsd.exe in the supplied command line 
batch via the common.options/gml.options/citygml.options files.
As a result, hxx and cxx files were created for each of the GML and CityGML xsd 
files. The root object tag in CityGML is <CityModel>, but
the root class is actually CityModelType. The corresponding constructor I used 
is found in citygmlbase.hxx and has the prototype:

::std::auto_ptr< ::citygml::CityModelType >
  CityModel (::xml_schema::dom::auto_ptr< xercesc::DOMDocument >& d,
             ::xml_schema::flags f,
             const ::xml_schema::properties&)
             
I used this constructor (which I've also pasted entirely at the end of my post) 
in order to create my object and iterate through its items:

const std::string fName = "waldbruecke_v1.0.0.gml";
std::auto_ptr<CityModelType> iCity(CityModel(fName, flags.dont_validate));
CityModelType::_GenericApplicationPropertyOfCityModel_const_iterator ci;        
                                     
                                             
(I supplied "flags.dont_validate" because I don't want the schemas to be 
validated via Internet.)

Within the above mentioned constructor a map is created, which seems to hold the 
correspondencies between CityGML(XML) tags and the
generated classes:

::xsd::cxx::tree::type_factory_map< char >& tfm ( 
::xsd::cxx::tree::type_factory_map_instance< 0, char > () );

This is where things start to go wrong. tfm actually contains two maps, type_map 
and element_map (typical for XML, I would say):

tfm    {type_map_=[624](...,...) element_map_={...} }    
xsd::cxx::tree::type_factory_map<char> &

Of these two, the first one seems to be ok, however element_map is just a long 
array of fields containing "error". I can't really tell
what that "error" means or what caused it. I haven't found any source where this 
string is assigned to the fields of the map, in the
cxx or txx files, so this would be the first problem. Afterwards, the actual 
object, r, is created through another pointer, tmp:

::std::auto_ptr< ::xsd::cxx::tree::type > tmp (
  tfm.create (
    "CityModel",
    "http://www.opengis.net/citygml/1.0",
    &::xsd::cxx::tree::factory_impl< ::citygml::CityModelType >,
    true, true, e, n, f, 0));

The resulting object pointer looks like this (there are 1870 parsed items):

ptr    {dom_info_=auto_ptr {...} map_=auto_ptr [1870]((0x01e6e0e8,0x01e6da38 
{_GenericApplicationPropertyOfBuilding_={...} }),...,...) container_=0x00000000 
}

Finally, the object is generated and returned by the constructor:

if (tmp.get () != 0)
{

  ::std::auto_ptr< ::citygml::CityModelType > r (
    dynamic_cast< ::citygml::CityModelType* > (tmp.get ()));

  if (r.get ())
    tmp.release ();
  else
    throw ::xsd::cxx::tree::not_derived< char > ();

  return r;
}

The object is made of three fields: flags_, container_ and v_. The 1870 items in 
the pointer exist in container_, however v_ is completely empty,
and this is the second problem because it's the v_ field that the iterator will 
look in to retrieve the CityModelType elements (back in the main
method). To conclude, I would say this second issue is caused by the first one, 
but I can't really tell why all this is happening. Hope to hear
from you soon. Thanks.


Cheers,
Victor


**********

::std::auto_ptr< ::citygml::CityModelType >
  CityModel (::xml_schema::dom::auto_ptr< xercesc::DOMDocument >& d,
             ::xml_schema::flags f,
             const ::xml_schema::properties&)
  {
    ::xml_schema::dom::auto_ptr< xercesc::DOMDocument > c (
      ((f & ::xml_schema::flags::keep_dom) &&
       !(f & ::xml_schema::flags::own_dom))
      ? static_cast< xercesc::DOMDocument* > (d->cloneNode (true))
      : 0);

    xercesc::DOMDocument& doc (c.get () ? *c : *d);
    const xercesc::DOMElement& e (*doc.getDocumentElement ());

    const ::xsd::cxx::xml::qualified_name< char > n (
      ::xsd::cxx::xml::dom::name< char > (e));

    if (f & ::xml_schema::flags::keep_dom)
      doc.setUserData (::xml_schema::dom::tree_node_key,
                       (c.get () ? &c : &d),
                       0);

    ::xsd::cxx::tree::type_factory_map< char >& tfm (
      ::xsd::cxx::tree::type_factory_map_instance< 0, char > ());

    ::std::auto_ptr< ::xsd::cxx::tree::type > tmp (
      tfm.create (
        "CityModel",
        "http://www.opengis.net/citygml/1.0",
        &::xsd::cxx::tree::factory_impl< ::citygml::CityModelType >,
        true, true, e, n, f, 0));

    if (tmp.get () != 0)
    {

      ::std::auto_ptr< ::citygml::CityModelType > r (
        dynamic_cast< ::citygml::CityModelType* > (tmp.get ()));

      if (r.get ())
        tmp.release ();
      else
        throw ::xsd::cxx::tree::not_derived< char > ();

      return r;
    }

    throw ::xsd::cxx::tree::unexpected_element < char > (
      n.name (),
      n.namespace_ (),
      "CityModel",
      "http://www.opengis.net/citygml/1.0");
  }
}

**********


      



More information about the xsd-users mailing list