File indexing completed on 2024-05-05 03:50:44
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2012 Utku Aydın <utkuaydin34@gmail.com> 0004 // 0005 0006 #include "FoursquareModel.h" 0007 #include "FoursquarePlugin.h" 0008 #include "FoursquareItem.h" 0009 0010 #include "MarbleGlobal.h" 0011 #include "MarbleModel.h" 0012 #include "GeoDataCoordinates.h" 0013 #include "GeoDataLatLonAltBox.h" 0014 #include "MarbleDebug.h" 0015 #include "MarbleMath.h" 0016 0017 #include <QUrl> 0018 #include <QJsonDocument> 0019 #include <QJsonArray> 0020 #include <QJsonObject> 0021 0022 namespace Marble 0023 { 0024 0025 FoursquareModel::FoursquareModel(const MarbleModel *marbleModel, QObject* parent) 0026 : AbstractDataPluginModel("foursquare", marbleModel, parent) 0027 { 0028 // Enjoy laziness 0029 } 0030 0031 FoursquareModel::~FoursquareModel() 0032 { 0033 } 0034 0035 void FoursquareModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number ) 0036 { 0037 if (marbleModel()->planetId() != QLatin1String("earth")) { 0038 return; 0039 } 0040 0041 QString clientId = "YPRWSYFW1RVL4PJQ2XS5G14RTOGTHOKZVHC1EP5KCCCYQPZF"; 0042 QString clientSecret = "5L2JDCAYQCEJWY5FNDU4A1RWATE4E5FIIXXRM41YBTFSERUH"; 0043 0044 QString apiUrl( "https://api.foursquare.com/v2/venues/search" ); 0045 qreal const distanceLon = marbleModel()->planetRadius() * distanceSphere( box.west(), box.north(), box.east(), box.north() ); 0046 qreal const distanceLat = marbleModel()->planetRadius() * distanceSphere( box.west(), box.north(), box.west(), box.south() ); 0047 qreal const area = distanceLon * distanceLat; 0048 if ( area > 10 * 1000 * KM2METER * KM2METER ) { 0049 // Large area (> 10.000 km^2) => too large for bbox queries 0050 apiUrl += QLatin1String("?ll=") + QString::number(box.center().latitude(Marble::GeoDataCoordinates::Degree)) + 0051 QLatin1Char(',') + QString::number(box.center().longitude(Marble::GeoDataCoordinates::Degree)) + 0052 QLatin1String("&intent=checkin"); 0053 } else { 0054 apiUrl += QLatin1String("?ne=") + QString::number(box.north(Marble::GeoDataCoordinates::Degree)) + 0055 QLatin1Char(',') + QString::number(box.east(Marble::GeoDataCoordinates::Degree)) + 0056 QLatin1String("&sw=") + QString::number(box.south(Marble::GeoDataCoordinates::Degree)) + 0057 QLatin1Char(',') + QString::number(box.west(Marble::GeoDataCoordinates::Degree)) + 0058 QLatin1String("&intent=browse"); 0059 } 0060 apiUrl += QLatin1String("&limit=") + QString::number(number) + 0061 QLatin1String("&client_id=") + clientId + 0062 QLatin1String("&client_secret=") + clientSecret + 0063 QLatin1String("&v=20120601"); 0064 downloadDescriptionFile( QUrl( apiUrl ) ); 0065 } 0066 0067 void FoursquareModel::parseFile( const QByteArray& file ) 0068 { 0069 const QJsonDocument jsonDoc = QJsonDocument::fromJson(file); 0070 const QJsonObject responseObject = jsonDoc.object().value(QStringLiteral("response")).toObject(); 0071 const QJsonValue venuesValue = responseObject.value(QStringLiteral("response")); 0072 0073 // Parse if any result exists 0074 if (venuesValue.isArray()) { 0075 // Add items to the list 0076 QList<AbstractDataPluginItem*> items; 0077 0078 const QJsonArray venueArray = venuesValue.toArray(); 0079 for (int venueIndex = 0; venueIndex < venueArray.size(); ++venueIndex) { 0080 const QJsonObject venueObject = venueArray[venueIndex].toObject(); 0081 0082 const QJsonObject firstCategoryObject = venueObject.value(QStringLiteral("categories")).toArray().at(0).toObject(); 0083 0084 const QString id = venueObject.value(QStringLiteral("id")).toString(); 0085 const QString name = venueObject.value(QStringLiteral("name")).toString(); 0086 const QString category = firstCategoryObject.value(QStringLiteral("name")).toString(); 0087 const QJsonObject locationObject = venueObject.value(QStringLiteral("location")).toObject(); 0088 const QString address = locationObject.value(QStringLiteral("address")).toString(); 0089 const QString city = locationObject.value(QStringLiteral("city")).toString(); 0090 const QString country = locationObject.value(QStringLiteral("country")).toString(); 0091 const double latitude = locationObject.value(QStringLiteral("lat")).toString().toDouble(); 0092 const double longitude = locationObject.value(QStringLiteral("lng")).toString().toDouble(); 0093 const int usersCount = venueObject.value(QStringLiteral("stats")).toObject().value(QStringLiteral("usersCount")).toInt(); 0094 0095 const QJsonValue categoryIconValue = firstCategoryObject.value(QStringLiteral("icon")); 0096 QString iconUrl; 0097 QString largeIconUrl; 0098 if (categoryIconValue.isObject()) { 0099 const QJsonObject categoryIconObject = categoryIconValue.toObject(); 0100 const QString iconPrefix = categoryIconObject.value(QStringLiteral("prefix")).toString(); 0101 const QString iconName = categoryIconObject.value(QStringLiteral("name")).toString(); 0102 iconUrl = iconPrefix 0103 + QLatin1String("32") // That's the icon size hardcoded 0104 + iconName; 0105 0106 largeIconUrl = iconPrefix 0107 + QLatin1String("64") // Larger icon 0108 + iconName; 0109 } 0110 0111 if( !itemExists( id ) ) { 0112 GeoDataCoordinates coordinates( longitude, latitude, 0.0, GeoDataCoordinates::Degree ); 0113 FoursquareItem *item = new FoursquareItem( this ); 0114 item->setId( id ); 0115 item->setCoordinate( coordinates ); 0116 item->setName( name ); 0117 item->setCategory( category ); 0118 item->setAddress( address ); 0119 item->setCity( city ); 0120 item->setCountry( country ); 0121 item->setUsersCount( usersCount ); 0122 item->setCategoryIconUrl( iconUrl ); 0123 item->setCategoryLargeIconUrl( largeIconUrl ); 0124 0125 items << item; 0126 } 0127 } 0128 addItemsToList( items ); 0129 } 0130 } 0131 0132 } 0133 0134 #include "moc_FoursquareModel.cpp"