File indexing completed on 2024-05-12 04:42:32

0001 /*
0002     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "accessibilitycloudparser.h"
0008 #include "../geo/geojson_p.h"
0009 
0010 #include <KPublicTransport/Equipment>
0011 
0012 #include <QDebug>
0013 #include <QDateTime>
0014 #include <QJsonArray>
0015 #include <QJsonDocument>
0016 #include <QJsonObject>
0017 #include <QPointF>
0018 #include <QUrl>
0019 
0020 using namespace KPublicTransport;
0021 
0022 bool AccessibilityCloudParser::parseLocations(const QByteArray &data)
0023 {
0024     QJsonParseError error;
0025     const auto obj = QJsonDocument::fromJson(data, &error).object();
0026     if (error.error != QJsonParseError::NoError) {
0027         qDebug() << error.errorString();
0028         return false;
0029     }
0030 
0031     const auto licensesObj = obj.value(QLatin1String("related")).toObject().value(QLatin1String("licenses")).toObject();
0032     QHash<QString, Attribution> licenses;
0033     for (auto it = licensesObj.begin(); it != licensesObj.end(); ++it) {
0034         const auto obj = it.value().toObject();
0035         const auto id = obj.value(QLatin1String("organizationId")).toString();
0036 
0037         Attribution attr;
0038         attr.setLicense(obj.value(QLatin1String("name")).toString());
0039         attr.setLicenseUrl(QUrl(obj.value(QLatin1String("websiteURL")).toString()));
0040         licenses.insert(id, attr);
0041     }
0042 
0043     const auto features = obj.value(QLatin1String("features")).toArray();
0044     for (const auto &featureV : features) {
0045         const auto feature = featureV.toObject();
0046         const auto coordinate = GeoJson::readPoint(feature.value(QLatin1String("geometry")).toObject());
0047         if (coordinate.isNull()) {
0048             continue;
0049         }
0050 
0051         const auto properties = feature.value(QLatin1String("properties")).toObject();
0052 
0053         // ignore old entries, seems to be mostly duplicates messing up matching with OSM data
0054         const auto lastUpdate = QDateTime::fromString(properties.value(QLatin1String("lastUpdate")).toString(), Qt::ISODate);
0055         if (lastUpdate.isValid() && lastUpdate.addDays(1) < QDateTime::currentDateTime()) {
0056             continue;
0057         }
0058 
0059         const auto type = properties.value(QLatin1String("category")).toString();
0060         Equipment e;
0061         if (type == QLatin1String("elevator")) {
0062             e.setType(Equipment::Elevator);
0063         } else if (type == QLatin1String("escalator")) {
0064             e.setType(Equipment::Escalator);
0065         }
0066         if (e.type() == Equipment::Unknown) {
0067             continue;
0068         }
0069 
0070         const auto working = properties.value(QLatin1String("isWorking")).toBool();
0071         e.setDisruptionEffect(working ? Disruption::NormalService : Disruption::NoService);
0072         const auto explanation = properties.value(QLatin1String("lastDisruptionProperties")).toObject().value(QLatin1String("stateExplanation")).toString();
0073         e.addNote(explanation);
0074 
0075         Location loc;
0076         loc.setType(Location::Equipment);
0077         loc.setCoordinate(coordinate.y(), coordinate.x());
0078         // there seem to be occasionally elements referring to the same piece of equipment (and thus same originalId)
0079         // but one of those having a widely wrong coordinate. Our merging code would then produce results that we cannot
0080         // match against OSM anymore. By including the sourceId we prevent merging in those cases, and let OSM matching take
0081         // care of the bogus elements
0082         loc.setIdentifier(QStringLiteral("a11ycloud"),
0083                           properties.value(QLatin1String("sourceId")).toString() +
0084                           QLatin1Char(':') +
0085                           properties.value(QLatin1String("originalId")).toString());
0086         loc.setName(properties.value(QLatin1String("description")).toString());
0087         loc.setData(e);
0088 
0089         locations.push_back(std::move(loc));
0090 
0091         const auto orgId = properties.value(QLatin1String("sourceOrganizationId")).toString();
0092         const auto attrIt = licenses.find(orgId);
0093         if (attrIt != licenses.end()) {
0094             attrIt.value().setName(properties.value(QLatin1String("organizationName")).toString());
0095             attributions.push_back(std::move(attrIt.value()));
0096             licenses.erase(attrIt);
0097         }
0098     }
0099 
0100     return true;
0101 }