File indexing completed on 2024-03-24 15:28:39

0001 /*
0002     SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include "kgeourihandler_p.h"
0007 
0008 #include <QUrl>
0009 #include <QUrlQuery>
0010 
0011 void KGeoUriHandler::setCoordinateTemplate(const QString &coordTmpl)
0012 {
0013     m_coordTmpl = coordTmpl;
0014 }
0015 
0016 void KGeoUriHandler::setQueryTemplate(const QString &queryTmpl)
0017 {
0018     m_queryTmpl = queryTmpl;
0019 }
0020 
0021 void KGeoUriHandler::setFallbackUrl(const QString &fallbackUrl)
0022 {
0023     m_fallbackUrl = fallbackUrl;
0024 }
0025 
0026 static bool isValidCoordinate(double c, double limit)
0027 {
0028     return c != 0.0 && c >= -limit && c <= limit;
0029 }
0030 
0031 QString KGeoUriHandler::handleUri(const QUrl &geoUri)
0032 {
0033     const auto pathElems = geoUri.path().split(QLatin1Char(';'));
0034     const auto coordElems = pathElems.isEmpty() ? QStringList() : pathElems.at(0).split(QLatin1Char(','));
0035 
0036     const auto lat = coordElems.size() < 2 ? 0.0 : coordElems.at(0).toDouble();
0037     const auto lon = coordElems.size() < 2 ? 0.0 : coordElems.at(1).toDouble();
0038 
0039     const auto geoQuery = QUrlQuery(geoUri.query());
0040     const auto query = geoQuery.queryItemValue(QStringLiteral("q"));
0041 
0042     bool zoomValid = false;
0043     int zoom = geoQuery.queryItemValue(QStringLiteral("z")).toInt(&zoomValid);
0044     if (!zoomValid || zoom < 0 || zoom > 21) {
0045         zoom = 18;
0046     }
0047 
0048     // unsupported coordinate reference system
0049     if (!pathElems.isEmpty() && std::any_of(pathElems.begin() + 1, pathElems.end(), [](const auto &elem) {
0050             return elem.startsWith(QLatin1String("crs="), Qt::CaseInsensitive) && !elem.endsWith(QLatin1String("=wgs84"), Qt::CaseInsensitive);
0051         })) {
0052         return m_fallbackUrl;
0053     }
0054 
0055     QString tmpl;
0056     if (!query.isEmpty()) {
0057         tmpl = m_queryTmpl;
0058     } else if (isValidCoordinate(lat, 90.0) && isValidCoordinate(lon, 180.0)) {
0059         tmpl = m_coordTmpl;
0060     } else {
0061         return m_fallbackUrl;
0062     }
0063 
0064     tmpl.replace(QLatin1String("<LAT>"), QString::number(lat));
0065     tmpl.replace(QLatin1String("<LON>"), QString::number(lon));
0066     tmpl.replace(QLatin1String("<Q>"), query);
0067     tmpl.replace(QLatin1String("<Z>"), QString::number(zoom));
0068     return tmpl;
0069 }