File indexing completed on 2024-05-12 03:50:11

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2008 Torsten Rahn <rahn@kde.org>
0004 // SPDX-FileCopyrightText: 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
0005 // SPDX-FileCopyrightText: 2008 Inge Wallin <inge@lysator.liu.se>
0006 //
0007 
0008 
0009 #include "GeoDataGeometry.h"
0010 #include "GeoDataGeometry_p.h"
0011 
0012 #include "GeoDataLinearRing.h"
0013 #include "GeoDataLineString.h"
0014 #include "GeoDataModel.h"
0015 #include "GeoDataMultiGeometry.h"
0016 #include "GeoDataMultiTrack.h"
0017 #include "GeoDataPoint.h"
0018 #include "GeoDataPolygon.h"
0019 #include "GeoDataTrack.h"
0020 #include "GeoDataTypes.h"
0021 
0022 #include "MarbleDebug.h"
0023 
0024 #include <QDataStream>
0025 
0026 
0027 namespace Marble
0028 {
0029 
0030 GeoDataGeometry::GeoDataGeometry( const GeoDataGeometry& other )
0031     : GeoDataObject(),
0032       d_ptr(other.d_ptr)
0033 {
0034     d_ptr->ref.ref();
0035 }
0036 
0037 GeoDataGeometry::GeoDataGeometry( GeoDataGeometryPrivate* priv )
0038     : GeoDataObject(),
0039       d_ptr(priv)
0040 {
0041     d_ptr->ref.ref();
0042 }
0043 
0044 GeoDataGeometry::~GeoDataGeometry()
0045 {
0046     if (!d_ptr->ref.deref())
0047         delete d_ptr;
0048 }
0049 
0050 void GeoDataGeometry::detach()
0051 {
0052     if(d_ptr->ref.load() == 1) {
0053         return;
0054     }
0055 
0056      GeoDataGeometryPrivate* new_d = d_ptr->copy();
0057 
0058     if (!d_ptr->ref.deref())
0059         delete d_ptr;
0060 
0061     d_ptr = new_d;
0062     d_ptr->ref.ref();
0063 }
0064 
0065 GeoDataGeometry& GeoDataGeometry::operator=( const GeoDataGeometry& other )
0066 {
0067     GeoDataObject::operator=( other );
0068 
0069     if (!d_ptr->ref.deref())
0070         delete d_ptr;
0071 
0072     d_ptr = other.d_ptr;
0073     d_ptr->ref.ref();
0074     
0075     return *this;
0076 }
0077 
0078 bool GeoDataGeometry::operator==(const GeoDataGeometry &other) const
0079 {
0080     if (nodeType() != other.nodeType()) {
0081         return false;
0082     }
0083 
0084     if (nodeType() == GeoDataTypes::GeoDataPolygonType) {
0085         const GeoDataPolygon &thisPoly = static_cast<const GeoDataPolygon &>(*this);
0086         const GeoDataPolygon &otherPoly = static_cast<const GeoDataPolygon &>(other);
0087 
0088         return thisPoly == otherPoly;
0089     } else if (nodeType() == GeoDataTypes::GeoDataLinearRingType) {
0090         const GeoDataLinearRing &thisRing = static_cast<const GeoDataLinearRing&>(*this);
0091         const GeoDataLinearRing &otherRing = static_cast<const GeoDataLinearRing&>(other);
0092 
0093         return thisRing == otherRing;
0094     } else if (nodeType() == GeoDataTypes::GeoDataLineStringType) {
0095         const GeoDataLineString &thisLine = static_cast<const GeoDataLineString &>(*this);
0096         const GeoDataLineString &otherLine = static_cast<const GeoDataLineString &>(other);
0097 
0098         return thisLine == otherLine;
0099     } else if (nodeType() == GeoDataTypes::GeoDataModelType) {
0100         const GeoDataModel &thisModel = static_cast<const GeoDataModel &>(*this);
0101         const GeoDataModel &otherModel = static_cast<const GeoDataModel &>(other);
0102 
0103         return thisModel == otherModel;
0104     } else if (nodeType() == GeoDataTypes::GeoDataMultiGeometryType) {
0105         const GeoDataMultiGeometry &thisMG = static_cast<const GeoDataMultiGeometry &>(*this);
0106         const GeoDataMultiGeometry &otherMG = static_cast<const GeoDataMultiGeometry &>(other);
0107 
0108         return thisMG == otherMG;
0109     } else if (nodeType() == GeoDataTypes::GeoDataTrackType) {
0110         const GeoDataTrack &thisTrack = static_cast<const GeoDataTrack &>(*this);
0111         const GeoDataTrack &otherTrack = static_cast<const GeoDataTrack &>(other);
0112 
0113         return thisTrack == otherTrack;
0114     } else if (nodeType() == GeoDataTypes::GeoDataMultiTrackType) {
0115         const GeoDataMultiTrack &thisMT = static_cast<const GeoDataMultiTrack &>(*this);
0116         const GeoDataMultiTrack &otherMT = static_cast<const GeoDataMultiTrack &>(other);
0117 
0118         return thisMT == otherMT;
0119     } else if (nodeType() == GeoDataTypes::GeoDataPointType) {
0120         const GeoDataPoint &thisPoint = static_cast<const GeoDataPoint &>(*this);
0121         const GeoDataPoint &otherPoint = static_cast<const GeoDataPoint &>(other);
0122 
0123         return thisPoint == otherPoint;
0124     }
0125 
0126     return false;
0127 }
0128 
0129 bool GeoDataGeometry::extrude() const
0130 {
0131     return d_ptr->m_extrude;
0132 }
0133 
0134 void GeoDataGeometry::setExtrude( bool extrude )
0135 {
0136     detach();
0137     d_ptr->m_extrude = extrude;
0138 }
0139 
0140 AltitudeMode GeoDataGeometry::altitudeMode() const
0141 {
0142     return d_ptr->m_altitudeMode;
0143 }
0144 
0145 void GeoDataGeometry::setAltitudeMode( const AltitudeMode altitudeMode )
0146 {
0147     detach();
0148     d_ptr->m_altitudeMode = altitudeMode;
0149 }
0150 
0151 const GeoDataLatLonAltBox& GeoDataGeometry::latLonAltBox() const
0152 {
0153     return d_ptr->m_latLonAltBox;
0154 }
0155 
0156 void GeoDataGeometry::pack( QDataStream& stream ) const
0157 {
0158     GeoDataObject::pack( stream );
0159 
0160     stream << d_ptr->m_extrude;
0161     stream << d_ptr->m_altitudeMode;
0162 }
0163 
0164 void GeoDataGeometry::unpack( QDataStream& stream )
0165 {
0166     detach();
0167     GeoDataObject::unpack( stream );
0168 
0169     int am;
0170     stream >> d_ptr->m_extrude;
0171     stream >> am;
0172     d_ptr->m_altitudeMode = (AltitudeMode) am;
0173 }
0174 
0175 bool GeoDataGeometry::equals(const GeoDataGeometry &other) const
0176 {
0177     return GeoDataObject::equals(other) &&
0178            d_ptr->m_extrude == other.d_ptr->m_extrude &&
0179            d_ptr->m_altitudeMode == other.d_ptr->m_altitudeMode;
0180 }
0181 
0182 }