Marble

GeoDataFeature.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 2007 Murad Tagirov <[email protected]>
9 // Copyright 2009 Patrick Spendrin <[email protected]>
10 //
11 
12 
13 #include "GeoDataFeature.h"
14 #include "GeoDataFeature_p.h"
15 
16 #include <QDataStream>
17 #include <QSize>
18 
19 #include "MarbleDirs.h"
20 #include "MarbleDebug.h"
21 
22 #include "GeoDataStyle.h"
23 #include "GeoDataStyleMap.h"
24 
25 #include "GeoDataContainer.h"
26 #include "GeoDataDocument.h"
27 #include "GeoDataFolder.h"
28 #include "GeoDataGroundOverlay.h"
29 #include "GeoDataNetworkLink.h"
30 #include "GeoDataNetworkLinkControl.h"
31 #include "GeoDataPhotoOverlay.h"
32 #include "GeoDataPlacemark.h"
33 #include "GeoDataScreenOverlay.h"
34 #include "GeoDataTour.h"
35 #include "GeoDataRegion.h"
36 #include "GeoDataCamera.h"
37 
38 namespace Marble
39 {
40 
41 const QSharedPointer<const GeoDataStyle> GeoDataFeaturePrivate::s_defaultStyle(new GeoDataStyle);
42 
43 GeoDataFeature::GeoDataFeature()
44  : d_ptr(new GeoDataFeaturePrivate())
45 {
46 }
47 
48 GeoDataFeature::GeoDataFeature( const GeoDataFeature& other )
49  : GeoDataObject(),
50  d_ptr(new GeoDataFeaturePrivate(*other.d_ptr))
51 {
52 }
53 
54 GeoDataFeature::GeoDataFeature( const QString& name )
55  : d_ptr(new GeoDataFeaturePrivate())
56 {
57  d_ptr->m_name = name;
58 }
59 
60 GeoDataFeature::GeoDataFeature(GeoDataFeaturePrivate *dd)
61  : GeoDataObject(),
62  d_ptr(dd)
63 {
64 }
65 
66 GeoDataFeature::GeoDataFeature(const GeoDataFeature& other, GeoDataFeaturePrivate *dd)
67  : GeoDataObject(),
68  d_ptr(dd)
69 {
70  Q_UNUSED(other);
71  // TODO: some classes pass "other" on and thus get duplicated id, also in operator=. Align behaviour
72 }
73 
74 GeoDataFeature::~GeoDataFeature()
75 {
76  delete d_ptr;
77 }
78 
79 GeoDataFeature& GeoDataFeature::operator=( const GeoDataFeature& other )
80 {
81  if (this != &other) {
82  *d_ptr = *other.d_ptr;
83  }
84 
85  return *this;
86 }
87 
88 bool GeoDataFeature::operator==(const GeoDataFeature &other) const
89 {
90  if (nodeType() != other.nodeType()) {
91  return false;
92  }
93 
94  if (nodeType() == GeoDataTypes::GeoDataDocumentType) {
95  const GeoDataDocument &thisDoc = static_cast<const GeoDataDocument &>(*this);
96  const GeoDataDocument &otherDoc = static_cast<const GeoDataDocument &>(other);
97 
98  return thisDoc == otherDoc;
99  } else if (nodeType() == GeoDataTypes::GeoDataFolderType) {
100  const GeoDataFolder &thisFolder = static_cast<const GeoDataFolder &>(*this);
101  const GeoDataFolder &otherFolder = static_cast<const GeoDataFolder &>(other);
102 
103  return thisFolder == otherFolder;
104  } else if (nodeType() == GeoDataTypes::GeoDataGroundOverlayType) {
105  const GeoDataGroundOverlay &thisGO = static_cast<const GeoDataGroundOverlay &>(*this);
106  const GeoDataGroundOverlay &otherGO = static_cast<const GeoDataGroundOverlay &>(other);
107 
108  return thisGO == otherGO;
109  } else if (nodeType() == GeoDataTypes::GeoDataNetworkLinkType) {
110  const GeoDataNetworkLink &thisNetLink = static_cast<const GeoDataNetworkLink &>(*this);
111  const GeoDataNetworkLink &otherNetLink = static_cast<const GeoDataNetworkLink &>(other);
112 
113  return thisNetLink == otherNetLink;
114  } else if (nodeType() == GeoDataTypes::GeoDataNetworkLinkControlType) {
115  const GeoDataNetworkLinkControl &thisNLC = static_cast<const GeoDataNetworkLinkControl &>(*this);
116  const GeoDataNetworkLinkControl &otherNLC = static_cast<const GeoDataNetworkLinkControl &>(other);
117 
118  return thisNLC == otherNLC;
119  } else if (nodeType() == GeoDataTypes::GeoDataPhotoOverlayType) {
120  const GeoDataPhotoOverlay &thisPO = static_cast<const GeoDataPhotoOverlay &>(*this);
121  const GeoDataPhotoOverlay &otherPO = static_cast<const GeoDataPhotoOverlay &>(other);
122 
123  return thisPO == otherPO;
124  } else if (nodeType() == GeoDataTypes::GeoDataPlacemarkType) {
125  const GeoDataPlacemark &thisPM = static_cast<const GeoDataPlacemark &>(*this);
126  const GeoDataPlacemark &otherPM = static_cast<const GeoDataPlacemark &>(other);
127 
128  return thisPM == otherPM;
129  } else if (nodeType() == GeoDataTypes::GeoDataScreenOverlayType) {
130  const GeoDataScreenOverlay &thisSO = static_cast<const GeoDataScreenOverlay &>(*this);
131  const GeoDataScreenOverlay &otherSO = static_cast<const GeoDataScreenOverlay &>(other);
132 
133  return thisSO == otherSO;
134  } else if (nodeType() == GeoDataTypes::GeoDataTourType) {
135  const GeoDataTour &thisTour = static_cast<const GeoDataTour &>(*this);
136  const GeoDataTour &otherTour = static_cast<const GeoDataTour &>(other);
137 
138  return thisTour == otherTour;
139  }
140 
141  return false;
142 }
143 
144 bool GeoDataFeature::equals( const GeoDataFeature &other ) const
145 {
146  Q_D(const GeoDataFeature);
147  const GeoDataFeaturePrivate* const other_d = other.d_func();
148 
149  if (!GeoDataObject::equals(other) ||
150  d->m_name != other_d->m_name ||
151  d->m_styleUrl != other_d->m_styleUrl ||
152  d->m_popularity != other_d->m_popularity ||
153  d->m_zoomLevel != other_d->m_zoomLevel ||
154  d->m_visible != other_d->m_visible ||
155  d->m_role != other_d->m_role ||
156  d->m_extendedData != other_d->m_extendedData ||
157  *style() != *other.style()) {
158  return false;
159  }
160 
161  if ((!d->m_styleMap && other_d->m_styleMap) ||
162  (d->m_styleMap && !other_d->m_styleMap)) {
163  return false;
164  }
165 
166  if ((d->m_styleMap && other_d->m_styleMap) &&
167  (*d->m_styleMap != *other_d->m_styleMap)) {
168  return false;
169  }
170 
171  if ((!d->m_featureExtendedData && other_d->m_featureExtendedData && other_d->m_featureExtendedData->m_abstractView) ||
172  (d->m_featureExtendedData && d->m_featureExtendedData->m_abstractView && !other_d->m_featureExtendedData)) {
173  return false;
174  }
175 
176  if ((d->m_featureExtendedData && other_d->m_featureExtendedData) &&
177  (*d->m_featureExtendedData != *other_d->m_featureExtendedData)) {
178  return false;
179  }
180 
181  return true;
182 }
183 
184 EnumFeatureId GeoDataFeature::featureId() const
185 {
186  Q_D(const GeoDataFeature);
187  return d->featureId();
188 }
189 
191 {
192  Q_D(const GeoDataFeature);
193  return d->m_name;
194 }
195 
196 void GeoDataFeature::setName( const QString &value )
197 {
198  Q_D(GeoDataFeature);
199  d->m_name = value;
200 }
201 
202 GeoDataSnippet GeoDataFeature::snippet() const
203 {
204  Q_D(const GeoDataFeature);
205  return d->featureExtendedData().m_snippet;
206 }
207 
208 void GeoDataFeature::setSnippet( const GeoDataSnippet &snippet )
209 {
210  Q_D(GeoDataFeature);
211  d->featureExtendedData().m_snippet = snippet;
212 }
213 
215 {
216  Q_D(const GeoDataFeature);
217  if (!d->m_featureExtendedData) {
218  return QString();
219  }
220 
221  return d->featureExtendedData().m_address;
222 }
223 
225 {
226  Q_D(GeoDataFeature);
227  if (value.isEmpty() && !d->m_featureExtendedData) {
228  return; // nothing to change
229  }
230 
231  d->featureExtendedData().m_address = value;
232 }
233 
235 {
236  Q_D(const GeoDataFeature);
237  if (!d->m_featureExtendedData) {
238  return QString();
239  }
240 
241  return d->featureExtendedData().m_phoneNumber;
242 }
243 
245 {
246  Q_D(GeoDataFeature);
247  if (value.isEmpty() && !d->m_featureExtendedData) {
248  return; // nothing to change
249  }
250 
251  d->featureExtendedData().m_phoneNumber = value;
252 }
253 
255 {
256  Q_D(const GeoDataFeature);
257  if (!d->m_featureExtendedData) {
258  return QString();
259  }
260 
261  return d->featureExtendedData().m_description;
262 }
263 
265 {
266  Q_D(GeoDataFeature);
267  if (value.isEmpty() && !d->m_featureExtendedData) {
268  return; // nothing to change
269  }
270 
271  d->featureExtendedData().m_description = value;
272 }
273 
275 {
276  Q_D(const GeoDataFeature);
277  if (!d->m_featureExtendedData) {
278  return false;
279  }
280 
281  return d->featureExtendedData().m_descriptionCDATA;
282 }
283 
285 {
286  Q_D(GeoDataFeature);
287  d->featureExtendedData().m_descriptionCDATA = cdata;
288 }
289 
291 {
292  Q_D(const GeoDataFeature);
293  if (!d->m_featureExtendedData) {
294  return nullptr;
295  }
296 
297  return d->featureExtendedData().m_abstractView;
298 }
299 
301 {
302  // FIXME: Calling detach() doesn't help at all because the m_abstractView
303  // object isn't actually copied in the Private class as well.
304  // detach();
305 
306  Q_D(GeoDataFeature);
307  return d->featureExtendedData().m_abstractView;
308 }
309 
311 {
312  Q_D(GeoDataFeature);
313  if (abstractView == nullptr && !d->m_featureExtendedData) {
314  return; // nothing to change
315  }
316 
317  d->featureExtendedData().m_abstractView = abstractView;
318 }
319 
321 {
322  Q_D(const GeoDataFeature);
323  return d->m_styleUrl;
324 }
325 
327 {
328  Q_D(GeoDataFeature);
329  d->m_styleUrl = value;
330 
331  if ( value.isEmpty() ) {
332  d->m_style = GeoDataStyle::Ptr();
333  return;
334  }
335 
336  QString styleUrl = value;
337  styleUrl.remove(QLatin1Char('#'));
338 
339  for (auto object = parent(); object != nullptr; object = object->parent()) {
340  if (GeoDataDocument *doc = geodata_cast<GeoDataDocument>(object)) {
341  GeoDataStyleMap &styleMap = doc->styleMap( styleUrl );
342  const QString normalStyleUrl = styleMap.value(QStringLiteral("normal"));
343  if (!normalStyleUrl.isEmpty()) {
344  styleUrl = normalStyleUrl;
345  styleUrl.remove(QLatin1Char('#'));
346  }
347  // Not calling setStyle here because we don't want
348  // re-parenting of the style
349  d->m_style = doc->style( styleUrl );
350  break;
351  }
352  }
353 }
354 
356 {
357  Q_D(const GeoDataFeature);
358  return d->m_visible;
359 }
360 
361 void GeoDataFeature::setVisible( bool value )
362 {
363  Q_D(GeoDataFeature);
364  d->m_visible = value;
365 }
366 
368 {
369  Q_D(const GeoDataFeature);
370  if ( parent() == nullptr ) {
371  return d->m_visible;
372  }
373  const GeoDataContainer *container = static_cast<const GeoDataContainer*>(parent());
374  return d->m_visible && container->isGloballyVisible();
375 }
376 
377 
378 const GeoDataTimeSpan &GeoDataFeature::timeSpan() const
379 {
380  Q_D(const GeoDataFeature);
381  return d->featureExtendedData().m_timeSpan;
382 }
383 
384 GeoDataTimeSpan &GeoDataFeature::timeSpan()
385 {
386  Q_D(GeoDataFeature);
387  return d->featureExtendedData().m_timeSpan;
388 }
389 
390 void GeoDataFeature::setTimeSpan( const GeoDataTimeSpan &timeSpan )
391 {
392  Q_D(GeoDataFeature);
393  d->featureExtendedData().m_timeSpan = timeSpan;
394 }
395 
396 const GeoDataTimeStamp &GeoDataFeature::timeStamp() const
397 {
398  Q_D(const GeoDataFeature);
399  return d->featureExtendedData().m_timeStamp;
400 }
401 
402 GeoDataTimeStamp &GeoDataFeature::timeStamp()
403 {
404  Q_D(GeoDataFeature);
405  return d->featureExtendedData().m_timeStamp;
406 }
407 
408 void GeoDataFeature::setTimeStamp( const GeoDataTimeStamp &timeStamp )
409 {
410  Q_D(GeoDataFeature);
411  d->featureExtendedData().m_timeStamp = timeStamp;
412 }
413 
415 {
416  Q_D(const GeoDataFeature);
417  return d->m_extendedData;
418 }
419 
421 {
422  Q_D(const GeoDataFeature);
423  if (d->m_style) {
424  return d->m_style;
425  }
426 
427  return GeoDataFeaturePrivate::s_defaultStyle;
428 }
429 
431 {
432  Q_D(const GeoDataFeature);
433  return d->m_style;
434 }
435 
437 {
438  Q_D(GeoDataFeature);
439  if (style)
440  style->setParent( this );
441  d->m_style = style;
442 }
443 
445 {
446  Q_D(GeoDataFeature);
447  return d->m_extendedData;
448 }
449 
451 {
452  Q_D(GeoDataFeature);
453  d->m_extendedData = extendedData;
454 }
455 
457 {
458  Q_D(const GeoDataFeature);
459  return d->featureExtendedData().m_region;
460 }
461 
463 {
464  Q_D(GeoDataFeature);
465  return d->featureExtendedData().m_region;
466 }
467 
469 {
470  Q_D(GeoDataFeature);
471  d->featureExtendedData().m_region = region;
472 }
473 
475 {
476  Q_D(const GeoDataFeature);
477  return d->m_role;
478 }
479 
481 {
482  Q_D(GeoDataFeature);
483  d->m_role = role;
484 }
485 
487 {
488  Q_D(const GeoDataFeature);
489  return d->m_styleMap;
490 }
491 
493 {
494  Q_D(GeoDataFeature);
495  d->m_styleMap = styleMap;
496 }
497 
499 {
500  Q_D(const GeoDataFeature);
501  return d->m_zoomLevel;
502 }
503 
505 {
506  Q_D(GeoDataFeature);
507  d->m_zoomLevel = zoomLevel;
508 }
509 
511 {
512  Q_D(const GeoDataFeature);
513  return d->m_popularity;
514 }
515 
517 {
518  Q_D(GeoDataFeature);
519  d->m_popularity = popularity;
520 }
521 
522 void GeoDataFeature::pack( QDataStream& stream ) const
523 {
524  Q_D(const GeoDataFeature);
525 
526  GeoDataObject::pack( stream );
527 
528  stream << d->m_name;
529  stream << d->featureExtendedData().m_address;
530  stream << d->featureExtendedData().m_phoneNumber;
531  stream << d->featureExtendedData().m_description;
532  stream << d->m_visible;
533 // stream << d->m_visualCategory;
534  stream << d->m_role;
535  stream << d->m_popularity;
536  stream << d->m_zoomLevel;
537 }
538 
540 {
541  Q_D(GeoDataFeature);
542  GeoDataObject::unpack( stream );
543 
544  stream >> d->m_name;
545  stream >> d->featureExtendedData().m_address;
546  stream >> d->featureExtendedData().m_phoneNumber;
547  stream >> d->featureExtendedData().m_description;
548  stream >> d->m_visible;
549 // stream >> (int)d->m_visualCategory;
550  stream >> d->m_role;
551  stream >> d->m_popularity;
552  stream >> d->m_zoomLevel;
553 }
554 
555 }
void unpack(QDataStream &steam) override
Reimplemented from Serializable.
A container for Features, Styles and in the future Schemas.
QSharedPointer< const GeoDataStyle > customStyle() const
Return the style assigned to the placemark with setStyle (can be 0)
const QString role() const
Return the role of the placemark.
Binds a QML item to a specific geodetic location in screen coordinates.
A base class for all geodata objects.
Definition: GeoDataObject.h:48
void setDescription(const QString &value)
Set the description of this feature to value.
void setExtendedData(const GeoDataExtendedData &extendedData)
Sets the ExtendedData of the feature.
virtual bool equals(const GeoDataObject &other) const
Compares the value of id and targetId of the two objects.
bool isVisible() const
Return whether this feature is visible or not.
A base class that can hold GeoDataFeatures.
QString description() const
Return the text description of the feature.
QSharedPointer< const GeoDataStyle > style() const
Return the style assigned to the placemark, or a default style if none has been set.
int zoomLevel() const
Return the popularity index of the placemark.
void setSnippet(const GeoDataSnippet &value)
Set a new name for this feature.
a class to map different styles to one style
void setPhoneNumber(const QString &value)
Set the phone number of this feature to value.
QString styleUrl() const
Return the styleUrl of the feature.
QString & remove(int position, int n)
a class which allows to add custom data to KML Feature.
qint64 popularity() const
Return the popularity of the feature.
const GeoDataAbstractView * abstractView() const
Get the Abstract view of the feature.
const GeoDataStyleMap * styleMap() const
Return a pointer to a GeoDataStyleMap object which represents the styleMap of this feature...
void pack(QDataStream &stream) const override
Reimplemented from Serializable.
void setPopularity(qint64 popularity)
Sets the popularity of the feature.
void setTimeStamp(const GeoDataTimeStamp &timeStamp)
Set the timestamp of the feature.
bool descriptionIsCDATA() const
test if the description is CDATA or not CDATA allows for special characters to be included in XML and...
void setName(const QString &value)
Set a new name for this feature.
const GeoDataTimeSpan & timeSpan() const
Return the timespan of the feature.
virtual const char * nodeType() const =0
Provides type information for downcasting a GeoNode.
bool isEmpty() const const
void unpack(QDataStream &stream) override
Unserialize the contents of the feature from stream.
const GeoDataRegion & region() const
Return the region assigned to the placemark.
QString phoneNumber() const
Return the phone number of the feature.
GeoDataExtendedData & extendedData()
Return the ExtendedData assigned to the feature.
A container that is used to arrange other GeoDataFeatures.
Definition: GeoDataFolder.h:49
bool isGloballyVisible() const
Return whether this feature is visible or not in the context of its parenting.
const GeoDataObject * parent() const
Provides the parent of the object in GeoDataContainers.
void setStyleUrl(const QString &value)
Set the styleUrl of this feature to value.
void setAddress(const QString &value)
Set the address of this feature to value.
GeoDataSnippet snippet() const
A short description of the feature.
void setTimeSpan(const GeoDataTimeSpan &timeSpan)
Set the timespan of the feature.
void setVisible(bool value)
Set a new value for visibility.
void setStyle(const QSharedPointer< GeoDataStyle > &style)
Sets the style of the placemark.
void pack(QDataStream &stream) const override
Serialize the contents of the feature to stream.
void setStyleMap(const GeoDataStyleMap *map)
Sets the styleMap of the feature.
QString address() const
Return the address of the feature.
void setDescriptionCDATA(bool cdata)
Set the description to be CDATA See:
A base class for all geodata features.
QString name() const
The name of the feature.
void setRegion(const GeoDataRegion &region)
Sets the region of the placemark.
GeoDataRegion describes the visibility and extent of a feature.
Definition: GeoDataRegion.h:48
void setRole(const QString &role)
Sets the role of the placemark.
void setZoomLevel(int index)
Sets the popularity index of the placemark.
const GeoDataTimeStamp & timeStamp() const
Return the timestamp of the feature.
void setAbstractView(GeoDataAbstractView *abstractView)
Set the abstract view of the feature.
a class representing a point of interest on the map
const T value(const Key &key, const T &defaultValue) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun Jul 5 2020 23:20:13 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.