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

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2007 Murad Tagirov <tmurad@gmail.com>
0004 // SPDX-FileCopyrightText: 2009 Patrick Spendrin <ps_ml@gmx.de>
0005 //
0006 
0007 
0008 // Own
0009 #include "GeoDataContainer.h"
0010 #include "GeoDataContainer_p.h"
0011 
0012 // Marble
0013 #include "MarbleDebug.h"
0014 #include "GeoDataFolder.h"
0015 #include "GeoDataPlacemark.h"
0016 #include "GeoDataDocument.h"
0017 #include "GeoDataLatLonAltBox.h"
0018 #include "GeoDataGeometry.h"
0019 #include "GeoDataNetworkLinkControl.h"
0020 #include "GeoDataNetworkLink.h"
0021 #include "GeoDataGroundOverlay.h"
0022 #include "GeoDataPhotoOverlay.h"
0023 #include "GeoDataScreenOverlay.h"
0024 #include "GeoDataTour.h"
0025 
0026 #include <QDataStream>
0027 
0028 namespace Marble
0029 {
0030 
0031 GeoDataContainer::GeoDataContainer()
0032     : GeoDataFeature( new GeoDataContainerPrivate )
0033 {
0034 }
0035 
0036 GeoDataContainer::GeoDataContainer(GeoDataContainerPrivate *priv)
0037     : GeoDataFeature(priv)
0038 {
0039     Q_D(GeoDataContainer);
0040     d->setParent(this);
0041 }
0042 
0043 GeoDataContainer::GeoDataContainer(const GeoDataContainer& other, GeoDataContainerPrivate *priv)
0044     : GeoDataFeature(other, priv)
0045 {
0046     Q_D(GeoDataContainer);
0047     d->setParent(this);
0048 }
0049 
0050 GeoDataContainer::GeoDataContainer( const GeoDataContainer& other )
0051     : GeoDataFeature(other, new GeoDataContainerPrivate(*other.d_func()))
0052 {
0053     Q_D(GeoDataContainer);
0054     d->setParent(this);
0055 }
0056 
0057 GeoDataContainer::~GeoDataContainer()
0058 {
0059 }
0060 
0061 GeoDataContainer& GeoDataContainer::operator=(const GeoDataContainer& other)
0062 {
0063     if (this != &other) {
0064         Q_D(GeoDataContainer);
0065         *d = *other.d_func();
0066     }
0067 
0068     return *this;
0069 }
0070 
0071 bool GeoDataContainer::equals( const GeoDataContainer &other ) const
0072 {
0073     if ( !GeoDataFeature::equals(other) ) {
0074         return false;
0075     }
0076 
0077     Q_D(const GeoDataContainer);
0078     const GeoDataContainerPrivate* const other_d = other.d_func();
0079     QVector<GeoDataFeature*>::const_iterator thisBegin = d->m_vector.constBegin();
0080     QVector<GeoDataFeature*>::const_iterator thisEnd = d->m_vector.constEnd();
0081     QVector<GeoDataFeature*>::const_iterator otherBegin = other_d->m_vector.constBegin();
0082     QVector<GeoDataFeature*>::const_iterator otherEnd = other_d->m_vector.constEnd();
0083 
0084     for (; thisBegin != thisEnd && otherBegin != otherEnd; ++thisBegin, ++otherBegin) {
0085         if (**thisBegin != **otherBegin) {
0086             return false;
0087         }
0088     }
0089 
0090     return thisBegin == thisEnd && otherBegin == otherEnd;
0091 }
0092 
0093 GeoDataLatLonAltBox GeoDataContainer::latLonAltBox() const
0094 {
0095     Q_D(const GeoDataContainer);
0096     GeoDataLatLonAltBox result;
0097 
0098     QVector<GeoDataFeature*>::const_iterator it = d->m_vector.constBegin();
0099     QVector<GeoDataFeature*>::const_iterator end = d->m_vector.constEnd();
0100     for (; it != end; ++it) {
0101 
0102         // Get all the placemarks from GeoDataContainer
0103         if (const GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(*it)) {
0104             // Only use visible placemarks for extracting their latLonAltBox and
0105             // making an union with the global latLonAltBox Marble will fit its
0106             // zoom to
0107             if (placemark->isVisible())
0108             {
0109                 if (result.isEmpty()) {
0110                     result = placemark->geometry()->latLonAltBox();
0111                 } else {
0112                     result |= placemark->geometry()->latLonAltBox();
0113                 }
0114             }
0115         }
0116         else if (const GeoDataContainer *container = dynamic_cast<GeoDataContainer *>(*it)) {
0117             if (result.isEmpty()) {
0118                 result = container->latLonAltBox();
0119             } else {
0120                 result |= container->latLonAltBox();
0121             }
0122         }
0123     }
0124     return result;
0125 }
0126 
0127 QVector<GeoDataFolder*> GeoDataContainer::folderList() const
0128 {
0129     Q_D(const GeoDataContainer);
0130     QVector<GeoDataFolder*> results;
0131 
0132     QVector<GeoDataFeature*>::const_iterator it = d->m_vector.constBegin();
0133     QVector<GeoDataFeature*>::const_iterator end = d->m_vector.constEnd();
0134 
0135     for (; it != end; ++it) {
0136         GeoDataFolder *folder = dynamic_cast<GeoDataFolder*>(*it);
0137         if ( folder ) {
0138             results.append( folder );
0139         }
0140     }
0141 
0142     return results;
0143 }
0144 
0145 QVector<GeoDataPlacemark*> GeoDataContainer::placemarkList() const
0146 {
0147     Q_D(const GeoDataContainer);
0148     QVector<GeoDataPlacemark*> results;
0149     for (auto it = d->m_vector.constBegin(), end = d->m_vector.constEnd(); it != end; ++it) {
0150         if (GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(*it)) {
0151             results.append(placemark);
0152         }
0153     }
0154     return results;
0155 }
0156 
0157 QVector<GeoDataFeature*> GeoDataContainer::featureList() const
0158 {
0159     Q_D(const GeoDataContainer);
0160     return d->m_vector;
0161 }
0162 
0163 /**
0164  * @brief  returns the requested child item
0165  */
0166 GeoDataFeature* GeoDataContainer::child( int i )
0167 {
0168     Q_D(GeoDataContainer);
0169     return d->m_vector.at(i);
0170 }
0171 
0172 const GeoDataFeature* GeoDataContainer::child( int i ) const
0173 {
0174     Q_D(const GeoDataContainer);
0175     return d->m_vector.at(i);
0176 }
0177 
0178 /**
0179  * @brief returns the position of an item in the list
0180  */
0181 int GeoDataContainer::childPosition( const GeoDataFeature* object ) const
0182 {
0183     Q_D(const GeoDataContainer);
0184     for (int i = 0; i < d->m_vector.size(); ++i) {
0185         if (d->m_vector.at(i) == object) {
0186             return i;
0187         }
0188     }
0189     return -1;
0190 }
0191 
0192 
0193 void GeoDataContainer::insert( GeoDataFeature *other, int index )
0194 {
0195     insert( index, other );
0196 }
0197 
0198 void GeoDataContainer::insert( int index, GeoDataFeature *feature )
0199 {
0200     Q_D(GeoDataContainer);
0201     feature->setParent(this);
0202     d->m_vector.insert( index, feature );
0203 }
0204 
0205 void GeoDataContainer::append( GeoDataFeature *other )
0206 {
0207     Q_D(GeoDataContainer);
0208     other->setParent(this);
0209     d->m_vector.append( other );
0210 }
0211 
0212 
0213 void GeoDataContainer::remove( int index )
0214 {
0215     Q_D(GeoDataContainer);
0216     d->m_vector.remove( index );
0217 }
0218 
0219 void GeoDataContainer::remove(int index, int count)
0220 {
0221     Q_D(GeoDataContainer);
0222     d->m_vector.remove( index, count );
0223 }
0224 
0225 int GeoDataContainer::removeAll(GeoDataFeature *feature)
0226 {
0227     Q_D(GeoDataContainer);
0228     return d->m_vector.removeAll(feature);
0229 }
0230 
0231 void GeoDataContainer::removeAt(int index)
0232 {
0233     Q_D(GeoDataContainer);
0234     d->m_vector.removeAt( index );
0235 }
0236 
0237 void GeoDataContainer::removeFirst()
0238 {
0239     Q_D(GeoDataContainer);
0240     d->m_vector.removeFirst();
0241 }
0242 
0243 void GeoDataContainer::removeLast()
0244 {
0245     Q_D(GeoDataContainer);
0246     d->m_vector.removeLast();
0247 }
0248 
0249 bool GeoDataContainer::removeOne( GeoDataFeature *feature )
0250 {
0251     Q_D(GeoDataContainer);
0252     return d->m_vector.removeOne( feature );
0253 }
0254 
0255 int GeoDataContainer::size() const
0256 {
0257     Q_D(const GeoDataContainer);
0258     return d->m_vector.size();
0259 }
0260 
0261 bool GeoDataContainer::isEmpty() const
0262 {
0263     return size() == 0;
0264 }
0265 
0266 GeoDataFeature& GeoDataContainer::at( int pos )
0267 {
0268     Q_D(GeoDataContainer);
0269     return *(d->m_vector[pos]);
0270 }
0271 
0272 const GeoDataFeature& GeoDataContainer::at( int pos ) const
0273 {
0274     Q_D(const GeoDataContainer);
0275     return *(d->m_vector.at(pos));
0276 }
0277 
0278 GeoDataFeature& GeoDataContainer::last()
0279 {
0280     Q_D(GeoDataContainer);
0281     return *(d->m_vector.last());
0282 }
0283 
0284 const GeoDataFeature& GeoDataContainer::last() const
0285 {
0286     Q_D(const GeoDataContainer);
0287     return *(d->m_vector.last());
0288 }
0289 
0290 GeoDataFeature& GeoDataContainer::first()
0291 {
0292     Q_D(GeoDataContainer);
0293     return *(d->m_vector.first());
0294 }
0295 
0296 const GeoDataFeature& GeoDataContainer::first() const
0297 {
0298     Q_D(const GeoDataContainer);
0299     return *(d->m_vector.first());
0300 }
0301 
0302 void GeoDataContainer::clear()
0303 {
0304     Q_D(GeoDataContainer);
0305     qDeleteAll(d->m_vector);
0306     d->m_vector.clear();
0307 }
0308 
0309 QVector<GeoDataFeature*>::Iterator GeoDataContainer::begin()
0310 {
0311     Q_D(GeoDataContainer);
0312     return d->m_vector.begin();
0313 }
0314 
0315 QVector<GeoDataFeature*>::Iterator GeoDataContainer::end()
0316 {
0317     Q_D(GeoDataContainer);
0318     return d->m_vector.end();
0319 }
0320 
0321 QVector<GeoDataFeature*>::ConstIterator GeoDataContainer::constBegin() const
0322 {
0323     Q_D(const GeoDataContainer);
0324     return d->m_vector.constBegin();
0325 }
0326 
0327 QVector<GeoDataFeature*>::ConstIterator GeoDataContainer::constEnd() const
0328 {
0329     Q_D(const GeoDataContainer);
0330     return d->m_vector.constEnd();
0331 }
0332 
0333 void GeoDataContainer::pack( QDataStream& stream ) const
0334 {
0335     Q_D(const GeoDataContainer);
0336     GeoDataFeature::pack( stream );
0337 
0338     stream << d->m_vector.count();
0339 
0340     for (QVector<GeoDataFeature*>::const_iterator iterator = d->m_vector.constBegin();
0341          iterator != d->m_vector.constEnd();
0342           ++iterator )
0343     {
0344         const GeoDataFeature *feature = *iterator;
0345         stream << feature->featureId();
0346         feature->pack( stream );
0347     }
0348 }
0349 
0350 void GeoDataContainer::unpack( QDataStream& stream )
0351 {
0352     Q_D(GeoDataContainer);
0353     GeoDataFeature::unpack( stream );
0354 
0355     int count;
0356     stream >> count;
0357 
0358     for ( int i = 0; i < count; ++i ) {
0359         int featureId;
0360         stream >> featureId;
0361         switch( featureId ) {
0362             case GeoDataDocumentId:
0363                 /* not usable!!!! */ break;
0364             case GeoDataFolderId:
0365                 {
0366                 GeoDataFolder *folder = new GeoDataFolder;
0367                 folder->unpack( stream );
0368                 d->m_vector.append( folder );
0369                 }
0370                 break;
0371             case GeoDataPlacemarkId:
0372                 {
0373                 GeoDataPlacemark *placemark = new GeoDataPlacemark;
0374                 placemark->unpack( stream );
0375                 d->m_vector.append( placemark );
0376                 }
0377                 break;
0378             case GeoDataNetworkLinkId:
0379                 break;
0380             case GeoDataScreenOverlayId:
0381                 break;
0382             case GeoDataGroundOverlayId:
0383                 break;
0384             default: break;
0385         };
0386     }
0387 }
0388 
0389 }