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

    }
Пример #2
0
    std::shared_ptr<const CityModel> load( const std::string& fname, const ParserParams& params , std::shared_ptr<CityGMLLogger> logger)
    {
        if (!logger) {
            logger = std::make_shared<StdLogger>();
        }

        if (!initXerces(logger)) {
            return nullptr;
        }

        std::shared_ptr<XMLCh> fileName = toXercesString(fname);

#ifdef NDEBUG
        try {
#endif
            xercesc::LocalFileInputSource fileSource(fileName.get());
            return parse(fileSource, params, logger, fname);
#ifdef NDEBUG
        } catch (xercesc::XMLException& e) {
            CITYGML_LOG_ERROR(logger, "Error parsing file " << fname << ": " << e.getMessage());
            return nullptr;
        }
#endif

    }
Пример #3
0
    bool AddressParser::parseElementStartTag(const NodeType::XMLNode& node, Attributes& attributes)
    {
        if (k_rootElements.count(node) == 0) {
            CITYGML_LOG_ERROR(m_logger, "Expected an address start tag but got <" << node << "> at " << getDocumentLocation());
            throw std::runtime_error("Unexpected start tag found.");
        }

        m_address = make_unique<Address>(attributes.getCityGMLIDAttribute());
        return true;
    }
Пример #4
0
void Tesselator::addContour(const std::vector<TVec3d>& pts, std::vector<std::vector<TVec2f> > textureCoordinatesLists )
{
    unsigned int len = pts.size();
    if ( len < 3 ) return;

    for (size_t i = 0; i < textureCoordinatesLists.size(); i++) {

        std::vector<TVec2f>& texCoords = textureCoordinatesLists.at(i);



        if (texCoords.size() != pts.size()) {
            if (!texCoords.empty()) {
                CITYGML_LOG_ERROR(_logger, "Invalid call to 'addContour'. The number of texture coordinates in list " << i << " (" << texCoords.size() << ") "
                             "does not match the number of vertices (" << pts.size() << "). The texture coordinates list will be resized which may cause invalid texture coordinates.");
            }

            texCoords.resize(pts.size(), TVec2f(0.f, 0.f));
        }
    }

    for (size_t i = 0; i < std::max(_texCoordsLists.size(), textureCoordinatesLists.size()); i++) {

        if (i >= _texCoordsLists.size()) {
            std::vector<TVec2f> texCoords(_vertices.size(), TVec2f(0.f, 0.f));
            texCoords.insert(texCoords.end(), textureCoordinatesLists.at(i).begin(), textureCoordinatesLists.at(i).end());
            _texCoordsLists.push_back(texCoords);
        } else if (i >= textureCoordinatesLists.size()) {
            _texCoordsLists.at(i).resize(_texCoordsLists.at(i).size() + pts.size(), TVec2f(0.f, 0.f));
        } else {
            _texCoordsLists.at(i).insert(_texCoordsLists.at(i).end(), textureCoordinatesLists.at(i).begin(), textureCoordinatesLists.at(i).end());
        }

    }

    unsigned int pos = _vertices.size();

    gluTessBeginContour( _tobj );

    for ( unsigned int i = 0; i < len; i++ )
    {
        _vertices.push_back( pts[i] );
        _indices.push_back(pos + i);

        gluTessVertex( _tobj, &(_vertices.back()[0]), &_indices.back() );
    }

    gluTessEndContour( _tobj );

#ifndef NDEBUG
    for (size_t i = 0; i < _texCoordsLists.size(); i++) {
        assert(_texCoordsLists.at(i).size() == _vertices.size());
    }
#endif
}
Пример #5
0
    bool PolygonElementParser::parseElementStartTag(const NodeType::XMLNode& node, Attributes& attributes)
    {

        if (!handlesElement(node)) {
            CITYGML_LOG_ERROR(m_logger, "Expected start tag of PolygonObject but got <" << node.name() << "> at " << getDocumentLocation());
            throw std::runtime_error("Unexpected start tag found.");
        }

        m_model = m_factory.createPolygon(attributes.getCityGMLIDAttribute());
        return true;

    }
    GeoTransform( const std::string& destURN, std::shared_ptr<citygml::CityGMLLogger> logger )
		: m_destSRSURN(destURN)
		, m_sourceURN("")
		, m_transformation(nullptr)
		, m_logger(logger)
    {
        OGRErr err = m_destSRS.SetFromUserInput(destURN.c_str());

        if (err != OGRERR_NONE) {
            CITYGML_LOG_ERROR(m_logger, "Could not create OGRSpatialReference for destination SRS " << destURN << ". OGR error code: " << err << ".");
            throw std::runtime_error("Invalid destination spatial reference system.");
        }
    }
Пример #7
0
    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...");
            return false;

        } else {
            m_documentParser.removeCurrentElementParser(this);
        }

        return true;
    }
    void setSourceSRS(const std::string& sourceURN) {

        if (m_transformation != nullptr) {
            OCTDestroyCoordinateTransformation(m_transformation);
            m_transformation = nullptr;
        }

        OGRSpatialReference sourceSRS;
        OGRErr err = sourceSRS.SetFromUserInput(sourceURN.c_str());

        if (err != OGRERR_NONE) {
            CITYGML_LOG_ERROR(m_logger, "Could not create OGRSpatialReference for source SRS " << sourceURN << ". OGR error code: " << err << ".");
            return;
        }

        m_transformation = OGRCreateCoordinateTransformation(&sourceSRS, &m_destSRS);
        if (m_transformation == nullptr) {
            CITYGML_LOG_ERROR(m_logger, "Could not create transformation from source SRS " << sourceURN << " to destination SRS " << m_destSRSURN << ".");
            return;
        }

        m_sourceURN = sourceURN;
    }
Пример #9
0
    bool CityGMLElementParser::startElement(const NodeType::XMLNode& node, Attributes& attributes)
    {
        if (!node.valid()) {
            CITYGML_LOG_ERROR(m_logger, "Invalid xml start tag (no name) found at " << getDocumentLocation());
            throw std::runtime_error("Error parsing xml document. Invalid start tag.");
        }

        if (!m_boundElement.valid()) {
            m_boundElement = node;
            return parseElementStartTag(node, attributes);
        } else {
            return parseChildElementStartTag(node, attributes);
        }
    }
    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;

    }
Пример #11
0
    std::shared_ptr<const CityModel> parse(xercesc::InputSource& stream, const ParserParams& params, std::shared_ptr<CityGMLLogger> logger, std::string filename = "") {



        CityGMLHandlerXerces handler( params, filename, logger );

        xercesc::SAX2XMLReader* parser = xercesc::XMLReaderFactory::createXMLReader();
        parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpaces, false);
        parser->setContentHandler( &handler );
        parser->setErrorHandler( &handler );

#ifdef NDEBUG
        try
        {
#endif
            parser->parse(stream);
#ifdef NDEBUG
        }
        catch ( const xercesc::XMLException& e )
        {
            CITYGML_LOG_ERROR(logger, "XML Exception occured: " << toStdString(e.getMessage()));
        }
        catch ( const xercesc::SAXParseException& e )
        {
            CITYGML_LOG_ERROR(logger, "SAXParser Exception occured: " << toStdString(e.getMessage()));
        }
        catch ( const std::exception& e )
        {
            CITYGML_LOG_ERROR(logger, "Unexpected Exception occured: " << e.what());
        }
#endif

        delete parser;

        return handler.getModel();
    }
    bool CityObjectElementParser::parseElementStartTag(const NodeType::XMLNode& node, Attributes& attributes)
    {
        initializeTypeIDTypeMap();

        auto it = typeIDTypeMap.find(node.typeID());

        if (it == typeIDTypeMap.end()) {
            CITYGML_LOG_ERROR(m_logger, "Expected start tag of CityObject but got <" << node.name() << "> at " << getDocumentLocation());
            throw std::runtime_error("Unexpected start tag found.");
        }

        m_model = m_factory.createCityObject(attributes.getCityGMLIDAttribute(), static_cast<CityObject::CityObjectsType>(it->second));
        return true;

    }
Пример #13
0
    bool CityGMLElementParser::endElement(const NodeType::XMLNode& node, const std::string& characters)
    {
        if (!m_boundElement.valid()) {
            // This might happen if an container element that usally contains a child element links to an exting object using XLink an thus
            // uses a combined start/end element: e.g.: <surfaceMember xlink:href="#..."/>
            // For such elements a child parser must only be created if there is no xlink attribute.
            CITYGML_LOG_ERROR(m_logger, "CityGMLElementParser::endElement called on unbound " << elementParserName() << " object for element <" << node << "> at " << getDocumentLocation());
            throw std::runtime_error("CityGMLElementParser::endElement called on unbound CityGMLElementParser object.");
        }

        if (m_boundElement == node) {
            m_documentParser.removeCurrentElementParser(this);
            return parseElementEndTag(node, characters);
        } else {
            return parseChildElementEndTag(node, characters);
        }
    }
Пример #14
0
    bool initXerces(std::shared_ptr<CityGMLLogger> logger) {

        if (xerces_initialized) {
            return true;
        }

        try {
            xerces_init_mutex.lock();
            // Check xerces_initialized again... it could have changed while waiting for the mutex
            if (!xerces_initialized) {
                xercesc::XMLPlatformUtils::Initialize();
                xerces_initialized = true;
            }
            xerces_init_mutex.unlock();
        }
        catch (const xercesc::XMLException& e) {
            CITYGML_LOG_ERROR(logger, "Could not initialize xercesc XMLPlatformUtils, a XML Exception occured : " << toStdString(e.getMessage()));
            return false;
        }

        return true;

    }
Пример #15
0
void LinearRing::removeDuplicateVertices(const std::vector<TextureTargetDefinition*>& targets, std::shared_ptr<CityGMLLogger> logger )
{
    // Currently TextureCoordinates sharing via xlink is not supported (every TextureTargetDefinition is the
    // sole owner of its TextureCoordinate objects... if this ever changes use an unordered_set for the texture coordinates
    std::vector<std::shared_ptr<TextureCoordinates>> coordinatesList;

    bool textureCoordinatesVerticesMismatch = false;

    for (auto& texTarget : targets) {

        for (unsigned int i = 0; i < texTarget->getTextureCoordinatesCount(); i++) {
            auto texCoords = texTarget->getTextureCoordinates(i);

            if (texCoords->targets(*this)) {

                coordinatesList.push_back(texCoords);

                if (m_vertices.size() != texCoords->getCoords().size()) {
                    CITYGML_LOG_WARN(logger, "Number of vertices in LinearRing with id '" << this->getId() << "' (" <<
                                     m_vertices.size() << ") does not match with number of texture coordinates in coordinates list "
                                     << " with id '" << texCoords->getId() << "' (" << texCoords->getCoords().size() << ")");
                    textureCoordinatesVerticesMismatch = true;
                }
            }
        }

    }

    // Remove duplicated vertex
    unsigned int len = m_vertices.size();
    if ( len < 2 ) return;

    unsigned int i = 0;
    while ( i < m_vertices.size() && m_vertices.size() > 2 )
    {
        if ( ( m_vertices[i] - m_vertices[ ( i + 1 ) % m_vertices.size() ] ).sqrLength() <= DBL_EPSILON )
        {
            m_vertices.erase( m_vertices.begin() + i );
            for (auto coordinates : coordinatesList) {
                coordinates->eraseCoordinate(i);
            }
        } else {
            i++;
        }
    }

#ifndef NDEBUG
    // Check integrity after duplicate removel... no need when the input was already corrupted
    if (textureCoordinatesVerticesMismatch) {
        return;
    }

    for (auto coordinates : coordinatesList) {
        if (coordinates->getCoords().size() != m_vertices.size()) {
            CITYGML_LOG_ERROR(logger, "Broken implementation. Duplicate vertex removal in LinearRing with id '" << this->getId()
                              << "' caused a mismatch of texture coordinates in coordinates list  with id '" << coordinates->getId()
                              << "' (" << m_vertices.size() << " != " <<coordinates->getCoords().size() << ")");
        }
    }
#endif
}
Пример #16
0
void CALLBACK Tesselator::errorCallback( GLenum errorCode, void* userData )
{
    Tesselator *tess = static_cast<Tesselator*>(userData);
    CITYGML_LOG_ERROR(tess->_logger, "Tesselator error: " << gluErrorString( errorCode ));
}