Marble

GeoDataFeature.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2007 Murad Tagirov <tmurad@gmail.com>
4// SPDX-FileCopyrightText: 2009 Patrick Spendrin <ps_ml@gmx.de>
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
33namespace Marble
34{
35
36GeoDataFeature::GeoDataFeature()
37 : d_ptr(new GeoDataFeaturePrivate())
38{
39}
40
41GeoDataFeature::GeoDataFeature( const GeoDataFeature& other )
42 : GeoDataObject(),
43 d_ptr(new GeoDataFeaturePrivate(*other.d_ptr))
44{
45}
46
47GeoDataFeature::GeoDataFeature( const QString& name )
48 : d_ptr(new GeoDataFeaturePrivate())
49{
50 d_ptr->m_name = name;
51}
52
53GeoDataFeature::GeoDataFeature(GeoDataFeaturePrivate *dd)
54 : GeoDataObject(),
55 d_ptr(dd)
56{
57}
58
59GeoDataFeature::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
67GeoDataFeature::~GeoDataFeature()
68{
69 delete d_ptr;
70}
71
72GeoDataFeature& GeoDataFeature::operator=( const GeoDataFeature& other )
73{
74 if (this != &other) {
75 *d_ptr = *other.d_ptr;
76 }
77
78 return *this;
79}
80
81bool 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
137bool 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
177EnumFeatureId 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
190{
192 d->m_name = value;
193}
194
195GeoDataSnippet GeoDataFeature::snippet() const
196{
197 Q_D(const GeoDataFeature);
198 return d->featureExtendedData().m_snippet;
199}
200
201void 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
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
371const GeoDataTimeSpan &GeoDataFeature::timeSpan() const
372{
373 Q_D(const GeoDataFeature);
374 return d->featureExtendedData().m_timeSpan;
375}
376
377GeoDataTimeSpan &GeoDataFeature::timeSpan()
378{
380 return d->featureExtendedData().m_timeSpan;
381}
382
383void GeoDataFeature::setTimeSpan( const GeoDataTimeSpan &timeSpan )
384{
386 d->featureExtendedData().m_timeSpan = timeSpan;
387}
388
389const GeoDataTimeStamp &GeoDataFeature::timeStamp() const
390{
391 Q_D(const GeoDataFeature);
392 return d->featureExtendedData().m_timeStamp;
393}
394
395GeoDataTimeStamp &GeoDataFeature::timeStamp()
396{
398 return d->featureExtendedData().m_timeStamp;
399}
400
401void 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
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
498void 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
510void GeoDataFeature::setPopularity( qint64 popularity )
511{
513 d->m_popularity = popularity;
514}
515
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}
A base class that can hold GeoDataFeatures.
A container for Features, Styles and in the future Schemas.
a class which allows to add custom data to KML Feature.
A base class for all geodata features.
void setStyle(const QSharedPointer< GeoDataStyle > &style)
Sets the style of the placemark.
void unpack(QDataStream &stream) override
Unserialize the contents of the feature from stream.
QString description() const
Return the text description of the feature.
QString styleUrl() const
Return the styleUrl of the feature.
void setTimeSpan(const GeoDataTimeSpan &timeSpan)
Set the timespan 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 setStyleUrl(const QString &value)
Set the styleUrl of this feature to value.
const GeoDataTimeSpan & timeSpan() const
Return the timespan of the feature.
bool isGloballyVisible() const
Return whether this feature is visible or not in the context of its parenting.
void setStyleMap(const GeoDataStyleMap *map)
Sets the styleMap of the feature.
int zoomLevel() const
Return the popularity index of the placemark.
void setExtendedData(const GeoDataExtendedData &extendedData)
Sets the ExtendedData of the feature.
void setRegion(const GeoDataRegion &region)
Sets the region of the placemark.
void setRole(const QString &role)
Sets the role of the placemark.
void setPhoneNumber(const QString &value)
Set the phone number of this feature to value.
const GeoDataRegion & region() const
Return the region assigned to the placemark.
QString name() const
The name of the feature.
GeoDataSnippet snippet() const
A short description of the feature.
void setPopularity(qint64 popularity)
Sets the popularity of the feature.
void setDescriptionCDATA(bool cdata)
Set the description to be CDATA See:
const GeoDataAbstractView * abstractView() const
Get the Abstract view of the feature.
qint64 popularity() const
Return the popularity of the feature.
void setZoomLevel(int index)
Sets the popularity index of the placemark.
QSharedPointer< const GeoDataStyle > customStyle() const
Return the style assigned to the placemark with setStyle (can be 0)
void setAddress(const QString &value)
Set the address of this feature to value.
QString address() const
Return the address of the feature.
const GeoDataTimeStamp & timeStamp() const
Return the timestamp of the feature.
const QString role() const
Return the role of the placemark.
QSharedPointer< const GeoDataStyle > style() const
Return the style assigned to the placemark, or a default style if none has been set.
QString phoneNumber() const
Return the phone number of the feature.
GeoDataExtendedData & extendedData()
Return the ExtendedData assigned to the feature.
void setName(const QString &value)
Set a new name for this feature.
void pack(QDataStream &stream) const override
Serialize the contents of the feature to stream.
void setAbstractView(GeoDataAbstractView *abstractView)
Set the abstract view of the feature.
const GeoDataStyleMap * styleMap() const
Return a pointer to a GeoDataStyleMap object which represents the styleMap of this feature.
bool isVisible() const
Return whether this feature is visible or not.
void setVisible(bool value)
Set a new value for visibility.
void setTimeStamp(const GeoDataTimeStamp &timeStamp)
Set the timestamp of the feature.
void setDescription(const QString &value)
Set the description of this feature to value.
void setSnippet(const GeoDataSnippet &value)
Set a new name for this feature.
A base class for all geodata objects.
virtual bool equals(const GeoDataObject &other) const
Compares the value of id and targetId of the two objects.
void pack(QDataStream &stream) const override
Reimplemented from Serializable.
const GeoDataObject * parent() const
Provides the parent of the object in GeoDataContainers.
void unpack(QDataStream &steam) override
Reimplemented from Serializable.
GeoDataRegion describes the visibility and extent of a feature.
a class to map different styles to one style
an addressable style group
virtual const char * nodeType() const =0
Provides type information for downcasting a GeoNode.
Binds a QML item to a specific geodetic location in screen coordinates.
T value(const Key &key, const T &defaultValue) const const
bool isEmpty() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:49:23 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.