File indexing completed on 2025-01-05 03:59:23

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