[libcitygml] 09/35: Imported Upstream version 1.4.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 21abc1fa88c923d5fdfed2fe8706f90aad6e987a
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Jul 24 16:29:28 2015 +0200

    Imported Upstream version 1.4.0
---
 CMakeLists.txt                                     |   2 +-
 TODO.md                                            |  18 ++--
 sources/CMakeLists.txt                             |   4 +
 sources/include/citygml/citygmlfactory.h           |   4 +-
 sources/include/citygml/geometry.h                 |  10 +-
 sources/include/citygml/linestring.h               |  40 +++++++
 sources/include/parser/attributes.h                |   4 +
 sources/include/parser/cityobjectelementparser.h   |   1 +
 .../include/parser/delayedchoiceelementparser.h    |   7 ++
 sources/include/parser/geocoordinatetransformer.h  |   1 +
 sources/include/parser/linestringelementparser.h   |  36 +++++++
 sources/include/parser/nodetypes.h                 |   9 +-
 sources/src/citygml/citygmlfactory.cpp             |  35 ++++++-
 sources/src/citygml/geometry.cpp                   |  22 +++-
 sources/src/citygml/linestring.cpp                 |  63 +++++++++++
 sources/src/citygml/object.cpp                     |  12 +--
 sources/src/parser/attributes.cpp                  |  10 +-
 sources/src/parser/cityobjectelementparser.cpp     |  68 ++++++++----
 sources/src/parser/geocoordinatetransformer.cpp    |  28 +++++
 sources/src/parser/geometryelementparser.cpp       |  25 +----
 .../src/parser/implicitgeometryelementparser.cpp   |  24 ++++-
 sources/src/parser/linestringelementparser.cpp     | 116 +++++++++++++++++++++
 sources/src/parser/nodetypes.cpp                   |  17 ++-
 sources/src/parser/sequenceparser.cpp              |   3 +
 24 files changed, 485 insertions(+), 74 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 73e3255..281c887 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.2 FATAL_ERROR)
 PROJECT ( libcitygml )
 
 set(META_VERSION_MAJOR       "1")
-set(META_VERSION_MINOR       "3")
+set(META_VERSION_MINOR       "4")
 set(META_VERSION_PATCH       "0")
 set(META_VERSION             "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}")
 
diff --git a/TODO.md b/TODO.md
index b3c0d88..bc7613e 100644
--- a/TODO.md
+++ b/TODO.md
@@ -5,27 +5,27 @@
   ... 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 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 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 sharing for all geometries (currently onl ImplicitGeometries)
 * 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)
+* 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
diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt
index 0264b1a..d03f0a6 100644
--- a/sources/CMakeLists.txt
+++ b/sources/CMakeLists.txt
@@ -40,6 +40,7 @@ SET(SOURCES
   src/citygml/citygmlfactory.cpp
   src/citygml/polygonmanager.cpp
   src/citygml/geometrymanager.cpp
+  src/citygml/linestring.cpp
 
   src/parser/nodetypes.cpp
   src/parser/attributes.cpp
@@ -66,6 +67,7 @@ SET(SOURCES
   src/parser/georeferencedtextureelementparser.cpp
   src/parser/geometryelementparser.cpp
   src/parser/polygonelementparser.cpp
+  src/parser/linestringelementparser.cpp
   src/parser/linearringelementparser.cpp
   src/parser/implicitgeometryelementparser.cpp
 )
@@ -96,6 +98,7 @@ SET(PUBLIC_HEADER
   include/citygml/texturecoordinates.h
   include/citygml/appearancetarget.h
   include/citygml/citygmlfactory.h
+  include/citygml/linestring.h
 )
 
 SET(HEADERS
@@ -135,6 +138,7 @@ SET(HEADERS
   include/parser/georeferencedtextureelementparser.h
   include/parser/geometryelementparser.h
   include/parser/polygonelementparser.h
+  include/parser/linestringelementparser.h
   include/parser/linearringelementparser.h
   include/parser/implicitgeometryelementparser.h
 )
diff --git a/sources/include/citygml/citygmlfactory.h b/sources/include/citygml/citygmlfactory.h
index 06bdf95..b6c9a44 100644
--- a/sources/include/citygml/citygmlfactory.h
+++ b/sources/include/citygml/citygmlfactory.h
@@ -18,6 +18,7 @@ namespace citygml {
     class Geometry;
     class ImplicitGeometry;
     class Polygon;
+    class LineString;
 
     class Appearance;
     class Texture;
@@ -33,9 +34,10 @@ namespace citygml {
 
         CityModel* createCityModel(const std::string& id);
         CityObject* createCityObject(const std::string& id, CityObject::CityObjectsType type);
-        Geometry* createGeometry(const std::string& id, Geometry::GeometryType type = Geometry::GeometryType::GT_Unknown, unsigned int lod = 0);
+        Geometry* createGeometry(const std::string& id, const CityObject::CityObjectsType& cityObjType = CityObject::CityObjectsType::COT_All, unsigned int lod = 0);
 
         std::shared_ptr<Polygon> createPolygon(const std::string& id);
+        std::shared_ptr<LineString> createLineString(const std::string& id);
 
         /**
          * @brief requests a polygon for a Geometry object that will be added later
diff --git a/sources/include/citygml/geometry.h b/sources/include/citygml/geometry.h
index 757730b..8179dc5 100644
--- a/sources/include/citygml/geometry.h
+++ b/sources/include/citygml/geometry.h
@@ -11,6 +11,7 @@ class Tesselator;
 
 namespace citygml {
 
+    class LineString;
     class Polygon;
     class AppearanceManager;
     class Appearance;
@@ -34,14 +35,16 @@ namespace citygml {
             GT_Ceiling          = 1 << 7
         };
 
-        // Get the geometry LOD
         unsigned int getLOD() const;
 
-        // Get the polygons
         unsigned int getPolygonsCount() const;
         Polygon& getPolygon( unsigned int i );
         const Polygon& getPolygon( unsigned int i ) const;
 
+        unsigned int getLineStringCount() const;
+        LineString& getLineString( unsigned int i );
+        const LineString& getLineString( unsigned int i ) const;
+
         unsigned int getGeometriesCount() const;
         const Geometry& getGeometry( unsigned int i ) const;
         Geometry& getGeometry( unsigned int i );
@@ -50,12 +53,12 @@ namespace citygml {
         GeometryType getType() const;
 
         std::string getTypeAsString() const;
-        //std::string getTypeAsString( void ) const { return getGeometryClassName( _type ); }
 
         unsigned int lod() const;
         void setLod(unsigned int lod);
 
         void addPolygon(std::shared_ptr<Polygon> );
+        void addLineString(std::shared_ptr<LineString>);
 
         /**
          * @brief finishes the geometry by finishing its child polygons after broadcasting its appearances to all child polygons
@@ -80,6 +83,7 @@ namespace citygml {
         std::vector<std::shared_ptr<Geometry>> m_childGeometries;
 
         std::vector<std::shared_ptr<Polygon>> m_polygons;
+        std::vector<std::shared_ptr<LineString>> m_lineStrings;
     };
 
     std::ostream& operator<<( std::ostream& os, const citygml::Geometry& s );
diff --git a/sources/include/citygml/linestring.h b/sources/include/citygml/linestring.h
new file mode 100644
index 0000000..b644e23
--- /dev/null
+++ b/sources/include/citygml/linestring.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <citygml/citygml_api.h>
+#include <citygml/object.h>
+#include <citygml/vecs.hpp>
+#include <memory>
+
+#include <vector>
+
+namespace citygml {
+
+    class CityGMLFactory;
+
+    /**
+     * @brief The LineString class implements the gml:LineString object may also be used as a container of a single gml::Point
+     */
+    class LIBCITYGML_EXPORT LineString : public Object {
+        friend class CityGMLFactory;
+    public:
+        int getDimensions() const;
+
+        const std::vector<TVec2d>& getVertices2D() const;
+        const std::vector<TVec3d>& getVertices3D() const;
+
+        std::vector<TVec2d>& getVertices2D();
+        std::vector<TVec3d>& getVertices3D();
+
+        void setVertices2D(const std::vector<TVec2d>& vertices);
+        void setVertices3D(const std::vector<TVec3d>& vertices);
+
+        void setDimensions(int dim);
+
+    protected:
+        LineString(const std::string& id);
+        std::vector<TVec2d> m_vertices_2d;
+        std::vector<TVec3d> m_vertices_3d;
+        int m_dimensions;
+    };
+
+}
diff --git a/sources/include/parser/attributes.h b/sources/include/parser/attributes.h
index a8cba55..b0b10cf 100644
--- a/sources/include/parser/attributes.h
+++ b/sources/include/parser/attributes.h
@@ -23,6 +23,10 @@ namespace citygml {
         virtual std::string getAttribute( const std::string& attname, const std::string& defvalue = "" ) const = 0;
         virtual const DocumentLocation& getDocumentLocation() const = 0;
 
+        /**
+         * @brief gets the citygml id attribute value or if not present generates a value based on the document location
+         * @return the value of the gml::id attribute or "genID_<CityGMLFileName>_<LineNumber>_<ColumnNumber>" if there is no id attribute
+         */
         std::string getCityGMLIDAttribute() const;
 
         bool hasXLinkAttribute() const;
diff --git a/sources/include/parser/cityobjectelementparser.h b/sources/include/parser/cityobjectelementparser.h
index abd85c7..d149aa8 100644
--- a/sources/include/parser/cityobjectelementparser.h
+++ b/sources/include/parser/cityobjectelementparser.h
@@ -48,6 +48,7 @@ namespace citygml {
 
         void parseGeometryForLODLevel(int lod);
         void parseImplicitGeometryForLODLevel(int lod);
+        void parseGeometryPropertyElementForLODLevel(int lod, const std::string& id);
     };
 
 }
diff --git a/sources/include/parser/delayedchoiceelementparser.h b/sources/include/parser/delayedchoiceelementparser.h
index 618a046..08ba2f4 100644
--- a/sources/include/parser/delayedchoiceelementparser.h
+++ b/sources/include/parser/delayedchoiceelementparser.h
@@ -15,6 +15,13 @@ namespace citygml {
      */
     class DelayedChoiceElementParser : public ElementParser {
     public:
+
+        /**
+         * @brief creates a DelayedChoiceElementParser
+         * @param documentParser
+         * @param logger
+         * @param choices the parsers to choose from. The DelayedChoiceElementParser takes ownership of the parsers.
+         */
         DelayedChoiceElementParser(CityGMLDocumentParser& documentParser, std::shared_ptr<CityGMLLogger> logger, std::vector<ElementParser*> choices);
 
         // ElementParser interface
diff --git a/sources/include/parser/geocoordinatetransformer.h b/sources/include/parser/geocoordinatetransformer.h
index 3bb1819..34d8cb6 100644
--- a/sources/include/parser/geocoordinatetransformer.h
+++ b/sources/include/parser/geocoordinatetransformer.h
@@ -24,6 +24,7 @@ namespace citygml {
         std::string m_destinationSRS;
         std::shared_ptr<CityGMLLogger> m_logger;
         std::unordered_map<std::string, std::string> m_transformedPolygonsSourceURNMap;
+        std::unordered_map<std::string, std::string> m_transformedLineStringsSourceURNMap;
 
         void transformRecursive(CityObject& obj, GeoTransform& transformation);
         void transformRecursive_helper(CityObject& obj, GeoTransform& transformation);
diff --git a/sources/include/parser/linestringelementparser.h b/sources/include/parser/linestringelementparser.h
new file mode 100644
index 0000000..c21643e
--- /dev/null
+++ b/sources/include/parser/linestringelementparser.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <parser/gmlobjectparser.h>
+
+#include <functional>
+#include <memory>
+
+namespace citygml {
+
+    class LineString;
+
+    class LineStringElementParser : public GMLObjectElementParser {
+    public:
+        LineStringElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void(std::shared_ptr<LineString>)> callback);
+
+        // ElementParser interface
+        virtual std::string elementParserName() const;
+        virtual bool handlesElement(const NodeType::XMLNode &node) const override;
+    protected:
+        // CityGMLElementParser interface
+        virtual bool parseElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) override;
+        virtual bool parseElementEndTag(const NodeType::XMLNode& node, const std::string& characters) override;
+        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<LineString> m_model;
+        std::function<void(std::shared_ptr<LineString>)> m_callback;
+
+        void parseDimension(Attributes& attributes);
+    };
+
+}
diff --git a/sources/include/parser/nodetypes.h b/sources/include/parser/nodetypes.h
index 0bbf14d..cc5aa72 100644
--- a/sources/include/parser/nodetypes.h
+++ b/sources/include/parser/nodetypes.h
@@ -147,6 +147,8 @@ namespace citygml {
         NODETYPE( GML, Surface )
         NODETYPE( GML, PolygonPatch)
 
+        NODETYPE( GML, LineString )
+
         // BLDG
         NODETYPE( BLDG, Building )
         NODETYPE( BLDG, BuildingPart )
@@ -178,7 +180,6 @@ namespace citygml {
         NODETYPE( BLDG, Lod2Solid )
         NODETYPE( BLDG, Lod3Solid )
         NODETYPE( BLDG, Lod4Solid )
-        NODETYPE( BLDG, Lod1Geometry )
         NODETYPE( BLDG, Lod2Geometry )
         NODETYPE( BLDG, Lod3Geometry )
         NODETYPE( BLDG, Lod4Geometry )
@@ -281,6 +282,12 @@ namespace citygml {
         NODETYPE( VEG, TrunkDiameter )
         NODETYPE( VEG, CrownDiameter )
 
+        NODETYPE( VEG, Lod0Geometry )
+        NODETYPE( VEG, Lod1Geometry )
+        NODETYPE( VEG, Lod2Geometry )
+        NODETYPE( VEG, Lod3Geometry )
+        NODETYPE( VEG, Lod4Geometry )
+
         // TRANS
         NODETYPE( TRANS, TransportationComplex )
         NODETYPE( TRANS, TrafficArea )
diff --git a/sources/src/citygml/citygmlfactory.cpp b/sources/src/citygml/citygmlfactory.cpp
index 1da94c4..739f43d 100644
--- a/sources/src/citygml/citygmlfactory.cpp
+++ b/sources/src/citygml/citygmlfactory.cpp
@@ -5,6 +5,7 @@
 #include "citygml/cityobject.h"
 #include "citygml/appearancetarget.h"
 #include "citygml/polygon.h"
+#include "citygml/linestring.h"
 #include "citygml/implictgeometry.h"
 #include "citygml/texture.h"
 #include "citygml/georeferencedtexture.h"
@@ -36,9 +37,32 @@ namespace citygml {
         return cityObject;
     }
 
-    Geometry* CityGMLFactory::createGeometry(const std::string& id, Geometry::GeometryType type, unsigned int lod)
+    Geometry::GeometryType mapCityObjectsTypeToGeometryType(const CityObject::CityObjectsType& cityObjType) {
+
+        switch (cityObjType) {
+        case CityObject::CityObjectsType::COT_RoofSurface:
+            return Geometry::GeometryType::GT_Roof;
+        case CityObject::CityObjectsType::COT_WallSurface:
+            return Geometry::GeometryType::GT_Wall;
+        case CityObject::CityObjectsType::COT_GroundSurface:
+            return Geometry::GeometryType::GT_Ground;
+        case CityObject::CityObjectsType::COT_ClosureSurface:
+            return Geometry::GeometryType::GT_Closure;
+        case CityObject::CityObjectsType::COT_FloorSurface:
+            return Geometry::GeometryType::GT_Floor;
+        case CityObject::CityObjectsType::COT_InteriorWallSurface:
+            return Geometry::GeometryType::GT_InteriorWall;
+        case CityObject::CityObjectsType::COT_CeilingSurface:
+            return Geometry::GeometryType::GT_Ceiling;
+        default:
+            return Geometry::GeometryType::GT_Unknown;
+        }
+
+    }
+
+    Geometry* CityGMLFactory::createGeometry(const std::string& id, const CityObject::CityObjectsType& cityObjType, unsigned int lod)
     {
-        Geometry* geom = new Geometry(id, type, lod);
+        Geometry* geom = new Geometry(id, mapCityObjectsTypeToGeometryType(cityObjType), lod);
         appearanceTargetCreated(geom);
         return geom;
     }
@@ -54,6 +78,13 @@ namespace citygml {
         return shared;
     }
 
+    std::shared_ptr<LineString> CityGMLFactory::createLineString(const std::string& id)
+    {
+        LineString* lineString = new LineString(id);
+        return std::shared_ptr<LineString>(lineString);
+
+    }
+
     void CityGMLFactory::requestSharedPolygonForGeometry(Geometry* geom, const std::string& polygonId)
     {
         m_polygonManager->requestSharedPolygonForGeometry(geom, polygonId);
diff --git a/sources/src/citygml/geometry.cpp b/sources/src/citygml/geometry.cpp
index 46705c9..da5018b 100644
--- a/sources/src/citygml/geometry.cpp
+++ b/sources/src/citygml/geometry.cpp
@@ -33,6 +33,21 @@ namespace citygml {
         return *m_polygons.at(i);
     }
 
+    unsigned int Geometry::getLineStringCount() const
+    {
+        return m_lineStrings.size();
+    }
+
+    LineString& Geometry::getLineString(unsigned int i)
+    {
+        return *m_lineStrings.at(i);
+    }
+
+    const LineString& Geometry::getLineString(unsigned int i) const
+    {
+        return *m_lineStrings.at(i);
+    }
+
     unsigned int Geometry::getGeometriesCount() const
     {
         return m_childGeometries.size();
@@ -99,7 +114,12 @@ namespace citygml {
 
     void Geometry::addPolygon( std::shared_ptr<Polygon> p )
     {
-        m_polygons.push_back( p );
+        m_polygons.push_back(p);
+    }
+
+    void Geometry::addLineString(std::shared_ptr<LineString> l)
+    {
+        m_lineStrings.push_back(l);
     }
 
     void Geometry::finish(Tesselator& tesselator, bool optimize, std::shared_ptr<CityGMLLogger> logger)
diff --git a/sources/src/citygml/linestring.cpp b/sources/src/citygml/linestring.cpp
new file mode 100644
index 0000000..cd97dc3
--- /dev/null
+++ b/sources/src/citygml/linestring.cpp
@@ -0,0 +1,63 @@
+#include <citygml/linestring.h>
+
+#include <citygml/citygmllogger.h>
+
+#include <stdexcept>
+
+citygml::LineString::LineString(const std::string& id) : Object(id)
+{
+    m_dimensions = -1;
+}
+
+int citygml::LineString::getDimensions() const
+{
+    return m_dimensions;
+}
+
+const std::vector<TVec2d>& citygml::LineString::getVertices2D() const
+{
+    return m_vertices_2d;
+}
+
+const std::vector<TVec3d>& citygml::LineString::getVertices3D() const
+{
+    return m_vertices_3d;
+}
+
+std::vector<TVec2d>& citygml::LineString::getVertices2D()
+{
+    return m_vertices_2d;
+}
+
+std::vector<TVec3d>& citygml::LineString::getVertices3D()
+{
+    return m_vertices_3d;
+}
+
+void citygml::LineString::setVertices2D(const std::vector<TVec2d>& vertices)
+{
+    if (m_dimensions != 2) {
+        setDimensions(2);
+    }
+
+    m_vertices_2d = vertices;
+}
+
+void citygml::LineString::setVertices3D(const std::vector<TVec3d>& vertices)
+{
+    if (m_dimensions != 3) {
+        setDimensions(3);
+    }
+
+    m_vertices_3d = vertices;
+}
+
+void citygml::LineString::setDimensions(int dim)
+{
+    m_dimensions = dim;
+    if (dim != 2 && !m_vertices_2d.empty()) {
+        throw std::runtime_error("LineString not set to dimension 2 but contains 2D vertices.");
+    } else if (dim != 3 && !m_vertices_3d.empty()) {
+        throw std::runtime_error("LineString not set to dimension 3 but contains 3D vertices.");
+    }
+}
diff --git a/sources/src/citygml/object.cpp b/sources/src/citygml/object.cpp
index 94b9957..f147481 100644
--- a/sources/src/citygml/object.cpp
+++ b/sources/src/citygml/object.cpp
@@ -7,12 +7,12 @@ namespace citygml {
 
     Object::Object(const std::string& id) : m_id( id )
     {
-         if ( m_id == "" )
-         {
-             std::stringstream ss;
-             ss << "PtrId_" << this;
-             m_id = ss.str();
-         }
+        if ( m_id == "" )
+        {
+         std::stringstream ss;
+         ss << "PtrId_" << this;
+         m_id = ss.str();
+        }
     }
 
     const std::string&Object::getId() const
diff --git a/sources/src/parser/attributes.cpp b/sources/src/parser/attributes.cpp
index a207751..d5b1af1 100644
--- a/sources/src/parser/attributes.cpp
+++ b/sources/src/parser/attributes.cpp
@@ -4,6 +4,8 @@
 
 #include "citygml/citygmllogger.h"
 
+#include "sstream"
+
 namespace citygml {
 
     Attributes::Attributes(std::shared_ptr<CityGMLLogger> logger)
@@ -13,7 +15,13 @@ namespace citygml {
 
     std::string Attributes::getCityGMLIDAttribute() const
     {
-        return getAttribute("gml:id", "");
+        std::string id = getAttribute("gml:id", "");
+        if (id.empty()) {
+            std::stringstream defaultID;
+            defaultID << "genID_" << getDocumentLocation().getDocumentFileName() << "_" << getDocumentLocation().getCurrentLine() << "_" << + getDocumentLocation().getCurrentColumn();
+            id = defaultID.str();
+        }
+        return id;
     }
 
     bool Attributes::hasXLinkAttribute() const
diff --git a/sources/src/parser/cityobjectelementparser.cpp b/sources/src/parser/cityobjectelementparser.cpp
index 3c98d8d..d1123cd 100644
--- a/sources/src/parser/cityobjectelementparser.cpp
+++ b/sources/src/parser/cityobjectelementparser.cpp
@@ -5,12 +5,16 @@
 #include "parser/appearanceelementparser.h"
 #include "parser/geometryelementparser.h"
 #include "parser/implicitgeometryelementparser.h"
+#include "parser/polygonelementparser.h"
 #include "parser/skipelementparser.h"
+#include "parser/delayedchoiceelementparser.h"
+#include "parser/linestringelementparser.h"
 
 #include "citygml/citygmlfactory.h"
 #include "citygml/citygmllogger.h"
 
 #include <stdexcept>
+#include <iostream>
 
 namespace citygml {
 
@@ -228,14 +232,11 @@ namespace citygml {
                    || node == NodeType::APP_AppearanceMemberNode) {
 
             setParserForNextElement(new AppearanceElementParser(m_documentParser, m_factory, m_logger));
-        } else if (node == NodeType::BLDG_Lod1GeometryNode
-                   || node == NodeType::BLDG_Lod1MultiCurveNode
+        } else if (node == NodeType::BLDG_Lod1MultiCurveNode
                    || node == NodeType::BLDG_Lod1MultiSurfaceNode
                    || node == NodeType::BLDG_Lod1SolidNode
                    || node == NodeType::BLDG_Lod1TerrainIntersectionNode
-                   || node == NodeType::GEN_Lod1GeometryNode
                    || node == NodeType::GEN_Lod1TerrainIntersectionNode
-                   || node == NodeType::FRN_Lod1GeometryNode
                    || node == NodeType::FRN_Lod1TerrainIntersectionNode
                    || node == NodeType::LUSE_Lod1MultiSurfaceNode
                    || node == NodeType::TRANS_Lod1MultiSurfaceNode
@@ -244,14 +245,11 @@ namespace citygml {
                    || node == NodeType::WTR_Lod1SolidNode) {
 
             parseGeometryForLODLevel(1);
-        } else if (node == NodeType::BLDG_Lod2GeometryNode
-                   || node == NodeType::BLDG_Lod2MultiCurveNode
+        } else if (node == NodeType::BLDG_Lod2MultiCurveNode
                    || node == NodeType::BLDG_Lod2MultiSurfaceNode
                    || node == NodeType::BLDG_Lod2SolidNode
                    || node == NodeType::BLDG_Lod2TerrainIntersectionNode
-                   || node == NodeType::GEN_Lod2GeometryNode
                    || node == NodeType::GEN_Lod2TerrainIntersectionNode
-                   || node == NodeType::FRN_Lod2GeometryNode
                    || node == NodeType::FRN_Lod2TerrainIntersectionNode
                    || node == NodeType::LUSE_Lod2MultiSurfaceNode
                    || node == NodeType::TRANS_Lod2MultiSurfaceNode
@@ -259,14 +257,11 @@ namespace citygml {
                    || node == NodeType::WTR_Lod2SurfaceNode) {
 
             parseGeometryForLODLevel(2);
-        } else if (node == NodeType::BLDG_Lod3GeometryNode
-                   || node == NodeType::BLDG_Lod3MultiCurveNode
+        } else if (node == NodeType::BLDG_Lod3MultiCurveNode
                    || node == NodeType::BLDG_Lod3MultiSurfaceNode
                    || node == NodeType::BLDG_Lod3SolidNode
                    || node == NodeType::BLDG_Lod3TerrainIntersectionNode
-                   || node == NodeType::GEN_Lod3GeometryNode
                    || node == NodeType::GEN_Lod3TerrainIntersectionNode
-                   || node == NodeType::FRN_Lod3GeometryNode
                    || node == NodeType::FRN_Lod3TerrainIntersectionNode
                    || node == NodeType::LUSE_Lod3MultiSurfaceNode
                    || node == NodeType::TRANS_Lod3MultiSurfaceNode
@@ -274,14 +269,11 @@ namespace citygml {
                    || node == NodeType::WTR_Lod3SurfaceNode) {
 
             parseGeometryForLODLevel(3);
-        } else if (node == NodeType::BLDG_Lod4GeometryNode
-                   || node == NodeType::BLDG_Lod4MultiCurveNode
+        } else if (node == NodeType::BLDG_Lod4MultiCurveNode
                    || node == NodeType::BLDG_Lod4MultiSurfaceNode
                    || node == NodeType::BLDG_Lod4SolidNode
                    || node == NodeType::BLDG_Lod4TerrainIntersectionNode
-                   || node == NodeType::GEN_Lod4GeometryNode
                    || node == NodeType::GEN_Lod4TerrainIntersectionNode
-                   || node == NodeType::FRN_Lod4GeometryNode
                    || node == NodeType::FRN_Lod4TerrainIntersectionNode
                    || node == NodeType::LUSE_Lod4MultiSurfaceNode
                    || node == NodeType::TRANS_Lod4MultiSurfaceNode
@@ -289,6 +281,25 @@ namespace citygml {
                    || node == NodeType::WTR_Lod4SurfaceNode) {
 
             parseGeometryForLODLevel(4);
+        } else if (node == NodeType::GEN_Lod1GeometryNode
+                   || node == NodeType::FRN_Lod1GeometryNode
+                   || node == NodeType::VEG_Lod1GeometryNode) {
+            parseGeometryPropertyElementForLODLevel(1, attributes.getCityGMLIDAttribute());
+        } else if (node == NodeType::GEN_Lod2GeometryNode
+                   || node == NodeType::FRN_Lod2GeometryNode
+                   || node == NodeType::BLDG_Lod2GeometryNode
+                   || node == NodeType::VEG_Lod2GeometryNode) {
+            parseGeometryPropertyElementForLODLevel(2, attributes.getCityGMLIDAttribute());
+        } else if (node == NodeType::GEN_Lod3GeometryNode
+                   || node == NodeType::FRN_Lod3GeometryNode
+                   || node == NodeType::BLDG_Lod3GeometryNode
+                   || node == NodeType::VEG_Lod3GeometryNode) {
+            parseGeometryPropertyElementForLODLevel(3, attributes.getCityGMLIDAttribute());
+        } else if (node == NodeType::GEN_Lod4GeometryNode
+                   || node == NodeType::FRN_Lod4GeometryNode
+                   || node == NodeType::BLDG_Lod4GeometryNode
+                   || node == NodeType::VEG_Lod4GeometryNode) {
+            parseGeometryPropertyElementForLODLevel(4, attributes.getCityGMLIDAttribute());
         } else if (node == NodeType::VEG_Lod1ImplicitRepresentationNode
                    || node == NodeType::FRN_Lod1ImplicitRepresentationNode
                    || node == NodeType::GEN_Lod1ImplicitRepresentationNode) {
@@ -363,7 +374,7 @@ namespace citygml {
                 m_model->setAttribute(node.name(), characters);
             }
             return true;
-        } else if (    node == NodeType::BLDG_BoundedByNode
+        } else if (node == NodeType::BLDG_BoundedByNode
                     || node == NodeType::BLDG_OuterBuildingInstallationNode
                     || node == NodeType::BLDG_InteriorBuildingInstallationNode
                     || node == NodeType::BLDG_InteriorFurnitureNode
@@ -372,7 +383,6 @@ namespace citygml {
                     || node == NodeType::BLDG_OpeningNode
                     || node == NodeType::APP_AppearanceNode
                     || node == NodeType::APP_AppearanceMemberNode
-                    || node == NodeType::BLDG_Lod1GeometryNode
                     || node == NodeType::BLDG_Lod1MultiCurveNode
                     || node == NodeType::BLDG_Lod1MultiSurfaceNode
                     || node == NodeType::BLDG_Lod1SolidNode
@@ -470,7 +480,7 @@ namespace citygml {
     {
         setParserForNextElement(new GeometryElementParser(m_documentParser, m_factory, m_logger, lod, m_model->getType(), [this](Geometry* geom) {
             m_model->addGeometry(geom);
-                                }));
+        }));
     }
 
     void CityObjectElementParser::parseImplicitGeometryForLODLevel(int lod)
@@ -480,4 +490,24 @@ namespace citygml {
         }));
     }
 
+    void CityObjectElementParser::parseGeometryPropertyElementForLODLevel(int lod, const std::string& id)
+    {
+        setParserForNextElement(new DelayedChoiceElementParser(m_documentParser, m_logger, {
+            new PolygonElementParser(m_documentParser, m_factory, m_logger, [id, lod, this](std::shared_ptr<Polygon> p) {
+                                                                       Geometry* geom = m_factory.createGeometry(id, m_model->getType(), lod);
+                                                                       geom->addPolygon(p);
+                                                                       m_model->addGeometry(geom);
+                                                                   }),
+            new LineStringElementParser(m_documentParser, m_factory, m_logger, [id, lod, this](std::shared_ptr<LineString> l) {
+                                                                       Geometry* geom = m_factory.createGeometry(id, m_model->getType(), lod);
+                                                                       geom->addLineString(l);
+                                                                       m_model->addGeometry(geom);
+                                                                   }),
+            new GeometryElementParser(m_documentParser, m_factory, m_logger, lod, m_model->getType(), [this](Geometry* geom) {
+                                                                       m_model->addGeometry(geom);
+                                                                   })
+        }));
+
+    }
+
 }
diff --git a/sources/src/parser/geocoordinatetransformer.cpp b/sources/src/parser/geocoordinatetransformer.cpp
index 36f23a4..df34024 100644
--- a/sources/src/parser/geocoordinatetransformer.cpp
+++ b/sources/src/parser/geocoordinatetransformer.cpp
@@ -6,6 +6,7 @@
 #include "citygml/implictgeometry.h"
 #include "citygml/geometry.h"
 #include "citygml/polygon.h"
+#include "citygml/linestring.h"
 #include "citygml/vecs.hpp"
 #include "citygml/envelope.h"
 
@@ -251,6 +252,33 @@ namespace citygml {
             }
         }
 
+        for (unsigned int i = 0; i < obj.getLineStringCount(); i++) {
+
+            LineString& lineString = obj.getLineString(i);
+
+            auto it = m_transformedLineStringsSourceURNMap.find(lineString.getId());
+
+            if (it == m_transformedLineStringsSourceURNMap.end()) {
+
+                if (lineString.getDimensions() == 2) {
+                    for (TVec2d& vertex : lineString.getVertices2D()) {
+                        transformation.transform(vertex);
+                    }
+                } else if (lineString.getDimensions() == 3) {
+                    for (TVec3d& vertex : lineString.getVertices3D()) {
+                        transformation.transform(vertex);
+                    }
+                }
+
+                m_transformedLineStringsSourceURNMap[lineString.getId()] = transformation.sourceURN();
+
+            } else if (it->second != transformation.sourceURN()) {
+                CITYGML_LOG_WARN(m_logger, "LineString with id '" << lineString.getId() << "' was already transformed from " << it->second << " to " << m_destinationSRS
+                                 << ". But the spatial reference system of Geometry object with id '" << obj.getId() << "' that also contains the LineString is different "
+                                 << "(" << transformation.sourceURN() << "). Ignoring new source SRS.");
+            }
+        }
+
         for (unsigned int i = 0; i < obj.getGeometriesCount(); i++) {
             transform(obj.getGeometry(i), transformation);
         }
diff --git a/sources/src/parser/geometryelementparser.cpp b/sources/src/parser/geometryelementparser.cpp
index 96c1f4a..e136d10 100644
--- a/sources/src/parser/geometryelementparser.cpp
+++ b/sources/src/parser/geometryelementparser.cpp
@@ -68,29 +68,6 @@ namespace citygml {
         return geometryTypeIDSet.count(node.typeID()) > 0;
     }
 
-    Geometry::GeometryType mapCityObjectsTypeToGeometryType(const CityObject::CityObjectsType& cityObjType) {
-
-        switch (cityObjType) {
-        case CityObject::CityObjectsType::COT_RoofSurface:
-            return Geometry::GeometryType::GT_Roof;
-        case CityObject::CityObjectsType::COT_WallSurface:
-            return Geometry::GeometryType::GT_Wall;
-        case CityObject::CityObjectsType::COT_GroundSurface:
-            return Geometry::GeometryType::GT_Ground;
-        case CityObject::CityObjectsType::COT_ClosureSurface:
-            return Geometry::GeometryType::GT_Closure;
-        case CityObject::CityObjectsType::COT_FloorSurface:
-            return Geometry::GeometryType::GT_Floor;
-        case CityObject::CityObjectsType::COT_InteriorWallSurface:
-            return Geometry::GeometryType::GT_InteriorWall;
-        case CityObject::CityObjectsType::COT_CeilingSurface:
-            return Geometry::GeometryType::GT_Ceiling;
-        default:
-            return Geometry::GeometryType::GT_Unknown;
-        }
-
-    }
-
     bool GeometryElementParser::parseElementStartTag(const NodeType::XMLNode& node, Attributes& attributes)
     {
 
@@ -99,7 +76,7 @@ namespace citygml {
             throw std::runtime_error("Unexpected start tag found.");
         }
 
-        m_model = m_factory.createGeometry(attributes.getCityGMLIDAttribute(), mapCityObjectsTypeToGeometryType(m_parentType), m_lodLevel);
+        m_model = m_factory.createGeometry(attributes.getCityGMLIDAttribute(), m_parentType, m_lodLevel);
         m_orientation = attributes.getAttribute("orientation", "+"); // A gml:OrientableSurface may define a negative orientation
         return true;
 
diff --git a/sources/src/parser/implicitgeometryelementparser.cpp b/sources/src/parser/implicitgeometryelementparser.cpp
index 72c7bfc..91fd904 100644
--- a/sources/src/parser/implicitgeometryelementparser.cpp
+++ b/sources/src/parser/implicitgeometryelementparser.cpp
@@ -8,6 +8,9 @@
 #include "parser/geometryelementparser.h"
 #include "parser/parserutils.hpp"
 #include "parser/skipelementparser.h"
+#include "parser/linestringelementparser.h"
+#include "parser/polygonelementparser.h"
+#include "parser/delayedchoiceelementparser.h"
 
 #include "citygml/implictgeometry.h"
 #include "citygml/citygmlfactory.h"
@@ -91,10 +94,23 @@ namespace citygml {
                 m_factory.requestSharedGeometryWithID(m_model, sharedGeomID);
             } else {
 
-                setParserForNextElement(new GeometryElementParser(m_documentParser, m_factory, m_logger, m_lodLevel, m_parentType, [this](Geometry* geom) {
-                                        std::shared_ptr<Geometry> shared = m_factory.shareGeometry(geom);
-                                        m_model->addGeometry(shared);
-                                    }));
+                std::string id = attributes.getCityGMLIDAttribute();
+
+                setParserForNextElement(new DelayedChoiceElementParser(m_documentParser, m_logger, {
+                    new PolygonElementParser(m_documentParser, m_factory, m_logger, [id, this](std::shared_ptr<Polygon> p) {
+                                                                               Geometry* geom = m_factory.createGeometry(id, m_parentType, m_lodLevel);
+                                                                               geom->addPolygon(p);
+                                                                               m_model->addGeometry(m_factory.shareGeometry(geom));
+                                                                           }),
+                    new LineStringElementParser(m_documentParser, m_factory, m_logger, [id, this](std::shared_ptr<LineString> l) {
+                                                                               Geometry* geom = m_factory.createGeometry(id, m_parentType, m_lodLevel);
+                                                                               geom->addLineString(l);
+                                                                               m_model->addGeometry(m_factory.shareGeometry(geom));
+                                                                           }),
+                    new GeometryElementParser(m_documentParser, m_factory, m_logger, m_lodLevel, m_parentType, [this](Geometry* geom) {
+                                                                               m_model->addGeometry(m_factory.shareGeometry(geom));
+                                                                           })
+                }));
             }
             return true;
         } else if (node == NodeType::CORE_LibraryObjectNode) {
diff --git a/sources/src/parser/linestringelementparser.cpp b/sources/src/parser/linestringelementparser.cpp
new file mode 100644
index 0000000..6cb6fb9
--- /dev/null
+++ b/sources/src/parser/linestringelementparser.cpp
@@ -0,0 +1,116 @@
+#include "parser/linestringelementparser.h"
+
+#include <unordered_map>
+
+#include "parser/nodetypes.h"
+#include "parser/attributes.h"
+#include "parser/documentlocation.h"
+#include "parser/parserutils.hpp"
+
+#include "citygml/linestring.h"
+#include "citygml/citygmlfactory.h"
+#include "citygml/citygmllogger.h"
+
+#include <mutex>
+#include <stdexcept>
+
+namespace citygml {
+
+    LineStringElementParser::LineStringElementParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr<CityGMLLogger> logger, std::function<void(std::shared_ptr<LineString>)> callback)
+        : GMLObjectElementParser(documentParser, factory, logger)
+    {
+        m_callback = callback;
+    }
+
+    std::string LineStringElementParser::elementParserName() const
+    {
+        return "LineStringElementParser";
+    }
+
+    bool LineStringElementParser::handlesElement(const NodeType::XMLNode& node) const
+    {
+        return node == NodeType::GML_LineStringNode || node == NodeType::GML_PointNode;
+    }
+
+    bool LineStringElementParser::parseElementStartTag(const NodeType::XMLNode& node, Attributes& attributes)
+    {
+
+        if (!handlesElement(node)) {
+            CITYGML_LOG_ERROR(m_logger, "Expected start tag <" << NodeType::GML_LineStringNode << "> or <" << NodeType::GML_PointNode << "> but got <" << node.name() << "> at " << getDocumentLocation());
+            throw std::runtime_error("Unexpected start tag found.");
+        }
+
+        m_model = m_factory.createLineString(attributes.getCityGMLIDAttribute());
+
+        parseDimension(attributes);
+
+        return true;
+
+    }
+
+    bool LineStringElementParser::parseElementEndTag(const NodeType::XMLNode&, const std::string&)
+    {
+        m_callback(m_model);
+        return true;
+    }
+
+    bool LineStringElementParser::parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes)
+    {
+        if (m_model == nullptr) {
+            throw std::runtime_error("LineStringElementParser::parseChildElementStartTag called before LineStringElementParser::parseElementStartTag");
+        }
+
+        if (node == NodeType::GML_PosListNode
+                || node == NodeType::GML_PosNode) {
+            parseDimension(attributes);
+            return true;
+        }
+
+        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
+    }
+
+    bool LineStringElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
+    {
+
+        if (m_model == nullptr) {
+            throw std::runtime_error("LineStringElementParser::parseChildElementEndTag called before LineStringElementParser::parseElementStartTag");
+        }
+
+        if (node == NodeType::GML_PosListNode
+                || node == NodeType::GML_PosNode) {
+
+            if (m_model->getDimensions() < 0) {
+                CITYGML_LOG_ERROR(m_logger, "No srsDimension given for LineString before or as attribute of <" << NodeType::GML_PosListNode << "> child element at " << getDocumentLocation());
+            } else if (m_model->getDimensions() == 2) {
+                m_model->setVertices2D(parseVecList<TVec2d>(characters, m_logger, getDocumentLocation()));
+            } else if (m_model->getDimensions() == 3) {
+                m_model->setVertices3D(parseVecList<TVec3d>(characters, m_logger, getDocumentLocation()));
+            } else {
+                CITYGML_LOG_WARN(m_logger, "Unsupported dimension of LineString positions at " << getDocumentLocation() << ". Only 2 and 3 dimensions are supported.");
+            }
+
+            return true;
+        }
+
+        return GMLObjectElementParser::parseChildElementEndTag(node, characters);
+
+    }
+
+    Object* LineStringElementParser::getObject()
+    {
+        return m_model.get();
+    }
+
+    void LineStringElementParser::parseDimension(Attributes& attributes)
+    {
+        std::string dim_str = attributes.getAttribute("srsDimension", "");
+
+        if (dim_str.empty()) {
+            return;
+        }
+
+        int dim = std::stoi(dim_str);
+        m_model->setDimensions(dim);
+    }
+
+}
diff --git a/sources/src/parser/nodetypes.cpp b/sources/src/parser/nodetypes.cpp
index 3ab81ed..47c02e0 100644
--- a/sources/src/parser/nodetypes.cpp
+++ b/sources/src/parser/nodetypes.cpp
@@ -173,12 +173,12 @@ namespace citygml {
                 INITIALIZE_NODE( GML, PolyhedralSurface )
                 INITIALIZE_NODE( GML, Surface )
                 INITIALIZE_NODE( GML, PolygonPatch)
+                INITIALIZE_NODE( GML, LineString)
 
                 INITIALIZE_NODE( BLDG, Lod1Solid )
                 INITIALIZE_NODE( BLDG, Lod2Solid )
                 INITIALIZE_NODE( BLDG, Lod3Solid )
                 INITIALIZE_NODE( BLDG, Lod4Solid )
-                INITIALIZE_NODE( BLDG, Lod1Geometry )
                 INITIALIZE_NODE( BLDG, Lod2Geometry )
                 INITIALIZE_NODE( BLDG, Lod3Geometry )
                 INITIALIZE_NODE( BLDG, Lod4Geometry )
@@ -323,6 +323,12 @@ namespace citygml {
                 INITIALIZE_NODE( VEG, TrunkDiameter )
                 INITIALIZE_NODE( VEG, CrownDiameter )
 
+                INITIALIZE_NODE( VEG, Lod0Geometry )
+                INITIALIZE_NODE( VEG, Lod1Geometry )
+                INITIALIZE_NODE( VEG, Lod2Geometry )
+                INITIALIZE_NODE( VEG, Lod3Geometry )
+                INITIALIZE_NODE( VEG, Lod4Geometry )
+
                 // TRANS
                 INITIALIZE_NODE( TRANS, TransportationComplex )
                 INITIALIZE_NODE( TRANS, TrafficArea )
@@ -544,7 +550,6 @@ namespace citygml {
     DEFINE_NODE( BLDG, Lod2Solid )
     DEFINE_NODE( BLDG, Lod3Solid )
     DEFINE_NODE( BLDG, Lod4Solid )
-    DEFINE_NODE( BLDG, Lod1Geometry )
     DEFINE_NODE( BLDG, Lod2Geometry )
     DEFINE_NODE( BLDG, Lod3Geometry )
     DEFINE_NODE( BLDG, Lod4Geometry )
@@ -581,6 +586,8 @@ namespace citygml {
     DEFINE_NODE( GML, Surface )
     DEFINE_NODE( GML, PolygonPatch)
 
+    DEFINE_NODE( GML, LineString)
+
     // BLDG
     DEFINE_NODE( BLDG, Building )
     DEFINE_NODE( BLDG, BuildingPart )
@@ -695,6 +702,12 @@ namespace citygml {
     DEFINE_NODE( VEG, TrunkDiameter )
     DEFINE_NODE( VEG, CrownDiameter )
 
+    DEFINE_NODE( VEG, Lod0Geometry )
+    DEFINE_NODE( VEG, Lod1Geometry )
+    DEFINE_NODE( VEG, Lod2Geometry )
+    DEFINE_NODE( VEG, Lod3Geometry )
+    DEFINE_NODE( VEG, Lod4Geometry )
+
     // TRANS
     DEFINE_NODE( TRANS, TransportationComplex )
     DEFINE_NODE( TRANS, TrafficArea )
diff --git a/sources/src/parser/sequenceparser.cpp b/sources/src/parser/sequenceparser.cpp
index 3e95d3f..e732918 100644
--- a/sources/src/parser/sequenceparser.cpp
+++ b/sources/src/parser/sequenceparser.cpp
@@ -27,10 +27,13 @@ namespace citygml {
         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...");
+            return false;
 
         } else {
             m_documentParser.removeCurrentElementParser(this);
         }
+
+        return true;
     }
 
     bool SequenceParser::handlesElement(const NodeType::XMLNode& node) const

-- 
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