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 }