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

KDE's Doxygen guidelines are available online.