File indexing completed on 2024-05-05 03:49:50
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2015 Marius-Valeriu Stanciu <stanciumarius94@gmail.com> 0004 // 0005 0006 #ifndef MARBLE_OSMPLACEMARKDATA_H 0007 #define MARBLE_OSMPLACEMARKDATA_H 0008 0009 // Qt 0010 #include <QHash> 0011 #include <QMetaType> 0012 #include <QString> 0013 0014 // Marble 0015 #include "GeoDataCoordinates.h" 0016 #include <marble_export.h> 0017 #include "GeoDocument.h" 0018 0019 class QXmlStreamAttributes; 0020 0021 namespace Marble 0022 { 0023 0024 /** Type of OSM element. */ 0025 enum class OsmType { 0026 Node, 0027 Way, 0028 Relation 0029 }; 0030 0031 /** Identifier for an OSM element. 0032 * @note OSM uses distinct id spaces for all its three basic element types, so just the numeric id 0033 * on its own doesn't identify an element without knowing its type. 0034 */ 0035 struct OsmIdentifier { 0036 inline OsmIdentifier() = default; 0037 inline OsmIdentifier(qint64 _id, OsmType _type) : id(_id), type(_type) {} 0038 0039 qint64 id = 0; 0040 OsmType type = OsmType::Way; 0041 0042 inline bool operator==(OsmIdentifier other) const { return id == other.id && type == other.type; } 0043 }; 0044 0045 /** 0046 * This class is used to encapsulate the osm data fields kept within a placemark's extendedData. 0047 * It stores OSM server generated data: id, version, changeset, uid, visible, user, timestamp; 0048 * It also stores a hash map of \<tags\> ( key-value mappings ) and a hash map of component osm 0049 * placemarks @see m_nodeReferences @see m_memberReferences 0050 * 0051 * The usual workflow with osmData goes as follows: 0052 * 0053 * Parsing stage: 0054 * The OsmParser parses tags (they have server-generated attributes), creates new placemarks and 0055 * assigns them new OsmPlacemarkData objects with all the needed information. 0056 * 0057 * Editing stage: 0058 * While editing placemarks that have OsmPlacemarkData, all relevant changes reflect on the 0059 * OsmPlacemarkData object as well, so as not to uncorrelate data from the actual placemarks. 0060 * 0061 * Writing stage: 0062 * The OsmObjectManager assigns OsmPlacemarkData objects to placemarks that do not have it 0063 * ( these are usually newly created placemarks within the editor, or placemarks loaded from 0064 * ".kml" files ). Placemarks that already have it, are simply written as-is. 0065 */ 0066 class MARBLE_EXPORT OsmPlacemarkData: public GeoNode 0067 { 0068 0069 public: 0070 OsmPlacemarkData(); 0071 0072 qint64 id() const; 0073 qint64 oid() const; 0074 QString version() const; 0075 QString changeset() const; 0076 QString uid() const; 0077 QString isVisible() const; 0078 QString user() const; 0079 QString timestamp() const; 0080 QString action() const; 0081 const char* nodeType() const override; 0082 0083 void setId( qint64 id ); 0084 void setVersion( const QString& version ); 0085 void setChangeset( const QString& changeset ); 0086 void setUid( const QString& uid ); 0087 void setVisible( const QString& visible ); 0088 void setUser( const QString& user ); 0089 void setTimestamp( const QString& timestamp ); 0090 void setAction( const QString& action ); 0091 0092 0093 /** 0094 * @brief tagValue returns the value of the tag that has @p key as key 0095 * or an empty qstring if there is no such tag 0096 */ 0097 QString tagValue( const QString &key ) const; 0098 0099 /** 0100 * @brief addTag this function inserts a string key=value mapping, 0101 * equivalent to the \<tag k="@p key" v="@p value"\> osm core data 0102 * element 0103 */ 0104 void addTag( const QString& key, const QString& value ); 0105 0106 /** 0107 * @brief removeTag removes the tag from the tag hash 0108 */ 0109 void removeTag( const QString& key ); 0110 0111 /** 0112 * @brief containsTag returns true if the tag hash contains an entry with 0113 * the @p key as key and @p value as value 0114 */ 0115 bool containsTag( const QString& key, const QString& value ) const; 0116 0117 /** 0118 * @brief containsTagKey returns true if the tag hash contains an entry with 0119 * the @p key as key 0120 */ 0121 bool containsTagKey( const QString& key ) const; 0122 0123 /** 0124 * @brief tagValue returns a pointer to the tag that has @p key as key 0125 * or the end iterator if there is no such tag 0126 */ 0127 QHash<QString, QString>::const_iterator findTag(const QString &key) const; 0128 0129 /** 0130 * @brief iterators for the tags hash. 0131 */ 0132 QHash< QString, QString >::const_iterator tagsBegin() const; 0133 QHash< QString, QString >::const_iterator tagsEnd() const; 0134 0135 0136 /** 0137 * @brief this function returns the osmData associated with a nd 0138 */ 0139 OsmPlacemarkData &nodeReference( const GeoDataCoordinates& coordinates ); 0140 OsmPlacemarkData nodeReference( const GeoDataCoordinates& coordinates ) const; 0141 0142 /** 0143 * @brief addRef this function inserts a GeoDataCoordinates = OsmPlacemarkData 0144 * mapping into the reference hash, equivalent to the \<member ref="@p key" \> 0145 * osm core data element 0146 */ 0147 void addNodeReference( const GeoDataCoordinates& key, const OsmPlacemarkData &value ); 0148 void removeNodeReference( const GeoDataCoordinates& key ); 0149 bool containsNodeReference( const GeoDataCoordinates& key ) const; 0150 0151 /** 0152 * @brief changeNodeReference is a convenience function that allows the quick change of 0153 * a node hash entry. This is generally used to update the osm data in case 0154 * nodes are being moved in the editor. 0155 */ 0156 void changeNodeReference( const GeoDataCoordinates& oldKey, const GeoDataCoordinates &newKey ); 0157 0158 /** 0159 * @brief iterators for the reference hashes. 0160 */ 0161 QHash< GeoDataCoordinates, OsmPlacemarkData > & nodeReferences(); 0162 QHash< GeoDataCoordinates, OsmPlacemarkData >::const_iterator nodeReferencesBegin() const; 0163 QHash< GeoDataCoordinates, OsmPlacemarkData >::const_iterator nodeReferencesEnd() const; 0164 0165 0166 0167 /** 0168 * @brief this function returns the osmData associated with a member boundary's index 0169 * -1 represents the outer boundary of a polygon, and 0,1,2... the inner boundaries, 0170 * in the order provided by polygon->innerBoundaries(); 0171 */ 0172 OsmPlacemarkData &memberReference( int key ); 0173 OsmPlacemarkData memberReference( int key ) const; 0174 0175 /** 0176 * @brief addRef this function inserts a int = OsmplacemarkData 0177 * mapping into the reference hash, equivalent to the osm \<nd ref="@p boundary of index @key" \> 0178 * core data element 0179 * @see m_memberReferences 0180 */ 0181 void addMemberReference( int key, const OsmPlacemarkData &value ); 0182 void removeMemberReference( int key ); 0183 bool containsMemberReference( int key ) const; 0184 0185 QHash< int, OsmPlacemarkData > & memberReferences(); 0186 QHash< int, OsmPlacemarkData >::const_iterator memberReferencesBegin() const; 0187 QHash< int, OsmPlacemarkData >::const_iterator memberReferencesEnd() const; 0188 0189 /** 0190 * @brief addRelation calling this makes the osm placemark a member of the relation 0191 * with @p id as id, while having the role @p role 0192 */ 0193 void addRelation( qint64 id, OsmType type, const QString &role ); 0194 void removeRelation( qint64 id ); 0195 bool containsRelation( qint64 id ) const; 0196 0197 QHash< OsmIdentifier, QString >::const_iterator relationReferencesBegin() const; 0198 QHash< OsmIdentifier, QString >::const_iterator relationReferencesEnd() const; 0199 0200 /** 0201 * @brief isNull returns false if the osmData is loaded from a source 0202 * or true if its just default constructed 0203 */ 0204 bool isNull() const; 0205 0206 /** 0207 * @brief isEmpty returns true if no attribute other than the id has been set 0208 */ 0209 bool isEmpty() const; 0210 0211 /** 0212 * @brief fromParserAttributes is a convenience function that parses all osm-related 0213 * arguments of a tag 0214 * @return an OsmPlacemarkData object containing all the necessary data 0215 */ 0216 static OsmPlacemarkData fromParserAttributes( const QXmlStreamAttributes &attributes ); 0217 0218 private: 0219 qint64 m_id; 0220 QHash<QString, QString> m_tags; 0221 0222 /** 0223 * @brief m_ndRefs is used to store a way's component nodes 0224 * ( It is empty for other placemark types ) 0225 */ 0226 QHash< GeoDataCoordinates, OsmPlacemarkData > m_nodeReferences; 0227 0228 /** 0229 * @brief m_memberRefs is used to store a polygon's member boundaries 0230 * the key represents the index of the boundary within the polygon geometry: 0231 * -1 represents the outerBoundary, and 0,1,2... its innerBoundaries, in the 0232 * order provided by polygon->innerBoundaries() 0233 */ 0234 QHash<int, OsmPlacemarkData> m_memberReferences; 0235 0236 /** 0237 * @brief m_relationReferences is used to store the relations the placemark is part of 0238 * and the role it has within them. 0239 * Eg. an entry ( "123", "stop" ) means that the parent placemark is a member of 0240 * the relation with id "123", while having the "stop" role 0241 */ 0242 QHash<OsmIdentifier, QString> m_relationReferences; 0243 0244 }; 0245 0246 } 0247 0248 // Makes qvariant_cast possible for OsmPlacemarkData objects 0249 Q_DECLARE_METATYPE( Marble::OsmPlacemarkData ) 0250 0251 #endif