Marble

GeoDataPolygon.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
4// SPDX-FileCopyrightText: 2008 Inge Wallin <inge@lysator.liu.se>
5//
6
7
8#include "GeoDataPolygon.h"
9#include "GeoDataPolygon_p.h"
10#include "GeoDataCoordinates.h"
11#include "GeoDataTypes.h"
12#include "MarbleDebug.h"
13
14#include <algorithm>
15#include <QDataStream>
16
17
18namespace Marble
19{
20
22 : GeoDataGeometry( new GeoDataPolygonPrivate( f ) )
23{
24 // nothing to do
25}
26
28 : GeoDataGeometry( other )
29{
30 // nothing to do
31}
32
34{
35#ifdef DEBUG_GEODATA
36 mDebug() << "delete polygon";
37#endif
38}
39
40const char *GeoDataPolygon::nodeType() const
41{
42 return GeoDataTypes::GeoDataPolygonType;
43}
44
45EnumGeometryId GeoDataPolygon::geometryId() const
46{
47 return GeoDataPolygonId;
48}
49
50GeoDataGeometry *GeoDataPolygon::copy() const
51{
52 return new GeoDataPolygon(*this);
53}
54
56{
57 Q_D(const GeoDataPolygon);
58 const GeoDataPolygonPrivate *other_d = other.d_func();
59
60 if ( !GeoDataGeometry::equals(other) ||
61 tessellate() != other.tessellate() ||
62 isClosed() != other.isClosed() ||
63 d->inner.size() != other_d->inner.size() ||
64 d->outer != other_d->outer ) {
65 return false;
66 }
67
70 QVector<GeoDataLinearRing>::const_iterator otherItBound = other_d->inner.constBegin();
71 QVector<GeoDataLinearRing>::const_iterator otherItEnd= other_d->inner.constEnd();
72
73 for ( ; itBound != itEnd && otherItBound != otherItEnd; ++itBound, ++otherItBound ) {
74 if ( *itBound != *otherItBound) {
75 return false;
76 }
77 }
78
79 Q_ASSERT ( itBound == itEnd && otherItBound == otherItEnd );
80 return true;
81}
82
83bool GeoDataPolygon::operator!=( const GeoDataPolygon &other ) const
84{
85 return !this->operator==(other);
86}
87
89{
90 return true;
91}
92
94{
95 Q_D(const GeoDataPolygon);
96 return d->m_tessellationFlags.testFlag(Tessellate);
97}
98
99void GeoDataPolygon::setTessellate( bool tessellate )
100{
101 // According to the KML reference the tesselation is done along great circles
102 // for polygons in Google Earth. Our "Tesselate" flag does this.
103 // Only for pure line strings and linear rings the
104 // latitude circles are followed for subsequent points that share the same latitude.
105 detach();
106
108 if ( tessellate ) {
109 d->m_tessellationFlags |= Tessellate;
110 } else {
111 d->m_tessellationFlags ^= Tessellate;
112 }
113}
114
116{
117 Q_D(const GeoDataPolygon);
118 return d->m_tessellationFlags;
119}
120
122{
123 detach();
124
126 d->m_tessellationFlags = f;
127}
128
130{
131 Q_D(const GeoDataPolygon);
132 return d->outer.latLonAltBox();
133}
134
136{
137 detach();
138
140 return (d->outer);
141}
142
144{
145 Q_D(const GeoDataPolygon);
146 return d->outer;
147}
148
150{
151 detach();
152
154 d->outer = boundary;
155}
156
158{
159 detach();
160
162 return d->inner;
163}
164
166{
167 Q_D(const GeoDataPolygon);
168 return d->inner;
169}
170
172{
173 detach();
174
176 d->inner.append(boundary);
177}
178
179void GeoDataPolygon::setRenderOrder(int renderOrder)
180{
181 detach();
182
184 d->m_renderOrder = renderOrder;
185}
186
187int GeoDataPolygon::renderOrder() const
188{
189 Q_D(const GeoDataPolygon);
190 return d->m_renderOrder;
191}
192
194{
195 Q_D(const GeoDataPolygon);
196
197 GeoDataObject::pack( stream );
198
199 d->outer.pack( stream );
200
201 stream << d->inner.size();
202 stream << (qint32)(d->m_tessellationFlags);
203
205 = d->inner.constBegin();
206 iterator != d->inner.constEnd();
207 ++iterator ) {
208 mDebug() << "innerRing: size" << d->inner.size();
209 GeoDataLinearRing linearRing = ( *iterator );
210 linearRing.pack( stream );
211 }
212}
213
215{
216 detach();
217
219
220 GeoDataObject::unpack( stream );
221
222 d->outer.unpack( stream );
223
224 qint32 size;
225 qint32 tessellationFlags;
226
227 stream >> size;
228 stream >> tessellationFlags;
229
230 d->m_tessellationFlags = (TessellationFlags)(tessellationFlags);
231
232 QVector<GeoDataLinearRing> &inner = d->inner;
233 inner.reserve(inner.size() + size);
234 for(qint32 i = 0; i < size; i++ ) {
235 GeoDataLinearRing linearRing;
236 linearRing.unpack( stream );
237 inner.append(linearRing);
238 }
239}
240
241bool GeoDataPolygon::contains( const GeoDataCoordinates &coordinates ) const
242{
243 if ( !outerBoundary().contains( coordinates ) ) {
244 // Not inside the polygon at all
245 return false;
246 }
247
248 for( const GeoDataLinearRing &ring: innerBoundaries() ) {
249 if ( ring.contains( coordinates ) ) {
250 // Inside the polygon, but in one of its holes
251 return false;
252 }
253 }
254
255 return true;
256}
257
258}
A 3d point representation.
A base class for all geodata features.
A class that defines a 3D bounding box for geographic data.
void unpack(QDataStream &stream) override
Unserialize the LineString from a stream.
void pack(QDataStream &stream) const override
Serialize the LineString to a stream.
A LinearRing that allows to store a closed, contiguous set of line segments.
void pack(QDataStream &stream) const override
Reimplemented from Serializable.
void unpack(QDataStream &steam) override
Reimplemented from Serializable.
A polygon that can have "holes".
QVector< GeoDataLinearRing > & innerBoundaries()
Returns a set of inner boundaries which are represented as LinearRings.
bool operator==(const GeoDataPolygon &other) const
Returns true/false depending on whether this and other are/are not equal.
~GeoDataPolygon() override
Destroys a Polygon.
void appendInnerBoundary(const GeoDataLinearRing &boundary)
Appends a given LinearRing as an inner boundary of the Polygon.
const GeoDataLatLonAltBox & latLonAltBox() const override
Returns the smallest latLonAltBox that contains the Polygon.
void setTessellate(bool tessellate)
Sets the tessellation property for the Polygon.
void setOuterBoundary(const GeoDataLinearRing &boundary)
Sets the given LinearRing as an outer boundary of the Polygon.
GeoDataLinearRing & outerBoundary()
Returns the outer boundary that is represented as a LinearRing.
const char * nodeType() const override
Provides type information for downcasting a GeoNode.
void setTessellationFlags(TessellationFlags f)
Sets the given tessellation flags for a Polygon.
void unpack(QDataStream &stream) override
Unserialize the Polygon from a stream.
virtual bool contains(const GeoDataCoordinates &coordinates) const
Returns whether the given coordinates lie within the polygon.
virtual bool isClosed() const
Returns whether a Polygon is a closed polygon.
void pack(QDataStream &stream) const override
Serialize the Polygon to a stream.
bool tessellate() const
Returns whether the Polygon follows the earth's surface.
GeoDataPolygon(TessellationFlags f=NoTessellation)
Creates a new Polygon.
TessellationFlags tessellationFlags() const
Returns the tessellation flags for a Polygon.
Binds a QML item to a specific geodetic location in screen coordinates.
void append(const T &value)
QVector::const_iterator constBegin() const const
QVector::const_iterator constEnd() const const
void reserve(int size)
int size() const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:44:46 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.