diff --git a/sources/CMakeLists.txt b/sources/CMakeLists.txt index eb7480a0..d653bad2 100644 --- a/sources/CMakeLists.txt +++ b/sources/CMakeLists.txt @@ -77,6 +77,8 @@ SET(SOURCES src/citygml/geometrymanager.cpp src/citygml/linestring.cpp src/citygml/address.cpp + src/citygml/rectifiedgridcoverage.cpp + src/citygml/externalreference.cpp src/parser/nodetypes.cpp src/parser/attributes.cpp @@ -98,11 +100,13 @@ SET(SOURCES src/parser/citymodelelementparser.cpp src/parser/cityobjectelementparser.cpp src/parser/appearanceelementparser.cpp + src/parser/externalreferenceparser.cpp src/parser/materialelementparser.cpp src/parser/textureelementparser.cpp src/parser/georeferencedtextureelementparser.cpp src/parser/geometryelementparser.cpp src/parser/polygonelementparser.cpp + src/parser/rectifiedgridcoverageparser.cpp src/parser/linestringelementparser.cpp src/parser/linearringelementparser.cpp src/parser/implicitgeometryelementparser.cpp @@ -145,6 +149,8 @@ SET(PUBLIC_HEADER include/citygml/citygmlfactory.h include/citygml/linestring.h include/citygml/address.h + include/citygml/rectifiedgridcoverage.h + include/citygml/externalreference.h ) SET(HEADERS @@ -179,11 +185,13 @@ SET(HEADERS include/parser/citymodelelementparser.h include/parser/cityobjectelementparser.h include/parser/appearanceelementparser.h + include/parser/externalreferenceparser.h include/parser/materialelementparser.h include/parser/textureelementparser.h include/parser/georeferencedtextureelementparser.h include/parser/geometryelementparser.h include/parser/polygonelementparser.h + include/parser/rectifiedgridcoverageparser.h include/parser/linestringelementparser.h include/parser/linearringelementparser.h include/parser/implicitgeometryelementparser.h diff --git a/sources/include/citygml/citygml.h b/sources/include/citygml/citygml.h index f39e3bb1..6e9be843 100644 --- a/sources/include/citygml/citygml.h +++ b/sources/include/citygml/citygml.h @@ -69,6 +69,7 @@ namespace citygml , minLOD( 0 ) , maxLOD( 4 ) , optimize( false ) + , tesselate( true ) , pruneEmptyObjects( false ) , destSRS( "" ) , srcSRS( "" ) diff --git a/sources/include/citygml/citygmlfactory.h b/sources/include/citygml/citygmlfactory.h index eb99bda3..e44d4c6b 100644 --- a/sources/include/citygml/citygmlfactory.h +++ b/sources/include/citygml/citygmlfactory.h @@ -2,6 +2,7 @@ #include #include +#include #include @@ -19,6 +20,7 @@ namespace citygml { class ImplicitGeometry; class Polygon; class LineString; + class RectifiedGridCoverage; class Appearance; class Texture; @@ -35,9 +37,11 @@ namespace citygml { CityModel* createCityModel(const std::string& id); CityObject* createCityObject(const std::string& id, CityObject::CityObjectsType type); Geometry* createGeometry(const std::string& id, const CityObject::CityObjectsType& cityObjType = CityObject::CityObjectsType::COT_All, unsigned int lod = 0, std::string srsName = ""); + RectifiedGridCoverage* createRectifiedGridCoverage(std::string const& id); std::shared_ptr createPolygon(const std::string& id); std::shared_ptr createLineString(const std::string& id); + std::shared_ptr createExternalReference(const std::string& id); /** * @brief requests a polygon for a Geometry object that will be added later diff --git a/sources/include/citygml/citymodel.h b/sources/include/citygml/citymodel.h index 4a28e35e..02752654 100644 --- a/sources/include/citygml/citymodel.h +++ b/sources/include/citygml/citymodel.h @@ -39,7 +39,7 @@ namespace citygml { const std::string& getSRSName() const; - void finish(Tesselator& tesselator, bool optimize, std::shared_ptr logger); + void finish(Tesselator& tesselator, bool optimize, bool tesselate, std::shared_ptr logger); std::vector themes() const; void setThemes(std::vector themes); diff --git a/sources/include/citygml/cityobject.h b/sources/include/citygml/cityobject.h index 40b388e4..fb791e3c 100644 --- a/sources/include/citygml/cityobject.h +++ b/sources/include/citygml/cityobject.h @@ -6,6 +6,8 @@ #include #include #include +#include +#include class Tesselator; namespace citygml { @@ -108,8 +110,16 @@ namespace citygml { // Access address const Address* address() const; void setAddress(std::unique_ptr
&& address); + + // Access rectifiedGridCoverage + RectifiedGridCoverage const* rectifiedGridCoverage() const; + void setRectifiedGridCoverage(RectifiedGridCoverage * rectifiedGridCoverage); + + // Access externalReference + ExternalReference const* externalReference() const; + void setExternalReference(ExternalReference * externalReference); - void finish(Tesselator& tesselator, bool optimize, std::shared_ptr logger); + void finish(Tesselator& tesselator, bool optimize, bool tesselate, std::shared_ptr logger); virtual ~CityObject(); @@ -120,6 +130,8 @@ namespace citygml { std::vector > m_implicitGeometries; std::vector > m_children; std::unique_ptr
m_address; + std::unique_ptr m_rectifiedGridCoverage; + std::unique_ptr m_externalReference; }; LIBCITYGML_EXPORT std::ostream& operator<<( std::ostream& os, const CityObject& o ); diff --git a/sources/include/citygml/externalreference.h b/sources/include/citygml/externalreference.h new file mode 100644 index 00000000..26f5b62d --- /dev/null +++ b/sources/include/citygml/externalreference.h @@ -0,0 +1,25 @@ +#pragma once + +#include + + +namespace citygml { + union LIBCITYGML_EXPORT ExternalObjectReference { + std::string name; + std::string uri; + + ExternalObjectReference(); + ~ExternalObjectReference(); + }; + + class LIBCITYGML_EXPORT ExternalReference: public Object { + friend class CityGMLFactory; + + protected: + ExternalReference(std::string const& id); +// ~ExternalReference() noexcept override; // Destructor + public: + std::string informationSystem; + ExternalObjectReference externalObject; + }; +} diff --git a/sources/include/citygml/geometry.h b/sources/include/citygml/geometry.h index ddc21723..523099ad 100644 --- a/sources/include/citygml/geometry.h +++ b/sources/include/citygml/geometry.h @@ -73,7 +73,7 @@ namespace citygml { * @param tesselator the tesselator to be used for tesselation * @param mergePolygons determines wether all polygons are merged into one */ - void finish(Tesselator& tesselator, bool optimize, std::shared_ptr logger); + void finish(Tesselator& tesselator, bool optimize, bool tesselate, std::shared_ptr logger); ~Geometry(); diff --git a/sources/include/citygml/polygon.h b/sources/include/citygml/polygon.h index a0167bd7..146f3943 100644 --- a/sources/include/citygml/polygon.h +++ b/sources/include/citygml/polygon.h @@ -82,7 +82,7 @@ namespace citygml { void addRing( LinearRing* ); - void finish(Tesselator& tesselator , bool optimize, std::shared_ptr logger); + void finish(Tesselator& tesselator , bool optimize, bool tesselate, std::shared_ptr logger); std::shared_ptr exteriorRing(){ return m_exteriorRing; diff --git a/sources/include/citygml/rectifiedgridcoverage.h b/sources/include/citygml/rectifiedgridcoverage.h new file mode 100644 index 00000000..de3487ac --- /dev/null +++ b/sources/include/citygml/rectifiedgridcoverage.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace citygml { + + class LIBCITYGML_EXPORT RectifiedGridCoverage : public FeatureObject + { + friend class CityGMLFactory; + + protected: + RectifiedGridCoverage(std::string const& id = "RectifiedGridCoverage"); + }; + + LIBCITYGML_EXPORT std::ostream& operator<<( std::ostream& os, const RectifiedGridCoverage& o ); + +} + diff --git a/sources/include/parser/externalreferenceparser.h b/sources/include/parser/externalreferenceparser.h new file mode 100644 index 00000000..7936f64d --- /dev/null +++ b/sources/include/parser/externalreferenceparser.h @@ -0,0 +1,30 @@ +#pragma once + +#include "parser/gmlobjectparser.h" +#include + + +namespace citygml { + class ExternalReferenceParser: public GMLObjectElementParser { + public: + ExternalReferenceParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr logger, std::function callback); + + // ElementParser interface + virtual std::string elementParserName() const override; + virtual bool handlesElement(NodeType::XMLNode const& node) const override; + + protected: + // CityGMLElementParser interaface + virtual bool parseElementStartTag(NodeType::XMLNode const& node, Attributes & attribute) override; + virtual bool parseElementEndTag(NodeType::XMLNode const& node, std::string const& characters) override; + virtual bool parseChildElementStartTag(NodeType::XMLNode const& node, Attributes & attributes) override; + virtual bool parseChildElementEndTag(NodeType::XMLNode const& node, std::string const& characters) override; + + // GMLObjectElementParser interface + virtual Object* getObject() override; + + private: + std::shared_ptr model; + std::function callback; + }; +} diff --git a/sources/include/parser/rectifiedgridcoverageparser.h b/sources/include/parser/rectifiedgridcoverageparser.h new file mode 100644 index 00000000..6becf07d --- /dev/null +++ b/sources/include/parser/rectifiedgridcoverageparser.h @@ -0,0 +1,34 @@ +#pragma once + +#include "parser/gmlfeaturecollectionparser.h" + +#include + + +namespace citygml { + + class RectifiedGridCoverageParser : public GMLFeatureCollectionElementParser { + public: + RectifiedGridCoverageParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr logger, std::function callback); + + // ElementParser interface + virtual std::string elementParserName() const override; + 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; + + // GMLFeatureCollectionElementParser interface + virtual FeatureObject* getFeatureObject() override; + + private: + std::function m_callback; + RectifiedGridCoverage * m_model; + }; +} + + diff --git a/sources/src/citygml/citygmlfactory.cpp b/sources/src/citygml/citygmlfactory.cpp index 1a80e4c8..cd88bc37 100644 --- a/sources/src/citygml/citygmlfactory.cpp +++ b/sources/src/citygml/citygmlfactory.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace citygml { @@ -26,6 +27,10 @@ namespace citygml { m_logger = logger; } + RectifiedGridCoverage* CityGMLFactory::createRectifiedGridCoverage(std::string const& id) { + return new RectifiedGridCoverage(id); + } + CityModel* CityGMLFactory::createCityModel(const std::string& id) { return new CityModel(id); @@ -88,7 +93,12 @@ namespace citygml { { LineString* lineString = new LineString(id); return std::shared_ptr(lineString); + } + std::shared_ptr CityGMLFactory::createExternalReference(const std::string& id) + { + ExternalReference * externalReference = new ExternalReference(id); + return std::shared_ptr(externalReference); } void CityGMLFactory::requestSharedPolygonForGeometry(Geometry* geom, const std::string& polygonId) diff --git a/sources/src/citygml/citymodel.cpp b/sources/src/citygml/citymodel.cpp index 9f411dd1..8e861b2a 100644 --- a/sources/src/citygml/citymodel.cpp +++ b/sources/src/citygml/citymodel.cpp @@ -115,11 +115,11 @@ namespace citygml } - void CityModel::finish(Tesselator& tesselator, bool optimize, std::shared_ptr logger) + void CityModel::finish(Tesselator& tesselator, bool optimize, bool tesselate, std::shared_ptr logger) { // Finish all cityobjcts for (auto& cityObj : m_roots) { - cityObj->finish(tesselator, optimize, logger); + cityObj->finish(tesselator, optimize, tesselate, logger); } // Build city objects map diff --git a/sources/src/citygml/cityobject.cpp b/sources/src/citygml/cityobject.cpp index 4b050621..703baf2b 100644 --- a/sources/src/citygml/cityobject.cpp +++ b/sources/src/citygml/cityobject.cpp @@ -98,20 +98,36 @@ namespace citygml { m_address = std::move(address); } - void CityObject::finish(Tesselator& tesselator, bool optimize, std::shared_ptr logger) + RectifiedGridCoverage const* CityObject::rectifiedGridCoverage() const { + return m_rectifiedGridCoverage.get(); + } + + void CityObject::setRectifiedGridCoverage(RectifiedGridCoverage * rectifiedGridCoverage) { + m_rectifiedGridCoverage = std::unique_ptr(rectifiedGridCoverage); + } + + ExternalReference const* CityObject::externalReference() const { + return m_externalReference.get(); + } + + void CityObject::setExternalReference(ExternalReference * externalReference) { + m_externalReference = std::unique_ptr(externalReference); + } + + void CityObject::finish(Tesselator& tesselator, bool optimize, bool tesselate, std::shared_ptr logger) { for (std::unique_ptr& geom : m_geometries) { - geom->finish(tesselator, optimize, logger); + geom->finish(tesselator, optimize, tesselate, logger); } for (std::unique_ptr& implictGeom : m_implicitGeometries) { for (int i = 0; i < implictGeom->getGeometriesCount(); i++) { - implictGeom->getGeometry(i).finish(tesselator, optimize, logger); + implictGeom->getGeometry(i).finish(tesselator, optimize, tesselate, logger); } } for (std::unique_ptr& child : m_children) { - child->finish(tesselator, optimize, logger); + child->finish(tesselator, optimize, tesselate, logger); } } diff --git a/sources/src/citygml/externalreference.cpp b/sources/src/citygml/externalreference.cpp new file mode 100644 index 00000000..0962f6fa --- /dev/null +++ b/sources/src/citygml/externalreference.cpp @@ -0,0 +1,12 @@ +#include + +namespace citygml { + ExternalObjectReference::ExternalObjectReference() { + } + + ExternalObjectReference::~ExternalObjectReference() { + } + + ExternalReference::ExternalReference(std::string const& id) : Object(id) { + } +} diff --git a/sources/src/citygml/geometry.cpp b/sources/src/citygml/geometry.cpp index 70115ee8..490b7576 100644 --- a/sources/src/citygml/geometry.cpp +++ b/sources/src/citygml/geometry.cpp @@ -137,7 +137,7 @@ namespace citygml { m_lineStrings.push_back(l); } - void Geometry::finish(Tesselator& tesselator, bool optimize, std::shared_ptr logger) + void Geometry::finish(Tesselator& tesselator, bool optimize, bool tesselate, std::shared_ptr logger) { // only need to finish geometry once if (m_finished) { @@ -148,12 +148,12 @@ namespace citygml { for (std::shared_ptr& child : m_childGeometries) { child->addTargetDefinitionsOf(*this); - child->finish(tesselator, optimize, logger); + child->finish(tesselator, optimize, tesselate, logger); } for (std::shared_ptr& polygon : m_polygons) { polygon->addTargetDefinitionsOf(*this); - polygon->finish(tesselator, optimize, logger); + polygon->finish(tesselator, optimize, tesselate, logger); } } diff --git a/sources/src/citygml/polygon.cpp b/sources/src/citygml/polygon.cpp index 31c36373..8644d411 100644 --- a/sources/src/citygml/polygon.cpp +++ b/sources/src/citygml/polygon.cpp @@ -231,7 +231,7 @@ namespace citygml { } } - void Polygon::finish(Tesselator& tesselator, bool optimize, std::shared_ptr logger) + void Polygon::finish(Tesselator& tesselator, bool optimize, bool tesselate, std::shared_ptr logger) { if (m_finished) { // This may happen as Polygons can be shared between geometries @@ -243,9 +243,10 @@ namespace citygml { if (optimize) { removeDuplicateVerticesInRings(logger); } - - computeIndices(tesselator, logger); - + + if (tesselate) { + computeIndices(tesselator, logger); + } } void Polygon::addRing( LinearRing* ring ) diff --git a/sources/src/citygml/rectifiedgridcoverage.cpp b/sources/src/citygml/rectifiedgridcoverage.cpp new file mode 100644 index 00000000..77b220ac --- /dev/null +++ b/sources/src/citygml/rectifiedgridcoverage.cpp @@ -0,0 +1,6 @@ +#include + +namespace citygml { + RectifiedGridCoverage::RectifiedGridCoverage(std::string const& id) : FeatureObject(id) { + } +} diff --git a/sources/src/parser/citygmldocumentparser.cpp b/sources/src/parser/citygmldocumentparser.cpp index 9feaae94..3450f72e 100644 --- a/sources/src/parser/citygmldocumentparser.cpp +++ b/sources/src/parser/citygmldocumentparser.cpp @@ -126,7 +126,7 @@ namespace citygml { tesselator.setKeepVertices(m_parserParams.keepVertices); CITYGML_LOG_INFO(m_logger, "Start postprocessing of the citymodel."); - m_rootModel->finish(tesselator, m_parserParams.optimize, m_logger); + m_rootModel->finish(tesselator, m_parserParams.optimize, m_parserParams.tesselate, m_logger); CITYGML_LOG_INFO(m_logger, "Finished postprocessing of the citymodel."); m_rootModel->setThemes(m_factory->getAllThemes()); diff --git a/sources/src/parser/cityobjectelementparser.cpp b/sources/src/parser/cityobjectelementparser.cpp index 1296c027..b0ad8204 100644 --- a/sources/src/parser/cityobjectelementparser.cpp +++ b/sources/src/parser/cityobjectelementparser.cpp @@ -10,6 +10,8 @@ #include "parser/delayedchoiceelementparser.h" #include "parser/linestringelementparser.h" #include "parser/addressparser.h" +#include "parser/rectifiedgridcoverageparser.h" +#include "parser/externalreferenceparser.h" #include #include @@ -273,6 +275,11 @@ namespace citygml { } else if (attributesSet.count(node.typeID()) > 0 || node == NodeType::GEN_ValueNode) { return true; + } else if (node == NodeType::GML_RectifiedGridCoverageNode) { + + setParserForNextElement(new RectifiedGridCoverageParser(m_documentParser, m_factory, m_logger, [this](RectifiedGridCoverage * rectifiedGridCoverage) { + m_model->setRectifiedGridCoverage(rectifiedGridCoverage); + })); } else if (node == NodeType::BLDG_BoundedByNode || node == NodeType::BLDG_OuterBuildingInstallationNode || node == NodeType::BLDG_InteriorBuildingInstallationNode @@ -291,7 +298,8 @@ namespace citygml { || node == NodeType::DEM_MassPointReliefNode || node == NodeType::DEM_BreaklineReliefNode || node == NodeType::DEM_RasterReliefNode - || node == NodeType::DEM_GridNode) { + || node == NodeType::DEM_GridNode + || node == NodeType::CORE_GeneralizesToNode) { setParserForNextElement(new CityObjectElementParser(m_documentParser, m_factory, m_logger, [this](CityObject* obj) { m_model->addChildCityObject(obj); })); @@ -306,6 +314,11 @@ namespace citygml { || node == NodeType::DEM_BreaklinesNode) { parseGeometryForLODLevel(std::stoi(m_model->getAttribute("dem:lod"))); + } else if (node == NodeType::GEN_Lod0TerrainIntersectionNode + || node == NodeType::WTR_Lod0MultiCurveNode + || node == NodeType::WTR_Lod0MultiSurfaceNode) { + + parseGeometryForLODLevel(0); } else if (node == NodeType::BLDG_Lod1MultiCurveNode || node == NodeType::BLDG_Lod1MultiSurfaceNode || node == NodeType::BLDG_Lod1SolidNode @@ -355,7 +368,10 @@ namespace citygml { || node == NodeType::WTR_Lod4SurfaceNode) { parseGeometryForLODLevel(4); - } else if (node == NodeType::GEN_Lod1GeometryNode + } else if (node == NodeType::GEN_Lod0GeometryNode) { + parseGeometryPropertyElementForLODLevel(0, attributes.getCityGMLIDAttribute()); + } + else if (node == NodeType::GEN_Lod1GeometryNode || node == NodeType::FRN_Lod1GeometryNode || node == NodeType::VEG_Lod1GeometryNode) { parseGeometryPropertyElementForLODLevel(1, attributes.getCityGMLIDAttribute()); @@ -374,6 +390,9 @@ namespace citygml { || node == NodeType::BLDG_Lod4GeometryNode || node == NodeType::VEG_Lod4GeometryNode) { parseGeometryPropertyElementForLODLevel(4, attributes.getCityGMLIDAttribute()); + } else if (node == NodeType::GEN_Lod0ImplicitRepresentationNode) { + + parseImplicitGeometryForLODLevel(0); } else if (node == NodeType::VEG_Lod1ImplicitRepresentationNode || node == NodeType::FRN_Lod1ImplicitRepresentationNode || node == NodeType::GEN_Lod1ImplicitRepresentationNode) { @@ -394,17 +413,14 @@ namespace citygml { || node == NodeType::GEN_Lod4ImplicitRepresentationNode) { parseImplicitGeometryForLODLevel(4); - } else if (node == NodeType::CORE_GeneralizesToNode - || node == NodeType::CORE_ExternalReferenceNode - || node == NodeType::GML_MultiPointNode + } else if (node == NodeType::CORE_ExternalReferenceNode){ + + setParserForNextElement(new ExternalReferenceParser(m_documentParser, m_factory, m_logger, [this](ExternalReference * externalReference){ + m_model->setExternalReference(externalReference); + })); + } else if (node == NodeType::GML_MultiPointNode || node == NodeType::GRP_GeometryNode - || node == NodeType::GEN_Lod0GeometryNode - || node == NodeType::GEN_Lod0ImplicitRepresentationNode - || node == NodeType::GEN_Lod0TerrainIntersectionNode - || node == NodeType::TRANS_Lod0NetworkNode - || node == NodeType::WTR_Lod0MultiCurveNode - || node == NodeType::WTR_Lod0MultiSurfaceNode - || node == NodeType::GML_RectifiedGridCoverageNode) { + || node == NodeType::TRANS_Lod0NetworkNode) { 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; diff --git a/sources/src/parser/externalreferenceparser.cpp b/sources/src/parser/externalreferenceparser.cpp new file mode 100644 index 00000000..f37eae53 --- /dev/null +++ b/sources/src/parser/externalreferenceparser.cpp @@ -0,0 +1,74 @@ +#include "parser/externalreferenceparser.h" + +#include "parser/attributes.h" +#include "parser/documentlocation.h" +#include "parser/nodetypes.h" +#include +#include + +namespace citygml { + ExternalReferenceParser::ExternalReferenceParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr logger, std::function callback) + : GMLObjectElementParser(documentParser, factory, logger) { + this->callback = callback; + } + + std::string ExternalReferenceParser::elementParserName() const { + return "ExternalReferenceParser"; + } + + bool ExternalReferenceParser::handlesElement(NodeType::XMLNode const& node) const { + return node.typeID() == NodeType::CORE_ExternalReferenceNode.typeID(); + } + + bool ExternalReferenceParser::parseElementStartTag(NodeType::XMLNode const& node, Attributes & attributes) { + if (!handlesElement(node)) { + CITYGML_LOG_ERROR(m_logger, "Expected start tag <" << NodeType::CORE_ExternalReferenceNode << "> but got <" << node.name() << "> at " << getDocumentLocation()); + } + + model = m_factory.createExternalReference(attributes.getCityGMLIDAttribute()); + + return true; + } + + bool ExternalReferenceParser::parseElementEndTag(NodeType::XMLNode const& node, std::string const&) { + callback(model.get()); + return true; + } + + bool ExternalReferenceParser::parseChildElementStartTag(NodeType::XMLNode const& node, Attributes & attributes) { + if (model == nullptr) { + throw std::runtime_error("ExternalReferenceParser::parseChildElementStartTag called before ExternalReferenceParser::parseElementStartTag"); + } + + if (node == NodeType::CORE_ExternalObjectNode + || node == NodeType::CORE_InformationSystemNode + || node == NodeType::CORE_NameNode + || node == NodeType::CORE_UriNode) { + return true; + } + + return GMLObjectElementParser::parseChildElementStartTag(node, attributes); + } + + bool ExternalReferenceParser::parseChildElementEndTag(NodeType::XMLNode const& node, std::string const& characters) { + if (model == nullptr) { + throw std::runtime_error("ExternalReferenceParser::parseChildElementEndTag called before ExternalReferenceParser::parseElementStartTag"); + } + + if (node == NodeType::CORE_ExternalObjectNode) { + return true; + } else if (node == NodeType::CORE_InformationSystemNode) { + model->informationSystem = characters; + } else if (node == NodeType::CORE_NameNode) { + model->externalObject.name = characters; + } else if (node == NodeType::CORE_UriNode) { + model->externalObject.uri = characters; + } + + return GMLObjectElementParser::parseChildElementEndTag(node, characters); + } + + Object * ExternalReferenceParser::getObject() { + return model.get(); + } +} diff --git a/sources/src/parser/rectifiedgridcoverageparser.cpp b/sources/src/parser/rectifiedgridcoverageparser.cpp new file mode 100644 index 00000000..febc619d --- /dev/null +++ b/sources/src/parser/rectifiedgridcoverageparser.cpp @@ -0,0 +1,85 @@ +#include "parser/rectifiedgridcoverageparser.h" + +#include "parser/nodetypes.h" +#include "parser/attributes.h" +#include "parser/documentlocation.h" +#include "parser/cityobjectelementparser.h" +#include "parser/appearanceelementparser.h" + +#include +#include +#include +#include + +#include + +namespace citygml { + RectifiedGridCoverageParser::RectifiedGridCoverageParser(CityGMLDocumentParser& documentParser, CityGMLFactory& factory, std::shared_ptr logger, std::function callback) + : GMLFeatureCollectionElementParser(documentParser, factory, logger) + { + m_callback = callback; + m_model = nullptr; + } + + bool RectifiedGridCoverageParser::handlesElement(const NodeType::XMLNode& node) const + { + return node == NodeType::GML_RectifiedGridCoverageNode; + } + + std::string RectifiedGridCoverageParser::elementParserName() const + { + return "RectifiedGridCoverageParser"; + } + + bool RectifiedGridCoverageParser::parseElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) + { + if (node != NodeType::GML_RectifiedGridCoverageNode) { + CITYGML_LOG_ERROR(m_logger, "Expected start tag <" << NodeType::CORE_CityModelNode.name() << "> got <" << node.name() << "> at " << getDocumentLocation()); + throw std::runtime_error("Unexpected start tag found."); + } + + m_model = m_factory.createRectifiedGridCoverage(attributes.getCityGMLIDAttribute()); + return true; + } + + bool RectifiedGridCoverageParser::parseElementEndTag(const NodeType::XMLNode& node, const std::string&) + { + if (node != NodeType::GML_RectifiedGridCoverageNode) { + CITYGML_LOG_WARN(m_logger, "Expected end tag <" << NodeType::CORE_CityModelNode.name() << "> got <" << node.name() << "> at " << getDocumentLocation()); + } + + if (getSourceSRSOverride()) { + Envelope *envelope = new Envelope(getEnvelope().srsName()); + envelope->setLowerBound(m_model->getEnvelope().getLowerBound()); + envelope->setUpperBound(m_model->getEnvelope().getUpperBound()); + m_model->setEnvelope(envelope); + } + m_callback(m_model); + return true; + } + + + bool RectifiedGridCoverageParser::parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) + { + if (m_model == nullptr) { + throw std::runtime_error("RectifiedGridCoverage::parseChildElementStartTag called before RectifiedGridCoverage::parseElementStartTag"); + } + + return GMLObjectElementParser::parseChildElementStartTag(node, attributes); + } + + bool RectifiedGridCoverageParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters) + { + + if (m_model == nullptr) { + throw std::runtime_error("RectifiedGridCoverage::parseChildElementEndTag called before RectifiedGridCoverage::parseElementStartTag"); + } + + return GMLObjectElementParser::parseChildElementEndTag(node, characters); + } + + FeatureObject* RectifiedGridCoverageParser::getFeatureObject() + { + return m_model; + } +}