[libcitygml] 07/35: Imported Upstream version 1.3.0

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Fri Jul 24 23:34:59 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository libcitygml.

commit 17e4451636773b7a766f44faf8e006ccb5dc40e7
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Jul 24 16:29:26 2015 +0200

    Imported Upstream version 1.3.0
---
 CMakeLists.txt                                     |   4 +-
 SpecsToCheck.md                                    |  24 ++
 TODO.md                                            |  22 +-
 osgplugin/CitygmlOsgViewer.cpp                     |  86 ++++++-
 osgplugin/ReaderWriterCityGML.cpp                  |  46 ++--
 sources/CMakeLists.txt                             |  39 ++-
 sources/include/citygml/cityobject.h               |   7 +-
 sources/include/citygml/material.h                 |  10 +-
 sources/include/parser/appearanceelementparser.h   |   8 +-
 .../include/parser/delayedchoiceelementparser.h    |   2 +-
 sources/include/parser/elementparser.h             |  11 +-
 sources/include/parser/geometryelementparser.h     |   7 +-
 .../include/parser/gmlfeaturecollectionparser.h    |   9 +-
 ...featurecollectionparser.h => gmlobjectparser.h} |  16 +-
 .../include/parser/implicitgeometryelementparser.h |   7 +-
 sources/include/parser/linearringelementparser.h   |   7 +-
 sources/include/parser/materialelementparser.h     |   6 +-
 sources/include/parser/nodetypes.h                 | 120 ++++++++-
 sources/include/parser/polygonelementparser.h      |   7 +-
 sources/include/parser/sequenceparser.h            |  43 ++++
 sources/include/parser/skipelementparser.h         |  35 +++
 sources/include/parser/textureelementparser.h      |   7 +-
 sources/src/citygml/appearancemanager.cpp          |   2 +-
 sources/src/citygml/cityobject.cpp                 |   9 +-
 sources/src/citygml/material.cpp                   |  24 +-
 sources/src/parser/appearanceelementparser.cpp     |  17 +-
 sources/src/parser/cityobjectelementparser.cpp     | 146 +++++++++--
 sources/src/parser/geometryelementparser.cpp       |  57 +++--
 .../parser/georeferencedtextureelementparser.cpp   |  14 +-
 sources/src/parser/gmlfeaturecollectionparser.cpp  |  31 +--
 sources/src/parser/gmlobjectparser.cpp             |  50 ++++
 .../src/parser/implicitgeometryelementparser.cpp   |  26 +-
 sources/src/parser/linearringelementparser.cpp     |  11 +-
 sources/src/parser/materialelementparser.cpp       |  28 ++-
 sources/src/parser/nodetypes.cpp                   | 277 ++++++++++++++++++---
 sources/src/parser/polygonelementparser.cpp        |  28 ++-
 sources/src/parser/sequenceparser.cpp              |  55 ++++
 sources/src/parser/skipelementparser.cpp           |  56 +++++
 sources/src/parser/textureelementparser.cpp        |  21 +-
 39 files changed, 1150 insertions(+), 225 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index fb08801..73e3255 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,8 +3,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.2 FATAL_ERROR)
 PROJECT ( libcitygml )
 
 set(META_VERSION_MAJOR       "1")
-set(META_VERSION_MINOR       "2")
-set(META_VERSION_PATCH       "1")
+set(META_VERSION_MINOR       "3")
+set(META_VERSION_PATCH       "0")
 set(META_VERSION             "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}")
 
 SET( CMAKE_MODULE_PATH "${libcitygml_SOURCE_DIR}/CMakeModules/;${CMAKE_MODULE_PATH}" )
diff --git a/SpecsToCheck.md b/SpecsToCheck.md
new file mode 100644
index 0000000..ba64b7c
--- /dev/null
+++ b/SpecsToCheck.md
@@ -0,0 +1,24 @@
+# Specification of Modules to check
+
+## CityGML
+
+CityGML Module			|	Namespace identifier								|	schemaLocation																|	Recommended namespace prefix	| Checked
+		--- 			| 						--- 							| 								--- 											| 				----			 	| ---
+Core 					|	http://www.opengis.net/citygml/1.0 					|	http://schemas.opengis.net/citygml/1.0/cityGMLBase.xsd 						|	core 							| ☑
+Appearance 				|	http://www.opengis.net/citygml/appearance/1.0		|	http://schemas.opengis.net/citygml/appearance/1.0/appearance.xsd			|	app 							| ☑
+Building				|	http://www.opengis.net/citygml/building/1.0			|	http://schemas.opengis.net/citygml/building/1.0/building.xsd				|	bldg 							| ☑
+CityFurniture			|	http://www.opengis.net/citygml/cityfurniture/1.0 	|	http://schemas.opengis.net/citygml/cityfurniture/1.0/cityFurniture.xsd		|	frn 							| ☑
+CityObjectGroup			|	http://www.opengis.net/citygml/cityobjectgroup/1.0	|	http://schemas.opengis.net/citygml/cityobjectgroup/1.0/cityObjectGroup.xsd	|	grp 							| ☑
+Generics				|	http://www.opengis.net/citygml/generics/1.0			|	http://schemas.opengis.net/citygml/generics/1.0/generics.xsd				|	gen 							| ☑
+LandUse					|	http://www.opengis.net/citygml/landuse/1.0			|	http://schemas.opengis.net/citygml/landuse/1.0/landUse.xsd					|	luse 							| ☑
+Relief					|	http://www.opengis.net/citygml/relief/1.0			|	http://schemas.opengis.net/citygml/relief/1.0/relief.xsd					|	dem 							| ☑
+Transportation			|	http://www.opengis.net/citygml/transportation/1.0	|	http://schemas.opengis.net/citygml/transportation/1.0/transportation.xsd	|	tran 							| ☑
+Vegetation				|	http://www.opengis.net/citygml/vegetation/1.0		|	http://schemas.opengis.net/citygml/vegetation/1.0/vegetation.xsd			|	veg 							| ☑
+WaterBody				|	http://www.opengis.net/citygml/waterbody/1.0		|	http://schemas.opengis.net/citygml/waterbody/1.0/waterBody.xsd				|	wtr 							| ☑
+
+## GML
+
+GML  Module				|	schemaLocation																| Checked
+		--- 			| 								--- 											| ---
+Basic Types 			|	http://schemas.opengis.net/gml/3.1.1/base/basicTypes.xsd					| ☐
+Geometry 				|	http://schemas.opengis.net/gml/3.1.1/base/geometryBasic0d1d.xsd				| ☐
\ No newline at end of file
diff --git a/TODO.md b/TODO.md
index d940865..b3c0d88 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,13 +1,31 @@
 # libcitygml TODO List
 
 # Correctness
-* Fix texture coordinates when tesselation removes or adds vertices
 * Check if the normals calculated for tesselation is always correct even if the vertices are in a spherical coordinate system
   ... if not one should think about removing the tesselation from libcitygml 
 * Check if OrientableSurfaces are supported properly... may be the vertices must be reverted if the orientation is '-'
 * Check if Appearance assignment is correct for shared polygons
 * Check if non implicit geoemtries can be shared
 * Ensure that polygons that are children of shared geometries are not also children of non shared geometries (otherwise a coordinate transformation might be applied on the vertices which is not allowed for shared geometries)
+* The namespace of the different modules may differ from the recommended one... make a namespace mapping based on the uri
+* Currently different city object types are grouped under the same enum type (CityObjectType) e.g. WaterSurface, WaterGroundSurface, WaterClosureSurface and WaterBody are of type COT_WaterBody. The reason for this is that every enum type is identified by an individual bit... however there are only 32 bits. Check if the bitmask is actually used... if not remove that constraint and define an individual enum type for every CityObject type
+* Some polygon types (PolygonSurface, Polygon, Triangle etc.) have an implicit ("planar") or explicit gml:SurfaceInterpolationType attribute... currently its ignored
+
+# Completness
+* Implement parsing of CityObject <generalizesTo> member (contains a cityobject or references one that is the generalization of the current one) => requires cityobject sharing
+* Implement parsing of CityObject <externalReference> member
+* Implement complete address parsing: Currently the address attributes (street, postalcode, etc.) are stored as indivdual address attributes. However a address can be assigned zero or more 2D or 3D point geometries (one gml:MultiPoint geometry) locating the entrance. This requires parsing of the <Address> as an individual element
+* Implement parsing of ImplicitGeometry <libraryObject> member
+* Implement GeoreferencedTexture parsing
+* Implement appearence <TexCoordGen> support
+* Implement <grp:geometry> support (Darunter kann eine beliebige GML Geometrie hängen)
+* Implement full support for <grp:groupMember> and <grp:parent> (requires city object sharing, currently only inline definitions are supported)
+* Implement lod0 parsing
+* Implement Relief/Terrain Model (Namespace DEM) parsing. More precisely implement ReliefComponentPropertyType parsing.
+	* Requires gml:MultiPointPropertyType parsing
+	* Requires gml:MultiCurvePropertyType parsing (also required for wtr module)
+	* Requires gml:RectifiedGridCoverage parsing
+* Implement gml:Tin parsing (possible child of <surfaceMember> element that uses delauny triangulation)
 
 # Refactoring
 * Change the NodeTypes so that typeID is a constant expression -> Use switch-case structures instead of if-then-else in the element parsers
@@ -15,7 +33,7 @@
 
 # Features
 * Enable CityObject filering by type mask (ParserParams)
-* Implement georefereced texture parsing
+
 
 # Optimization
 * Remove empty objects
diff --git a/osgplugin/CitygmlOsgViewer.cpp b/osgplugin/CitygmlOsgViewer.cpp
index d3c72cb..ed54383 100644
--- a/osgplugin/CitygmlOsgViewer.cpp
+++ b/osgplugin/CitygmlOsgViewer.cpp
@@ -5,23 +5,95 @@
 
 #include <osgGA/SphericalManipulator>
 #include <osgGA/StateSetManipulator>
+#include <osgGA/GUIEventHandler>
+#include <osgGA/GUIEventAdapter>
+#include <osgGA/GUIActionAdapter>
 #include <osgViewer/ViewerEventHandlers>
 
+#include <osgUtil/LineSegmentIntersector>
+#include <osgUtil/Optimizer>
+
 #include <iostream>
 
+class PickingHandler : public osgGA::GUIEventHandler {
+public:
+
+    PickingHandler() {
+        m_xMouseCoordAtLastPress = -1;
+        m_yMouseCoordAtLastPress = -1;
+    }
+
+    // EventHandler interface
+    virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor*) {
+        if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {
+
+            if (m_xMouseCoordAtLastPress != ea.getX() || m_yMouseCoordAtLastPress != ea.getY()) {
+                return false;
+            }
+
+            return printDescriptionOfIntersectedDrawable(ea, aa);
+
+
+        } else if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {
+            m_xMouseCoordAtLastPress = ea.getX();
+            m_yMouseCoordAtLastPress = ea.getY();
+        }
+
+        return false;
+    }
+
+private:
+
+    bool printDescriptionOfIntersectedDrawable(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
+
+        osgUtil::LineSegmentIntersector::Intersections intersections;
+        if (!aa.computeIntersections(ea, intersections)) {
+            return false;
+        }
+
+
+        osgUtil::LineSegmentIntersector::Intersection firstIntersection = *intersections.begin();
+
+        if (firstIntersection.drawable == nullptr) {
+            return false;
+        }
+
+        if (firstIntersection.drawable->getNumDescriptions() == 0) {
+            std::cout << "Intersected drawable has no description:" << std::endl;
+            return true;
+        }
+
+        std::cout << "Description of intersected drawable:" << std::endl;
+        for (const std::string& desc : firstIntersection.drawable->getDescriptions()) {
+            std::cout << "  " << desc << std::endl;
+        }
+        std::cout << std::endl;
+
+        return true;
+    }
+
+    int m_xMouseCoordAtLastPress;
+    int m_yMouseCoordAtLastPress;
+};
+
+
 int main(int argc, char *argv[])
 {
-    osg::setNotifyLevel(osg::INFO);
+    osg::setNotifyLevel(osg::WARN);
 
     std::cout << "Using plugin directory: " << PLUGIN_BIN_DIR << std::endl;
     osgDB::Registry::instance()->getLibraryFilePathList().push_front(PLUGIN_BIN_DIR);
 
+    osgDB::Registry::instance()->addFileExtensionAlias("gml", "citygml");
+
     if (argc < 2) {
         std::cerr << "No citygml file specified..." << std::endl;
         return 1;
     }
 
-    osg::ref_ptr<osgDB::Options> options = new osgDB::Options("usemaxlodonly");
+    osg::ref_ptr<osgDB::Options> options = new osgDB::Options("usemaxlodonly storegeomids");
+
+    std::cout << "Loading file: " << argv[1] << std::endl;
     osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(argv[1], options);
 
     if (node == nullptr) {
@@ -29,6 +101,13 @@ int main(int argc, char *argv[])
         return 1;
     }
 
+    std::cout << "Optimizing node..." << std::endl;
+    osgUtil::Optimizer optimizer;
+    optimizer.optimize(node, osgUtil::Optimizer::ALL_OPTIMIZATIONS);
+
+    std::cout << "Setup viewer..." << std::endl;
+
+
     osg::ref_ptr<osgGA::SphericalManipulator> manip = new osgGA::SphericalManipulator();
     manip->setAutoComputeHomePosition(true);
     manip->setNode(node);
@@ -40,7 +119,10 @@ int main(int argc, char *argv[])
     viewer.addEventHandler(new osgGA::StateSetManipulator(node->getOrCreateStateSet()));
     viewer.addEventHandler(new osgViewer::StatsHandler());
     viewer.addEventHandler(new osgViewer::WindowSizeHandler());
+    viewer.addEventHandler(new PickingHandler());
+    viewer.addEventHandler(new osgViewer::HelpHandler());
     viewer.run();
 
     return 0;
 }
+
diff --git a/osgplugin/ReaderWriterCityGML.cpp b/osgplugin/ReaderWriterCityGML.cpp
index c8143a6..a516a30 100644
--- a/osgplugin/ReaderWriterCityGML.cpp
+++ b/osgplugin/ReaderWriterCityGML.cpp
@@ -92,6 +92,7 @@ public:
     CityGMLSettings( void )
         : _printNames(false)
         , _useMaxLODOnly(false)
+        , _storeGeomIDs(false)
         , _theme("")
     {}
 
@@ -111,7 +112,7 @@ public:
             else if ( currentOption == "pruneemptyobjects" ) _params.pruneEmptyObjects = true;
             else if ( currentOption == "usemaxlodonly" ) _useMaxLODOnly = true;
             else if ( currentOption == "usetheme" ) iss >> _theme;
-
+            else if ( currentOption == "storegeomids" ) _storeGeomIDs = true;
         }
     }
 
@@ -119,6 +120,7 @@ public:
     citygml::ParserParams _params;
     bool _printNames;
     bool _useMaxLODOnly;
+    bool _storeGeomIDs;
     std::map< std::string, osg::Texture2D* > _textureMap;
     std::string _theme;
 };
@@ -140,14 +142,15 @@ public:
         supportsOption( "destSRS", "Transform geometry to given reference system" );
         supportsOption( "useMaxLODonly", "Use the highest available LOD for geometry of one object" );
         supportsOption( "appearanceTheme", "Name of the appearance theme to use" );
+        supportsOption( "storegeomids", "Store the citygml id of geometry objects in the corresponding osg::Geometry object as a description string." );
 
         m_logger = std::make_shared<CityGMLOSGPluginLogger>();
     }
 
-    virtual const char* className( void ) const { return "CityGML Reader"; }
+    virtual const char* className( void ) const override { return "CityGML Reader"; }
 
-    virtual ReadResult readNode( const std::string&, const osgDB::ReaderWriter::Options* ) const;
-    virtual ReadResult readNode( std::istream&, const osgDB::ReaderWriter::Options* ) const;
+    virtual ReadResult readNode( const std::string&, const osgDB::ReaderWriter::Options* ) const override;
+    virtual ReadResult readNode( std::istream&, const osgDB::ReaderWriter::Options* ) const override;
 
 private:
 
@@ -155,8 +158,7 @@ private:
     static unsigned int getHighestLodForObject(const citygml::CityObject& object);
 
     ReadResult readCity(std::shared_ptr<const citygml::CityModel>, CityGMLSettings& ) const;
-    bool createCityObject(const citygml::CityObject&, CityGMLSettings&, osg::Group*, const TVec3d &offset, unsigned int minimumLODToConsider = 0 ) const;
-
+    bool createCityObject(const citygml::CityObject&, CityGMLSettings&, osg::Group*, const osg::Vec3d& offset = osg::Vec3d(0.0, 0.0, 0.0), unsigned int minimumLODToConsider = 0) const;
 };
 
 // Register with Registry to instantiate the above reader/writer.
@@ -251,26 +253,22 @@ osgDB::ReaderWriter::ReadResult ReaderWriterCityGML::readCity(std::shared_ptr<co
 
     const citygml::ConstCityObjects& roots = city->getRootCityObjects();
 
+
     if(roots.size() == 0) return nullptr;
 
-    const citygml::Envelope& env = city->getEnvelope();
-    TVec3d offset;
-    if(env.validBounds()){
-        offset = env.getLowerBound();
-    }else{
-        const citygml::Envelope& env = roots.at(0)->getEnvelope();
-        if(env.validBounds()){
-            offset = env.getLowerBound();
-        }
+
+    osg::Vec3d offset(0, 0, 0);
+    if (city->getEnvelope().validBounds()) {
+        TVec3d lb = city->getEnvelope().getLowerBound();
+        offset = osg::Vec3d(lb.x, lb.y, lb.z);
     }
 
-    osg::notify(osg::NOTICE) << "Applying model offset of " << offset.x  << ", " << offset.y << ", " << offset.z << std::endl;
+    for ( unsigned int i = 0; i < roots.size(); ++i ) createCityObject( *roots[i], settings, root, offset );
 
-    for ( unsigned int i = 0; i < roots.size(); ++i ) createCityObject( *roots[i], settings, root, offset);
 
     osg::notify(osg::NOTICE) << "Done." << std::endl;
     root->setMatrix(
-        osg::Matrixd::translate(osg::Vec3d(offset.x,offset.y,offset.z)));
+        osg::Matrixd::translate(offset));
 
     return root;
 }
@@ -356,14 +354,14 @@ void setMaterial(osg::ref_ptr<osg::StateSet> stateset, const citygml::Polygon& p
     material->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4(diffuse.r, diffuse.g, diffuse.b, diffuse.a ) );
     material->setSpecular( osg::Material::FRONT_AND_BACK, osg::Vec4(specular.r, specular.g, specular.b, specular.a ) );
     material->setEmission( osg::Material::FRONT_AND_BACK, osg::Vec4(emissive.r, emissive.g, emissive.b, emissive.a ) );
-    material->setShininess( osg::Material::FRONT_AND_BACK, citygmlMaterial->getShininess() );
+    material->setShininess( osg::Material::FRONT_AND_BACK, 128.f * citygmlMaterial->getShininess() );
     material->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4( ambient, ambient, ambient, 1.0 ) );
     material->setTransparency( osg::Material::FRONT_AND_BACK, citygmlMaterial->getTransparency() );
     stateset->setAttributeAndModes( material, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON );
     stateset->setMode( GL_LIGHTING, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON );
 }
 
-void createOsgGeometryFromCityGMLGeometry(const citygml::Geometry& geometry, CityGMLSettings& settings, osg::Geode* geometryContainer, const TVec3d& offset) {
+void createOsgGeometryFromCityGMLGeometry(const citygml::Geometry& geometry, CityGMLSettings& settings, osg::Geode* geometryContainer, const osg::Vec3d& offset ) {
     for ( unsigned int j = 0; j < geometry.getPolygonsCount(); j++ )
     {
         const citygml::Polygon& p = geometry.getPolygon(j);
@@ -382,7 +380,8 @@ void createOsgGeometryFromCityGMLGeometry(const citygml::Geometry& geometry, Cit
         vertices->reserve( vert.size() );
         for ( unsigned int k = 0; k < vert.size(); k++ )
         {
-            osg::Vec3d pt( vert[k].x - offset.x, vert[k].y - offset.y, vert[k].z - offset.z);
+            TVec3d v = vert[k];
+            osg::Vec3d pt = osg::Vec3d( v.x, v.y, v.z ) - offset;
             vertices->push_back( pt );
         }
 
@@ -399,6 +398,9 @@ void createOsgGeometryFromCityGMLGeometry(const citygml::Geometry& geometry, Cit
         setMaterial(stateset, p, settings);
         setTexture(stateset, geom, p, settings);
 
+        if (settings._storeGeomIDs) {
+            geom->addDescription(p.getId());
+        }
 
         geometryContainer->addDrawable( geom );
     }
@@ -409,7 +411,7 @@ void createOsgGeometryFromCityGMLGeometry(const citygml::Geometry& geometry, Cit
     }
 }
 
-bool ReaderWriterCityGML::createCityObject(const citygml::CityObject& object, CityGMLSettings& settings, osg::Group* parent, const TVec3d& offset, unsigned int minimumLODToConsider ) const
+bool ReaderWriterCityGML::createCityObject(const citygml::CityObject& object, CityGMLSettings& settings, osg::Group* parent, const osg::Vec3d& offset , unsigned int minimumLODToConsider) const
 {
     // Skip objects without geometry
     if ( !parent ) return false;
diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt
index 1ca7c03..0264b1a 100644
--- a/sources/CMakeLists.txt
+++ b/sources/CMakeLists.txt
@@ -42,15 +42,22 @@ SET(SOURCES
   src/citygml/geometrymanager.cpp
 
   src/parser/nodetypes.cpp
+  src/parser/attributes.cpp
+
+  src/parser/geocoordinatetransformer.cpp
+
   src/parser/citygmldocumentparser.cpp
+  src/parser/parserxercesc.cpp
   src/parser/citygmlelementparser.cpp
   src/parser/elementparser.cpp
+
   src/parser/delayedchoiceelementparser.cpp
-  src/parser/attributes.cpp
-  src/parser/parserxercesc.cpp
-  src/parser/geocoordinatetransformer.cpp
+  src/parser/skipelementparser.cpp
+  src/parser/sequenceparser.cpp
 
+  src/parser/gmlobjectparser.cpp
   src/parser/gmlfeaturecollectionparser.cpp
+
   src/parser/citymodelelementparser.cpp
   src/parser/cityobjectelementparser.cpp
   src/parser/appearanceelementparser.cpp
@@ -96,22 +103,30 @@ SET(HEADERS
 
   include/citygml/citygml_api.h.in
 
-  include/parser/nodetypes.h
-  include/parser/citygmldocumentparser.h
-  include/parser/citygmlelementparser.h
-  include/parser/elementparser.h
-  include/parser/delayedchoiceelementparser.h
-  include/parser/attributes.h
-  include/parser/documentlocation.h
-  include/parser/geocoordinatetransformer.h
-  include/parser/parserutils.hpp
   include/citygml/tesselator.h
   include/citygml/utils.h
   include/citygml/appearancemanager.h
   include/citygml/polygonmanager.h
   include/citygml/geometrymanager.h
 
+  include/parser/nodetypes.h
+  include/parser/attributes.h
+  include/parser/documentlocation.h
+
+  include/parser/parserutils.hpp
+  include/parser/geocoordinatetransformer.h
+
+  include/parser/citygmldocumentparser.h
+  include/parser/citygmlelementparser.h
+  include/parser/elementparser.h
+
+  include/parser/delayedchoiceelementparser.h
+  include/parser/skipelementparser.h
+  include/parser/sequenceparser.h
+
+  include/parser/gmlobjectparser.h
   include/parser/gmlfeaturecollectionparser.h
+
   include/parser/citymodelelementparser.h
   include/parser/cityobjectelementparser.h
   include/parser/appearanceelementparser.h
diff --git a/sources/include/citygml/cityobject.h b/sources/include/citygml/cityobject.h
index 90bc564..9de0a66 100644
--- a/sources/include/citygml/cityobject.h
+++ b/sources/include/citygml/cityobject.h
@@ -37,7 +37,7 @@ namespace citygml {
             COT_PlantCover                  = 1 << 12,
             COT_SolitaryVegetationObject    = 1 << 13,
             COT_WaterBody                   = 1 << 14,
-            COT_TINRelief                   = 1 << 15,
+            COT_ReliefFeature               = 1 << 15,
             COT_LandUse                     = 1 << 16,
             COT_Tunnel						= 1 << 17,
             COT_Bridge						= 1 << 18,
@@ -53,6 +53,11 @@ namespace citygml {
             COT_FloorSurface                = 1 << 27,
             COT_InteriorWallSurface         = 1 << 28,
             COT_CeilingSurface              = 1 << 29,
+            COT_CityObjectGroup             = 1 << 30,
+
+            // covers all supertypes of tran::_TransportationObject that are not Track, Road, Railway or Square...
+            // there are to many for to few bits to explicitly enumerate them. However Track, Road, Railway or Square should be used most of the time
+            COT_TransportationObject        = 1 << 31,
 
             COT_All                         = 0xFFFFFFFF
         };
diff --git a/sources/include/citygml/material.h b/sources/include/citygml/material.h
index 312745b..778b4a0 100644
--- a/sources/include/citygml/material.h
+++ b/sources/include/citygml/material.h
@@ -26,16 +26,23 @@ namespace citygml {
         float getAmbientIntensity() const;
         void setAmbientIntensity(float intensity);
 
+        /**
+         * @brief the shininess of the material
+         * @return a value between 0 and 1, where 1 is the brightest intensity
+         * @note openGL defines the shininess as a value beteen 0 and 128 with 128 beeing the brightest intensity
+         */
         float getShininess() const;
         void setShininess(float shininess);
 
         float getTransparency() const;
         void setTransparency(float transparancy);
 
+        bool isSmooth() const;
+        void setIsSmooth(bool isSmooth);
+
         virtual std::shared_ptr<Material> asMaterial() override;
         virtual std::shared_ptr<const Material> asMaterial() const override;
 
-
     protected:
         Material( const std::string& id );
         TVec3f m_diffuse;
@@ -44,6 +51,7 @@ namespace citygml {
         float m_ambientIntensity;
         float m_shininess;
         float m_transparency;
+        bool m_isSmooth;
     };
 
 }
diff --git a/sources/include/parser/appearanceelementparser.h b/sources/include/parser/appearanceelementparser.h
index d059fd2..8cfb1f4 100644
--- a/sources/include/parser/appearanceelementparser.h
+++ b/sources/include/parser/appearanceelementparser.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <parser/citygmlelementparser.h>
+#include <parser/gmlobjectparser.h>
 
 #include <string>
 #include <vector>
@@ -11,7 +11,7 @@ namespace citygml {
     class CityObject;
     class Appearance;
 
-    class AppearanceElementParser : public CityGMLElementParser {
+    class AppearanceElementParser : public GMLObjectElementParser {
     public:
         AppearanceElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger);
 
@@ -26,8 +26,12 @@ namespace citygml {
         virtual bool parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
         virtual bool parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
 
+        // GMLObjectElementParser interface
+        virtual Object* getObject() override;
+
     private:
         std::vector<std::shared_ptr<Appearance>> m_surfaceDataList;
+        std::shared_ptr<Object> m_appearanceObj;
         std::string m_theme;
     };
 
diff --git a/sources/include/parser/delayedchoiceelementparser.h b/sources/include/parser/delayedchoiceelementparser.h
index fde8aa2..618a046 100644
--- a/sources/include/parser/delayedchoiceelementparser.h
+++ b/sources/include/parser/delayedchoiceelementparser.h
@@ -3,7 +3,7 @@
 #include <vector>
 #include <memory>
 
-#include "parser/citygmlelementparser.h"
+#include "parser/elementparser.h"
 
 namespace citygml {
 
diff --git a/sources/include/parser/elementparser.h b/sources/include/parser/elementparser.h
index 22d444a..2429146 100644
--- a/sources/include/parser/elementparser.h
+++ b/sources/include/parser/elementparser.h
@@ -15,7 +15,8 @@ namespace citygml {
 
     /**
      * @brief The ElementParser is the base class for parsers that only handle a specific subset of elements
-     * @see CityGMLElementParser
+     *
+     * For a basic explanation of the parsing process @see CityGMLElementParser
      */
     class ElementParser {
     public:
@@ -38,14 +39,22 @@ namespace citygml {
 
         /**
          * @brief returns wether the parser handels elements of type node
+         * @note this is required for the delayed choice mechanism @see DelayedChoiceElementParser
          */
         virtual bool handlesElement(const NodeType::XMLNode& node) const = 0;
 
+        /**
+         * @brief the name of the parser (for logging purposes)
+         */
         virtual std::string elementParserName() const = 0;
 
         virtual ~ElementParser();
 
     protected:
+        /**
+         * @brief sets a parser that will be called for the next element.
+         * @note The parser will be deleted after parsing the elment.
+         */
         void setParserForNextElement(ElementParser* parser);
         virtual const DocumentLocation& getDocumentLocation() const;
 
diff --git a/sources/include/parser/geometryelementparser.h b/sources/include/parser/geometryelementparser.h
index 3ef14f5..5b8d871 100644
--- a/sources/include/parser/geometryelementparser.h
+++ b/sources/include/parser/geometryelementparser.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <parser/citygmlelementparser.h>
+#include <parser/gmlobjectparser.h>
 #include <citygml/cityobject.h>
 
 #include <string>
@@ -10,7 +10,7 @@ namespace citygml {
 
     class Geometry;
 
-    class GeometryElementParser : public CityGMLElementParser {
+    class GeometryElementParser : public GMLObjectElementParser {
     public:
         GeometryElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger,
                               int lodLevel, CityObject::CityObjectsType parentType, std::function<void(Geometry*)> callback);
@@ -25,6 +25,9 @@ namespace citygml {
         virtual bool parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
         virtual bool parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
 
+        // GMLObjectElementParser interface
+        virtual Object* getObject() override;
+
     private:
         Geometry* m_model;
         std::function<void(Geometry*)> m_callback;
diff --git a/sources/include/parser/gmlfeaturecollectionparser.h b/sources/include/parser/gmlfeaturecollectionparser.h
index 9bfd9ab..0cf058b 100644
--- a/sources/include/parser/gmlfeaturecollectionparser.h
+++ b/sources/include/parser/gmlfeaturecollectionparser.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <parser/citygmlelementparser.h>
+#include <parser/gmlobjectparser.h>
 
 namespace citygml {
 
@@ -10,7 +10,7 @@ namespace citygml {
     /**
      * @brief abstract base class for all CityGMLElementParser's that parse citygml elements which inherit from gml:AbstractFeatureCollectionType
      */
-    class GMLFeatureCollectionElementParser : public CityGMLElementParser {
+    class GMLFeatureCollectionElementParser : public GMLObjectElementParser {
     public:
         GMLFeatureCollectionElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger);
 
@@ -21,8 +21,13 @@ namespace citygml {
 
         virtual FeatureObject* getFeatureObject() = 0;
 
+        // GMLObjectElementParser interface
+        virtual Object* getObject() override;
+
     private:
         Envelope* m_bounds;
+
+
     };
 
 }
diff --git a/sources/include/parser/gmlfeaturecollectionparser.h b/sources/include/parser/gmlobjectparser.h
similarity index 51%
copy from sources/include/parser/gmlfeaturecollectionparser.h
copy to sources/include/parser/gmlobjectparser.h
index 9bfd9ab..11a68e5 100644
--- a/sources/include/parser/gmlfeaturecollectionparser.h
+++ b/sources/include/parser/gmlobjectparser.h
@@ -4,25 +4,25 @@
 
 namespace citygml {
 
-    class Envelope;
-    class FeatureObject;
+    class Object;
 
     /**
-     * @brief abstract base class for all CityGMLElementParser's that parse citygml elements which inherit from gml:AbstractFeatureCollectionType
+     * @brief abstract base class for all CityGMLElementParser's that parse citygml elements which inherit from gml:AbstractGMLType
      */
-    class GMLFeatureCollectionElementParser : public CityGMLElementParser {
+    class GMLObjectElementParser : public CityGMLElementParser {
     public:
-        GMLFeatureCollectionElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger);
+        GMLObjectElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger);
 
     protected:
         // CityGMLElementParser interface
         virtual bool parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
         virtual bool parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
 
-        virtual FeatureObject* getFeatureObject() = 0;
+        /**
+         * @brief returns the object in which the parsed information will be stored
+         */
+        virtual Object* getObject() = 0;
 
-    private:
-        Envelope* m_bounds;
     };
 
 }
diff --git a/sources/include/parser/implicitgeometryelementparser.h b/sources/include/parser/implicitgeometryelementparser.h
index 71bf05c..06dfc04 100644
--- a/sources/include/parser/implicitgeometryelementparser.h
+++ b/sources/include/parser/implicitgeometryelementparser.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <parser/citygmlelementparser.h>
+#include <parser/gmlobjectparser.h>
 #include <citygml/cityobject.h>
 
 #include <string>
@@ -10,7 +10,7 @@ namespace citygml {
 
     class ImplicitGeometry;
 
-    class ImplicitGeometryElementParser : public CityGMLElementParser {
+    class ImplicitGeometryElementParser : public GMLObjectElementParser {
     public:
         ImplicitGeometryElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger,
                               int lodLevel, CityObject::CityObjectsType parentType, std::function<void(ImplicitGeometry*)> callback);
@@ -25,6 +25,9 @@ namespace citygml {
         virtual bool parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
         virtual bool parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
 
+        // GMLObjectElementParser interface
+        virtual Object* getObject() override;
+
     private:
         ImplicitGeometry* m_model;
         std::function<void(ImplicitGeometry*)> m_callback;
diff --git a/sources/include/parser/linearringelementparser.h b/sources/include/parser/linearringelementparser.h
index bb18118..c9413f0 100644
--- a/sources/include/parser/linearringelementparser.h
+++ b/sources/include/parser/linearringelementparser.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <parser/citygmlelementparser.h>
+#include <parser/gmlobjectparser.h>
 
 #include <functional>
 
@@ -8,7 +8,7 @@ namespace citygml {
 
     class LinearRing;
 
-    class LinearRingElementParser : public CityGMLElementParser {
+    class LinearRingElementParser : public GMLObjectElementParser {
     public:
         LinearRingElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, bool interior, std::function<void(LinearRing*)> callback);
 
@@ -22,6 +22,9 @@ namespace citygml {
         virtual bool parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
         virtual bool parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
 
+        // GMLObjectElementParser interface
+        virtual Object* getObject() override;
+
     private:
         LinearRing* m_model;
         std::function<void(LinearRing*)> m_callback;
diff --git a/sources/include/parser/materialelementparser.h b/sources/include/parser/materialelementparser.h
index dd502e0..90e0e9c 100644
--- a/sources/include/parser/materialelementparser.h
+++ b/sources/include/parser/materialelementparser.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <parser/citygmlelementparser.h>
+#include <parser/gmlobjectparser.h>
 
 #include <functional>
 #include <memory>
@@ -10,7 +10,7 @@ namespace citygml {
 
     class Material;
 
-    class MaterialElementParser : public CityGMLElementParser {
+    class MaterialElementParser : public GMLObjectElementParser {
     public:
         MaterialElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void(std::shared_ptr<Material>)> callback);
 
@@ -25,6 +25,8 @@ namespace citygml {
         virtual bool parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
         virtual bool parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
 
+        // GMLObjectElementParser interface
+        virtual Object* getObject() override;
     private:
         std::shared_ptr<Material> m_model;
         std::function<void(std::shared_ptr<Material>)> m_callback;
diff --git a/sources/include/parser/nodetypes.h b/sources/include/parser/nodetypes.h
index 1c08dcc..0bbf14d 100644
--- a/sources/include/parser/nodetypes.h
+++ b/sources/include/parser/nodetypes.h
@@ -16,8 +16,9 @@ namespace citygml {
             XMLNode();
             XMLNode(std::string prefix, std::string name);
 
-            const std::string& name() const;
+            const std::string name() const;
             const std::string& prefix() const;
+            const std::string& baseName() const;
             int typeID() const;
 
             bool operator==(const XMLNode& other) const;
@@ -42,15 +43,37 @@ namespace citygml {
         NODETYPE( CORE, CityObjectMember )
         NODETYPE( CORE, CreationDate )
         NODETYPE( CORE, TerminationDate )
+        NODETYPE( CORE, GeneralizesTo)
+
+        NODETYPE( CORE, ExternalReference)
+        NODETYPE( CORE, InformationSystem)
+        NODETYPE( CORE, ExternalObject)
+
+        NODETYPE( CORE, Uri)
+        NODETYPE( CORE, Name)
+
+        NODETYPE( CORE, Address )
+
         NODETYPE( CORE, ImplicitGeometry )
         NODETYPE( CORE, RelativeGMLGeometry )
         NODETYPE( CORE, TransformationMatrix )
+        NODETYPE( CORE, ReferencePoint)
+        NODETYPE( CORE, MimeType)
+        NODETYPE( CORE, LibraryObject)
 
         // GRP
         NODETYPE( GRP, CityObjectGroup )
         NODETYPE( GRP, GroupMember )
+        NODETYPE( GRP, Class )
+        NODETYPE( GRP, Function )
+        NODETYPE( GRP, Usage )
+        NODETYPE( GRP, Parent )
+        NODETYPE( GRP, Geometry )
 
         // GEN
+        NODETYPE( GEN, Class )
+        NODETYPE( GEN, Function )
+        NODETYPE( GEN, Usage )
         NODETYPE( GEN, GenericCityObject )
         NODETYPE( GEN, StringAttribute )
         NODETYPE( GEN, DoubleAttribute )
@@ -59,14 +82,21 @@ namespace citygml {
         NODETYPE( GEN, UriAttribute )
         NODETYPE( GEN, Value )
 
+        NODETYPE( GEN, Lod0Geometry )
         NODETYPE( GEN, Lod1Geometry )
         NODETYPE( GEN, Lod2Geometry )
         NODETYPE( GEN, Lod3Geometry )
         NODETYPE( GEN, Lod4Geometry )
+        NODETYPE( GEN, Lod0TerrainIntersection )
         NODETYPE( GEN, Lod1TerrainIntersection )
         NODETYPE( GEN, Lod2TerrainIntersection )
         NODETYPE( GEN, Lod3TerrainIntersection )
         NODETYPE( GEN, Lod4TerrainIntersection )
+        NODETYPE( GEN, Lod0ImplicitRepresentation )
+        NODETYPE( GEN, Lod1ImplicitRepresentation )
+        NODETYPE( GEN, Lod2ImplicitRepresentation )
+        NODETYPE( GEN, Lod3ImplicitRepresentation )
+        NODETYPE( GEN, Lod4ImplicitRepresentation )
 
         // TEX
         // NODETYPE( GML, TexturedSurface ) // Deprecated
@@ -76,6 +106,7 @@ namespace citygml {
         NODETYPE( GML, Identifier )
         NODETYPE( GML, Name )
         NODETYPE( GML, DescriptionReference )
+        NODETYPE( GML, MetaDataProperty )
         NODETYPE( GML, Coordinates )
         NODETYPE( GML, Pos )
         NODETYPE( GML, BoundedBy )
@@ -111,6 +142,11 @@ namespace citygml {
         NODETYPE( GML, Interior )
         NODETYPE( GML, Exterior )
 
+        NODETYPE( GML, Shell )
+        NODETYPE( GML, PolyhedralSurface )
+        NODETYPE( GML, Surface )
+        NODETYPE( GML, PolygonPatch)
+
         // BLDG
         NODETYPE( BLDG, Building )
         NODETYPE( BLDG, BuildingPart )
@@ -137,10 +173,6 @@ namespace citygml {
         NODETYPE( BLDG, RoomInstallation)
         NODETYPE( BLDG, Opening)
         NODETYPE( BLDG, RoofType)
-        NODETYPE( BLDG, ExternalReference)
-        NODETYPE( BLDG, InformationSystem)
-        NODETYPE( BLDG, ExternalObject)
-        NODETYPE( BLDG, Uri)
 
         NODETYPE( BLDG, Lod1Solid )
         NODETYPE( BLDG, Lod2Solid )
@@ -175,10 +207,11 @@ namespace citygml {
         NODETYPE( BLDG, BuildingFurniture )
 
         NODETYPE( BLDG, CityFurniture )
-
-        NODETYPE( BLDG, Address )
+        NODETYPE( BLDG, Address)
 
         // CityFurniture
+        NODETYPE( FRN, Class )
+        NODETYPE( FRN, Function )
         NODETYPE( FRN, CityFurniture )
         NODETYPE( FRN, Lod1Geometry )
         NODETYPE( FRN, Lod2Geometry )
@@ -212,17 +245,44 @@ namespace citygml {
 
         // WTR
         NODETYPE( WTR, WaterBody )
+        NODETYPE( WTR, WaterSurface )
+        NODETYPE( WTR, WaterGroundSurface )
+        NODETYPE( WTR, WaterClosureSurface )
+        NODETYPE( WTR, Class )
+        NODETYPE( WTR, Function )
+        NODETYPE( WTR, Usage )
+        NODETYPE( WTR, WaterLevel )
+        NODETYPE( WTR, Lod0MultiCurve )
+        NODETYPE( WTR, Lod0MultiSurface )
+        NODETYPE( WTR, Lod1MultiCurve )
+        NODETYPE( WTR, Lod1MultiSurface )
+        NODETYPE( WTR, Lod1Solid )
+        NODETYPE( WTR, Lod2Solid )
+        NODETYPE( WTR, Lod3Solid )
+        NODETYPE( WTR, Lod4Solid )
+        NODETYPE( WTR, Lod2Surface )
+        NODETYPE( WTR, Lod3Surface )
+        NODETYPE( WTR, Lod4Surface )
+        NODETYPE( WTR, BoundedBy )
 
         // VEG
         NODETYPE( VEG, PlantCover )
         NODETYPE( VEG, SolitaryVegetationObject )
-        NODETYPE( VEG, Species )
         NODETYPE( VEG, Lod1ImplicitRepresentation )
         NODETYPE( VEG, Lod2ImplicitRepresentation )
         NODETYPE( VEG, Lod3ImplicitRepresentation )
         NODETYPE( VEG, Lod4ImplicitRepresentation )
 
+        NODETYPE( VEG, Class )
+        NODETYPE( VEG, Function )
+        NODETYPE( VEG, AverageHeight )
+        NODETYPE( VEG, Species )
+        NODETYPE( VEG, Height )
+        NODETYPE( VEG, TrunkDiameter )
+        NODETYPE( VEG, CrownDiameter )
+
         // TRANS
+        NODETYPE( TRANS, TransportationComplex )
         NODETYPE( TRANS, TrafficArea )
         NODETYPE( TRANS, AuxiliaryTrafficArea )
         NODETYPE( TRANS, Track )
@@ -230,12 +290,44 @@ namespace citygml {
         NODETYPE( TRANS, Railway )
         NODETYPE( TRANS, Square )
 
+        NODETYPE( TRANS, Usage )
+        NODETYPE( TRANS, Function )
+        NODETYPE( TRANS, SurfaceMaterial )
+
+        NODETYPE( TRANS, Lod0Network )
+        NODETYPE( TRANS, Lod1MultiSurface )
+        NODETYPE( TRANS, Lod2MultiSurface )
+        NODETYPE( TRANS, Lod3MultiSurface )
+        NODETYPE( TRANS, Lod4MultiSurface )
+
+
         // LUSE
         NODETYPE( LUSE, LandUse )
 
-        // dem
-        NODETYPE( LUSE, Lod )
-        NODETYPE( LUSE, TINRelief )
+        NODETYPE( LUSE, Class )
+        NODETYPE( LUSE, Usage )
+        NODETYPE( LUSE, Function )
+
+        NODETYPE( LUSE, Lod1MultiSurface )
+        NODETYPE( LUSE, Lod2MultiSurface )
+        NODETYPE( LUSE, Lod3MultiSurface )
+        NODETYPE( LUSE, Lod4MultiSurface )
+
+        // DEM (Relief)
+        NODETYPE( DEM, ReliefFeature )
+        NODETYPE( DEM, TINRelief )
+        NODETYPE( DEM, RasterRelief )
+        NODETYPE( DEM, MassPointRelief )
+        NODETYPE( DEM, BreaklineRelief )
+        NODETYPE( DEM, Lod )
+        NODETYPE( DEM, Extent )
+        NODETYPE( DEM, ReliefComponent )
+        NODETYPE( DEM, Tin )
+        NODETYPE( DEM, Grid )
+        NODETYPE( DEM, ReliefPoints )
+        NODETYPE( DEM, RidgeOrValleyLines )
+        NODETYPE( DEM, Breaklines )
+        NODETYPE( DEM, Elevation )
 
         // SUB
         NODETYPE( SUB, Tunnel )
@@ -257,12 +349,17 @@ namespace citygml {
         NODETYPE( APP, TextureMap )
         NODETYPE( APP, Target )
         NODETYPE( APP, TexCoordList )
+        NODETYPE( APP, TexCoordGen )
         NODETYPE( APP, TextureCoordinates )
+        NODETYPE( APP, WorldToTexture )
         NODETYPE( APP, TextureType )
         NODETYPE( APP, Repeat )
         NODETYPE( APP, WrapMode )
         NODETYPE( APP, BorderColor )
         NODETYPE( APP, PreferWorldFile )
+        NODETYPE( APP, ReferencePoint)
+        NODETYPE( APP, Orientation)
+        NODETYPE( APP, isSmooth)
 
         NODETYPE( APP, X3DMaterial )
         NODETYPE( APP, Material )
@@ -276,6 +373,7 @@ namespace citygml {
         NODETYPE( APP, IsFront )
         NODETYPE( APP, Theme )
         NODETYPE( APP, MimeType )
+
     private:
         static void initializeNodeTypes();
 
diff --git a/sources/include/parser/polygonelementparser.h b/sources/include/parser/polygonelementparser.h
index 1b3b3d7..315df87 100644
--- a/sources/include/parser/polygonelementparser.h
+++ b/sources/include/parser/polygonelementparser.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <parser/citygmlelementparser.h>
+#include <parser/gmlobjectparser.h>
 
 #include <functional>
 #include <memory>
@@ -9,7 +9,7 @@ namespace citygml {
 
     class Polygon;
 
-    class PolygonElementParser : public CityGMLElementParser {
+    class PolygonElementParser : public GMLObjectElementParser {
     public:
         PolygonElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void(std::shared_ptr<Polygon>)> callback);
 
@@ -23,6 +23,9 @@ namespace citygml {
         virtual bool parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
         virtual bool parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
 
+        // GMLObjectElementParser interface
+        virtual Object* getObject() override;
+
     private:
         std::shared_ptr<Polygon> m_model;
         std::function<void(std::shared_ptr<Polygon>)> m_callback;
diff --git a/sources/include/parser/sequenceparser.h b/sources/include/parser/sequenceparser.h
new file mode 100644
index 0000000..30a1299
--- /dev/null
+++ b/sources/include/parser/sequenceparser.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <vector>
+#include <memory>
+#include <functional>
+
+#include "parser/citygmlelementparser.h"
+
+namespace citygml {
+
+    /**
+     * @brief The SequenceParser parses a sequence of elements
+     *
+     * The sequence parser can be used if an xml element can contain more than one child elements. If a
+     * parser finds the start tag of such an element (e.g. <gml:patches>) it can invoke the sequence parser, which
+     * in turn calls a predefined parser for each child until the end tag of the element is found.
+     */
+    class SequenceParser : public ElementParser {
+    public:
+        /**
+         * @brief initializes the parser for an element that can contain multiple children
+         * @param documentParser the CityGMLDocumentParser instance
+         * @param logger a CityGMLLogger logger instance
+         * @param childParserFactory a factory for the parser for the child elements
+         * @param parentElement the element that contains the child objects
+         */
+        SequenceParser(CityGMLDocumentParser& documentParser, std::shared_ptr<CityGMLLogger> logger, std::function<ElementParser*()> childParserFactory, const NodeType::XMLNode& parentElement);
+
+        // ElementParser interface
+        virtual bool startElement(const NodeType::XMLNode& node, Attributes& attributes);
+        virtual bool endElement(const NodeType::XMLNode& node, const std::string& characters);
+        virtual bool handlesElement(const NodeType::XMLNode& node) const;
+        virtual std::string elementParserName() const;
+
+    private:
+        std::function<ElementParser*()> m_childParserFactory;
+        mutable std::unique_ptr<ElementParser> m_childParserInstance;
+        NodeType::XMLNode m_containerType;
+
+        ElementParser& getChildParserDummyInstance() const;
+    };
+
+}
diff --git a/sources/include/parser/skipelementparser.h b/sources/include/parser/skipelementparser.h
new file mode 100644
index 0000000..057a357
--- /dev/null
+++ b/sources/include/parser/skipelementparser.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <parser/elementparser.h>
+
+namespace citygml {
+
+    /**
+     * @brief A parser that just skips over the element (and all its child elements) for which it was called
+     * @note The SkipElementParser can be called for the content of an element that might be empty. In
+     *       that case the SkipElementParser will return control to the calling parser after the end element of that element was parsed.
+     *       Hence the the calling parser should not expect to parse the end element.
+     */
+    class SkipElementParser : public ElementParser {
+    public:
+        /**
+         * @brief initializes the SkipElementParser
+         * @param skipNode if a valid node is passed the skip parser is bound to that node and skips all its children.
+         *                 In that case the start tag of the node must already been parsed.
+         *                 If the node is not valid (Default) the skip parser will be bound to the first element it encounters.
+         */
+        SkipElementParser(CityGMLDocumentParser& documentParser, std::shared_ptr<CityGMLLogger> logger, const NodeType::XMLNode& skipNode = NodeType::XMLNode());
+
+        // ElementParser interface
+        virtual std::string elementParserName() const override;
+        virtual bool handlesElement(const NodeType::XMLNode &node) const override;
+        virtual bool startElement(const NodeType::XMLNode& node, Attributes& attributes) override;
+        virtual bool endElement(const NodeType::XMLNode& node, const std::string& characters)  override;
+
+    private:
+        NodeType::XMLNode m_skipNode;
+        int m_depth;
+
+    };
+
+}
diff --git a/sources/include/parser/textureelementparser.h b/sources/include/parser/textureelementparser.h
index e0574f0..b190681 100644
--- a/sources/include/parser/textureelementparser.h
+++ b/sources/include/parser/textureelementparser.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <parser/citygmlelementparser.h>
+#include <parser/gmlobjectparser.h>
 
 #include <functional>
 #include <memory>
@@ -12,7 +12,7 @@ namespace citygml {
     class TextureTargetDefinition;
     class TextureCoordinates;
 
-    class TextureElementParser : public CityGMLElementParser {
+    class TextureElementParser : public GMLObjectElementParser {
     public:
         TextureElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void(std::shared_ptr<Texture>)> callback);
 
@@ -27,6 +27,9 @@ namespace citygml {
         virtual bool parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
         virtual bool parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
 
+        // GMLObjectElementParser interface
+        virtual Object* getObject() override;
+
     private:
         std::shared_ptr<Texture> m_model;
         std::function<void(std::shared_ptr<Texture>)> m_callback;
diff --git a/sources/src/citygml/appearancemanager.cpp b/sources/src/citygml/appearancemanager.cpp
index 7f04fe4..d2e36d2 100644
--- a/sources/src/citygml/appearancemanager.cpp
+++ b/sources/src/citygml/appearancemanager.cpp
@@ -54,7 +54,7 @@ namespace citygml {
         m_materialTargetDefinitions.push_back(targetDef);
     }
 
-    template<class T> void assignTargetDefinition(std::shared_ptr<T>& targetDef, std::unordered_map<std::string, AppearanceTarget*> targetMap, std::shared_ptr<CityGMLLogger>& logger) {
+    template<class T> void assignTargetDefinition(std::shared_ptr<T>& targetDef, const std::unordered_map<std::string, AppearanceTarget*>& targetMap, std::shared_ptr<CityGMLLogger>& logger) {
         std::string targetID = targetDef->getTargetID();
         auto it = targetMap.find(targetID);
 
diff --git a/sources/src/citygml/cityobject.cpp b/sources/src/citygml/cityobject.cpp
index 6c08b21..7073192 100644
--- a/sources/src/citygml/cityobject.cpp
+++ b/sources/src/citygml/cityobject.cpp
@@ -160,8 +160,8 @@ namespace citygml {
             return "SolitaryVegetationObject";
         case CityObject::COT_WaterBody:
             return "WaterBody";
-        case CityObject::COT_TINRelief:
-            return "TINRelief";
+        case CityObject::COT_ReliefFeature:
+            return "ReliefFeature";
         case CityObject::COT_LandUse:
             return "LandUse";
         case CityObject::COT_Tunnel:
@@ -190,6 +190,8 @@ namespace citygml {
             return "InteriorWallSurface";
         case CityObject::COT_CeilingSurface:
             return "CeilingSurface";
+        case CityObject::COT_TransportationObject:
+            return "TransportationObject";
         default:
             return "Unknown";
         }
@@ -217,7 +219,7 @@ namespace citygml {
          {cityObjectsTypeToLowerString(CityObject::COT_PlantCover), CityObject::COT_PlantCover},
          {cityObjectsTypeToLowerString(CityObject::COT_SolitaryVegetationObject), CityObject::COT_SolitaryVegetationObject},
          {cityObjectsTypeToLowerString(CityObject::COT_WaterBody), CityObject::COT_WaterBody},
-         {cityObjectsTypeToLowerString(CityObject::COT_TINRelief), CityObject::COT_TINRelief},
+         {cityObjectsTypeToLowerString(CityObject::COT_ReliefFeature), CityObject::COT_ReliefFeature},
          {cityObjectsTypeToLowerString(CityObject::COT_LandUse), CityObject::COT_LandUse},
          {cityObjectsTypeToLowerString(CityObject::COT_Tunnel), CityObject::COT_Tunnel},
          {cityObjectsTypeToLowerString(CityObject::COT_Bridge), CityObject::COT_Bridge},
@@ -232,6 +234,7 @@ namespace citygml {
          {cityObjectsTypeToLowerString(CityObject::COT_FloorSurface), CityObject::COT_FloorSurface},
          {cityObjectsTypeToLowerString(CityObject::COT_InteriorWallSurface), CityObject::COT_InteriorWallSurface},
          {cityObjectsTypeToLowerString(CityObject::COT_CeilingSurface), CityObject::COT_CeilingSurface},
+         {cityObjectsTypeToLowerString(CityObject::COT_TransportationObject), CityObject::COT_TransportationObject}
     };
 
     CityObject::CityObjectsType cityObjectsTypeFromString(const std::string& s, bool& valid)
diff --git a/sources/src/citygml/material.cpp b/sources/src/citygml/material.cpp
index 08c2a42..976f72e 100644
--- a/sources/src/citygml/material.cpp
+++ b/sources/src/citygml/material.cpp
@@ -2,11 +2,33 @@
 
 namespace citygml {
 
-    Material::Material(const std::string& id) : Appearance( id, "Material" ), m_ambientIntensity( 0.f ), m_shininess( 0.f ), m_transparency( 0.f )
+    Material::Material(const std::string& id) : Appearance( id, "Material" )
     {
+        // Sets default values of the X3DMaterial definied in the citygml 1.0.0 spec see page 32 (section 9.3 Material)
+        m_ambientIntensity =  0.2f;
 
+        m_diffuse = TVec3f(0.8f, 0.8f, 0.8f);
+        m_emissive = TVec3f(0.f, 0.f, 0.f);
+        m_specular = TVec3f(1.f, 1.f, 1.f);
+
+        m_shininess = 0.2f;
+        m_transparency = 0.f;
+
+        m_isSmooth = false;
+
+    }
+
+    bool Material::isSmooth() const
+    {
+        return m_isSmooth;
     }
 
+    void Material::setIsSmooth(bool isSmooth)
+    {
+        m_isSmooth = isSmooth;
+    }
+
+
     TVec3f Material::getDiffuse() const
     {
         return m_diffuse;
diff --git a/sources/src/parser/appearanceelementparser.cpp b/sources/src/parser/appearanceelementparser.cpp
index 7e2ff36..2f6456c 100644
--- a/sources/src/parser/appearanceelementparser.cpp
+++ b/sources/src/parser/appearanceelementparser.cpp
@@ -10,6 +10,7 @@
 #include "parser/textureelementparser.h"
 #include "parser/materialelementparser.h"
 #include "parser/georeferencedtextureelementparser.h"
+#include "parser/skipelementparser.h"
 
 #include "citygml/appearance.h"
 #include "citygml/texture.h"
@@ -17,13 +18,14 @@
 #include "citygml/georeferencedtexture.h"
 #include "citygml/citygmlfactory.h"
 #include "citygml/citygmllogger.h"
+#include "citygml/object.h"
 
 #include <stdexcept>
 
 namespace citygml {
 
     AppearanceElementParser::AppearanceElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger)
-        : CityGMLElementParser(documentParser, factory, logger)
+        : GMLObjectElementParser(documentParser, factory, logger)
     {
 
     }
@@ -44,13 +46,15 @@ namespace citygml {
             CITYGML_LOG_ERROR(m_logger, "Expected start tag <" << NodeType::APP_AppearanceNode.name() << "> got <" << node << "> at " << getDocumentLocation());
             throw std::runtime_error("Unexpected start tag found.");
         }
+
+        m_appearanceObj = std::make_shared<Object>(attributes.getCityGMLIDAttribute());
         return true;
     }
 
     bool AppearanceElementParser::parseElementEndTag(const NodeType::XMLNode&, const std::string&)
     {
         if (m_theme.empty()) {
-            CITYGML_LOG_ERROR(m_logger, "Appearance node that ends at " << getDocumentLocation() << " has not theme defined. Using empty theme.");
+            CITYGML_LOG_INFO(m_logger, "Appearance node that ends at " << getDocumentLocation() << " has not theme defined. Using empty theme.");
         }
 
         if (m_surfaceDataList.empty()) {
@@ -97,7 +101,7 @@ namespace citygml {
             return true;
 
         }
-        return false;
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
     }
 
     bool AppearanceElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
@@ -111,7 +115,12 @@ namespace citygml {
         } else if (node == NodeType::APP_SurfaceDataMemberNode) {
             return true;
         }
-        return false;
+        return GMLObjectElementParser::parseChildElementEndTag(node, characters);
+    }
+
+    Object* AppearanceElementParser::getObject()
+    {
+        return m_appearanceObj.get();
     }
 
 
diff --git a/sources/src/parser/cityobjectelementparser.cpp b/sources/src/parser/cityobjectelementparser.cpp
index 3445fb0..3c98d8d 100644
--- a/sources/src/parser/cityobjectelementparser.cpp
+++ b/sources/src/parser/cityobjectelementparser.cpp
@@ -5,6 +5,7 @@
 #include "parser/appearanceelementparser.h"
 #include "parser/geometryelementparser.h"
 #include "parser/implicitgeometryelementparser.h"
+#include "parser/skipelementparser.h"
 
 #include "citygml/citygmlfactory.h"
 #include "citygml/citygmllogger.h"
@@ -23,6 +24,7 @@ namespace citygml {
     std::mutex CityObjectElementParser::initializedAttributeSetMutex;
 
     #define HANDLE_TYPE( prefix, elementName ) std::pair<int, CityObject::CityObjectsType>(NodeType::prefix ## _ ## elementName ## Node.typeID(), CityObject::COT_ ## elementName)
+    #define HANDLE_GROUP_TYPE( prefix, elementName, enumtype ) std::pair<int, CityObject::CityObjectsType>(NodeType::prefix ## _ ## elementName ## Node.typeID(), enumtype)
     #define HANDLE_ATTR( prefix, elementName ) NodeType::prefix ## _ ## elementName ## Node.typeID()
 
     CityObjectElementParser::CityObjectElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void (CityObject*)> callback)
@@ -57,10 +59,15 @@ namespace citygml {
                 typeIDTypeMap.insert(HANDLE_TYPE(TRANS, Road));
                 typeIDTypeMap.insert(HANDLE_TYPE(TRANS, Railway));
                 typeIDTypeMap.insert(HANDLE_TYPE(TRANS, Square));
+                typeIDTypeMap.insert(HANDLE_GROUP_TYPE(TRANS, TransportationComplex, CityObject::CityObjectsType::COT_TransportationObject));
+                typeIDTypeMap.insert(HANDLE_GROUP_TYPE(TRANS, TrafficArea, CityObject::CityObjectsType::COT_TransportationObject));
+                typeIDTypeMap.insert(HANDLE_GROUP_TYPE(TRANS, AuxiliaryTrafficArea, CityObject::CityObjectsType::COT_TransportationObject));
                 typeIDTypeMap.insert(HANDLE_TYPE(VEG, PlantCover));
                 typeIDTypeMap.insert(HANDLE_TYPE(VEG, SolitaryVegetationObject));
                 typeIDTypeMap.insert(HANDLE_TYPE(WTR, WaterBody));
-                typeIDTypeMap.insert(HANDLE_TYPE(LUSE, TINRelief));
+                typeIDTypeMap.insert(HANDLE_GROUP_TYPE(WTR, WaterSurface, CityObject::COT_WaterBody));
+                typeIDTypeMap.insert(HANDLE_GROUP_TYPE(WTR, WaterGroundSurface, CityObject::COT_WaterBody));
+                typeIDTypeMap.insert(HANDLE_GROUP_TYPE(WTR, WaterClosureSurface, CityObject::COT_WaterBody));
                 typeIDTypeMap.insert(HANDLE_TYPE(LUSE, LandUse));
                 typeIDTypeMap.insert(HANDLE_TYPE(SUB, Tunnel));
                 typeIDTypeMap.insert(HANDLE_TYPE(BRID, Bridge));
@@ -74,6 +81,8 @@ namespace citygml {
                 typeIDTypeMap.insert(HANDLE_TYPE(BLDG, FloorSurface));
                 typeIDTypeMap.insert(HANDLE_TYPE(BLDG, InteriorWallSurface));
                 typeIDTypeMap.insert(HANDLE_TYPE(BLDG, CeilingSurface));
+                typeIDTypeMap.insert(HANDLE_TYPE(GRP, CityObjectGroup));
+                typeIDTypeMap.insert(HANDLE_TYPE(DEM, ReliefFeature));
 
                 typeIDTypeMapInitialized = true;
             }
@@ -96,10 +105,13 @@ namespace citygml {
                 attributesSet.insert(HANDLE_ATTR(BLDG, YearOfConstruction));
                 attributesSet.insert(HANDLE_ATTR(BLDG, YearOfDemolition));
                 attributesSet.insert(HANDLE_ATTR(BLDG, StoreyHeightsAboveGround));
+                attributesSet.insert(HANDLE_ATTR(BLDG, StoreyHeightsBelowGround));
                 attributesSet.insert(HANDLE_ATTR(BLDG, StoreysBelowGround));
+                attributesSet.insert(HANDLE_ATTR(BLDG, StoreysAboveGround));
                 attributesSet.insert(HANDLE_ATTR(BLDG, MeasuredHeight));
-                attributesSet.insert(HANDLE_ATTR(BLDG, Address));
                 attributesSet.insert(HANDLE_ATTR(BLDG, RoofType));
+                attributesSet.insert(HANDLE_ATTR(CORE, Address));
+                attributesSet.insert(HANDLE_ATTR(BLDG, Address));
                 attributesSet.insert(HANDLE_ATTR(XAL, XalAddress));
                 attributesSet.insert(HANDLE_ATTR(XAL, Administrativearea));
                 attributesSet.insert(HANDLE_ATTR(XAL, Country));
@@ -115,6 +127,32 @@ namespace citygml {
                 attributesSet.insert(HANDLE_ATTR(XAL, Locality));
                 attributesSet.insert(HANDLE_ATTR(XAL, AddressDetails));
                 attributesSet.insert(HANDLE_ATTR(XAL, DependentLocalityName));
+                attributesSet.insert(HANDLE_ATTR(VEG, Class ));
+                attributesSet.insert(HANDLE_ATTR(VEG, Function ));
+                attributesSet.insert(HANDLE_ATTR(VEG, AverageHeight ));
+                attributesSet.insert(HANDLE_ATTR(VEG, Species ));
+                attributesSet.insert(HANDLE_ATTR(VEG, Height ));
+                attributesSet.insert(HANDLE_ATTR(VEG, TrunkDiameter ));
+                attributesSet.insert(HANDLE_ATTR(VEG, CrownDiameter ));
+                attributesSet.insert(HANDLE_ATTR(FRN, Class));
+                attributesSet.insert(HANDLE_ATTR(FRN, Function));
+                attributesSet.insert(HANDLE_ATTR(GRP, Class));
+                attributesSet.insert(HANDLE_ATTR(GRP, Function));
+                attributesSet.insert(HANDLE_ATTR(GRP, Usage));
+                attributesSet.insert(HANDLE_ATTR(GEN, Class));
+                attributesSet.insert(HANDLE_ATTR(GEN, Function));
+                attributesSet.insert(HANDLE_ATTR(GEN, Usage));
+                attributesSet.insert(HANDLE_ATTR(LUSE, Class));
+                attributesSet.insert(HANDLE_ATTR(LUSE, Function));
+                attributesSet.insert(HANDLE_ATTR(LUSE, Usage));
+                attributesSet.insert(HANDLE_ATTR(DEM, Lod));
+                attributesSet.insert(HANDLE_ATTR(TRANS, Usage));
+                attributesSet.insert(HANDLE_ATTR(TRANS, Function));
+                attributesSet.insert(HANDLE_ATTR(TRANS, SurfaceMaterial));
+                attributesSet.insert(HANDLE_ATTR(WTR, Class));
+                attributesSet.insert(HANDLE_ATTR(WTR, Function));
+                attributesSet.insert(HANDLE_ATTR(WTR, Usage));
+                attributesSet.insert(HANDLE_ATTR(WTR, WaterLevel));
 
                 attributesSetInitialized = true;
             }
@@ -177,7 +215,12 @@ namespace citygml {
                    || node == NodeType::BLDG_RoomInstallationNode
                    || node == NodeType::BLDG_InteriorRoomNode
                    || node == NodeType::BLDG_OpeningNode
-                   || node == NodeType::BLDG_ConsistsOfBuildingPartNode) {
+                   || node == NodeType::BLDG_ConsistsOfBuildingPartNode
+                   || node == NodeType::GRP_GroupMemberNode
+                   || node == NodeType::GRP_ParentNode
+                   || node == NodeType::TRANS_TrafficAreaNode
+                   || node == NodeType::TRANS_AuxiliaryTrafficAreaNode
+                   || node == NodeType::WTR_BoundedByNode) {
             setParserForNextElement(new CityObjectElementParser(m_documentParser, m_factory, m_logger, [this](CityObject* obj) {
                                         m_model->addChildCityObject(obj);
                                     }));
@@ -193,7 +236,12 @@ namespace citygml {
                    || node == NodeType::GEN_Lod1GeometryNode
                    || node == NodeType::GEN_Lod1TerrainIntersectionNode
                    || node == NodeType::FRN_Lod1GeometryNode
-                   || node == NodeType::FRN_Lod1TerrainIntersectionNode) {
+                   || node == NodeType::FRN_Lod1TerrainIntersectionNode
+                   || node == NodeType::LUSE_Lod1MultiSurfaceNode
+                   || node == NodeType::TRANS_Lod1MultiSurfaceNode
+                   || node == NodeType::WTR_Lod1MultiCurveNode
+                   || node == NodeType::WTR_Lod1MultiSurfaceNode
+                   || node == NodeType::WTR_Lod1SolidNode) {
 
             parseGeometryForLODLevel(1);
         } else if (node == NodeType::BLDG_Lod2GeometryNode
@@ -204,7 +252,11 @@ namespace citygml {
                    || node == NodeType::GEN_Lod2GeometryNode
                    || node == NodeType::GEN_Lod2TerrainIntersectionNode
                    || node == NodeType::FRN_Lod2GeometryNode
-                   || node == NodeType::FRN_Lod2TerrainIntersectionNode) {
+                   || node == NodeType::FRN_Lod2TerrainIntersectionNode
+                   || node == NodeType::LUSE_Lod2MultiSurfaceNode
+                   || node == NodeType::TRANS_Lod2MultiSurfaceNode
+                   || node == NodeType::WTR_Lod2SolidNode
+                   || node == NodeType::WTR_Lod2SurfaceNode) {
 
             parseGeometryForLODLevel(2);
         } else if (node == NodeType::BLDG_Lod3GeometryNode
@@ -215,7 +267,11 @@ namespace citygml {
                    || node == NodeType::GEN_Lod3GeometryNode
                    || node == NodeType::GEN_Lod3TerrainIntersectionNode
                    || node == NodeType::FRN_Lod3GeometryNode
-                   || node == NodeType::FRN_Lod3TerrainIntersectionNode) {
+                   || node == NodeType::FRN_Lod3TerrainIntersectionNode
+                   || node == NodeType::LUSE_Lod3MultiSurfaceNode
+                   || node == NodeType::TRANS_Lod3MultiSurfaceNode
+                   || node == NodeType::WTR_Lod3SolidNode
+                   || node == NodeType::WTR_Lod3SurfaceNode) {
 
             parseGeometryForLODLevel(3);
         } else if (node == NodeType::BLDG_Lod4GeometryNode
@@ -226,30 +282,48 @@ namespace citygml {
                    || node == NodeType::GEN_Lod4GeometryNode
                    || node == NodeType::GEN_Lod4TerrainIntersectionNode
                    || node == NodeType::FRN_Lod4GeometryNode
-                   || node == NodeType::FRN_Lod4TerrainIntersectionNode) {
+                   || node == NodeType::FRN_Lod4TerrainIntersectionNode
+                   || node == NodeType::LUSE_Lod4MultiSurfaceNode
+                   || node == NodeType::TRANS_Lod4MultiSurfaceNode
+                   || node == NodeType::WTR_Lod4SolidNode
+                   || node == NodeType::WTR_Lod4SurfaceNode) {
 
             parseGeometryForLODLevel(4);
         } else if (node == NodeType::VEG_Lod1ImplicitRepresentationNode
-                   || node == NodeType::FRN_Lod1ImplicitRepresentationNode) {
+                   || node == NodeType::FRN_Lod1ImplicitRepresentationNode
+                   || node == NodeType::GEN_Lod1ImplicitRepresentationNode) {
 
             parseImplicitGeometryForLODLevel(1);
         } else if (node == NodeType::VEG_Lod2ImplicitRepresentationNode
-                   || node == NodeType::FRN_Lod2ImplicitRepresentationNode) {
+                   || node == NodeType::FRN_Lod2ImplicitRepresentationNode
+                   || node == NodeType::GEN_Lod2ImplicitRepresentationNode) {
 
             parseImplicitGeometryForLODLevel(2);
         } else if (node == NodeType::VEG_Lod3ImplicitRepresentationNode
-                   || node == NodeType::FRN_Lod3ImplicitRepresentationNode) {
+                   || node == NodeType::FRN_Lod3ImplicitRepresentationNode
+                   || node == NodeType::GEN_Lod3ImplicitRepresentationNode) {
 
             parseImplicitGeometryForLODLevel(3);
         } else if (node == NodeType::VEG_Lod4ImplicitRepresentationNode
-                   || node == NodeType::FRN_Lod4ImplicitRepresentationNode) {
+                   || node == NodeType::FRN_Lod4ImplicitRepresentationNode
+                   || node == NodeType::GEN_Lod4ImplicitRepresentationNode) {
 
             parseImplicitGeometryForLODLevel(4);
-        } else if (node == NodeType::BLDG_ExternalReferenceNode
-                   || node == NodeType::BLDG_InformationSystemNode
-                   || node == NodeType::BLDG_ExternalObjectNode
-                   || node == NodeType::BLDG_UriNode) {
+        } else if (node == NodeType::CORE_GeneralizesToNode
+                   || node == NodeType::CORE_ExternalReferenceNode
+                   || node == NodeType::GML_MultiPointNode
+                   || node == NodeType::GRP_GeometryNode
+                   || node == NodeType::DEM_ReliefComponentNode
+                   || node == NodeType::GEN_Lod0GeometryNode
+                   || node == NodeType::GEN_Lod0ImplicitRepresentationNode
+                   || node == NodeType::GEN_Lod0TerrainIntersectionNode
+                   || node == NodeType::TRANS_Lod0NetworkNode
+                   || node == NodeType::WTR_Lod0MultiCurveNode
+                   || node == NodeType::WTR_Lod0MultiSurfaceNode) {
+            CITYGML_LOG_INFO(m_logger, "Skipping CityObject child element <" << node  << ">  at " << getDocumentLocation() << " (Currently not supported!)");
+            setParserForNextElement(new SkipElementParser(m_documentParser, m_logger, node));
             return true;
+
         } else {
             return GMLFeatureCollectionElementParser::parseChildElementStartTag(node, attributes);
         }
@@ -326,14 +400,15 @@ namespace citygml {
                     || node == NodeType::GEN_Lod2TerrainIntersectionNode
                     || node == NodeType::GEN_Lod3TerrainIntersectionNode
                     || node == NodeType::GEN_Lod4TerrainIntersectionNode
+                    || node == NodeType::GEN_Lod1ImplicitRepresentationNode
+                    || node == NodeType::GEN_Lod2ImplicitRepresentationNode
+                    || node == NodeType::GEN_Lod3ImplicitRepresentationNode
+                    || node == NodeType::GEN_Lod4ImplicitRepresentationNode
                     || node == NodeType::VEG_Lod1ImplicitRepresentationNode
                     || node == NodeType::VEG_Lod2ImplicitRepresentationNode
                     || node == NodeType::VEG_Lod3ImplicitRepresentationNode
                     || node == NodeType::VEG_Lod4ImplicitRepresentationNode
-                    || node == NodeType::BLDG_ExternalReferenceNode
-                    || node == NodeType::BLDG_InformationSystemNode
-                    || node == NodeType::BLDG_ExternalObjectNode
-                    || node == NodeType::BLDG_UriNode
+                    || node == NodeType::CORE_ExternalReferenceNode
                     || node == NodeType::BLDG_ConsistsOfBuildingPartNode
                     || node == NodeType::FRN_Lod1GeometryNode
                     || node == NodeType::FRN_Lod1TerrainIntersectionNode
@@ -346,7 +421,38 @@ namespace citygml {
                     || node == NodeType::FRN_Lod3ImplicitRepresentationNode
                     || node == NodeType::FRN_Lod4GeometryNode
                     || node == NodeType::FRN_Lod4TerrainIntersectionNode
-                    || node == NodeType::FRN_Lod4ImplicitRepresentationNode) {
+                    || node == NodeType::FRN_Lod4ImplicitRepresentationNode
+                    || node == NodeType::CORE_GeneralizesToNode
+                    || node == NodeType::GML_MultiPointNode
+                    || node == NodeType::GRP_GroupMemberNode
+                    || node == NodeType::GRP_ParentNode
+                    || node == NodeType::LUSE_Lod1MultiSurfaceNode
+                    || node == NodeType::LUSE_Lod2MultiSurfaceNode
+                    || node == NodeType::LUSE_Lod3MultiSurfaceNode
+                    || node == NodeType::LUSE_Lod4MultiSurfaceNode
+                    || node == NodeType::DEM_ReliefComponentNode
+                    || node == NodeType::GEN_Lod0GeometryNode
+                    || node == NodeType::GEN_Lod0ImplicitRepresentationNode
+                    || node == NodeType::GEN_Lod0TerrainIntersectionNode
+                    || node == NodeType::TRANS_Lod0NetworkNode
+                    || node == NodeType::TRANS_TrafficAreaNode
+                    || node == NodeType::TRANS_AuxiliaryTrafficAreaNode
+                    || node == NodeType::TRANS_Lod1MultiSurfaceNode
+                    || node == NodeType::TRANS_Lod2MultiSurfaceNode
+                    || node == NodeType::TRANS_Lod3MultiSurfaceNode
+                    || node == NodeType::TRANS_Lod4MultiSurfaceNode
+                    || node == NodeType::WTR_Lod0MultiCurveNode
+                    || node == NodeType::WTR_Lod0MultiSurfaceNode
+                    || node == NodeType::WTR_Lod1MultiCurveNode
+                    || node == NodeType::WTR_Lod1MultiSurfaceNode
+                    || node == NodeType::WTR_Lod1SolidNode
+                    || node == NodeType::WTR_Lod2SolidNode
+                    || node == NodeType::WTR_Lod3SolidNode
+                    || node == NodeType::WTR_Lod4SolidNode
+                    || node == NodeType::WTR_Lod2SurfaceNode
+                    || node == NodeType::WTR_Lod3SurfaceNode
+                    || node == NodeType::WTR_Lod4SurfaceNode
+                    || node == NodeType::WTR_BoundedByNode) {
 
             return true;
         }
diff --git a/sources/src/parser/geometryelementparser.cpp b/sources/src/parser/geometryelementparser.cpp
index 11ad015..96c1f4a 100644
--- a/sources/src/parser/geometryelementparser.cpp
+++ b/sources/src/parser/geometryelementparser.cpp
@@ -7,12 +7,15 @@
 #include "parser/documentlocation.h"
 #include "parser/polygonelementparser.h"
 #include "parser/delayedchoiceelementparser.h"
+#include "parser/sequenceparser.h"
 
 #include "citygml/geometry.h"
 #include "citygml/citygmlfactory.h"
 #include "citygml/citygmllogger.h"
 #include "citygml/polygon.h"
 
+#include <mutex>
+
 #include <stdexcept>
 
 namespace citygml {
@@ -21,10 +24,11 @@ namespace citygml {
     // The nodes that are valid Geometry Objects
     std::unordered_set<int> geometryTypeIDSet;
     bool geometryTypeIDSetInitialized = false;
+    std::mutex geometryElement_initializedTypeIDMutex;
 
     GeometryElementParser::GeometryElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger,
                                                  int lodLevel, CityObject::CityObjectsType parentType,  std::function<void(Geometry*)> callback)
-        : CityGMLElementParser(documentParser, factory, logger)
+        : GMLObjectElementParser(documentParser, factory, logger)
     {
         m_callback = callback;
         m_lodLevel = lodLevel;
@@ -39,15 +43,26 @@ namespace citygml {
     bool GeometryElementParser::handlesElement(const NodeType::XMLNode& node) const
     {
         if(!geometryTypeIDSetInitialized) {
-            geometryTypeIDSet.insert(NodeType::GML_CompositeSolidNode.typeID());
-            geometryTypeIDSet.insert(NodeType::GML_SolidNode.typeID());
-            geometryTypeIDSet.insert(NodeType::GML_MultiSurfaceNode.typeID());
-            geometryTypeIDSet.insert(NodeType::GML_CompositeSurfaceNode.typeID());
-            geometryTypeIDSet.insert(NodeType::GML_TriangulatedSurfaceNode.typeID());
-            geometryTypeIDSet.insert(NodeType::GML_OrientableSurfaceNode.typeID());
-            geometryTypeIDSet.insert(NodeType::GML_MultiSolidNode.typeID());
-            geometryTypeIDSet.insert(NodeType::GML_CompositeSolidNode.typeID());
-            geometryTypeIDSetInitialized = true;
+
+            std::lock_guard<std::mutex> lock(geometryElement_initializedTypeIDMutex);
+
+            if (!geometryTypeIDSetInitialized) {
+
+                geometryTypeIDSet.insert(NodeType::GML_CompositeSolidNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_SolidNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_MultiSurfaceNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_CompositeSurfaceNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_TriangulatedSurfaceNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_OrientableSurfaceNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_MultiSolidNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_CompositeSolidNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_ShellNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_PolyhedralSurfaceNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_SurfaceNode.typeID());
+                geometryTypeIDSet.insert(NodeType::GML_ShellNode.typeID());
+                geometryTypeIDSetInitialized = true;
+
+            }
         }
 
         return geometryTypeIDSet.count(node.typeID()) > 0;
@@ -120,9 +135,7 @@ namespace citygml {
             return true;
 
         } else if (node == NodeType::GML_SurfaceMemberNode
-                   || node == NodeType::GML_BaseSurfaceNode
-                   || node == NodeType::GML_PatchesNode
-                   || node == NodeType::GML_TrianglePatchesNode) {
+                   || node == NodeType::GML_BaseSurfaceNode) {
 
             if (attributes.hasXLinkAttribute()) {
                 m_factory.requestSharedPolygonForGeometry(m_model, attributes.getXLinkValue());
@@ -138,9 +151,18 @@ namespace citygml {
                 setParserForNextElement(new DelayedChoiceElementParser(m_documentParser, m_logger, parsers));
             }
             return true;
+        } else if (node == NodeType::GML_PatchesNode
+                   || node == NodeType::GML_TrianglePatchesNode) {
+
+            std::function<ElementParser*()> patchParserFactory = [this]() {
+                return new PolygonElementParser(m_documentParser, m_factory, m_logger, [this](std::shared_ptr<Polygon> poly) {m_model->addPolygon(poly);});
+            };
+
+            setParserForNextElement(new SequenceParser(m_documentParser, m_logger, patchParserFactory, node));
+
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
     }
 
     bool GeometryElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
@@ -160,8 +182,13 @@ namespace citygml {
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementEndTag(node, characters);
 
     }
 
+    Object* GeometryElementParser::getObject()
+    {
+        return m_model;
+    }
+
 }
diff --git a/sources/src/parser/georeferencedtextureelementparser.cpp b/sources/src/parser/georeferencedtextureelementparser.cpp
index 3e14aeb..6520ab5 100644
--- a/sources/src/parser/georeferencedtextureelementparser.cpp
+++ b/sources/src/parser/georeferencedtextureelementparser.cpp
@@ -5,6 +5,7 @@
 #include "parser/nodetypes.h"
 #include "parser/attributes.h"
 #include "parser/documentlocation.h"
+#include "parser/skipelementparser.h"
 
 #include "citygml/georeferencedtexture.h"
 #include "citygml/citygmlfactory.h"
@@ -37,25 +38,28 @@ namespace citygml {
             CITYGML_LOG_ERROR(m_logger, "Expected start tag <" << NodeType::APP_GeoreferencedTextureNode.name() << "> got " << node << " at " << getDocumentLocation());
             throw std::runtime_error("Unexpected start tag found.");
         }
+
+        CITYGML_LOG_WARN(m_logger, "Skipping contents of GeoReferencedTextureElement at " << getDocumentLocation() << ". (Currently not supported!)");
+
         return true;
     }
 
     bool GeoReferencedTextureElementParser::parseElementEndTag(const NodeType::XMLNode&, const std::string&)
     {
         // Not Implemented
-        return false;
+        return true;
     }
 
     bool GeoReferencedTextureElementParser::parseChildElementStartTag(const NodeType::XMLNode&, Attributes&)
     {
-        // Not Implemented
-        return false;
+        setParserForNextElement(new SkipElementParser(m_documentParser, m_logger));
+        return true;
     }
 
     bool GeoReferencedTextureElementParser::parseChildElementEndTag(const NodeType::XMLNode&, const std::string&)
     {
-        // Not Implemented
-        return false;
+        setParserForNextElement(new SkipElementParser(m_documentParser, m_logger));
+        return true;
     }
 
 
diff --git a/sources/src/parser/gmlfeaturecollectionparser.cpp b/sources/src/parser/gmlfeaturecollectionparser.cpp
index a0e6920..fc1d287 100644
--- a/sources/src/parser/gmlfeaturecollectionparser.cpp
+++ b/sources/src/parser/gmlfeaturecollectionparser.cpp
@@ -16,7 +16,7 @@
 namespace citygml {
 
     GMLFeatureCollectionElementParser::GMLFeatureCollectionElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger)
-        : CityGMLElementParser(documentParser, factory, logger)
+        : GMLObjectElementParser(documentParser, factory, logger)
     {
         m_bounds = nullptr;
     }
@@ -27,14 +27,9 @@ namespace citygml {
             throw std::runtime_error("Invalid call to GMLFeatureCollectionElementParser::parseChildElementStartTag");
         }
 
-        if (   node == NodeType::GML_DescriptionNode
-            || node == NodeType::GML_IdentifierNode
-            || node == NodeType::GML_NameNode
-            || node == NodeType::GML_DescriptionReferenceNode
-            || node == NodeType::GML_LowerCornerNode
-            || node == NodeType::GML_UpperCornerNode
-            || node == NodeType::GML_BoundedByNode) {
-
+        if (node == NodeType::GML_LowerCornerNode
+                || node == NodeType::GML_UpperCornerNode
+                || node == NodeType::GML_BoundedByNode) {
             return true;
         } else if (node == NodeType::GML_EnvelopeNode) {
 
@@ -46,7 +41,7 @@ namespace citygml {
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
     }
 
     bool GMLFeatureCollectionElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
@@ -55,14 +50,7 @@ namespace citygml {
             throw std::runtime_error("Invalid call to GMLFeatureCollectionElementParser::parseChildElementEndTag");
         }
 
-        if (   node == NodeType::GML_DescriptionNode
-            || node == NodeType::GML_IdentifierNode
-            || node == NodeType::GML_NameNode
-            || node == NodeType::GML_DescriptionReferenceNode) {
-
-                getFeatureObject()->setAttribute(node.name(), characters);
-                return true;
-        } else if (node == NodeType::GML_LowerCornerNode) {
+        if (node == NodeType::GML_LowerCornerNode) {
 
             if (m_bounds != nullptr) {
                 m_bounds->setLowerBound(parseValue<TVec3d>(characters, m_logger, getDocumentLocation()));
@@ -87,7 +75,12 @@ namespace citygml {
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementEndTag(node, characters);
+    }
+
+    Object* GMLFeatureCollectionElementParser::getObject()
+    {
+        return getFeatureObject();
     }
 
 
diff --git a/sources/src/parser/gmlobjectparser.cpp b/sources/src/parser/gmlobjectparser.cpp
new file mode 100644
index 0000000..151035c
--- /dev/null
+++ b/sources/src/parser/gmlobjectparser.cpp
@@ -0,0 +1,50 @@
+#include "parser/gmlobjectparser.h"
+
+#include <citygml/object.h>
+
+namespace citygml {
+
+    GMLObjectElementParser::GMLObjectElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger)
+        : CityGMLElementParser(documentParser, factory, logger)
+    {
+
+    }
+
+    bool GMLObjectElementParser::parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes)
+    {
+        if (getObject() == nullptr) {
+            throw std::runtime_error("Invalid call to GMLObjectElementParser::parseChildElementStartTag");
+        }
+
+        if (   node == NodeType::GML_DescriptionNode
+            || node == NodeType::GML_IdentifierNode
+            || node == NodeType::GML_NameNode
+            || node == NodeType::GML_DescriptionReferenceNode
+            || node == NodeType::GML_MetaDataPropertyNode) {
+
+            return true;
+        }
+
+        return false;
+    }
+
+    bool GMLObjectElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
+    {
+        if (getObject() == nullptr) {
+            throw std::runtime_error("Invalid call to GMLObjectElementParser::parseChildElementEndTag");
+        }
+
+        if (   node == NodeType::GML_DescriptionNode
+            || node == NodeType::GML_IdentifierNode
+            || node == NodeType::GML_NameNode
+            || node == NodeType::GML_DescriptionReferenceNode
+            || node == NodeType::GML_MetaDataPropertyNode) {
+
+                getObject()->setAttribute(node.name(), characters);
+                return true;
+        }
+
+        return false;
+    }
+
+}
diff --git a/sources/src/parser/implicitgeometryelementparser.cpp b/sources/src/parser/implicitgeometryelementparser.cpp
index 5d37387..72c7bfc 100644
--- a/sources/src/parser/implicitgeometryelementparser.cpp
+++ b/sources/src/parser/implicitgeometryelementparser.cpp
@@ -7,6 +7,7 @@
 #include "parser/documentlocation.h"
 #include "parser/geometryelementparser.h"
 #include "parser/parserutils.hpp"
+#include "parser/skipelementparser.h"
 
 #include "citygml/implictgeometry.h"
 #include "citygml/citygmlfactory.h"
@@ -19,7 +20,7 @@ namespace citygml {
 
     ImplicitGeometryElementParser::ImplicitGeometryElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger,
                                                  int lodLevel, CityObject::CityObjectsType parentType,  std::function<void(ImplicitGeometry*)> callback)
-        : CityGMLElementParser(documentParser, factory, logger)
+        : GMLObjectElementParser(documentParser, factory, logger)
     {
         m_callback = callback;
         m_lodLevel = lodLevel;
@@ -64,7 +65,9 @@ namespace citygml {
         }
 
         if (   node == NodeType::CORE_TransformationMatrixNode
-            || node == NodeType::GML_ReferencePointNode) {
+            || node == NodeType::CORE_ReferencePointNode
+            || node == NodeType::GML_ReferencePointNode
+            || node == NodeType::CORE_MimeTypeNode) {
 
             return true;
 
@@ -94,9 +97,13 @@ namespace citygml {
                                     }));
             }
             return true;
+        } else if (node == NodeType::CORE_LibraryObjectNode) {
+            CITYGML_LOG_INFO(m_logger, "Skipping ImplicitGeometry child element <" << node  << ">  at " << getDocumentLocation() << " (Currently not supported!)");
+            setParserForNextElement(new SkipElementParser(m_documentParser, m_logger));
+            return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
     }
 
     bool ImplicitGeometryElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
@@ -117,13 +124,22 @@ namespace citygml {
             return true;
         } else if (   node == NodeType::CORE_RelativeGMLGeometryNode
                    || node == NodeType::GML_PointNode
-                   || node == NodeType::GML_ReferencePointNode) {
+                   || node == NodeType::CORE_ReferencePointNode
+                   || node == NodeType::GML_ReferencePointNode
+                   || node == NodeType::CORE_LibraryObjectNode) {
 
             return true;
+        } else if (node == NodeType::CORE_MimeTypeNode) {
+            m_model->setAttribute(node.name(), characters);
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementEndTag(node, characters);
+
+    }
 
+    Object* ImplicitGeometryElementParser::getObject()
+    {
+        return m_model;
     }
 
 }
diff --git a/sources/src/parser/linearringelementparser.cpp b/sources/src/parser/linearringelementparser.cpp
index 13ba822..25d60c0 100644
--- a/sources/src/parser/linearringelementparser.cpp
+++ b/sources/src/parser/linearringelementparser.cpp
@@ -16,7 +16,7 @@
 namespace citygml {
 
     LinearRingElementParser::LinearRingElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, bool interior, std::function<void(LinearRing*)> callback)
-        : CityGMLElementParser(documentParser, factory, logger)
+        : GMLObjectElementParser(documentParser, factory, logger)
     {
         m_callback = callback;
         m_interior = interior;
@@ -70,7 +70,7 @@ namespace citygml {
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
     }
 
     bool LinearRingElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
@@ -88,8 +88,13 @@ namespace citygml {
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementEndTag(node, characters);
 
     }
 
+    Object* LinearRingElementParser::getObject()
+    {
+        return m_model;
+    }
+
 }
diff --git a/sources/src/parser/materialelementparser.cpp b/sources/src/parser/materialelementparser.cpp
index 31428f9..228534d 100644
--- a/sources/src/parser/materialelementparser.cpp
+++ b/sources/src/parser/materialelementparser.cpp
@@ -6,6 +6,7 @@
 #include "parser/attributes.h"
 #include "parser/documentlocation.h"
 #include "parser/parserutils.hpp"
+#include "parser/skipelementparser.h"
 
 #include "citygml/material.h"
 #include "citygml/citygmlfactory.h"
@@ -16,7 +17,7 @@
 namespace citygml {
 
     MaterialElementParser::MaterialElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void(std::shared_ptr<Material>)> callback)
-        : CityGMLElementParser(documentParser, factory, logger)
+        : GMLObjectElementParser(documentParser, factory, logger)
     {
         m_model = nullptr;
         m_callback = callback;
@@ -56,21 +57,21 @@ namespace citygml {
             throw std::runtime_error("MaterialElementParser::parseChildElementStartTag called before MaterialElementParser::parseElementStartTag");
         }
 
-        if (node == NodeType::GML_NameNode
-            || node == NodeType::APP_DiffuseColorNode
+        if (node == NodeType::APP_DiffuseColorNode
             || node == NodeType::APP_EmissiveColorNode
             || node == NodeType::APP_SpecularColorNode
             || node == NodeType::APP_ShininessNode
             || node == NodeType::APP_TransparencyNode
             || node == NodeType::APP_AmbientIntensityNode
-            || node == NodeType::APP_IsFrontNode) {
+            || node == NodeType::APP_IsFrontNode
+            || node == NodeType::APP_isSmoothNode) {
             return true;
         } else if (node == NodeType::APP_TargetNode) {
             m_lastTargetDefinitionID = attributes.getCityGMLIDAttribute();
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
     }
 
     bool MaterialElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
@@ -79,10 +80,7 @@ namespace citygml {
             throw std::runtime_error("MaterialElementParser::parseChildElementEndTag called before MaterialElementParser::parseElementStartTag");
         }
 
-        if (node == NodeType::GML_NameNode) {
-
-            m_model->setAttribute(node.name(), characters);
-        } else if (node == NodeType::APP_DiffuseColorNode) {
+        if (node == NodeType::APP_DiffuseColorNode) {
 
             m_model->setDiffuse(parseValue<TVec3f>(characters, m_logger, getDocumentLocation()));
         } else if (node == NodeType::APP_EmissiveColorNode) {
@@ -103,17 +101,23 @@ namespace citygml {
         } else if (node == NodeType::APP_IsFrontNode) {
 
             m_model->setIsFront(parseValue<bool>(characters, m_logger, getDocumentLocation()));
+        } else if (node == NodeType::APP_isSmoothNode) {
+
+            m_model->setIsSmooth(parseValue<bool>(characters, m_logger, getDocumentLocation()));
         } else if (node == NodeType::APP_TargetNode) {
 
             m_factory.createMaterialTargetDefinition(parseReference(characters, m_logger, getDocumentLocation()), m_model, m_lastTargetDefinitionID);
             m_lastTargetDefinitionID = "";
-        } else {
-            return false;
+        }  else {
+            return GMLObjectElementParser::parseChildElementEndTag(node, characters);
         }
         return true;
     }
 
-
+    Object* MaterialElementParser::getObject()
+    {
+        return m_model.get();
+    }
 
 
 }
diff --git a/sources/src/parser/nodetypes.cpp b/sources/src/parser/nodetypes.cpp
index 5e5dcde..3ab81ed 100644
--- a/sources/src/parser/nodetypes.cpp
+++ b/sources/src/parser/nodetypes.cpp
@@ -20,16 +20,21 @@ namespace citygml {
         m_typeID = NodeType::typeCount++;
     }
 
-    const std::string&NodeType::XMLNode::name() const
+    const std::string NodeType::XMLNode::name() const
     {
-        return m_name;
+        return m_prefix + ":" + m_name;
     }
 
-    const std::string&NodeType::XMLNode::prefix() const
+    const std::string& NodeType::XMLNode::prefix() const
     {
         return m_prefix;
     }
 
+    const std::string& NodeType::XMLNode::baseName() const
+    {
+        return m_name;
+    }
+
     int NodeType::XMLNode::typeID() const
     {
         return m_typeID;
@@ -50,10 +55,23 @@ namespace citygml {
         return !m_name.empty();
     }
 
+    std::ostream& operator<<(std::ostream& os, const NodeType::XMLNode& o)
+    {
+        if (!o.valid()) {
+            os << "InvalidNode";
+        } else {
+            os << o.name();
+        }
+
+        return os;
+    }
+
+    const NodeType::XMLNode NodeType::InvalidNode = XMLNode("", "");
+
 #define INITIALIZE_NODE( prefix, elementname ) \
     NodeType::prefix ## _ ## elementname ## Node = XMLNode( #prefix , #elementname ); \
     NodeType::nodeNameTypeMap[toLower(#elementname)] = &NodeType::prefix ## _ ## elementname ## Node; \
-    NodeType::nodeNameWithPrefixTypeMap[toLower(#prefix) + ":" + toLower(#elementname)] = &NodeType::prefix ## _ ## elementname ## Node;
+    NodeType::nodeNameWithPrefixTypeMap[toLower(#prefix ":" #elementname)] = &NodeType::prefix ## _ ## elementname ## Node;
 
     void NodeType::initializeNodeTypes()
     {
@@ -62,20 +80,43 @@ namespace citygml {
             std::lock_guard<std::mutex> lock(NodeType::initializedMutex);
 
             if (!nodesInitialized) {
+
                 // CORE
                 INITIALIZE_NODE( CORE, CityModel )
                 INITIALIZE_NODE( CORE, CityObjectMember )
                 INITIALIZE_NODE( CORE, CreationDate )
                 INITIALIZE_NODE( CORE, TerminationDate )
+                INITIALIZE_NODE( CORE, GeneralizesTo)
+
+                INITIALIZE_NODE( CORE, ExternalReference)
+                INITIALIZE_NODE( CORE, InformationSystem)
+                INITIALIZE_NODE( CORE, ExternalObject)
+
+                INITIALIZE_NODE( CORE, Uri)
+                INITIALIZE_NODE( CORE, Name)
+
+                INITIALIZE_NODE( CORE, Address )
+
                 INITIALIZE_NODE( CORE, ImplicitGeometry )
                 INITIALIZE_NODE( CORE, RelativeGMLGeometry )
                 INITIALIZE_NODE( CORE, TransformationMatrix )
+                INITIALIZE_NODE( CORE, ReferencePoint)
+                INITIALIZE_NODE( CORE, MimeType)
+                INITIALIZE_NODE( CORE, LibraryObject)
 
                 // GRP
                 INITIALIZE_NODE( GRP, CityObjectGroup )
                 INITIALIZE_NODE( GRP, GroupMember )
+                INITIALIZE_NODE( GRP, Class )
+                INITIALIZE_NODE( GRP, Function )
+                INITIALIZE_NODE( GRP, Usage )
+                INITIALIZE_NODE( GRP, Parent )
+                INITIALIZE_NODE( GRP, Geometry )
 
                 // GEN
+                INITIALIZE_NODE( GEN, Class )
+                INITIALIZE_NODE( GEN, Function )
+                INITIALIZE_NODE( GEN, Usage )
                 INITIALIZE_NODE( GEN, GenericCityObject )
                 INITIALIZE_NODE( GEN, StringAttribute )
                 INITIALIZE_NODE( GEN, DoubleAttribute )
@@ -84,14 +125,21 @@ namespace citygml {
                 INITIALIZE_NODE( GEN, UriAttribute )
                 INITIALIZE_NODE( GEN, Value )
 
+                INITIALIZE_NODE( GEN, Lod0Geometry )
                 INITIALIZE_NODE( GEN, Lod1Geometry )
                 INITIALIZE_NODE( GEN, Lod2Geometry )
                 INITIALIZE_NODE( GEN, Lod3Geometry )
                 INITIALIZE_NODE( GEN, Lod4Geometry )
+                INITIALIZE_NODE( GEN, Lod0TerrainIntersection )
                 INITIALIZE_NODE( GEN, Lod1TerrainIntersection )
                 INITIALIZE_NODE( GEN, Lod2TerrainIntersection )
                 INITIALIZE_NODE( GEN, Lod3TerrainIntersection )
                 INITIALIZE_NODE( GEN, Lod4TerrainIntersection )
+                INITIALIZE_NODE( GEN, Lod0ImplicitRepresentation )
+                INITIALIZE_NODE( GEN, Lod1ImplicitRepresentation )
+                INITIALIZE_NODE( GEN, Lod2ImplicitRepresentation )
+                INITIALIZE_NODE( GEN, Lod3ImplicitRepresentation )
+                INITIALIZE_NODE( GEN, Lod4ImplicitRepresentation )
 
                 // TEX
                 // INITIALIZE_NODE( GML, TexturedSurface ) // Deprecated
@@ -101,6 +149,7 @@ namespace citygml {
                 INITIALIZE_NODE( GML, Identifier )
                 INITIALIZE_NODE( GML, Name )
                 INITIALIZE_NODE( GML, DescriptionReference )
+                INITIALIZE_NODE( GML, MetaDataProperty )
                 INITIALIZE_NODE( GML, Coordinates )
                 INITIALIZE_NODE( GML, Pos )
                 INITIALIZE_NODE( GML, BoundedBy )
@@ -120,6 +169,10 @@ namespace citygml {
                 INITIALIZE_NODE( GML, PosList )
                 INITIALIZE_NODE( GML, OrientableSurface )
                 INITIALIZE_NODE( GML, LinearRing )
+                INITIALIZE_NODE( GML, Shell )
+                INITIALIZE_NODE( GML, PolyhedralSurface )
+                INITIALIZE_NODE( GML, Surface )
+                INITIALIZE_NODE( GML, PolygonPatch)
 
                 INITIALIZE_NODE( BLDG, Lod1Solid )
                 INITIALIZE_NODE( BLDG, Lod2Solid )
@@ -164,7 +217,6 @@ namespace citygml {
                 INITIALIZE_NODE( BLDG, Door )
                 INITIALIZE_NODE( BLDG, Window )
                 INITIALIZE_NODE( BLDG, BuildingInstallation )
-                INITIALIZE_NODE( BLDG, Address )
                 INITIALIZE_NODE( BLDG, MeasuredHeight )
                 INITIALIZE_NODE( BLDG, Class )
                 INITIALIZE_NODE( BLDG, Type )
@@ -186,6 +238,8 @@ namespace citygml {
                 INITIALIZE_NODE( BLDG, ConsistsOfBuildingPart )
 
                 // CityFurniture
+                INITIALIZE_NODE( FRN, Class )
+                INITIALIZE_NODE( FRN, Function )
                 INITIALIZE_NODE( FRN, CityFurniture )
                 INITIALIZE_NODE( FRN, Lod1Geometry )
                 INITIALIZE_NODE( FRN, Lod2Geometry )
@@ -210,13 +264,11 @@ namespace citygml {
                 INITIALIZE_NODE( BLDG, CeilingSurface )
                 INITIALIZE_NODE( BLDG, BuildingFurniture )
                 INITIALIZE_NODE( BLDG, RoofType)
-                INITIALIZE_NODE( BLDG, ExternalReference)
-                INITIALIZE_NODE( BLDG, InformationSystem)
-                INITIALIZE_NODE( BLDG, ExternalObject)
-                INITIALIZE_NODE( BLDG, Uri)
 
                 INITIALIZE_NODE( BLDG, CityFurniture )
 
+                INITIALIZE_NODE( BLDG, Address)
+
                 // ADDRESS
                 INITIALIZE_NODE( XAL, XalAddress )
                 INITIALIZE_NODE( XAL, Administrativearea )
@@ -233,19 +285,46 @@ namespace citygml {
                 INITIALIZE_NODE( XAL, Locality )
                 INITIALIZE_NODE( XAL, AddressDetails )
                 INITIALIZE_NODE( XAL, DependentLocalityName )
+
                 // WTR
                 INITIALIZE_NODE( WTR, WaterBody )
+                INITIALIZE_NODE( WTR, WaterSurface )
+                INITIALIZE_NODE( WTR, WaterGroundSurface )
+                INITIALIZE_NODE( WTR, WaterClosureSurface )
+                INITIALIZE_NODE( WTR, Class )
+                INITIALIZE_NODE( WTR, Function )
+                INITIALIZE_NODE( WTR, Usage )
+                INITIALIZE_NODE( WTR, WaterLevel )
+                INITIALIZE_NODE( WTR, Lod0MultiCurve )
+                INITIALIZE_NODE( WTR, Lod0MultiSurface )
+                INITIALIZE_NODE( WTR, Lod1MultiCurve )
+                INITIALIZE_NODE( WTR, Lod1MultiSurface )
+                INITIALIZE_NODE( WTR, Lod1Solid )
+                INITIALIZE_NODE( WTR, Lod2Solid )
+                INITIALIZE_NODE( WTR, Lod3Solid )
+                INITIALIZE_NODE( WTR, Lod4Solid )
+                INITIALIZE_NODE( WTR, Lod2Surface )
+                INITIALIZE_NODE( WTR, Lod3Surface )
+                INITIALIZE_NODE( WTR, Lod4Surface )
+                INITIALIZE_NODE( WTR, BoundedBy )
 
                 // VEG
                 INITIALIZE_NODE( VEG, PlantCover )
                 INITIALIZE_NODE( VEG, SolitaryVegetationObject )
-                INITIALIZE_NODE( VEG, Species )
                 INITIALIZE_NODE( VEG, Lod1ImplicitRepresentation )
                 INITIALIZE_NODE( VEG, Lod2ImplicitRepresentation )
                 INITIALIZE_NODE( VEG, Lod3ImplicitRepresentation )
                 INITIALIZE_NODE( VEG, Lod4ImplicitRepresentation )
+                INITIALIZE_NODE( VEG, Class )
+                INITIALIZE_NODE( VEG, Function )
+                INITIALIZE_NODE( VEG, AverageHeight )
+                INITIALIZE_NODE( VEG, Species )
+                INITIALIZE_NODE( VEG, Height )
+                INITIALIZE_NODE( VEG, TrunkDiameter )
+                INITIALIZE_NODE( VEG, CrownDiameter )
 
                 // TRANS
+                INITIALIZE_NODE( TRANS, TransportationComplex )
                 INITIALIZE_NODE( TRANS, TrafficArea )
                 INITIALIZE_NODE( TRANS, AuxiliaryTrafficArea )
                 INITIALIZE_NODE( TRANS, Track )
@@ -253,12 +332,43 @@ namespace citygml {
                 INITIALIZE_NODE( TRANS, Railway )
                 INITIALIZE_NODE( TRANS, Square )
 
+                INITIALIZE_NODE( TRANS, Usage )
+                INITIALIZE_NODE( TRANS, Function )
+                INITIALIZE_NODE( TRANS, SurfaceMaterial )
+
+                INITIALIZE_NODE( TRANS, Lod0Network )
+                INITIALIZE_NODE( TRANS, Lod1MultiSurface )
+                INITIALIZE_NODE( TRANS, Lod2MultiSurface )
+                INITIALIZE_NODE( TRANS, Lod3MultiSurface )
+                INITIALIZE_NODE( TRANS, Lod4MultiSurface )
+
                 // LUSE
                 INITIALIZE_NODE( LUSE, LandUse )
 
-                // dem
-                INITIALIZE_NODE( LUSE, Lod )
-                INITIALIZE_NODE( LUSE, TINRelief )
+                INITIALIZE_NODE( LUSE, Class )
+                INITIALIZE_NODE( LUSE, Usage )
+                INITIALIZE_NODE( LUSE, Function )
+
+                INITIALIZE_NODE( LUSE, Lod1MultiSurface )
+                INITIALIZE_NODE( LUSE, Lod2MultiSurface )
+                INITIALIZE_NODE( LUSE, Lod3MultiSurface )
+                INITIALIZE_NODE( LUSE, Lod4MultiSurface )
+
+                // DEM (Relief)
+                INITIALIZE_NODE( DEM, ReliefFeature )
+                INITIALIZE_NODE( DEM, TINRelief )
+                INITIALIZE_NODE( DEM, RasterRelief )
+                INITIALIZE_NODE( DEM, MassPointRelief )
+                INITIALIZE_NODE( DEM, BreaklineRelief )
+                INITIALIZE_NODE( DEM, Lod )
+                INITIALIZE_NODE( DEM, Extent )
+                INITIALIZE_NODE( DEM, ReliefComponent )
+                INITIALIZE_NODE( DEM, Tin )
+                INITIALIZE_NODE( DEM, Grid )
+                INITIALIZE_NODE( DEM, ReliefPoints )
+                INITIALIZE_NODE( DEM, RidgeOrValleyLines )
+                INITIALIZE_NODE( DEM, Breaklines )
+                INITIALIZE_NODE( DEM, Elevation )
 
                 // SUB
                 INITIALIZE_NODE( SUB, Tunnel )
@@ -285,6 +395,9 @@ namespace citygml {
                 INITIALIZE_NODE( APP, WrapMode )
                 INITIALIZE_NODE( APP, BorderColor )
                 INITIALIZE_NODE( APP, PreferWorldFile )
+                INITIALIZE_NODE( APP, ReferencePoint)
+                INITIALIZE_NODE( APP, Orientation)
+                INITIALIZE_NODE( APP, isSmooth)
 
                 INITIALIZE_NODE( APP, X3DMaterial )
                 INITIALIZE_NODE( APP, Material )
@@ -319,9 +432,12 @@ namespace citygml {
 
         std::string nodeName = lowerName;
 
-        size_t pos = name.find_first_of( ":" );
+        size_t pos = nodeName.find_first_of( ":" );
         if ( pos != std::string::npos ) {
-            nodeName = name.substr(pos);
+            nodeName = nodeName.substr(pos + 1);
+        } else {
+            // node has no prefix... try with core prefix
+            return getXMLNodeFor("core:" + name);
         }
 
         auto it = nodeNameTypeMap.find(nodeName);
@@ -333,22 +449,6 @@ namespace citygml {
         }
     }
 
-    std::ostream& operator<<(std::ostream& os, const NodeType::XMLNode& o)
-    {
-        if (!o.valid()) {
-            os << "InvalidNode";
-        } else {
-            if (!o.prefix().empty()) {
-                os << o.prefix() << ":";
-            }
-            os << o.name();
-        }
-
-        return os;
-    }
-
-    const NodeType::XMLNode NodeType::InvalidNode = XMLNode("", "");
-
 #define DEFINE_NODE( prefix, elementname ) NodeType::XMLNode NodeType::prefix ## _ ## elementname ## Node;
 
     // CORE
@@ -356,15 +456,37 @@ namespace citygml {
     DEFINE_NODE( CORE, CityObjectMember )
     DEFINE_NODE( CORE, CreationDate )
     DEFINE_NODE( CORE, TerminationDate )
+    DEFINE_NODE( CORE, GeneralizesTo)
+
+    DEFINE_NODE( CORE, ExternalReference)
+    DEFINE_NODE( CORE, InformationSystem)
+    DEFINE_NODE( CORE, ExternalObject)
+
+    DEFINE_NODE( CORE, Uri)
+    DEFINE_NODE( CORE, Name)
+
+    DEFINE_NODE( CORE, Address )
+
     DEFINE_NODE( CORE, ImplicitGeometry )
     DEFINE_NODE( CORE, RelativeGMLGeometry )
     DEFINE_NODE( CORE, TransformationMatrix )
+    DEFINE_NODE( CORE, ReferencePoint)
+    DEFINE_NODE( CORE, MimeType)
+    DEFINE_NODE( CORE, LibraryObject)
 
     // GRP
     DEFINE_NODE( GRP, CityObjectGroup )
     DEFINE_NODE( GRP, GroupMember )
+    DEFINE_NODE( GRP, Class )
+    DEFINE_NODE( GRP, Function )
+    DEFINE_NODE( GRP, Usage )
+    DEFINE_NODE( GRP, Parent )
+    DEFINE_NODE( GRP, Geometry )
 
     // GEN
+    DEFINE_NODE( GEN, Class )
+    DEFINE_NODE( GEN, Function )
+    DEFINE_NODE( GEN, Usage )
     DEFINE_NODE( GEN, GenericCityObject )
     DEFINE_NODE( GEN, StringAttribute )
     DEFINE_NODE( GEN, DoubleAttribute )
@@ -373,14 +495,21 @@ namespace citygml {
     DEFINE_NODE( GEN, UriAttribute )
     DEFINE_NODE( GEN, Value )
 
+    DEFINE_NODE( GEN, Lod0Geometry )
     DEFINE_NODE( GEN, Lod1Geometry )
     DEFINE_NODE( GEN, Lod2Geometry )
     DEFINE_NODE( GEN, Lod3Geometry )
     DEFINE_NODE( GEN, Lod4Geometry )
+    DEFINE_NODE( GEN, Lod0TerrainIntersection )
     DEFINE_NODE( GEN, Lod1TerrainIntersection )
     DEFINE_NODE( GEN, Lod2TerrainIntersection )
     DEFINE_NODE( GEN, Lod3TerrainIntersection )
     DEFINE_NODE( GEN, Lod4TerrainIntersection )
+    DEFINE_NODE( GEN, Lod0ImplicitRepresentation )
+    DEFINE_NODE( GEN, Lod1ImplicitRepresentation )
+    DEFINE_NODE( GEN, Lod2ImplicitRepresentation )
+    DEFINE_NODE( GEN, Lod3ImplicitRepresentation )
+    DEFINE_NODE( GEN, Lod4ImplicitRepresentation )
 
     // TEX
     // DEFINE_NODE( GML, TexturedSurface ) // Deprecated
@@ -390,6 +519,7 @@ namespace citygml {
     DEFINE_NODE( GML, Identifier )
     DEFINE_NODE( GML, Name )
     DEFINE_NODE( GML, DescriptionReference )
+    DEFINE_NODE( GML, MetaDataProperty )
     DEFINE_NODE( GML, Coordinates )
     DEFINE_NODE( GML, Pos )
     DEFINE_NODE( GML, BoundedBy )
@@ -446,6 +576,11 @@ namespace citygml {
     DEFINE_NODE( GML, Interior )
     DEFINE_NODE( GML, Exterior )
 
+    DEFINE_NODE( GML, Shell )
+    DEFINE_NODE( GML, PolyhedralSurface )
+    DEFINE_NODE( GML, Surface )
+    DEFINE_NODE( GML, PolygonPatch)
+
     // BLDG
     DEFINE_NODE( BLDG, Building )
     DEFINE_NODE( BLDG, BuildingPart )
@@ -453,7 +588,6 @@ namespace citygml {
     DEFINE_NODE( BLDG, Door )
     DEFINE_NODE( BLDG, Window )
     DEFINE_NODE( BLDG, BuildingInstallation )
-    DEFINE_NODE( BLDG, Address )
     DEFINE_NODE( BLDG, MeasuredHeight )
     DEFINE_NODE( BLDG, Class )
     DEFINE_NODE( BLDG, Type )
@@ -475,6 +609,8 @@ namespace citygml {
     DEFINE_NODE( BLDG, ConsistsOfBuildingPart )
 
     // CityFurniture
+    DEFINE_NODE( FRN, Class )
+    DEFINE_NODE( FRN, Function )
     DEFINE_NODE( FRN, CityFurniture )
     DEFINE_NODE( FRN, Lod1Geometry )
     DEFINE_NODE( FRN, Lod2Geometry )
@@ -499,13 +635,11 @@ namespace citygml {
     DEFINE_NODE( BLDG, CeilingSurface )
     DEFINE_NODE( BLDG, BuildingFurniture )
     DEFINE_NODE( BLDG, RoofType)
-    DEFINE_NODE( BLDG, ExternalReference)
-    DEFINE_NODE( BLDG, InformationSystem)
-    DEFINE_NODE( BLDG, ExternalObject)
-    DEFINE_NODE( BLDG, Uri)
 
     DEFINE_NODE( BLDG, CityFurniture )
 
+    DEFINE_NODE( BLDG, Address)
+
     // ADDRESS
     DEFINE_NODE( XAL, XalAddress )
     DEFINE_NODE( XAL, Administrativearea )
@@ -522,19 +656,47 @@ namespace citygml {
     DEFINE_NODE( XAL, Locality )
     DEFINE_NODE( XAL, AddressDetails )
     DEFINE_NODE( XAL, DependentLocalityName )
+
     // WTR
     DEFINE_NODE( WTR, WaterBody )
+    DEFINE_NODE( WTR, WaterSurface )
+    DEFINE_NODE( WTR, WaterGroundSurface )
+    DEFINE_NODE( WTR, WaterClosureSurface )
+    DEFINE_NODE( WTR, Class )
+    DEFINE_NODE( WTR, Function )
+    DEFINE_NODE( WTR, Usage )
+    DEFINE_NODE( WTR, WaterLevel )
+    DEFINE_NODE( WTR, Lod0MultiCurve )
+    DEFINE_NODE( WTR, Lod0MultiSurface )
+    DEFINE_NODE( WTR, Lod1MultiCurve )
+    DEFINE_NODE( WTR, Lod1MultiSurface )
+    DEFINE_NODE( WTR, Lod1Solid )
+    DEFINE_NODE( WTR, Lod2Solid )
+    DEFINE_NODE( WTR, Lod3Solid )
+    DEFINE_NODE( WTR, Lod4Solid )
+    DEFINE_NODE( WTR, Lod2Surface )
+    DEFINE_NODE( WTR, Lod3Surface )
+    DEFINE_NODE( WTR, Lod4Surface )
+    DEFINE_NODE( WTR, BoundedBy )
 
     // VEG
     DEFINE_NODE( VEG, PlantCover )
     DEFINE_NODE( VEG, SolitaryVegetationObject )
-    DEFINE_NODE( VEG, Species )
     DEFINE_NODE( VEG, Lod1ImplicitRepresentation )
     DEFINE_NODE( VEG, Lod2ImplicitRepresentation )
     DEFINE_NODE( VEG, Lod3ImplicitRepresentation )
     DEFINE_NODE( VEG, Lod4ImplicitRepresentation )
 
+    DEFINE_NODE( VEG, Class )
+    DEFINE_NODE( VEG, Function )
+    DEFINE_NODE( VEG, AverageHeight )
+    DEFINE_NODE( VEG, Species )
+    DEFINE_NODE( VEG, Height )
+    DEFINE_NODE( VEG, TrunkDiameter )
+    DEFINE_NODE( VEG, CrownDiameter )
+
     // TRANS
+    DEFINE_NODE( TRANS, TransportationComplex )
     DEFINE_NODE( TRANS, TrafficArea )
     DEFINE_NODE( TRANS, AuxiliaryTrafficArea )
     DEFINE_NODE( TRANS, Track )
@@ -542,12 +704,43 @@ namespace citygml {
     DEFINE_NODE( TRANS, Railway )
     DEFINE_NODE( TRANS, Square )
 
+    DEFINE_NODE( TRANS, Usage )
+    DEFINE_NODE( TRANS, Function )
+    DEFINE_NODE( TRANS, SurfaceMaterial )
+
+    DEFINE_NODE( TRANS, Lod0Network )
+    DEFINE_NODE( TRANS, Lod1MultiSurface )
+    DEFINE_NODE( TRANS, Lod2MultiSurface )
+    DEFINE_NODE( TRANS, Lod3MultiSurface )
+    DEFINE_NODE( TRANS, Lod4MultiSurface )
+
     // LUSE
     DEFINE_NODE( LUSE, LandUse )
 
-    // dem
-    DEFINE_NODE( LUSE, Lod )
-    DEFINE_NODE( LUSE, TINRelief )
+    DEFINE_NODE( LUSE, Class )
+    DEFINE_NODE( LUSE, Usage )
+    DEFINE_NODE( LUSE, Function )
+
+    DEFINE_NODE( LUSE, Lod1MultiSurface )
+    DEFINE_NODE( LUSE, Lod2MultiSurface )
+    DEFINE_NODE( LUSE, Lod3MultiSurface )
+    DEFINE_NODE( LUSE, Lod4MultiSurface )
+
+    // DEM (Relief)
+    DEFINE_NODE( DEM, ReliefFeature )
+    DEFINE_NODE( DEM, TINRelief )
+    DEFINE_NODE( DEM, RasterRelief )
+    DEFINE_NODE( DEM, MassPointRelief )
+    DEFINE_NODE( DEM, BreaklineRelief )
+    DEFINE_NODE( DEM, Lod )
+    DEFINE_NODE( DEM, Extent )
+    DEFINE_NODE( DEM, ReliefComponent )
+    DEFINE_NODE( DEM, Tin )
+    DEFINE_NODE( DEM, Grid )
+    DEFINE_NODE( DEM, ReliefPoints )
+    DEFINE_NODE( DEM, RidgeOrValleyLines )
+    DEFINE_NODE( DEM, Breaklines )
+    DEFINE_NODE( DEM, Elevation )
 
     // SUB
     DEFINE_NODE( SUB, Tunnel )
@@ -574,6 +767,9 @@ namespace citygml {
     DEFINE_NODE( APP, WrapMode )
     DEFINE_NODE( APP, BorderColor )
     DEFINE_NODE( APP, PreferWorldFile )
+    DEFINE_NODE( APP, ReferencePoint)
+    DEFINE_NODE( APP, Orientation)
+    DEFINE_NODE( APP, isSmooth)
 
     DEFINE_NODE( APP, X3DMaterial )
     DEFINE_NODE( APP, Material )
@@ -588,5 +784,4 @@ namespace citygml {
     DEFINE_NODE( APP, IsFront )
     DEFINE_NODE( APP, Theme )
     DEFINE_NODE( APP, MimeType )
-
 }
diff --git a/sources/src/parser/polygonelementparser.cpp b/sources/src/parser/polygonelementparser.cpp
index 3d54b82..9adb1ec 100644
--- a/sources/src/parser/polygonelementparser.cpp
+++ b/sources/src/parser/polygonelementparser.cpp
@@ -11,6 +11,7 @@
 #include "citygml/citygmlfactory.h"
 #include "citygml/citygmllogger.h"
 
+#include <mutex>
 #include <stdexcept>
 
 namespace citygml {
@@ -19,9 +20,10 @@ namespace citygml {
     // The nodes that are valid Polygon Objects
     std::unordered_set<int> typeIDSet;
     bool typeIDSetInitialized = false;
+    std::mutex polygonElementParser_initializedTypeIDMutex;
 
     PolygonElementParser::PolygonElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void(std::shared_ptr<Polygon>)> callback)
-        : CityGMLElementParser(documentParser, factory, logger)
+        : GMLObjectElementParser(documentParser, factory, logger)
     {
         m_callback = callback;
     }
@@ -33,11 +35,16 @@ namespace citygml {
 
     bool PolygonElementParser::handlesElement(const NodeType::XMLNode& node) const
     {
-        if(!typeIDSetInitialized) {
-            typeIDSet.insert(NodeType::GML_TriangleNode.typeID());
-            typeIDSet.insert(NodeType::GML_RectangleNode.typeID());
-            typeIDSet.insert(NodeType::GML_PolygonNode.typeID());
-            typeIDSetInitialized = true;
+        if (!typeIDSetInitialized) {
+            std::lock_guard<std::mutex> lock(polygonElementParser_initializedTypeIDMutex);
+
+            if(!typeIDSetInitialized) {
+                typeIDSet.insert(NodeType::GML_TriangleNode.typeID());
+                typeIDSet.insert(NodeType::GML_RectangleNode.typeID());
+                typeIDSet.insert(NodeType::GML_PolygonNode.typeID());
+                typeIDSet.insert(NodeType::GML_PolygonPatchNode.typeID());
+                typeIDSetInitialized = true;
+            }
         }
 
         return typeIDSet.count(node.typeID()) > 0;
@@ -80,7 +87,7 @@ namespace citygml {
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
     }
 
     bool PolygonElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
@@ -95,10 +102,15 @@ namespace citygml {
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementEndTag(node, characters);
 
     }
 
+    Object* PolygonElementParser::getObject()
+    {
+        return m_model.get();
+    }
+
     void PolygonElementParser::parseRingElement(bool interior)
     {
         setParserForNextElement(new LinearRingElementParser(m_documentParser, m_factory, m_logger, interior, [this](LinearRing* ring){
diff --git a/sources/src/parser/sequenceparser.cpp b/sources/src/parser/sequenceparser.cpp
new file mode 100644
index 0000000..3e95d3f
--- /dev/null
+++ b/sources/src/parser/sequenceparser.cpp
@@ -0,0 +1,55 @@
+#include "parser/sequenceparser.h"
+
+#include "citygml/citygmllogger.h"
+#include "parser/documentlocation.h"
+#include "parser/citygmldocumentparser.h"
+
+namespace citygml {
+
+    SequenceParser::SequenceParser(CityGMLDocumentParser& documentParser, std::shared_ptr<CityGMLLogger> logger, std::function<ElementParser*()> childParserFactory, const NodeType::XMLNode& parentElement)
+     : ElementParser(documentParser, logger)
+    {
+        m_childParserFactory = childParserFactory;
+        m_containerType = parentElement;
+        m_childParserInstance = nullptr;
+    }
+
+    bool SequenceParser::startElement(const NodeType::XMLNode& node, Attributes& attributes)
+    {
+        // Note that at this point the start tag of the parent element has already been parsed... hence node must be a child element
+        ElementParser* childParser = m_childParserFactory();
+        setParserForNextElement(childParser);
+        return childParser->startElement(node, attributes);
+    }
+
+    bool SequenceParser::endElement(const NodeType::XMLNode& node, const std::string&)
+    {
+        if (node != m_containerType) {
+            CITYGML_LOG_ERROR(m_logger, "Sequence parser was bound to container element <" << m_containerType << "> but found unexpected"
+                                       " end tag <" << node << "> at " << getDocumentLocation() << ". Ignoring tag...");
+
+        } else {
+            m_documentParser.removeCurrentElementParser(this);
+        }
+    }
+
+    bool SequenceParser::handlesElement(const NodeType::XMLNode& node) const
+    {
+        return getChildParserDummyInstance().handlesElement(node);
+    }
+
+    std::string SequenceParser::elementParserName() const
+    {
+        return "SequenceParser (" + getChildParserDummyInstance().elementParserName() + ")";
+    }
+
+    ElementParser& SequenceParser::getChildParserDummyInstance() const
+    {
+        // Lazy initialize the dummy object (its only used for logging and error reporting)
+        if (m_childParserInstance == nullptr) {
+            m_childParserInstance = std::unique_ptr<ElementParser>(m_childParserFactory());
+        }
+        return *m_childParserInstance;
+    }
+
+}
diff --git a/sources/src/parser/skipelementparser.cpp b/sources/src/parser/skipelementparser.cpp
new file mode 100644
index 0000000..b796965
--- /dev/null
+++ b/sources/src/parser/skipelementparser.cpp
@@ -0,0 +1,56 @@
+#include <parser/skipelementparser.h>
+#include <parser/citygmldocumentparser.h>
+#include <parser/documentlocation.h>
+
+#include <citygml/citygmllogger.h>
+
+namespace citygml {
+
+    SkipElementParser::SkipElementParser(CityGMLDocumentParser& documentParser, std::shared_ptr<CityGMLLogger> logger, const NodeType::XMLNode& skipNode)
+        : ElementParser(documentParser, logger)
+    {
+        m_skipNode = skipNode;
+        if (skipNode.valid()) {
+            m_depth = 1;
+        }
+    }
+
+    std::string SkipElementParser::elementParserName() const
+    {
+        return "SkipElementParser";
+    }
+
+    bool SkipElementParser::handlesElement(const NodeType::XMLNode&) const
+    {
+        return true;
+    }
+
+    bool SkipElementParser::startElement(const NodeType::XMLNode& node, Attributes&)
+    {
+        if (!m_skipNode.valid()) {
+            CITYGML_LOG_TRACE(m_logger, "Skipping element <" << node << "> at " << getDocumentLocation());
+            m_skipNode = node;
+            m_depth = 1;
+        } else if (node == m_skipNode) {
+            m_depth++;
+        }
+
+        return true;
+    }
+
+    bool SkipElementParser::endElement(const NodeType::XMLNode& node, const std::string&)
+    {
+        if (!m_skipNode.valid()) {
+            m_documentParser.removeCurrentElementParser(this);
+        } else if (node == m_skipNode) {
+            m_depth--;
+
+            if (m_depth == 0) {
+                m_documentParser.removeCurrentElementParser(this);
+            }
+        }
+
+        return true;
+    }
+
+}
diff --git a/sources/src/parser/textureelementparser.cpp b/sources/src/parser/textureelementparser.cpp
index 176342e..b9fb63a 100644
--- a/sources/src/parser/textureelementparser.cpp
+++ b/sources/src/parser/textureelementparser.cpp
@@ -6,6 +6,7 @@
 #include "parser/attributes.h"
 #include "parser/documentlocation.h"
 #include "parser/parserutils.hpp"
+#include "parser/skipelementparser.h"
 
 #include "citygml/cityobject.h"
 #include "citygml/citygmlfactory.h"
@@ -19,7 +20,7 @@
 namespace citygml {
 
     TextureElementParser::TextureElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void (std::shared_ptr<Texture>)> callback)
-        : CityGMLElementParser(documentParser, factory, logger)
+        : GMLObjectElementParser(documentParser, factory, logger)
     {
         m_callback = callback;
         m_model = nullptr;
@@ -59,8 +60,7 @@ namespace citygml {
             throw std::runtime_error("TextureElementParser::parseChildElementStartTag called before TextureElementParser::parseElementStartTag");
         }
 
-        if (node == NodeType::GML_NameNode
-            || node == NodeType::APP_ImageURINode
+        if (node == NodeType::APP_ImageURINode
             || node == NodeType::APP_TextureTypeNode
             || node == NodeType::APP_WrapModeNode
             || node == NodeType::APP_BorderColorNode
@@ -86,7 +86,7 @@ namespace citygml {
             return true;
         }
 
-        return false;
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
     }
 
     bool TextureElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
@@ -95,10 +95,7 @@ namespace citygml {
             throw std::runtime_error("TextureElementParser::parseChildElementEndTag called before TextureElementParser::parseElementStartTag");
         }
 
-        if (node == NodeType::GML_NameNode) {
-
-            m_model->setAttribute(node.name(), characters);
-        } else if (node == NodeType::APP_ImageURINode) {
+        if (node == NodeType::APP_ImageURINode) {
 
             m_model->setUrl(characters);
         } else if (node == NodeType::APP_TextureTypeNode) {
@@ -142,12 +139,18 @@ namespace citygml {
 
             m_currentTexTargetDef = nullptr;
         } else if (node == NodeType::APP_MimeTypeNode) {
+            m_model->setAttribute(node.name(), characters);
         } else {
-            return false;
+            return GMLObjectElementParser::parseChildElementEndTag(node, characters);
         }
         return true;
     }
 
+    Object* TextureElementParser::getObject()
+    {
+        return m_model.get();
+    }
+
 
 
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/libcitygml.git



More information about the Pkg-grass-devel mailing list