File indexing completed on 2024-05-12 05:22:32

0001 /*
0002     SPDX-FileCopyrightText: 2012 Jan Grulich <grulja@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "staticmapurl.h"
0008 
0009 #include <QUrlQuery>
0010 
0011 using namespace KGAPI2;
0012 
0013 class Q_DECL_HIDDEN StaticMapUrl::Private
0014 {
0015 public:
0016     Private();
0017     Private(const Private &other);
0018 
0019     void init(const Private &other);
0020 
0021     StaticMapUrl::LocationType locationType;
0022     StaticMapUrl::ImageFormat format;
0023 
0024     QString locationString;
0025     KContacts::Address locationAddress;
0026     KContacts::Geo locationGeo;
0027 
0028     StaticMapUrl::MapType maptype;
0029     QList<StaticMapMarker> markers;
0030     QList<StaticMapPath> paths;
0031     StaticMapUrl::Scale scale;
0032     bool sensor;
0033     QSize size;
0034 
0035     QString visibleString;
0036     KContacts::Address visibleAddress;
0037     KContacts::Geo visibleGeo;
0038     StaticMapUrl::LocationType visibleLocationType;
0039 
0040     qint32 zoom;
0041 };
0042 
0043 StaticMapUrl::Private::Private()
0044     : locationType(StaticMapUrl::Undefined)
0045     , format(StaticMapUrl::PNG)
0046     , maptype(StaticMapUrl::Roadmap)
0047     , scale(StaticMapUrl::Normal)
0048     , sensor(false)
0049     , visibleLocationType(StaticMapUrl::Undefined)
0050     , zoom(-1)
0051 {
0052 }
0053 
0054 StaticMapUrl::Private::Private(const Private &other)
0055 {
0056     init(other);
0057 }
0058 
0059 void StaticMapUrl::Private::init(const StaticMapUrl::Private &other)
0060 {
0061     locationType = other.locationType;
0062     format = other.format;
0063     locationString = other.locationString;
0064     locationAddress = other.locationAddress;
0065     locationGeo = other.locationGeo;
0066     maptype = other.maptype;
0067     markers = other.markers;
0068     paths = other.paths;
0069     scale = other.scale;
0070     sensor = other.sensor;
0071     size = other.size;
0072     visibleString = other.visibleString;
0073     visibleAddress = other.visibleAddress;
0074     visibleGeo = other.visibleGeo;
0075     visibleLocationType = other.visibleLocationType;
0076     zoom = other.zoom;
0077 }
0078 
0079 StaticMapUrl::StaticMapUrl()
0080     : d(new Private)
0081 {
0082 }
0083 
0084 StaticMapUrl::StaticMapUrl(const StaticMapUrl &other)
0085     : d(new Private(*(other.d)))
0086 {
0087 }
0088 
0089 StaticMapUrl::~StaticMapUrl()
0090 {
0091     delete d;
0092 }
0093 
0094 StaticMapUrl &StaticMapUrl::operator=(const StaticMapUrl &other)
0095 {
0096     if (&other == this) {
0097         return *this;
0098     }
0099 
0100     d->init(*(other.d));
0101     return *this;
0102 }
0103 
0104 StaticMapUrl::StaticMapUrl(const QString &location, const QSize &size, quint32 zoom, bool sensor)
0105     : d(new Private)
0106 {
0107     setLocation(location);
0108     setSize(size);
0109     setZoomLevel(zoom);
0110     setSensorUsed(sensor);
0111 }
0112 
0113 StaticMapUrl::StaticMapUrl(const KContacts::Address &address, const QSize &size, quint32 zoom, bool sensor)
0114     : d(new Private)
0115 {
0116     setLocation(address);
0117     setSize(size);
0118     setZoomLevel(zoom);
0119     setSensorUsed(sensor);
0120 }
0121 
0122 StaticMapUrl::StaticMapUrl(const KContacts::Geo &geo, const QSize &size, quint32 zoom, bool sensor)
0123     : d(new Private)
0124 {
0125     setLocation(geo);
0126     setSize(size);
0127     setZoomLevel(zoom);
0128     setSensorUsed(sensor);
0129 }
0130 
0131 StaticMapUrl::LocationType StaticMapUrl::locationType() const
0132 {
0133     return d->locationType;
0134 }
0135 
0136 StaticMapUrl::ImageFormat StaticMapUrl::format() const
0137 {
0138     return d->format;
0139 }
0140 
0141 void StaticMapUrl::setFormat(const StaticMapUrl::ImageFormat format)
0142 {
0143     d->format = format;
0144 }
0145 
0146 bool StaticMapUrl::isValid() const
0147 {
0148     bool maOrPa = true;
0149 
0150     if (d->markers.isEmpty()) {
0151         for (const StaticMapPath &path : std::as_const(d->paths)) {
0152             if (!path.isValid()) {
0153                 maOrPa = false;
0154             }
0155         }
0156     } else {
0157         for (const StaticMapMarker &marker : std::as_const(d->markers)) {
0158             if (!marker.isValid()) {
0159                 maOrPa = false;
0160             }
0161         }
0162     }
0163 
0164     if (maOrPa) {
0165         if ((d->locationType == Undefined || d->zoom == -1) && (d->visibleLocationType == Undefined)) {
0166             return false;
0167         }
0168     }
0169 
0170     return !(d->size.isEmpty());
0171 }
0172 
0173 QString StaticMapUrl::locationString() const
0174 {
0175     return d->locationString;
0176 }
0177 
0178 void StaticMapUrl::setLocation(const QString &location)
0179 {
0180     d->locationString = location;
0181     d->locationType = String;
0182     d->locationAddress.clear();
0183     d->locationGeo.setLatitude(91);
0184     d->locationGeo.setLongitude(181);
0185 }
0186 
0187 KContacts::Address StaticMapUrl::locationAddress() const
0188 {
0189     return d->locationAddress;
0190 }
0191 
0192 void StaticMapUrl::setLocation(const KContacts::Address &address)
0193 {
0194     d->locationAddress = address;
0195     d->locationType = KABCAddress;
0196     d->locationString.clear();
0197     d->locationGeo.setLatitude(91);
0198     d->locationGeo.setLongitude(181);
0199 }
0200 
0201 KContacts::Geo StaticMapUrl::locationGeo() const
0202 {
0203     return d->locationGeo;
0204 }
0205 
0206 void StaticMapUrl::setLocation(const KContacts::Geo &geo)
0207 {
0208     d->locationGeo = geo;
0209     d->locationType = KABCGeo;
0210     d->locationString.clear();
0211     d->locationAddress.clear();
0212 }
0213 
0214 StaticMapUrl::MapType StaticMapUrl::mapType() const
0215 {
0216     return d->maptype;
0217 }
0218 
0219 void StaticMapUrl::setMapType(const StaticMapUrl::MapType type)
0220 {
0221     d->maptype = type;
0222 }
0223 
0224 QList<StaticMapMarker> StaticMapUrl::markers() const
0225 {
0226     return d->markers;
0227 }
0228 
0229 void StaticMapUrl::setMarker(const StaticMapMarker &marker)
0230 {
0231     QList<StaticMapMarker> markers;
0232     markers << marker;
0233     d->markers = markers;
0234 }
0235 
0236 void StaticMapUrl::setMarkers(const QList<StaticMapMarker> &markers)
0237 {
0238     d->markers = markers;
0239 }
0240 
0241 QList<StaticMapPath> StaticMapUrl::paths() const
0242 {
0243     return d->paths;
0244 }
0245 
0246 void StaticMapUrl::setPath(const StaticMapPath &path)
0247 {
0248     QList<StaticMapPath> paths;
0249     paths << path;
0250     d->paths = paths;
0251 }
0252 
0253 void StaticMapUrl::setPaths(const QList<StaticMapPath> &paths)
0254 {
0255     d->paths = paths;
0256 }
0257 
0258 QSize StaticMapUrl::size() const
0259 {
0260     return d->size;
0261 }
0262 
0263 void StaticMapUrl::setSize(const QSize &size)
0264 {
0265     d->size = size;
0266 }
0267 
0268 StaticMapUrl::Scale StaticMapUrl::scale() const
0269 {
0270     return d->scale;
0271 }
0272 
0273 void StaticMapUrl::setScale(const Scale scale)
0274 {
0275     d->scale = scale;
0276 }
0277 
0278 bool StaticMapUrl::sensorUsed() const
0279 {
0280     return d->sensor;
0281 }
0282 
0283 void StaticMapUrl::setSensorUsed(const bool sensor)
0284 {
0285     d->sensor = sensor;
0286 }
0287 
0288 QString StaticMapUrl::visibleLocationString() const
0289 {
0290     return d->visibleString;
0291 }
0292 
0293 void StaticMapUrl::setVisibleLocation(const QString &location)
0294 {
0295     d->visibleString = location;
0296     d->visibleLocationType = String;
0297     d->visibleAddress.clear();
0298     d->visibleGeo.setLatitude(911);
0299     d->visibleGeo.setLongitude(181);
0300 }
0301 
0302 KContacts::Address StaticMapUrl::visibleLocationAddress() const
0303 {
0304     return d->locationAddress;
0305 }
0306 
0307 void StaticMapUrl::setVisibleLocation(const KContacts::Address &address)
0308 {
0309     d->visibleAddress = address;
0310     d->visibleLocationType = KABCAddress;
0311     d->visibleString.clear();
0312     d->visibleGeo.setLatitude(911);
0313     d->visibleGeo.setLongitude(181);
0314 }
0315 
0316 KContacts::Geo StaticMapUrl::visibleLocationGeo() const
0317 {
0318     return d->locationGeo;
0319 }
0320 
0321 void StaticMapUrl::setVisibleLocation(const KContacts::Geo &geo)
0322 {
0323     d->visibleGeo = geo;
0324     d->visibleLocationType = KABCGeo;
0325     d->visibleString.clear();
0326     d->visibleAddress.clear();
0327 }
0328 
0329 StaticMapUrl::LocationType StaticMapUrl::visibleLocationType() const
0330 {
0331     return d->visibleLocationType;
0332 }
0333 
0334 qint8 StaticMapUrl::zoomLevel() const
0335 {
0336     return d->zoom;
0337 }
0338 
0339 void StaticMapUrl::setZoomLevel(const quint32 zoom)
0340 {
0341     d->zoom = zoom;
0342 }
0343 
0344 QUrl StaticMapUrl::url() const
0345 {
0346     QUrl url(QStringLiteral("http://maps.googleapis.com/maps/api/staticmap"));
0347     QUrlQuery query(url);
0348 
0349     if (d->locationType != Undefined) {
0350         QString param;
0351 
0352         switch (d->locationType) {
0353         case Undefined:
0354         case String:
0355             param = d->locationString;
0356             param.replace(QLatin1StringView(", "), QLatin1StringView(","));
0357             param.replace(QLatin1StringView(". "), QLatin1StringView("."));
0358             param.replace(QLatin1Char(' '), QLatin1Char('+'));
0359             query.addQueryItem(QStringLiteral("center"), param);
0360             break;
0361         case KABCAddress:
0362             param = d->locationAddress.formatted(KContacts::AddressFormatStyle::Postal);
0363             param.replace(QLatin1StringView(", "), QLatin1StringView(","));
0364             param.replace(QLatin1StringView(". "), QLatin1StringView("."));
0365             param.replace(QLatin1Char(' '), QLatin1Char('+'));
0366             param.replace(QLatin1Char('\n'), QLatin1Char(','));
0367             query.addQueryItem(QStringLiteral("center"), param);
0368             break;
0369         case KABCGeo:
0370             param = QString::number(d->locationGeo.latitude()) + QLatin1Char(',') + QString::number(d->locationGeo.longitude());
0371             query.addQueryItem(QStringLiteral("center"), param);
0372             break;
0373         }
0374     }
0375 
0376     if (d->zoom != -1) {
0377         query.addQueryItem(QStringLiteral("zoom"), QString::number(d->zoom));
0378     }
0379 
0380     if (!d->size.isEmpty()) {
0381         QString size = QString::number(d->size.width()) + QLatin1Char('x') + QString::number(d->size.height());
0382         query.addQueryItem(QStringLiteral("size"), size);
0383     }
0384 
0385     if (d->scale != Normal) {
0386         query.addQueryItem(QStringLiteral("scale"), QString::number(2));
0387     }
0388     if (d->format != PNG) {
0389         QString format;
0390 
0391         switch (d->format) {
0392         case PNG:
0393         case PNG32:
0394             format = QStringLiteral("png32");
0395             break;
0396         case GIF:
0397             format = QStringLiteral("gif");
0398             break;
0399         case JPG:
0400             format = QStringLiteral("jpg");
0401             break;
0402         case JPGBaseline:
0403             format = QStringLiteral("jpg-baseline");
0404             break;
0405         }
0406 
0407         query.addQueryItem(QStringLiteral("format"), format);
0408     }
0409 
0410     if (d->maptype != Roadmap) {
0411         QString maptype;
0412 
0413         switch (d->maptype) {
0414         case Roadmap:
0415         case Satellite:
0416             maptype = QStringLiteral("satellite");
0417             break;
0418         case Terrain:
0419             maptype = QStringLiteral("terrain");
0420             break;
0421         case Hybrid:
0422             maptype = QStringLiteral("hybrid");
0423             break;
0424         }
0425 
0426         query.addQueryItem(QStringLiteral("maptype"), maptype);
0427     }
0428 
0429     for (const StaticMapMarker &marker : std::as_const(d->markers)) {
0430         if (marker.isValid()) {
0431             query.addQueryItem(QStringLiteral("markers"), marker.toString());
0432         }
0433     }
0434 
0435     for (const StaticMapPath &path : std::as_const(d->paths)) {
0436         if (path.isValid()) {
0437             query.addQueryItem(QStringLiteral("path"), path.toString());
0438         }
0439     }
0440 
0441     if (d->visibleLocationType != Undefined) {
0442         QString param;
0443 
0444         switch (d->visibleLocationType) {
0445         case Undefined:
0446         case String:
0447             param = d->visibleString;
0448             param.replace(QLatin1StringView(", "), QLatin1StringView(","));
0449             param.replace(QLatin1StringView(". "), QLatin1StringView("."));
0450             param.replace(QLatin1Char(' '), QLatin1Char('+'));
0451             query.addQueryItem(QStringLiteral("visible"), param);
0452             break;
0453         case KABCAddress:
0454             param = d->visibleAddress.formatted(KContacts::AddressFormatStyle::Postal);
0455             param.replace(QLatin1StringView(", "), QLatin1StringView(","));
0456             param.replace(QLatin1StringView(". "), QLatin1StringView("."));
0457             param.replace(QLatin1Char(' '), QLatin1Char('+'));
0458             param.replace(QLatin1Char('\n'), QLatin1Char(','));
0459             query.addQueryItem(QStringLiteral("visible"), param);
0460             break;
0461         case KABCGeo:
0462             param = QString::number(d->visibleGeo.latitude()) + QLatin1Char(',') + QString::number(d->visibleGeo.longitude());
0463             query.addQueryItem(QStringLiteral("visible"), param);
0464             break;
0465         }
0466     }
0467 
0468     if (d->sensor) {
0469         query.addQueryItem(QStringLiteral("sensor"), QStringLiteral("true"));
0470     } else {
0471         query.addQueryItem(QStringLiteral("sensor"), QStringLiteral("false"));
0472     }
0473 
0474     url.setQuery(query);
0475     return url;
0476 }