Marble

GeoDataFeature.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2007 Murad Tagirov <[email protected]>
4 // SPDX-FileCopyrightText: 2009 Patrick Spendrin <[email protected]>
5 //
6 
7 
8 #include "GeoDataFeature.h"
9 #include "GeoDataFeature_p.h"
10 
11 #include <QDataStream>
12 #include <QSize>
13 
14 #include "MarbleDirs.h"
15 #include "MarbleDebug.h"
16 
17 #include "GeoDataStyle.h"
18 #include "GeoDataStyleMap.h"
19 
20 #include "GeoDataContainer.h"
21 #include "GeoDataDocument.h"
22 #include "GeoDataFolder.h"
23 #include "GeoDataGroundOverlay.h"
24 #include "GeoDataNetworkLink.h"
25 #include "GeoDataNetworkLinkControl.h"
26 #include "GeoDataPhotoOverlay.h"
27 #include "GeoDataPlacemark.h"
28 #include "GeoDataScreenOverlay.h"
29 #include "GeoDataTour.h"
30 #include "GeoDataRegion.h"
31 #include "GeoDataCamera.h"
32 
33 namespace Marble
34 {
35 
36 const QSharedPointer<const GeoDataStyle> GeoDataFeaturePrivate::s_defaultStyle(new GeoDataStyle);
37 
38 GeoDataFeature::GeoDataFeature()
39  : d_ptr(new GeoDataFeaturePrivate())
40 {
41 }
42 
43 GeoDataFeature::GeoDataFeature( const GeoDataFeature& other )
44  : GeoDataObject(),
45  d_ptr(new GeoDataFeaturePrivate(*other.d_ptr))
46 {
47 }
48 
49 GeoDataFeature::GeoDataFeature( const QString& name )
50  : d_ptr(new GeoDataFeaturePrivate())
51 {
52  d_ptr->m_name = name;
53 }
54 
55 GeoDataFeature::GeoDataFeature(GeoDataFeaturePrivate *dd)
56  : GeoDataObject(),
57  d_ptr(dd)
58 {
59 }
60 
61 GeoDataFeature::GeoDataFeature(const GeoDataFeature& other, GeoDataFeaturePrivate *dd)
62  : GeoDataObject(),
63  d_ptr(dd)
64 {
65  Q_UNUSED(other);
66  // TODO: some classes pass "other" on and thus get duplicated id, also in operator=. Align behaviour
67 }
68 
69 GeoDataFeature::~GeoDataFeature()
70 {
71  delete d_ptr;
72 }
73 
74 GeoDataFeature& GeoDataFeature::operator=( const GeoDataFeature& other )
75 {
76  if (this != &other) {
77  *d_ptr = *other.d_ptr;
78  }
79 
80  return *this;
81 }
82 
83 bool GeoDataFeature::operator==(const GeoDataFeature &other) const
84 {
85  if (nodeType() != other.nodeType()) {
86  return false;
87  }
88 
89  if (nodeType() == GeoDataTypes::GeoDataDocumentType) {
90  const GeoDataDocument &thisDoc = static_cast<const GeoDataDocument &>(*this);
91  const GeoDataDocument &otherDoc = static_cast<const GeoDataDocument &>(other);
92 
93  return thisDoc == otherDoc;
94  } else if (nodeType() == GeoDataTypes::GeoDataFolderType) {
95  const GeoDataFolder &thisFolder = static_cast<const GeoDataFolder &>(*this);
96  const GeoDataFolder &otherFolder = static_cast<const GeoDataFolder &>(other);
97 
98  return thisFolder == otherFolder;
99  } else if (nodeType() == GeoDataTypes::GeoDataGroundOverlayType) {
100  const GeoDataGroundOverlay &thisGO = static_cast<const GeoDataGroundOverlay &>(*this);
101  const GeoDataGroundOverlay &otherGO = static_cast<const GeoDataGroundOverlay &>(other);
102 
103  return thisGO == otherGO;
104  } else if (nodeType() == GeoDataTypes::GeoDataNetworkLinkType) {
105  const GeoDataNetworkLink &thisNetLink = static_cast<const GeoDataNetworkLink &>(*this);
106  const GeoDataNetworkLink &otherNetLink = static_cast<const GeoDataNetworkLink &>(other);
107 
108  return thisNetLink == otherNetLink;
109  } else if (nodeType() == GeoDataTypes::GeoDataNetworkLinkControlType) {
110  const GeoDataNetworkLinkControl &thisNLC = static_cast<const GeoDataNetworkLinkControl &>(*this);
111  const GeoDataNetworkLinkControl &otherNLC = static_cast<const GeoDataNetworkLinkControl &>(other);
112 
113  return thisNLC == otherNLC;
114  } else if (nodeType() == GeoDataTypes::GeoDataPhotoOverlayType) {
115  const GeoDataPhotoOverlay &thisPO = static_cast<const GeoDataPhotoOverlay &>(*this);
116  const GeoDataPhotoOverlay &otherPO = static_cast<const GeoDataPhotoOverlay &>(other);
117 
118  return thisPO == otherPO;
119  } else if (nodeType() == GeoDataTypes::GeoDataPlacemarkType) {
120  const GeoDataPlacemark &thisPM = static_cast<const GeoDataPlacemark &>(*this);
121  const GeoDataPlacemark &otherPM = static_cast<const GeoDataPlacemark &>(other);
122 
123  return thisPM == otherPM;
124  } else if (nodeType() == GeoDataTypes::GeoDataScreenOverlayType) {
125  const GeoDataScreenOverlay &thisSO = static_cast<const GeoDataScreenOverlay &>(*this);
126  const GeoDataScreenOverlay &otherSO = static_cast<const GeoDataScreenOverlay &>(other);
127 
128  return thisSO == otherSO;
129  } else if (nodeType() == GeoDataTypes::GeoDataTourType) {
130  const GeoDataTour &thisTour = static_cast<const GeoDataTour &>(*this);
131  const GeoDataTour &otherTour = static_cast<const GeoDataTour &>(other);
132 
133  return thisTour == otherTour;
134  }
135 
136  return false;
137 }
138 
139 bool GeoDataFeature::equals( const GeoDataFeature &other ) const
140 {
141  Q_D(const GeoDataFeature);
142  const GeoDataFeaturePrivate* const other_d = other.d_func();
143 
144  if (!GeoDataObject::equals(other) ||
145  d->m_name != other_d->m_name ||
146  d->m_styleUrl != other_d->m_styleUrl ||
147  d->m_popularity != other_d->m_popularity ||
148  d->m_zoomLevel != other_d->m_zoomLevel ||
149  d->m_visible != other_d->m_visible ||
150  d->m_role != other_d->m_role ||
151  d->m_extendedData != other_d->m_extendedData ||
152  *style() != *other.style()) {
153  return false;
154  }
155 
156  if ((!d->m_styleMap && other_d->m_styleMap) ||
157  (d->m_styleMap && !other_d->m_styleMap)) {
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_featureExtendedData && other_d->m_featureExtendedData && other_d->m_featureExtendedData->m_abstractView) ||
167  (d->m_featureExtendedData && d->m_featureExtendedData->m_abstractView && !other_d->m_featureExtendedData)) {
168  return false;
169  }
170 
171  if ((d->m_featureExtendedData && other_d->m_featureExtendedData) &&
172  (*d->m_featureExtendedData != *other_d->m_featureExtendedData)) {
173  return false;
174  }
175 
176  return true;
177 }
178 
179 EnumFeatureId GeoDataFeature::featureId() const
180 {
181  Q_D(const GeoDataFeature);
182  return d->featureId();
183 }
184 
186 {
187  Q_D(const GeoDataFeature);
188  return d->m_name;
189 }
190 
191 void GeoDataFeature::setName( const QString &value )
192 {
193  Q_D(GeoDataFeature);
194  d->m_name = value;
195 }
196 
197 GeoDataSnippet GeoDataFeature::snippet() const
198 {
199  Q_D(const GeoDataFeature);
200  return d->featureExtendedData().m_snippet;
201 }
202 
203 void GeoDataFeature::setSnippet( const GeoDataSnippet &snippet )
204 {
205  Q_D(GeoDataFeature);
206  d->featureExtendedData().m_snippet = snippet;
207 }
208 
210 {
211  Q_D(const GeoDataFeature);
212  if (!d->m_featureExtendedData) {
213  return QString();
214  }
215 
216  return d->featureExtendedData().m_address;
217 }
218 
220 {
221  Q_D(GeoDataFeature);
222  if (value.isEmpty() && !d->m_featureExtendedData) {
223  return; // nothing to change
224  }
225 
226  d->featureExtendedData().m_address = value;
227 }
228 
230 {
231  Q_D(const GeoDataFeature);
232  if (!d->m_featureExtendedData) {
233  return QString();
234  }
235 
236  return d->featureExtendedData().m_phoneNumber;
237 }
238 
240 {
241  Q_D(GeoDataFeature);
242  if (value.isEmpty() && !d->m_featureExtendedData) {
243  return; // nothing to change
244  }
245 
246  d->featureExtendedData().m_phoneNumber = value;
247 }
248 
250 {
251  Q_D(const GeoDataFeature);
252  if (!d->m_featureExtendedData) {
253  return QString();
254  }
255 
256  return d->featureExtendedData().m_description;
257 }
258 
260 {
261  Q_D(GeoDataFeature);
262  if (value.isEmpty() && !d->m_featureExtendedData) {
263  return; // nothing to change
264  }
265 
266  d->featureExtendedData().m_description = value;
267 }
268 
270 {
271  Q_D(const GeoDataFeature);
272  if (!d->m_featureExtendedData) {
273  return false;
274  }
275 
276  return d->featureExtendedData().m_descriptionCDATA;
277 }
278 
280 {
281  Q_D(GeoDataFeature);
282  d->featureExtendedData().m_descriptionCDATA = cdata;
283 }
284 
286 {
287  Q_D(const GeoDataFeature);
288  if (!d->m_featureExtendedData) {
289  return nullptr;
290  }
291 
292  return d->featureExtendedData().m_abstractView;
293 }
294 
296 {
297  // FIXME: Calling detach() doesn't help at all because the m_abstractView
298  // object isn't actually copied in the Private class as well.
299  // detach();
300 
301  Q_D(GeoDataFeature);
302  return d->featureExtendedData().m_abstractView;
303 }
304 
306 {
307  Q_D(GeoDataFeature);
308  if (abstractView == nullptr && !d->m_featureExtendedData) {
309  return; // nothing to change
310  }
311 
312  d->featureExtendedData().m_abstractView = abstractView;
313 }
314 
316 {
317  Q_D(const GeoDataFeature);
318  return d->m_styleUrl;
319 }
320 
322 {
323  Q_D(GeoDataFeature);
324  d->m_styleUrl = value;
325 
326  if ( value.isEmpty() ) {
327  d->m_style = GeoDataStyle::Ptr();
328  return;
329  }
330 
331  QString styleUrl = value;
332  styleUrl.remove(QLatin1Char('#'));
333 
334  for (auto object = parent(); object != nullptr; object = object->parent()) {
335  if (GeoDataDocument *doc = geodata_cast<GeoDataDocument>(object)) {
336  GeoDataStyleMap &styleMap = doc->styleMap( styleUrl );
337  const QString normalStyleUrl = styleMap.value(QStringLiteral("normal"));
338  if (!normalStyleUrl.isEmpty()) {
339  styleUrl = normalStyleUrl;
340  styleUrl.remove(QLatin1Char('#'));
341  }
342  // Not calling setStyle here because we don't want
343  // re-parenting of the style
344  d->m_style = doc->style( styleUrl );
345  break;
346  }
347  }
348 }
349 
351 {
352  Q_D(const GeoDataFeature);
353  return d->m_visible;
354 }
355 
356 void GeoDataFeature::setVisible( bool value )
357 {
358  Q_D(GeoDataFeature);
359  d->m_visible = value;
360 }
361 
363 {
364  Q_D(const GeoDataFeature);
365  if ( parent() == nullptr ) {
366  return d->m_visible;
367  }
368  const GeoDataContainer *container = static_cast<const GeoDataContainer*>(parent());
369  return d->m_visible && container->isGloballyVisible();
370 }
371 
372 
373 const GeoDataTimeSpan &GeoDataFeature::timeSpan() const
374 {
375  Q_D(const GeoDataFeature);
376  return d->featureExtendedData().m_timeSpan;
377 }
378 
379 GeoDataTimeSpan &GeoDataFeature::timeSpan()
380 {
381  Q_D(GeoDataFeature);
382  return d->featureExtendedData().m_timeSpan;
383 }
384 
385 void GeoDataFeature::setTimeSpan( const GeoDataTimeSpan &timeSpan )
386 {
387  Q_D(GeoDataFeature);
388  d->featureExtendedData().m_timeSpan = timeSpan;
389 }
390 
391 const GeoDataTimeStamp &GeoDataFeature::timeStamp() const
392 {
393  Q_D(const GeoDataFeature);
394  return d->featureExtendedData().m_timeStamp;
395 }
396 
397 GeoDataTimeStamp &GeoDataFeature::timeStamp()
398 {
399  Q_D(GeoDataFeature);
400  return d->featureExtendedData().m_timeStamp;
401 }
402 
403 void GeoDataFeature::setTimeStamp( const GeoDataTimeStamp &timeStamp )
404 {
405  Q_D(GeoDataFeature);
406  d->featureExtendedData().m_timeStamp = timeStamp;
407 }
408 
410 {
411  Q_D(const GeoDataFeature);
412  return d->m_extendedData;
413 }
414 
416 {
417  Q_D(const GeoDataFeature);
418  if (d->m_style) {
419  return d->m_style;
420  }
421 
422  return GeoDataFeaturePrivate::s_defaultStyle;
423 }
424 
426 {
427  Q_D(const GeoDataFeature);
428  return d->m_style;
429 }
430 
432 {
433  Q_D(GeoDataFeature);
434  if (style)
435  style->setParent( this );
436  d->m_style = style;
437 }
438 
440 {
441  Q_D(GeoDataFeature);
442  return d->m_extendedData;
443 }
444 
446 {
447  Q_D(GeoDataFeature);
448  d->m_extendedData = extendedData;
449 }
450 
452 {
453  Q_D(const GeoDataFeature);
454  return d->featureExtendedData().m_region;
455 }
456 
458 {
459  Q_D(GeoDataFeature);
460  return d->featureExtendedData().m_region;
461 }
462 
464 {
465  Q_D(GeoDataFeature);
466  d->featureExtendedData().m_region = region;
467 }
468 
470 {
471  Q_D(const GeoDataFeature);
472  return d->m_role;
473 }
474 
476 {
477  Q_D(GeoDataFeature);
478  d->m_role = role;
479 }
480 
482 {
483  Q_D(const GeoDataFeature);
484  return d->m_styleMap;
485 }
486 
488 {
489  Q_D(GeoDataFeature);
490  d->m_styleMap = styleMap;
491 }
492 
494 {
495  Q_D(const GeoDataFeature);
496  return d->m_zoomLevel;
497 }
498 
500 {
501  Q_D(GeoDataFeature);
502  d->m_zoomLevel = zoomLevel;
503 }
504 
506 {
507  Q_D(const GeoDataFeature);
508  return d->m_popularity;
509 }
510 
512 {
513  Q_D(GeoDataFeature);
514  d->m_popularity = popularity;
515 }
516 
517 void GeoDataFeature::pack( QDataStream& stream ) const
518 {
519  Q_D(const GeoDataFeature);
520 
521  GeoDataObject::pack( stream );
522 
523  stream << d->m_name;
524  stream << d->featureExtendedData().m_address;
525  stream << d->featureExtendedData().m_phoneNumber;
526  stream << d->featureExtendedData().m_description;
527  stream << d->m_visible;
528 // stream << d->m_visualCategory;
529  stream << d->m_role;
530  stream << d->m_popularity;
531  stream << d->m_zoomLevel;
532 }
533 
535 {
536  Q_D(GeoDataFeature);
537  GeoDataObject::unpack( stream );
538 
539  stream >> d->m_name;
540  stream >> d->featureExtendedData().m_address;
541  stream >> d->featureExtendedData().m_phoneNumber;
542  stream >> d->featureExtendedData().m_description;
543  stream >> d->m_visible;
544 // stream >> (int)d->m_visualCategory;
545  stream >> d->m_role;
546  stream >> d->m_popularity;
547  stream >> d->m_zoomLevel;
548 }
549 
550 }
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:43
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:33
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:43
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-2021 The KDE developers.
Generated on Tue Dec 7 2021 23:10:58 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.