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 }