From 056923dd904857e338df37d6b83e7220f336615f Mon Sep 17 00:00:00 2001 From: Shehzan Mohammed Date: Fri, 31 Aug 2018 11:30:32 -0400 Subject: [PATCH 1/2] Add a source SRS CLI option --- sources/include/citygml/citygml.h | 3 +++ sources/include/parser/citygmldocumentparser.h | 2 ++ sources/include/parser/gmlfeaturecollectionparser.h | 1 + sources/src/parser/citygmldocumentparser.cpp | 5 +++++ sources/src/parser/gmlfeaturecollectionparser.cpp | 10 ++++++++++ test/citygmltest.cpp | 1 + 6 files changed, 22 insertions(+) diff --git a/sources/include/citygml/citygml.h b/sources/include/citygml/citygml.h index 41c97362..f39e3bb1 100644 --- a/sources/include/citygml/citygml.h +++ b/sources/include/citygml/citygml.h @@ -59,6 +59,7 @@ namespace citygml // pruneEmptyObjects: remove the objects which do not contains any geometrical entity // tesselate: convert the interior & exteriors polygons to triangles // destSRS: the SRS (WKT, EPSG, OGC URN, etc.) where the coordinates must be transformed, default ("") is no transformation + // srsSRS: the SRS (WKT, EPSG, OGC URN, etc.) to overrride the SRS in the CityGML data (if any), default ("") means no override or use included SRS class LIBCITYGML_EXPORT ParserParams { @@ -70,6 +71,7 @@ namespace citygml , optimize( false ) , pruneEmptyObjects( false ) , destSRS( "" ) + , srcSRS( "" ) , keepVertices ( false ) { } @@ -82,6 +84,7 @@ namespace citygml bool tesselate; bool keepVertices; std::string destSRS; + std::string srcSRS; }; LIBCITYGML_EXPORT std::shared_ptr load( std::istream& stream, const ParserParams& params, std::shared_ptr logger = nullptr); diff --git a/sources/include/parser/citygmldocumentparser.h b/sources/include/parser/citygmldocumentparser.h index cb17a132..e0169aff 100644 --- a/sources/include/parser/citygmldocumentparser.h +++ b/sources/include/parser/citygmldocumentparser.h @@ -19,6 +19,8 @@ namespace citygml { std::shared_ptr getModel(); + const ParserParams getParserParams() const; + // Methods used by CityGMLElementParser void setCurrentElementParser(ElementParser* parser); diff --git a/sources/include/parser/gmlfeaturecollectionparser.h b/sources/include/parser/gmlfeaturecollectionparser.h index 0cf058be..f50cdd4c 100644 --- a/sources/include/parser/gmlfeaturecollectionparser.h +++ b/sources/include/parser/gmlfeaturecollectionparser.h @@ -26,6 +26,7 @@ namespace citygml { private: Envelope* m_bounds; + bool m_srsSRSOverride; }; diff --git a/sources/src/parser/citygmldocumentparser.cpp b/sources/src/parser/citygmldocumentparser.cpp index 0e40448b..9feaae94 100644 --- a/sources/src/parser/citygmldocumentparser.cpp +++ b/sources/src/parser/citygmldocumentparser.cpp @@ -30,6 +30,11 @@ namespace citygml { return m_rootModel; } + const ParserParams CityGMLDocumentParser::getParserParams() const + { + return m_parserParams; + } + void CityGMLDocumentParser::setCurrentElementParser(ElementParser* parser) { m_parserStack.push(std::shared_ptr(parser)); diff --git a/sources/src/parser/gmlfeaturecollectionparser.cpp b/sources/src/parser/gmlfeaturecollectionparser.cpp index 7c529d9f..ea1908c4 100644 --- a/sources/src/parser/gmlfeaturecollectionparser.cpp +++ b/sources/src/parser/gmlfeaturecollectionparser.cpp @@ -1,6 +1,7 @@ #include "parser/gmlfeaturecollectionparser.h" #include "parser/attributes.h" +#include "parser/citygmldocumentparser.h" #include "parser/parserutils.hpp" #include "parser/nodetypes.h" @@ -19,6 +20,12 @@ namespace citygml { : GMLObjectElementParser(documentParser, factory, logger) { m_bounds = nullptr; + m_srsSRSOverride = false; + std::string paramsSrcSRS = documentParser.getParserParams().srcSRS; + if (!paramsSrcSRS.empty()) { + m_bounds = new Envelope(paramsSrcSRS); + m_srsSRSOverride = true; + } } bool GMLFeatureCollectionElementParser::parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes) @@ -33,6 +40,9 @@ namespace citygml { return true; } else if (node == NodeType::GML_EnvelopeNode) { + if (m_srsSRSOverride) { + return true; + } if (m_bounds != nullptr) { CITYGML_LOG_WARN(m_logger, "Duplicate definition of " << NodeType::GML_EnvelopeNode << " at " << getDocumentLocation()); return true; diff --git a/test/citygmltest.cpp b/test/citygmltest.cpp index 7b87d797..cb445e6b 100644 --- a/test/citygmltest.cpp +++ b/test/citygmltest.cpp @@ -62,6 +62,7 @@ int main( int argc, char **argv ) if ( param == "-log" ) { log = true; fargc = i+1; } //if ( param == "-filter" ) { if ( i == argc - 1 ) usage(); params.objectsMask = argv[i+1]; i++; fargc = i+1; } if ( param == "-destsrs" ) { if ( i == argc - 1 ) usage(); params.destSRS = argv[i+1]; i++; fargc = i+1; } + if ( param == "-srcsrs" ) { if ( i == argc - 1 ) usage(); params.srcSRS = argv[i+1]; i++; fargc = i+1; } } if ( argc - fargc < 1 ) usage(); From d1f8254f25a56fccb0502d0963183dd13ec22e0c Mon Sep 17 00:00:00 2001 From: Shehzan Mohammed Date: Fri, 30 Nov 2018 03:10:02 -0500 Subject: [PATCH 2/2] Fix propagation of srsOverride into objects --- .../include/parser/gmlfeaturecollectionparser.h | 5 ++++- sources/src/parser/citymodelelementparser.cpp | 6 ++++++ sources/src/parser/cityobjectelementparser.cpp | 6 ++++++ sources/src/parser/gmlfeaturecollectionparser.cpp | 14 +++++++++++--- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/sources/include/parser/gmlfeaturecollectionparser.h b/sources/include/parser/gmlfeaturecollectionparser.h index f50cdd4c..a1305b58 100644 --- a/sources/include/parser/gmlfeaturecollectionparser.h +++ b/sources/include/parser/gmlfeaturecollectionparser.h @@ -24,9 +24,12 @@ namespace citygml { // GMLObjectElementParser interface virtual Object* getObject() override; + const Envelope& getEnvelope() const; + bool getSourceSRSOverride() const; + private: Envelope* m_bounds; - bool m_srsSRSOverride; + bool m_sourceSRSOverride; }; diff --git a/sources/src/parser/citymodelelementparser.cpp b/sources/src/parser/citymodelelementparser.cpp index 915dd91a..b662b090 100644 --- a/sources/src/parser/citymodelelementparser.cpp +++ b/sources/src/parser/citymodelelementparser.cpp @@ -49,6 +49,12 @@ namespace citygml { 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; } diff --git a/sources/src/parser/cityobjectelementparser.cpp b/sources/src/parser/cityobjectelementparser.cpp index dd43786a..26628a02 100644 --- a/sources/src/parser/cityobjectelementparser.cpp +++ b/sources/src/parser/cityobjectelementparser.cpp @@ -237,6 +237,12 @@ namespace citygml { bool CityObjectElementParser::parseElementEndTag(const NodeType::XMLNode&, const std::string&) { + 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); m_model = nullptr; return true; diff --git a/sources/src/parser/gmlfeaturecollectionparser.cpp b/sources/src/parser/gmlfeaturecollectionparser.cpp index ea1908c4..1ee7bbfe 100644 --- a/sources/src/parser/gmlfeaturecollectionparser.cpp +++ b/sources/src/parser/gmlfeaturecollectionparser.cpp @@ -20,11 +20,11 @@ namespace citygml { : GMLObjectElementParser(documentParser, factory, logger) { m_bounds = nullptr; - m_srsSRSOverride = false; + m_sourceSRSOverride = false; std::string paramsSrcSRS = documentParser.getParserParams().srcSRS; if (!paramsSrcSRS.empty()) { m_bounds = new Envelope(paramsSrcSRS); - m_srsSRSOverride = true; + m_sourceSRSOverride = true; } } @@ -40,7 +40,7 @@ namespace citygml { return true; } else if (node == NodeType::GML_EnvelopeNode) { - if (m_srsSRSOverride) { + if (m_sourceSRSOverride) { return true; } if (m_bounds != nullptr) { @@ -93,6 +93,14 @@ namespace citygml { return getFeatureObject(); } + const Envelope& GMLFeatureCollectionElementParser::getEnvelope() const + { + return *m_bounds; + } + bool GMLFeatureCollectionElementParser::getSourceSRSOverride() const + { + return m_sourceSRSOverride; + } }