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