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