File indexing completed on 2024-05-12 15:29:53

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2015 Marius-Valeriu Stanciu <stanciumarius94@gmail.com>
0004 //
0005 
0006 // Self
0007 #include "osm/OsmPlacemarkData.h"
0008 
0009 // Marble
0010 #include "GeoDataExtendedData.h"
0011 
0012 #include <QXmlStreamAttributes>
0013 
0014 namespace Marble
0015 {
0016 
0017 inline uint qHash(Marble::OsmIdentifier ident, uint seed)
0018 {
0019     return ::qHash(ident.id, seed) ^ ::qHash((int)ident.type, seed);
0020 }
0021 
0022 OsmPlacemarkData::OsmPlacemarkData():
0023     m_id( 0 )
0024 {
0025     // nothing to do
0026 }
0027 
0028 qint64 OsmPlacemarkData::id() const
0029 {
0030     return m_id;
0031 }
0032 
0033 qint64 OsmPlacemarkData::oid() const
0034 {
0035     auto const value = m_tags.value(QStringLiteral("mx:oid")).toLong();
0036     return value > 0 ? value : m_id;
0037 }
0038 
0039 QString OsmPlacemarkData::changeset() const
0040 {
0041     return m_tags.value(QStringLiteral("mx:changeset"));
0042 }
0043 
0044 QString OsmPlacemarkData::version() const
0045 {
0046     return m_tags.value(QStringLiteral("mx:version"));
0047 }
0048 
0049 QString OsmPlacemarkData::uid() const
0050 {
0051     return m_tags.value(QStringLiteral("mx:uid"));
0052 }
0053 
0054 QString OsmPlacemarkData::isVisible() const
0055 {
0056     return m_tags.value(QStringLiteral("mx:visible"));
0057 }
0058 
0059 QString OsmPlacemarkData::user() const
0060 {
0061     return m_tags.value(QStringLiteral("mx:user"));
0062 }
0063 
0064 QString OsmPlacemarkData::timestamp() const
0065 {
0066     return m_tags.value(QStringLiteral("mx:timestamp"));
0067 }
0068 
0069 QString OsmPlacemarkData::action() const
0070 {
0071     return m_tags.value(QStringLiteral("mx:action"));
0072 }
0073 
0074 void OsmPlacemarkData::setId( qint64 id )
0075 {
0076     m_id = id;
0077 }
0078 
0079 void OsmPlacemarkData::setVersion( const QString& version )
0080 {
0081     m_tags[QStringLiteral("mx:version")] = version;
0082 }
0083 
0084 void OsmPlacemarkData::setChangeset( const QString& changeset )
0085 {
0086     m_tags[QStringLiteral("mx:changeset")] = changeset;
0087 }
0088 
0089 void OsmPlacemarkData::setUid( const QString& uid )
0090 {
0091     m_tags[QStringLiteral("mx:uid")] = uid;
0092 }
0093 
0094 void OsmPlacemarkData::setVisible( const QString& visible )
0095 {
0096     m_tags[QStringLiteral("mx:visible")] = visible;
0097 }
0098 
0099 void OsmPlacemarkData::setUser( const QString& user )
0100 {
0101    m_tags[QStringLiteral("mx:user")] = user;
0102 }
0103 
0104 void OsmPlacemarkData::setTimestamp( const QString& timestamp )
0105 {
0106     m_tags[QStringLiteral("mx:timestamp")] = timestamp;
0107 }
0108 
0109 void OsmPlacemarkData::setAction( const QString& action )
0110 {
0111     m_tags[QStringLiteral("mx:action")] = action;
0112 }
0113 
0114 
0115 
0116 QString OsmPlacemarkData::tagValue( const QString& key ) const
0117 {
0118     return m_tags.value( key );
0119 }
0120 
0121 void OsmPlacemarkData::addTag( const QString& key, const QString& value )
0122 {
0123     m_tags.insert( key, value );
0124 }
0125 
0126 void OsmPlacemarkData::removeTag( const QString &key )
0127 {
0128     m_tags.remove( key );
0129 }
0130 
0131 bool OsmPlacemarkData::containsTag( const QString &key, const QString &value ) const
0132 {
0133     auto const iter = m_tags.constFind(key);
0134     return iter == m_tags.constEnd() ? false : iter.value() == value;
0135 }
0136 
0137 bool OsmPlacemarkData::containsTagKey( const QString &key ) const
0138 {
0139     return m_tags.contains( key );
0140 }
0141 
0142 QHash<QString, QString>::const_iterator OsmPlacemarkData::findTag(const QString &key) const
0143 {
0144     return m_tags.constFind(key);
0145 }
0146 
0147 QHash< QString, QString >::const_iterator OsmPlacemarkData::tagsBegin() const
0148 {
0149     return m_tags.begin();
0150 }
0151 
0152 QHash< QString, QString >::const_iterator OsmPlacemarkData::tagsEnd() const
0153 {
0154     return m_tags.constEnd();
0155 }
0156 
0157 
0158 
0159 
0160 
0161 OsmPlacemarkData &OsmPlacemarkData::nodeReference( const GeoDataCoordinates &coordinates )
0162 {
0163     return m_nodeReferences[ coordinates ];
0164 }
0165 
0166 OsmPlacemarkData OsmPlacemarkData::nodeReference( const GeoDataCoordinates &coordinates ) const
0167 {
0168     return m_nodeReferences.value( coordinates );
0169 }
0170 
0171 void OsmPlacemarkData::addNodeReference( const GeoDataCoordinates &key, const OsmPlacemarkData &value )
0172 {
0173     m_nodeReferences.insert( key, value );
0174 }
0175 
0176 void OsmPlacemarkData::removeNodeReference( const GeoDataCoordinates &key )
0177 {
0178     m_nodeReferences.remove( key );
0179 }
0180 
0181 bool OsmPlacemarkData::containsNodeReference( const GeoDataCoordinates &key ) const
0182 {
0183     return m_nodeReferences.contains( key );
0184 }
0185 
0186 void OsmPlacemarkData::changeNodeReference( const GeoDataCoordinates &oldKey, const GeoDataCoordinates &newKey )
0187 {
0188     m_nodeReferences.insert( newKey, m_nodeReferences.value( oldKey ) );
0189     m_nodeReferences.remove( oldKey );
0190 }
0191 
0192 QHash<GeoDataCoordinates, OsmPlacemarkData> &OsmPlacemarkData::nodeReferences()
0193 {
0194     return m_nodeReferences;
0195 }
0196 
0197 QHash< GeoDataCoordinates, OsmPlacemarkData >::const_iterator OsmPlacemarkData::nodeReferencesBegin() const
0198 {
0199     return m_nodeReferences.begin();
0200 }
0201 
0202 QHash< GeoDataCoordinates, OsmPlacemarkData >::const_iterator OsmPlacemarkData::nodeReferencesEnd() const
0203 {
0204     return m_nodeReferences.constEnd();
0205 }
0206 
0207 
0208 OsmPlacemarkData &OsmPlacemarkData::memberReference( int key )
0209 {
0210     return m_memberReferences[ key ];
0211 }
0212 
0213 OsmPlacemarkData OsmPlacemarkData::memberReference( int key ) const
0214 {
0215     return m_memberReferences.value( key );
0216 }
0217 
0218 
0219 void OsmPlacemarkData::addMemberReference( int key, const OsmPlacemarkData &value )
0220 {
0221     m_memberReferences.insert( key, value );
0222 }
0223 
0224 void OsmPlacemarkData::removeMemberReference( int key )
0225 {
0226     // If an inner boundary is deleted, all indexes higher than the deleted one
0227     // must be lowered by 1 to keep order.
0228     QHash< int, OsmPlacemarkData > newHash;
0229     QHash< int, OsmPlacemarkData >::iterator it = m_memberReferences.begin();
0230     QHash< int, OsmPlacemarkData >::iterator end = m_memberReferences.end();
0231 
0232     for ( ; it != end; ++it ) {
0233         if ( it.key() > key ) {
0234             newHash.insert( it.key() - 1, it.value() );
0235         }
0236         else if ( it.key() < key ) {
0237             newHash.insert( it.key(), it.value() );
0238         }
0239     }
0240     m_memberReferences = newHash;
0241 }
0242 
0243 bool OsmPlacemarkData::containsMemberReference( int key ) const
0244 {
0245     return m_memberReferences.contains( key );
0246 }
0247 
0248 QHash<int, OsmPlacemarkData> &OsmPlacemarkData::memberReferences()
0249 {
0250     return m_memberReferences;
0251 }
0252 
0253 QHash< int, OsmPlacemarkData >::const_iterator OsmPlacemarkData::memberReferencesBegin() const
0254 {
0255     return m_memberReferences.begin();
0256 }
0257 
0258 QHash< int, OsmPlacemarkData >::const_iterator OsmPlacemarkData::memberReferencesEnd() const
0259 {
0260     return m_memberReferences.constEnd();
0261 }
0262 
0263 void OsmPlacemarkData::addRelation( qint64 id, OsmType type, const QString &role )
0264 {
0265     m_relationReferences.insert( { id, type }, role );
0266 }
0267 
0268 void OsmPlacemarkData::removeRelation( qint64 id )
0269 {
0270     /// ### this is wrong and just done this way for backward behavior compatible
0271     /// ### this method should probably take type as an additional argument
0272     m_relationReferences.remove( { id, OsmType::Node } );
0273     m_relationReferences.remove( { id, OsmType::Way } );
0274     m_relationReferences.remove( { id, OsmType::Relation } );
0275 }
0276 
0277 bool OsmPlacemarkData::containsRelation( qint64 id ) const
0278 {
0279     /// ### this is wrong and just done this way for backward behavior compatible
0280     /// ### this method should probably take type as an additional argument
0281     return m_relationReferences.contains( { id, OsmType::Node } )
0282         || m_relationReferences.contains( { id, OsmType::Way } )
0283         || m_relationReferences.contains( { id, OsmType::Relation } );
0284 }
0285 
0286 QHash< OsmIdentifier, QString >::const_iterator OsmPlacemarkData::relationReferencesBegin() const
0287 {
0288     return m_relationReferences.begin();
0289 }
0290 
0291 QHash< OsmIdentifier, QString >::const_iterator OsmPlacemarkData::relationReferencesEnd() const
0292 {
0293     return m_relationReferences.constEnd();
0294 }
0295 
0296 bool OsmPlacemarkData::isNull() const
0297 {
0298     return !m_id;
0299 }
0300 
0301 bool OsmPlacemarkData::isEmpty() const
0302 {
0303     return m_tags.isEmpty() &&
0304             m_nodeReferences.isEmpty() &&
0305             m_memberReferences.isEmpty() &&
0306             m_relationReferences.isEmpty();
0307 }
0308 
0309 OsmPlacemarkData OsmPlacemarkData::fromParserAttributes( const QXmlStreamAttributes &attributes )
0310 {
0311     OsmPlacemarkData osmData;
0312     osmData.setId(attributes.value(QLatin1String("id")).toLongLong());
0313     if (const auto s = attributes.value(QLatin1String("version")); !s.isEmpty()) {
0314         osmData.setVersion(s.toString());
0315     }
0316     if (const auto s = attributes.value(QLatin1String("changeset")); !s.isEmpty()) {
0317         osmData.setChangeset(s.toString());
0318     }
0319     if (const auto s = attributes.value(QLatin1String("user")); !s.isEmpty()) {
0320         osmData.setUser(s.toString());
0321     }
0322     if (const auto s = attributes.value(QLatin1String("uid")); !s.isEmpty()) {
0323         osmData.setUid(s.toString());
0324     }
0325     if (const auto s = attributes.value(QLatin1String("visible")); !s.isEmpty()) {
0326         osmData.setVisible(s.toString());
0327     }
0328     if (const auto s = attributes.value(QLatin1String("timestamp")); !s.isEmpty()) {
0329         osmData.setTimestamp(s.toString());
0330     }
0331     if (const auto s = attributes.value(QLatin1String("action")); !s.isEmpty()) {
0332         osmData.setAction(s.toString());
0333     }
0334     return osmData;
0335 }
0336 
0337 const char *OsmPlacemarkData::nodeType() const
0338 {
0339     return "OsmPlacemarkDataType";
0340 }
0341 
0342 }