File indexing completed on 2025-01-05 03:58:53
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 "digikam_debug.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 }