1 /*
2 SPDX-FileCopyrightText: 2012 Jan Grulich <grulja@gmail.com>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6
7 #include "staticmapurl.h"
8
9 #include <QUrlQuery>
10
11 using namespace KGAPI2;
12
13
14 class Q_DECL_HIDDEN StaticMapUrl::Private
15 {
16 public:
17 Private();
18 Private(const Private& other);
19
20 void init(const Private &other);
21
22 StaticMapUrl::LocationType locationType;
23 StaticMapUrl::ImageFormat format;
24
25 QString locationString;
26 KContacts::Address locationAddress;
27 KContacts::Geo locationGeo;
28
29 StaticMapUrl::MapType maptype;
30 QList<StaticMapMarker> markers;
31 QList<StaticMapPath> paths;
32 StaticMapUrl::Scale scale;
33 bool sensor;
34 QSize size;
35
36 QString visibleString;
37 KContacts::Address visibleAddress;
38 KContacts::Geo visibleGeo;
39 StaticMapUrl::LocationType visibleLocationType;
40
41 qint32 zoom;
42 };
43
Private()44 StaticMapUrl::Private::Private():
45 locationType(StaticMapUrl::Undefined),
46 format(StaticMapUrl::PNG),
47 maptype(StaticMapUrl::Roadmap),
48 scale(StaticMapUrl::Normal),
49 sensor(false),
50 visibleLocationType(StaticMapUrl::Undefined),
51 zoom(-1)
52 {
53 }
54
Private(const Private & other)55 StaticMapUrl::Private::Private(const Private & other)
56 {
57 init(other);
58 }
59
init(const StaticMapUrl::Private & other)60 void StaticMapUrl::Private::init(const StaticMapUrl::Private& other)
61 {
62 locationType = other.locationType;
63 format = other.format;
64 locationString = other.locationString;
65 locationAddress = other.locationAddress;
66 locationGeo = other.locationGeo;
67 maptype = other.maptype;
68 markers = other.markers;
69 paths = other.paths;
70 scale = other.scale;
71 sensor = other.sensor;
72 size = other.size;
73 visibleString = other.visibleString;
74 visibleAddress = other.visibleAddress;
75 visibleGeo = other.visibleGeo;
76 visibleLocationType = other.visibleLocationType;
77 zoom = other.zoom;
78 }
79
StaticMapUrl()80 StaticMapUrl::StaticMapUrl():
81 d(new Private)
82 {
83 }
84
StaticMapUrl(const StaticMapUrl & other)85 StaticMapUrl::StaticMapUrl(const StaticMapUrl& other):
86 d(new Private(*(other.d)))
87 {
88 }
89
~StaticMapUrl()90 StaticMapUrl::~StaticMapUrl()
91 {
92 delete d;
93 }
94
95
operator =(const StaticMapUrl & other)96 StaticMapUrl& StaticMapUrl::operator=(const StaticMapUrl& other)
97 {
98 if (&other == this) {
99 return *this;
100 }
101
102 d->init(*(other.d));
103 return *this;
104 }
105
StaticMapUrl(const QString & location,const QSize & size,quint32 zoom,bool sensor)106 StaticMapUrl::StaticMapUrl(const QString &location, const QSize &size,
107 quint32 zoom, bool sensor):
108 d(new Private)
109 {
110 setLocation(location);
111 setSize(size);
112 setZoomLevel(zoom);
113 setSensorUsed(sensor);
114 }
115
StaticMapUrl(const KContacts::Address & address,const QSize & size,quint32 zoom,bool sensor)116 StaticMapUrl::StaticMapUrl(const KContacts::Address &address, const QSize &size,
117 quint32 zoom, bool sensor):
118 d(new Private)
119 {
120 setLocation(address);
121 setSize(size);
122 setZoomLevel(zoom);
123 setSensorUsed(sensor);
124 }
125
StaticMapUrl(const KContacts::Geo & geo,const QSize & size,quint32 zoom,bool sensor)126 StaticMapUrl::StaticMapUrl(const KContacts::Geo &geo, const QSize &size,
127 quint32 zoom, bool sensor):
128 d(new Private)
129 {
130 setLocation(geo);
131 setSize(size);
132 setZoomLevel(zoom);
133 setSensorUsed(sensor);
134 }
135
locationType() const136 StaticMapUrl::LocationType StaticMapUrl::locationType() const
137 {
138 return d->locationType;
139 }
140
format() const141 StaticMapUrl::ImageFormat StaticMapUrl::format() const
142 {
143 return d->format;
144 }
145
setFormat(const StaticMapUrl::ImageFormat format)146 void StaticMapUrl::setFormat(const StaticMapUrl::ImageFormat format)
147 {
148 d->format = format;
149 }
150
isValid() const151 bool StaticMapUrl::isValid() const
152 {
153 bool maOrPa = true;
154
155 if (d->markers.isEmpty()) {
156 for (const StaticMapPath & path : std::as_const(d->paths)) {
157 if (!path.isValid()) {
158 maOrPa = false;
159 }
160 }
161 } else {
162
163 for (const StaticMapMarker & marker : std::as_const(d->markers)) {
164 if (!marker.isValid()) {
165 maOrPa = false;
166 }
167 }
168
169 }
170
171 if (maOrPa) {
172 if ((d->locationType == Undefined || d->zoom == -1) && (d->visibleLocationType == Undefined)) {
173 return false;
174 }
175 }
176
177 return !(d->size.isEmpty());
178 }
179
locationString() const180 QString StaticMapUrl::locationString() const
181 {
182 return d->locationString;
183 }
184
setLocation(const QString & location)185 void StaticMapUrl::setLocation(const QString& location)
186 {
187 d->locationString = location;
188 d->locationType = String;
189 d->locationAddress.clear();
190 d->locationGeo.setLatitude(91);
191 d->locationGeo.setLongitude(181);
192 }
193
locationAddress() const194 KContacts::Address StaticMapUrl::locationAddress() const
195 {
196 return d->locationAddress;
197 }
198
setLocation(const KContacts::Address & address)199 void StaticMapUrl::setLocation(const KContacts::Address& address)
200 {
201 d->locationAddress = address;
202 d->locationType = KABCAddress;
203 d->locationString.clear();
204 d->locationGeo.setLatitude(91);
205 d->locationGeo.setLongitude(181);
206 }
207
locationGeo() const208 KContacts::Geo StaticMapUrl::locationGeo() const
209 {
210 return d->locationGeo;
211 }
212
setLocation(const KContacts::Geo & geo)213 void StaticMapUrl::setLocation(const KContacts::Geo& geo)
214 {
215 d->locationGeo = geo;
216 d->locationType = KABCGeo;
217 d->locationString.clear();
218 d->locationAddress.clear();
219 }
220
mapType() const221 StaticMapUrl::MapType StaticMapUrl::mapType() const
222 {
223 return d->maptype;
224 }
225
setMapType(const StaticMapUrl::MapType type)226 void StaticMapUrl::setMapType(const StaticMapUrl::MapType type)
227 {
228 d->maptype = type;
229 }
230
markers() const231 QList< StaticMapMarker > StaticMapUrl::markers() const
232 {
233 return d->markers;
234 }
235
setMarker(const StaticMapMarker & marker)236 void StaticMapUrl::setMarker(const StaticMapMarker& marker)
237 {
238 QList<StaticMapMarker> markers;
239 markers << marker;
240 d->markers = markers;
241 }
242
setMarkers(const QList<StaticMapMarker> & markers)243 void StaticMapUrl::setMarkers(const QList< StaticMapMarker >& markers)
244 {
245 d->markers = markers;
246 }
247
paths() const248 QList<StaticMapPath> StaticMapUrl::paths() const
249 {
250 return d->paths;
251 }
252
setPath(const StaticMapPath & path)253 void StaticMapUrl::setPath(const StaticMapPath & path)
254 {
255 QList<StaticMapPath> paths;
256 paths << path;
257 d->paths = paths;
258 }
259
setPaths(const QList<StaticMapPath> & paths)260 void StaticMapUrl::setPaths(const QList< StaticMapPath >& paths)
261 {
262 d->paths = paths;
263 }
264
size() const265 QSize StaticMapUrl::size() const
266 {
267 return d->size;
268 }
269
setSize(const QSize & size)270 void StaticMapUrl::setSize(const QSize& size)
271 {
272 d->size = size;
273 }
274
scale() const275 StaticMapUrl::Scale StaticMapUrl::scale() const
276 {
277 return d->scale;
278 }
279
setScale(const Scale scale)280 void StaticMapUrl::setScale(const Scale scale)
281 {
282 d->scale = scale;
283 }
284
sensorUsed() const285 bool StaticMapUrl::sensorUsed() const
286 {
287 return d->sensor;
288 }
289
setSensorUsed(const bool sensor)290 void StaticMapUrl::setSensorUsed(const bool sensor)
291 {
292 d->sensor = sensor;
293 }
294
visibleLocationString() const295 QString StaticMapUrl::visibleLocationString() const
296 {
297 return d->visibleString;
298 }
299
setVisibleLocation(const QString & location)300 void StaticMapUrl::setVisibleLocation(const QString & location)
301 {
302 d->visibleString = location;
303 d->visibleLocationType = String;
304 d->visibleAddress.clear();
305 d->visibleGeo.setLatitude(911);
306 d->visibleGeo.setLongitude(181);
307 }
308
visibleLocationAddress() const309 KContacts::Address StaticMapUrl::visibleLocationAddress() const
310 {
311 return d->locationAddress;
312 }
313
setVisibleLocation(const KContacts::Address & address)314 void StaticMapUrl::setVisibleLocation(const KContacts::Address & address)
315 {
316 d->visibleAddress = address;
317 d->visibleLocationType = KABCAddress;
318 d->visibleString.clear();
319 d->visibleGeo.setLatitude(911);
320 d->visibleGeo.setLongitude(181);
321 }
322
visibleLocationGeo() const323 KContacts::Geo StaticMapUrl::visibleLocationGeo() const
324 {
325 return d->locationGeo;
326 }
327
setVisibleLocation(const KContacts::Geo & geo)328 void StaticMapUrl::setVisibleLocation(const KContacts::Geo & geo)
329 {
330 d->visibleGeo = geo;
331 d->visibleLocationType = KABCGeo;
332 d->visibleString.clear();
333 d->visibleAddress.clear();
334 }
335
visibleLocationType() const336 StaticMapUrl::LocationType StaticMapUrl::visibleLocationType() const
337 {
338 return d->visibleLocationType;
339 }
340
zoomLevel() const341 qint8 StaticMapUrl::zoomLevel() const
342 {
343 return d->zoom;
344 }
345
setZoomLevel(const quint32 zoom)346 void StaticMapUrl::setZoomLevel(const quint32 zoom)
347 {
348 d->zoom = zoom;
349 }
350
url() const351 QUrl StaticMapUrl::url() const
352 {
353 QUrl url(QStringLiteral("http://maps.googleapis.com/maps/api/staticmap"));
354 QUrlQuery query(url);
355
356 if (d->locationType != Undefined) {
357 QString param;
358
359 switch (d->locationType) {
360 case Undefined:
361 case String:
362 param = d->locationString;
363 param.replace(QLatin1String(", "), QLatin1String(","));
364 param.replace(QLatin1String(". "), QLatin1String("."));
365 param.replace(QLatin1Char(' '), QLatin1Char('+'));
366 query.addQueryItem(QStringLiteral("center"), param);
367 break;
368 case KABCAddress:
369 param = d->locationAddress.formattedAddress();
370 param.replace(QLatin1String(", "), QLatin1String(","));
371 param.replace(QLatin1String(". "), QLatin1String("."));
372 param.replace(QLatin1Char(' '), QLatin1Char('+'));
373 param.replace(QLatin1Char('\n'), QLatin1Char(','));
374 query.addQueryItem(QStringLiteral("center"), param);
375 break;
376 case KABCGeo:
377 param = QString::number(d->locationGeo.latitude()) + QLatin1Char(',') +
378 QString::number(d->locationGeo.longitude());
379 query.addQueryItem(QStringLiteral("center"), param);
380 break;
381 }
382 }
383
384 if (d->zoom != -1) {
385 query.addQueryItem(QStringLiteral("zoom"), QString::number(d->zoom));
386 }
387
388 if (!d->size.isEmpty()) {
389 QString size = QString::number(d->size.width()) + QLatin1Char('x') +
390 QString::number(d->size.height());
391 query.addQueryItem(QStringLiteral("size"), size);
392 }
393
394 if (d->scale != Normal) {
395 query.addQueryItem(QStringLiteral("scale"), QString::number(2));
396 }
397 if (d->format != PNG) {
398 QString format;
399
400 switch (d->format) {
401 case PNG:
402 case PNG32:
403 format = QStringLiteral("png32");
404 break;
405 case GIF:
406 format = QStringLiteral("gif");
407 break;
408 case JPG:
409 format = QStringLiteral("jpg");
410 break;
411 case JPGBaseline:
412 format = QStringLiteral("jpg-baseline");
413 break;
414 }
415
416 query.addQueryItem(QStringLiteral("format"), format);
417 }
418
419 if (d->maptype != Roadmap) {
420 QString maptype;
421
422 switch (d->maptype) {
423 case Roadmap:
424 case Satellite:
425 maptype = QStringLiteral("satellite");
426 break;
427 case Terrain:
428 maptype = QStringLiteral("terrain");
429 break;
430 case Hybrid:
431 maptype = QStringLiteral("hybrid");
432 break;
433 }
434
435 query.addQueryItem(QStringLiteral("maptype"), maptype);
436 }
437
438 for (const StaticMapMarker & marker : std::as_const(d->markers)) {
439 if (marker.isValid()) {
440 query.addQueryItem(QStringLiteral("markers"), marker.toString());
441 }
442 }
443
444 for (const StaticMapPath & path : std::as_const(d->paths)) {
445 if (path.isValid()) {
446 query.addQueryItem(QStringLiteral("path"), path.toString());
447 }
448 }
449
450 if (d->visibleLocationType != Undefined) {
451
452 QString param;
453
454 switch (d->visibleLocationType) {
455 case Undefined:
456 case String:
457 param = d->visibleString;
458 param.replace(QLatin1String(", "), QLatin1String(","));
459 param.replace(QLatin1String(". "), QLatin1String("."));
460 param.replace(QLatin1Char(' '), QLatin1Char('+'));
461 query.addQueryItem(QStringLiteral("visible"), param);
462 break;
463 case KABCAddress:
464 param = d->visibleAddress.formattedAddress();
465 param.replace(QLatin1String(", "), QLatin1String(","));
466 param.replace(QLatin1String(". "), QLatin1String("."));
467 param.replace(QLatin1Char(' '), QLatin1Char('+'));
468 param.replace(QLatin1Char('\n'), QLatin1Char(','));
469 query.addQueryItem(QStringLiteral("visible"), param);
470 break;
471 case KABCGeo:
472 param = QString::number(d->visibleGeo.latitude()) + QLatin1Char(',') +
473 QString::number(d->visibleGeo.longitude());
474 query.addQueryItem(QStringLiteral("visible"), param);
475 break;
476 }
477 }
478
479 if (d->sensor) {
480 query.addQueryItem(QStringLiteral("sensor"), QStringLiteral("true"));
481 } else {
482 query.addQueryItem(QStringLiteral("sensor"), QStringLiteral("false"));
483 }
484
485 url.setQuery(query);
486 return url;
487 }
488