File indexing completed on 2024-05-12 03:50:15

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2012 Thibaut Gridel <tgridel@free.fr>
0004 
0005 #include "GeoDataMultiTrack.h"
0006 #include "GeoDataMultiTrack_p.h"
0007 
0008 #include "GeoDataLineString.h"
0009 #include "GeoDataLinearRing.h"
0010 #include "GeoDataPoint.h"
0011 #include "GeoDataPolygon.h"
0012 #include "GeoDataTrack.h"
0013 #include "GeoDataTypes.h"
0014 
0015 #include "MarbleDebug.h"
0016 
0017 #include <QDataStream>
0018 
0019 
0020 namespace Marble
0021 {
0022 
0023 GeoDataMultiTrack::GeoDataMultiTrack()
0024     : GeoDataGeometry( new GeoDataMultiTrackPrivate )
0025 {
0026 }
0027 
0028 GeoDataMultiTrack::GeoDataMultiTrack( const GeoDataGeometry& other )
0029     : GeoDataGeometry( other )
0030 {
0031 }
0032 
0033 GeoDataMultiTrack::~GeoDataMultiTrack()
0034 {
0035 }
0036 
0037 const char *GeoDataMultiTrack::nodeType() const
0038 {
0039     return GeoDataTypes::GeoDataMultiTrackType;
0040 }
0041 
0042 EnumGeometryId GeoDataMultiTrack::geometryId() const
0043 {
0044     return GeoDataMultiTrackId;
0045 }
0046 
0047 GeoDataGeometry *GeoDataMultiTrack::copy() const
0048 {
0049     return new GeoDataMultiTrack(*this);
0050 }
0051 
0052 bool GeoDataMultiTrack::operator==( const GeoDataMultiTrack& other ) const
0053 {
0054     if ( !equals(other) ) return false;
0055 
0056     Q_D(const GeoDataMultiTrack);
0057     const GeoDataMultiTrackPrivate *other_d = other.d_func();
0058 
0059     QVector<GeoDataTrack*>::const_iterator d_it = d->m_vector.constBegin();
0060     QVector<GeoDataTrack*>::const_iterator d_end = d->m_vector.constEnd();
0061     QVector<GeoDataTrack*>::const_iterator other_it = other_d->m_vector.constBegin();
0062     QVector<GeoDataTrack*>::const_iterator other_end = other_d->m_vector.constEnd();
0063 
0064 
0065     for (; d_it != d_end && other_it != other_end; ++d_it, ++other_it) {
0066         if ( **d_it != **other_it ) return false;
0067     }
0068 
0069     return d_it == d_end && other_it == other_end;
0070 }
0071 
0072 bool GeoDataMultiTrack::operator!=( const GeoDataMultiTrack& other ) const
0073 {
0074     return !this->operator==( other );
0075 }
0076 
0077 const GeoDataLatLonAltBox& GeoDataMultiTrack::latLonAltBox() const
0078 {
0079     Q_D(const GeoDataMultiTrack);
0080 
0081     QVector<GeoDataTrack*>::const_iterator it = d->m_vector.constBegin();
0082     QVector<GeoDataTrack*>::const_iterator end = d->m_vector.constEnd();
0083 
0084     d->m_latLonAltBox.clear();
0085     for (; it != end; ++it) {
0086         if ( !(*it)->latLonAltBox().isEmpty() ) {
0087             if (d->m_latLonAltBox.isEmpty() ) {
0088                 d->m_latLonAltBox = (*it)->latLonAltBox();
0089             }
0090             else {
0091                 d->m_latLonAltBox |= (*it)->latLonAltBox();
0092             }
0093         }
0094     }
0095     return d->m_latLonAltBox;
0096 }
0097 
0098 int GeoDataMultiTrack::size() const
0099 {
0100     Q_D(const GeoDataMultiTrack);
0101     return d->m_vector.size();
0102 }
0103 
0104 QVector<GeoDataTrack> GeoDataMultiTrack::vector() const
0105 {
0106     Q_D(const GeoDataMultiTrack);
0107 
0108     QVector<GeoDataTrack> results;
0109     results.reserve(d->m_vector.size());
0110 
0111     QVector<GeoDataTrack*>::const_iterator it = d->m_vector.constBegin();
0112     QVector<GeoDataTrack*>::const_iterator end = d->m_vector.constEnd();
0113 
0114     for (; it != end; ++it) {
0115             const GeoDataTrack f(**it);
0116             results.append( f );
0117     }
0118 
0119     return results;
0120 }
0121 
0122 GeoDataTrack& GeoDataMultiTrack::at( int pos )
0123 {
0124     mDebug() << "detaching!";
0125     detach();
0126 
0127     Q_D(GeoDataMultiTrack);
0128     return *(d->m_vector[pos]);
0129 }
0130 
0131 const GeoDataTrack& GeoDataMultiTrack::at( int pos ) const
0132 {
0133     Q_D(const GeoDataMultiTrack);
0134     return *(d->m_vector.at(pos));
0135 }
0136 
0137 GeoDataTrack& GeoDataMultiTrack::operator[]( int pos )
0138 {
0139     detach();
0140 
0141     Q_D(GeoDataMultiTrack);
0142     return *(d->m_vector[pos]);
0143 }
0144 
0145 const GeoDataTrack& GeoDataMultiTrack::operator[]( int pos ) const
0146 {
0147     Q_D(const GeoDataMultiTrack);
0148     return *(d->m_vector[pos]);
0149 }
0150 
0151 GeoDataTrack& GeoDataMultiTrack::last()
0152 {
0153     detach();
0154 
0155     Q_D(GeoDataMultiTrack);
0156     return *(d->m_vector.last());
0157 }
0158 
0159 GeoDataTrack& GeoDataMultiTrack::first()
0160 {
0161     detach();
0162 
0163     Q_D(GeoDataMultiTrack);
0164     return *(d->m_vector.first());
0165 }
0166 
0167 const GeoDataTrack& GeoDataMultiTrack::last() const
0168 {
0169     Q_D(const GeoDataMultiTrack);
0170     return *(d->m_vector.last());
0171 }
0172 
0173 const GeoDataTrack& GeoDataMultiTrack::first() const
0174 {
0175     Q_D(const GeoDataMultiTrack);
0176     return *(d->m_vector.first());
0177 }
0178 
0179 QVector<GeoDataTrack*>::Iterator GeoDataMultiTrack::begin()
0180 {
0181     detach();
0182 
0183     Q_D(GeoDataMultiTrack);
0184     return d->m_vector.begin();
0185 }
0186 
0187 QVector<GeoDataTrack*>::Iterator GeoDataMultiTrack::end()
0188 {
0189     detach();
0190 
0191     Q_D(GeoDataMultiTrack);
0192     return d->m_vector.end();
0193 }
0194 
0195 QVector<GeoDataTrack*>::ConstIterator GeoDataMultiTrack::constBegin() const
0196 {
0197     Q_D(const GeoDataMultiTrack);
0198     return d->m_vector.constBegin();
0199 }
0200 
0201 QVector<GeoDataTrack*>::ConstIterator GeoDataMultiTrack::constEnd() const
0202 {
0203     Q_D(const GeoDataMultiTrack);
0204     return d->m_vector.constEnd();
0205 }
0206 
0207 /**
0208  * @brief  returns the requested child item
0209  */
0210 GeoDataTrack* GeoDataMultiTrack::child( int i )
0211 {
0212     detach();
0213 
0214     Q_D(const GeoDataMultiTrack);
0215     return d->m_vector.at(i);
0216 }
0217 
0218 const GeoDataTrack* GeoDataMultiTrack::child( int i ) const
0219 {
0220     Q_D(const GeoDataMultiTrack);
0221     return d->m_vector.at(i);
0222 }
0223 
0224 /**
0225  * @brief returns the position of an item in the list
0226  */
0227 int GeoDataMultiTrack::childPosition( const GeoDataTrack *object ) const
0228 {
0229     Q_D(const GeoDataMultiTrack);
0230     for (int i = 0; i < d->m_vector.size(); ++i) {
0231         if (d->m_vector.at(i) == object) {
0232             return i;
0233         }
0234     }
0235     return -1;
0236 }
0237 
0238 /**
0239 * @brief add an element
0240 */
0241 void GeoDataMultiTrack::append( GeoDataTrack *other )
0242 {
0243     detach();
0244 
0245     Q_D(GeoDataMultiTrack);
0246     other->setParent( this );
0247     d->m_vector.append(other);
0248 }
0249 
0250 
0251 GeoDataMultiTrack& GeoDataMultiTrack::operator << ( const GeoDataTrack& value )
0252 {
0253     detach();
0254 
0255     Q_D(GeoDataMultiTrack);
0256     GeoDataTrack *g = new GeoDataTrack( value );
0257     g->setParent( this );
0258     d->m_vector.append(g);
0259     return *this;
0260 }
0261 
0262 void GeoDataMultiTrack::clear()
0263 {
0264     detach();
0265 
0266     Q_D(GeoDataMultiTrack);
0267     qDeleteAll(d->m_vector);
0268     d->m_vector.clear();
0269 }
0270 
0271 void GeoDataMultiTrack::pack( QDataStream& stream ) const
0272 {
0273     Q_D(const GeoDataMultiTrack);
0274 
0275     GeoDataGeometry::pack( stream );
0276 
0277     stream << d->m_vector.size();
0278 
0279     for( QVector<GeoDataTrack*>::const_iterator iterator
0280           = d->m_vector.constBegin();
0281          iterator != d->m_vector.constEnd();
0282          ++iterator ) {
0283         const GeoDataTrack *geometry = *iterator;
0284         stream << geometry->geometryId();
0285         geometry->pack( stream );
0286     }
0287 }
0288 
0289 void GeoDataMultiTrack::unpack( QDataStream& stream )
0290 {
0291     detach();
0292 
0293     Q_D(GeoDataMultiTrack);
0294     GeoDataGeometry::unpack( stream );
0295 
0296     int size = 0;
0297 
0298     stream >> size;
0299 
0300     for( int i = 0; i < size; i++ ) {
0301         int geometryId;
0302         stream >> geometryId;
0303         switch( geometryId ) {
0304             case InvalidGeometryId:
0305                 break;
0306             case GeoDataTrackId:
0307                 {
0308                 GeoDataTrack *track = new GeoDataTrack;
0309                 track->unpack( stream );
0310                 d->m_vector.append( track );
0311                 }
0312                 break;
0313             case GeoDataModelId:
0314                 break;
0315             default: break;
0316         };
0317     }
0318 }
0319 
0320 }