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 }