bool GMLFeatureCollectionElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
    {
        if (getFeatureObject() == nullptr) {
            throw std::runtime_error("Invalid call to GMLFeatureCollectionElementParser::parseChildElementEndTag");
        }

        if (node == NodeType::GML_LowerCornerNode) {

            if (m_bounds != nullptr) {
                m_bounds->setLowerBound(parseValue<TVec3d>(characters, m_logger, getDocumentLocation()));
            } else {
                CITYGML_LOG_WARN(m_logger, "Definition of " << NodeType::GML_LowerCornerNode << " outside " << NodeType::GML_EnvelopeNode << " at " << getDocumentLocation());
            }
            return true;
        } else if (node == NodeType::GML_UpperCornerNode) {

            if (m_bounds != nullptr) {
                m_bounds->setUpperBound(parseValue<TVec3d>(characters, m_logger, getDocumentLocation()));
            } else {
                CITYGML_LOG_WARN(m_logger, "Definition of " << NodeType::GML_UpperCornerNode << " outside " << NodeType::GML_EnvelopeNode << " at " << getDocumentLocation());
            }
            return true;
        } else if (node == NodeType::GML_EnvelopeNode) {

            getFeatureObject()->setEnvelope(m_bounds);
            return true;
        } else if (node == NodeType::GML_BoundedByNode) {

            return true;
        }

        return GMLObjectElementParser::parseChildElementEndTag(node, characters);
    }
    void GeoCoordinateTransformer::transform(Geometry& obj, GeoTransform& transformation) {

        if (!transformation.valid()) {
            CITYGML_LOG_WARN(m_logger, "No valid spatial reference system is given for Geometry with id '" << obj.getId() << "'. Child Polygons are not transformed"
                                       << "(unless they are shared with another geometry for which a spatial reference system is defined)");
            return;
        }

        for (unsigned int i = 0; i < obj.getPolygonsCount(); i++) {

            const auto poly = obj.getPolygon(i);

            auto it = m_transformedPolygonsSourceURNMap.find(poly.get());

            if (it == m_transformedPolygonsSourceURNMap.end()) {

                for (TVec3d& vertex : poly->getVertices()) {
                    transformation.transform(vertex);
                }

                m_transformedPolygonsSourceURNMap[poly.get()] = transformation.sourceURN();

            } else if (it->second != transformation.sourceURN()) {
                CITYGML_LOG_WARN(m_logger, "Polygon with id '" << poly->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 polygon is different "
                                 << "(" << transformation.sourceURN() << "). Ignoring new source SRS.");
            }
        }

        for (unsigned int i = 0; i < obj.getLineStringCount(); i++) {

            const auto lineString = obj.getLineString(i);

            auto it = m_transformedLineStringsSourceURNMap.find(lineString.get());

            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.get()] = 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);
        }
    }
    void  GeoCoordinateTransformer::transformRecursive_helper(CityObject& obj, GeoTransform& transformation) {

        if (obj.getEnvelope().validBounds()) {

            if (transformation.valid()) {
                TVec3d lowerBound = obj.getEnvelope().getLowerBound();
                TVec3d upperBound = obj.getEnvelope().getUpperBound();

                transformation.transform(lowerBound);
                transformation.transform(upperBound);

                Envelope* newEnvelope = new Envelope(m_destinationSRS);
                newEnvelope->setLowerBound(lowerBound);
                newEnvelope->setUpperBound(upperBound);

                obj.setEnvelope(newEnvelope);
            } else {
                CITYGML_LOG_WARN(m_logger, "No valid spatial reference system is given for CityObject with id '" << obj.getId() << "'. Envelope (Bounding Box) is not transformed.");
            }
        }

        for (unsigned int i = 0; i < obj.getChildCityObjectsCount(); i++) {
            transformRecursive(obj.getChildCityObject(i), transformation);
        }

        for (unsigned int i = 0; i < obj.getImplicitGeometryCount(); i++) {
            transformRecursive(obj.getImplicitGeometry(i), transformation);
        }

        for (unsigned int i = 0; i < obj.getGeometriesCount(); i++) {
            transform(obj.getGeometry(i), transformation);
        }
    }
    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);

    }
    bool GMLFeatureCollectionElementParser::parseChildElementStartTag(const NodeType::XMLNode& node, Attributes& attributes)
    {
        if (getFeatureObject() == nullptr) {
            throw std::runtime_error("Invalid call to GMLFeatureCollectionElementParser::parseChildElementStartTag");
        }

        if (node == NodeType::GML_LowerCornerNode
                || node == NodeType::GML_UpperCornerNode
                || node == NodeType::GML_BoundedByNode) {
            return true;
        } else if (node == NodeType::GML_EnvelopeNode) {

            if (m_sourceSRSOverride) {
                return true;
            }
            if (m_bounds != nullptr) {
                CITYGML_LOG_WARN(m_logger, "Duplicate definition of " << NodeType::GML_EnvelopeNode << " at " << getDocumentLocation());
                return true;
            }
            m_bounds = new Envelope(attributes.getAttribute("srsName"));
            return true;
        }

        return GMLObjectElementParser::parseChildElementStartTag(node, attributes);
    }
예제 #6
0
    void PolygonManager::addPolygon(std::shared_ptr<Polygon> poly)
    {
        if (m_sharedPolygons.count(poly->getId()) > 0) {
            CITYGML_LOG_WARN(m_logger, "Duplicate definition of Polygon with id '" << poly->getId() << "'... overwriting existing object.");
        }

        m_sharedPolygons[poly->getId()] = poly;
    }
    void  GeoCoordinateTransformer::transformRecursive_helper(ImplicitGeometry& obj, GeoTransform& transformation) {

        TVec3d referencePoint = obj.getReferencePoint();
        if (transformation.valid()) {
            transformation.transform(referencePoint);
            obj.setReferencePoint(referencePoint);
            obj.setSRSName(m_destinationSRS);
        } else {
            CITYGML_LOG_WARN(m_logger, "No valid spatial reference system is given for ImplicitGeometry with id '" << obj.getId() << "'. Reference Point is not transformed.");
        }

        // Do not transform the geometry of an ImplicitGeometry object. Implicit Geometries share Geometry objects but each implicit geometry
        // defines its own transformation on the vertices of the shared geometry. Hence those vertices are in a local coordinate system. Read
        // the citygml documentation for more details.
        //for (unsigned int i = 0; i < obj.getGeometriesCount(); i++) {
        //  transform(obj.getGeometry(i), transformation);
        //}
    }
예제 #8
0
    void PolygonManager::finish()
    {
        CITYGML_LOG_INFO(m_logger, "Start processing polygon requests (" << m_polygonRequests.size() << ").");
        for (const PolygonRequest& request : m_polygonRequests) {

            auto it = m_sharedPolygons.find(request.polygonID);
            if (it == m_sharedPolygons.end()) {
                CITYGML_LOG_WARN(m_logger, "Geometry object with id '" << request.target->getId() << "' requests Polygon with id '" << request.polygonID << "' but no such"
                                 << " Polygon object exists.");
                continue;
            }

            request.target->addPolygon(it->second);

        }

        m_sharedPolygons.clear();
        m_polygonRequests.clear();

        CITYGML_LOG_INFO(m_logger, "Finished processing polygon requests.");
    }
예제 #9
0
void CALLBACK Tesselator::endCallback( void* userData )
{
    Tesselator *tess = static_cast<Tesselator*>(userData);

    unsigned int len = tess->_curIndices.size();

    switch ( tess->_curMode )
    {
    case GL_TRIANGLES:
        for ( unsigned int i = 0; i < len; i++ ) tess->_outIndices.push_back( tess->_curIndices[i] );
        break;
    case GL_TRIANGLE_FAN:
    case GL_TRIANGLE_STRIP:
        {
            unsigned int first = tess->_curIndices[0];
            unsigned int prev = tess->_curIndices[1];

            assert(first < tess->_vertices.size());
            assert(prev < tess->_vertices.size());

            for ( unsigned int i = 2; i < len; i++ )
            {
                if ( tess->_curMode == GL_TRIANGLE_FAN || i%2 == 0 ) tess->_outIndices.push_back( first );
                tess->_outIndices.push_back( prev );
                if ( tess->_curMode == GL_TRIANGLE_STRIP )
                {
                    if ( i%2 == 1) tess->_outIndices.push_back( first );
                    first = prev;
                }
                prev = tess->_curIndices[i];
                tess->_outIndices.push_back( prev );
            }
        }
        break;
    default:
        CITYGML_LOG_WARN(tess->_logger, "Tesselator: non-supported GLU tesselator primitive " << tess->_curMode);
    }

    tess->_curIndices.clear();
}
 void GeoCoordinateTransformer::transformToDestinationSRS(CityModel* model) {
     CITYGML_LOG_WARN(m_logger, "Coordinate transformation to " << m_destinationSRS << " requested, but libcitygml was build without GDAL. The coordinates will not be transformed.");
 }
예제 #11
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
}
    bool CityObjectElementParser::parseChildElementEndTag(const NodeType::XMLNode& node, const std::string& characters)
    {
        if (m_model == nullptr) {
            throw std::runtime_error("CityObjectElementParser::parseChildElementEndTag called before CityObjectElementParser::parseElementStartTag");
        }

        initializeAttributesSet();

        if (    node == NodeType::GEN_StringAttributeNode
             || node == NodeType::GEN_DoubleAttributeNode
             || node == NodeType::GEN_IntAttributeNode
             || node == NodeType::GEN_DateAttributeNode
             || node == NodeType::GEN_UriAttributeNode) {

            m_lastAttributeName = "";
            return true;

        } else if (node == NodeType::GEN_ValueNode) {

            if (!m_lastAttributeName.empty()) {
                m_model->setAttribute(m_lastAttributeName, characters);
            } else {
                CITYGML_LOG_WARN(m_logger, "Found value node (" << NodeType::GEN_ValueNode << ") outside attribute node... ignore.");
            }

            return true;
        } else if (attributesSet.count(node.typeID()) > 0) {
            if (!characters.empty()) {
                m_model->setAttribute(node.name(), characters);
            }
            return true;
        } else if (node == NodeType::BLDG_BoundedByNode
                    || node == NodeType::BLDG_OuterBuildingInstallationNode
                    || node == NodeType::BLDG_InteriorBuildingInstallationNode
                    || node == NodeType::BLDG_InteriorFurnitureNode
                    || node == NodeType::BLDG_RoomInstallationNode
                    || node == NodeType::BLDG_InteriorRoomNode
                    || node == NodeType::BLDG_OpeningNode
                    || node == NodeType::APP_AppearanceNode
                    || node == NodeType::APP_AppearanceMemberNode
                    || node == NodeType::BLDG_Lod1MultiCurveNode
                    || node == NodeType::BLDG_Lod1MultiSurfaceNode
                    || node == NodeType::BLDG_Lod1SolidNode
                    || node == NodeType::BLDG_Lod1TerrainIntersectionNode
                    || node == NodeType::BLDG_Lod2GeometryNode
                    || node == NodeType::BLDG_Lod2MultiCurveNode
                    || node == NodeType::BLDG_Lod2MultiSurfaceNode
                    || node == NodeType::BLDG_Lod2SolidNode
                    || node == NodeType::BLDG_Lod2TerrainIntersectionNode
                    || node == NodeType::BLDG_Lod3GeometryNode
                    || node == NodeType::BLDG_Lod3MultiCurveNode
                    || node == NodeType::BLDG_Lod3MultiSurfaceNode
                    || node == NodeType::BLDG_Lod3SolidNode
                    || node == NodeType::BLDG_Lod3TerrainIntersectionNode
                    || node == NodeType::BLDG_Lod4GeometryNode
                    || node == NodeType::BLDG_Lod4MultiCurveNode
                    || node == NodeType::BLDG_Lod4MultiSurfaceNode
                    || node == NodeType::BLDG_Lod4SolidNode
                    || node == NodeType::BLDG_Lod4TerrainIntersectionNode
                    || node == NodeType::GEN_Lod1GeometryNode
                    || node == NodeType::GEN_Lod2GeometryNode
                    || node == NodeType::GEN_Lod3GeometryNode
                    || node == NodeType::GEN_Lod4GeometryNode
                    || node == NodeType::GEN_Lod1TerrainIntersectionNode
                    || node == NodeType::GEN_Lod2TerrainIntersectionNode
                    || node == NodeType::GEN_Lod3TerrainIntersectionNode
                    || node == NodeType::GEN_Lod4TerrainIntersectionNode
                    || node == NodeType::GEN_Lod1ImplicitRepresentationNode
                    || node == NodeType::GEN_Lod2ImplicitRepresentationNode
                    || node == NodeType::GEN_Lod3ImplicitRepresentationNode
                    || node == NodeType::GEN_Lod4ImplicitRepresentationNode
                    || node == NodeType::VEG_Lod1ImplicitRepresentationNode
                    || node == NodeType::VEG_Lod2ImplicitRepresentationNode
                    || node == NodeType::VEG_Lod3ImplicitRepresentationNode
                    || node == NodeType::VEG_Lod4ImplicitRepresentationNode
                    || node == NodeType::CORE_ExternalReferenceNode
                    || node == NodeType::BLDG_ConsistsOfBuildingPartNode
                    || node == NodeType::FRN_Lod1GeometryNode
                    || node == NodeType::FRN_Lod1TerrainIntersectionNode
                    || node == NodeType::FRN_Lod1ImplicitRepresentationNode
                    || node == NodeType::FRN_Lod2GeometryNode
                    || node == NodeType::FRN_Lod2TerrainIntersectionNode
                    || node == NodeType::FRN_Lod2ImplicitRepresentationNode
                    || node == NodeType::FRN_Lod3GeometryNode
                    || node == NodeType::FRN_Lod3TerrainIntersectionNode
                    || node == NodeType::FRN_Lod3ImplicitRepresentationNode
                    || node == NodeType::FRN_Lod4GeometryNode
                    || node == NodeType::FRN_Lod4TerrainIntersectionNode
                    || node == NodeType::FRN_Lod4ImplicitRepresentationNode
                    || node == NodeType::CORE_GeneralizesToNode
                    || node == NodeType::GML_MultiPointNode
                    || node == NodeType::GRP_GroupMemberNode
                    || node == NodeType::GRP_ParentNode
                    || node == NodeType::LUSE_Lod1MultiSurfaceNode
                    || node == NodeType::LUSE_Lod2MultiSurfaceNode
                    || node == NodeType::LUSE_Lod3MultiSurfaceNode
                    || node == NodeType::LUSE_Lod4MultiSurfaceNode
                    || node == NodeType::DEM_ReliefComponentNode
                    || node == NodeType::GEN_Lod0GeometryNode
                    || node == NodeType::GEN_Lod0ImplicitRepresentationNode
                    || node == NodeType::GEN_Lod0TerrainIntersectionNode
                    || node == NodeType::TRANS_Lod0NetworkNode
                    || node == NodeType::TRANS_TrafficAreaNode
                    || node == NodeType::TRANS_AuxiliaryTrafficAreaNode
                    || node == NodeType::TRANS_Lod1MultiSurfaceNode
                    || node == NodeType::TRANS_Lod2MultiSurfaceNode
                    || node == NodeType::TRANS_Lod3MultiSurfaceNode
                    || node == NodeType::TRANS_Lod4MultiSurfaceNode
                    || node == NodeType::WTR_Lod0MultiCurveNode
                    || node == NodeType::WTR_Lod0MultiSurfaceNode
                    || node == NodeType::WTR_Lod1MultiCurveNode
                    || node == NodeType::WTR_Lod1MultiSurfaceNode
                    || node == NodeType::WTR_Lod1SolidNode
                    || node == NodeType::WTR_Lod2SolidNode
                    || node == NodeType::WTR_Lod3SolidNode
                    || node == NodeType::WTR_Lod4SolidNode
                    || node == NodeType::WTR_Lod2SurfaceNode
                    || node == NodeType::WTR_Lod3SurfaceNode
                    || node == NodeType::WTR_Lod4SurfaceNode
                    || node == NodeType::WTR_BoundedByNode) {

            return true;
        }

        return GMLFeatureCollectionElementParser::parseChildElementEndTag(node, characters);

    }