Marble

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

KDE's Doxygen guidelines are available online.