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); }
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); //} }
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."); }
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."); }
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); }