[xsd-users] CityGML deserialization - <cityObjectMember> tag
[Corrected]
Adrian Victor Manoliu
victor.manoliu at yahoo.com
Wed Apr 20 03:54:23 EDT 2011
Hello,
After a long pause I've returned to my CityGML project and everything started to
make sense quicker than I expected. Thank you for your help, it helped me
realise which way to go. To sum up what I've written below (in case you don't
have the time to read everything), the CityGML serialization works, however one
tag is not generated properly - <cityObjectMember> is always replaced by
<gml:featureMember>, perhaps a problem caused by substitution groups.
First, a brief reminder on how to actually serialize CityGML tags. It took me
some time to understand the CityGML schema hierarchies and also the way
serialization works. For example, in the previous posts I was trying to iterate
on the _GenericApplicationPropertyOf... fields, and these are never really used,
at least not in my case. The objects to use were the feature collection members:
citygml::CityModelType iCityModel ---> the root object
citygml::CityModelType::featureMember_sequence iSequence ---> its members
gml::FeaturePropertyType iFeatureProperty ---> one item
building::BuildingType iBuilding ---> an example of an object, in this case a
building
Supposing the building has been created and personalised:
iFeatureProperty._Feature(iBuilding)
iSequence.push_back(iFeatureProperty);
Other objects can be added the same way as the building and at the end the
sequence is assigned to the city model:
iCityModel.featureMember(iSequence);
Afterwards, the iteration and extraction of items and attributes is basically
the reverse procedure.
Right now I'm having another issue. All the tags are generated the way they
should be, except for one - the rather important <cityObjectMember> tag. This
is probably linked to the old substitution group story, since in cityGMLBase.xsd
this item is defined like this:
<xs:element name="cityObjectMember" type="gml:FeaturePropertyType"
substitutionGroup="gml:featureMember"/>
The cityObjectMember is actually the wrapper for each child of CityModel
representing city objects (and not properties like appearance or other). Now,
this differs from other items, for example the appearance item found at the same
level in the hierarchy is like this:
<xs:complexType name="AppearancePropertyType">
<xs:complexContent>
<xs:extension base="gml:FeaturePropertyType">
<xs:sequence minOccurs="0">
<xs:element name="Appearance" type="AppearanceType"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
When comparing these two in the generated .cxx files:
cityGMLBase.cxx:
static const ::xsd::cxx::tree::element_factory_initializer< 0, char,
::gml::FeaturePropertyType >
_xsd_cityObjectMember_element_factory_init (
"featureMember",
"http://www.opengis.net/gml",
"cityObjectMember",
"http://www.opengis.net/citygml/1.0");
and appearance.cxx:
static const ::xsd::cxx::tree::element_factory_initializer< 0, char,
::citygml::appearance::AppearancePropertyType >
_xsd_appearanceMember_element_factory_init (
"featureMember",
"http://www.opengis.net/gml",
"appearanceMember",
"http://www.opengis.net/appearance/1.0");
Considering iSequence to be the feature sequence of the city model, an
<app:appearanceMember> tag with an <app:Appearance> child is generated well
whenever I do:
appearance::AppearancePropertyType* iAppearanceProperty = new
appearance::AppearancePropertyType();
appearance::AppearanceType* iAppearance = new appearance::AppearanceType();
[...appearance/texture creation...]
iAppearanceProperty->Appearance(*iAppearance);
iSequence->push_back(*iAppearanceProperty);
However, when I try:
building::BuildingType* iBuilding = new building::BuildingType();
[...building creation...]
citygml::CityModelType::featureMember_type* iFeatureMember = new
citygml::CityModelType::featureMember_type();
iFeatureMember->_Feature(*iBuilding);
iSequence->push_back(*iFeatureMember);
the result is a <gml:featureMember> tag. If I remove schema locations from the
namespace map, the tag becomes something like:
>
with p2 being the unknown gml namespace, so it actually takes the namespace of
the feature.
If I try:
citygml::CityModelType::featureMember_type* iFeatureMember = new
citygml::CityModelType::featureMember_type();
// this first line acts the same as and can be replaced by:
FeaturePropertyType* iFeatureMember = new FeaturePropertyType();
citygml::CityModelType::featureMember_type::_Feature_type* iFeature = new
citygml::CityModelType::featureMember_type::_Feature_type();
iFeatureMember->_Feature(*iFeature);
iSequence->push_back(*iFeatureMember);
upon creating this empty dummy object the tag remains <gml:featureMember>.
Please let me know if there is a way to obtain the right tag. Thank you.
Victor
________________________________
From: Boris Kolpackov <boris at codesynthesis.com>
To: Adrian Victor Manoliu <victor.manoliu at yahoo.com>
Cc: xsd-users at codesynthesis.com
Sent: Mon, February 28, 2011 3:48:35 PM
Subject: Re: [xsd-users] CityGML deserialization - CityModel generation
Hi Adrian,
Adrian Victor Manoliu <victor.manoliu at yahoo.com> writes:
> const std::string fName = "waldbruecke_v1.0.0.gml";
> std::auto_ptr<CityModelType> iCity(CityModel(fName, flags.dont_validate));
>
> [...]
>
> Now, once I have iCity, I simply want to iterate over its elements, that
> is the Buildings, BuildingParts etc. by doing something like this (I have
> been doing this from the start):
>
> CityModelType::_GenericApplicationPropertyOfCityModel_const_iterator ci;
>
> for (ci = iCity->_GenericApplicationPropertyOfCityModel().begin();
> ci != iCity->_GenericApplicationPropertyOfCityModel().end();
> ++ci)
> {
> [...]
> }
>
> however in this case I don't see how I could know what type to cast these
> objects to
You need to study the GML/CityGML schemas to see which concrete elements
(and types) substitute which abstract elements.
Here is an example body of the above for-loop. Hopefully, it will get you
started:
for (ci = iCity->_GenericApplicationPropertyOfCityModel().begin();
ci != iCity->_GenericApplicationPropertyOfCityModel().end();
++ci)
{
xml_schema::type& x (*ci);
if (gml::FeaturePropertyType* cityObjectMember =
dynamic_cast<gml::FeaturePropertyType*> (&x))
{
gml::FeaturePropertyType::_Feature_const_iterator fi;
for (fi = cityObjectMember->_Feature ().begin ();
fi != cityObjectMember->_Feature ().end ();
++fi)
{
gml::AbstractFeatureType& f (*fi);
if (citygml::building::BuildingType* b =
dynamic_cast<citygml::building::BuildingType*> (&f);
{
// We've got a building.
}
else if (...)
{
...
}
}
}
}
Boris
More information about the xsd-users
mailing list