1
0
mirror of https://github.com/clementine-player/Clementine synced 2025-02-02 20:36:44 +01:00

Filter out songkick concerts that are too far away.

This commit is contained in:
John Maguire 2012-06-20 14:12:37 +02:00
parent 86cced782e
commit 0d5d1dbad1
5 changed files with 94 additions and 20 deletions

View File

@ -1,5 +1,6 @@
#include "geolocator.h"
#include <cmath>
#include <limits>
#include <qjson/parser.h>
@ -7,8 +8,9 @@
#include <QStringList>
#include "core/closure.h"
#include "core/logging.h"
const char* Geolocator::kUrl = "https://data.clementine-player.org/geolocate";
const char* Geolocator::kUrl = "http://data.clementine-player.org/geolocate";
using std::numeric_limits;
@ -22,6 +24,43 @@ Geolocator::LatLng::LatLng(int lat_e6, int lng_e6)
lng_e6_(lng_e6) {
}
Geolocator::LatLng::LatLng(const QString& latlng)
: lat_e6_(numeric_limits<int>::min()),
lng_e6_(numeric_limits<int>::min()) {
QStringList split = latlng.split(",");
if (split.length() != 2) {
return;
}
const double lat = split[0].toDouble();
const double lng = split[1].toDouble();
lat_e6_ = static_cast<int>(lat * 1e6);
lng_e6_ = static_cast<int>(lng * 1e6);
}
Geolocator::LatLng::LatLng(const QString& lat, const QString& lng) {
lat_e6_ = static_cast<int>(lat.toDouble() * 1e6);
lng_e6_ = static_cast<int>(lng.toDouble() * 1e6);
}
int Geolocator::LatLng::Distance(const Geolocator::LatLng& other) const {
static const int kEarthRadiusMetres = 6372800;
double lat_a = lat_e6() / 1000000.0 * (M_PI / 180.0);
double lng_a = lng_e6() / 1000000.0 * (M_PI / 180.0);
double lat_b = other.lat_e6() / 1000000.0 * (M_PI / 180.0);
double lng_b = other.lng_e6() / 1000000.0 * (M_PI / 180.0);
double delta_longitude = lng_b - lng_a;
double sines = sin(lat_a) * sin(lat_b);
double cosines = cos(lat_a) * cos(lat_b) * cos(delta_longitude);
double central_angle = acos(sines + cosines);
double distance_metres = kEarthRadiusMetres * central_angle;
return static_cast<int>(distance_metres);
}
bool Geolocator::LatLng::IsValid() const {
return lat_e6_ != numeric_limits<int>::min() &&
lng_e6_ != numeric_limits<int>::min();
@ -34,7 +73,7 @@ Geolocator::Geolocator(QObject* parent)
void Geolocator::Geolocate() {
QNetworkRequest req = QNetworkRequest(QUrl(kUrl));
QNetworkReply* reply = network_.get(req);
NewClosure(reply, SIGNAL(finished()), this, SLOT(RequestFinished()));
NewClosure(reply, SIGNAL(finished()), this, SLOT(RequestFinished(QNetworkReply*)), reply);
}
void Geolocator::RequestFinished(QNetworkReply* reply) {
@ -54,16 +93,13 @@ void Geolocator::RequestFinished(QNetworkReply* reply) {
QVariantMap map = result.toMap();
QString latlng = map["latlng"].toString();
QStringList split = latlng.split(",");
if (split.length() != 2) {
emit Finished(LatLng());
return;
}
double lat = split[0].toDouble();
double lng = split[1].toDouble();
emit Finished(
LatLng(static_cast<int>(lat * 1e6),
static_cast<int>(lng * 1e6)));
LatLng ll(latlng);
qLog(Debug) << "Gelocated to:" << ll;
emit Finished(ll);
}
QDebug operator<<(QDebug dbg, const Geolocator::LatLng& ll) {
dbg.nospace() << "(" << ll.lat_e6() << "," << ll.lng_e6() << ")";
return dbg.space();
}

View File

@ -16,19 +16,22 @@ class Geolocator : public QObject {
public:
LatLng();
LatLng(int lat_e6, int lng_e6);
explicit LatLng(const QString& latlng);
LatLng(const QString& lat, const QString& lng);
int lat_e6() const { return lat_e6_; }
int lng_e6() const { return lng_e6_; }
bool IsValid() const;
int Distance(const LatLng& other) const;
private:
const int lat_e6_;
const int lng_e6_;
int lat_e6_;
int lng_e6_;
};
signals:
void Finished(LatLng latlng);
void Finished(Geolocator::LatLng latlng);
private slots:
void RequestFinished(QNetworkReply* reply);
@ -39,4 +42,7 @@ class Geolocator : public QObject {
static const char* kUrl;
};
QDebug operator<<(QDebug dbg, const Geolocator::LatLng& ll);
Q_DECLARE_METATYPE(Geolocator::LatLng);
#endif // GEOLOCATOR_H

View File

@ -44,6 +44,7 @@
#include "engines/enginebase.h"
#include "globalsearch/searchprovider.h"
#include "internet/digitallyimportedclient.h"
#include "internet/geolocator.h"
#include "internet/somafmservice.h"
#include "library/directory.h"
#include "playlist/playlist.h"
@ -293,6 +294,7 @@ int main(int argc, char *argv[]) {
qRegisterMetaType<QList<PodcastEpisode> >("QList<PodcastEpisode>");
qRegisterMetaType<PodcastList>("PodcastList");
qRegisterMetaType<PodcastEpisodeList>("PodcastEpisodeList");
qRegisterMetaType<Geolocator::LatLng>("Geolocator::LatLng");
qRegisterMetaType<GstBuffer*>("GstBuffer*");
qRegisterMetaType<GstElement*>("GstElement*");

View File

@ -34,7 +34,10 @@ const char* SongkickConcerts::kSongkickArtistCalendarUrl =
"apikey=8rgKfy1WU6IlJFfN";
SongkickConcerts::SongkickConcerts() {
Geolocator* geolocator = new Geolocator;
geolocator->Geolocate();
connect(geolocator, SIGNAL(Finished(Geolocator::LatLng)), SLOT(GeolocateFinished(Geolocator::LatLng)));
NewClosure(geolocator, SIGNAL(Finished(Geolocator::LatLng)), geolocator, SLOT(deleteLater()));
}
void SongkickConcerts::FetchInfo(int id, const Song& metadata) {
@ -120,15 +123,35 @@ void SongkickConcerts::CalendarRequestFinished(QNetworkReply* reply, int id) {
foreach (const QVariant& v, events) {
QVariantMap event = v.toMap();
{
QString display_name = event["displayName"].toString();
QVariantMap venue = event["venue"].toMap();
const bool valid_latlng =
venue["lng"].isValid() && venue["lat"].isValid();
if (valid_latlng && latlng_.IsValid()) {
static const int kFilterDistanceMetres = 250 * 1e3; // 250km
Geolocator::LatLng latlng(
venue["lat"].toString(), venue["lng"].toString());
if (latlng_.IsValid() && latlng.IsValid()) {
int distance_metres = latlng_.Distance(latlng);
if (distance_metres > kFilterDistanceMetres) {
qLog(Debug) << "Filtered concert:"
<< display_name
<< "as too far away:"
<< distance_metres;
continue;
}
}
}
writer.writeStartElement("div");
{
writer.writeStartElement("a");
writer.writeAttribute("href", event["uri"].toString());
writer.writeCharacters(event["displayName"].toString());
writer.writeCharacters(display_name);
writer.writeEndElement();
}
QVariantMap venue = event["venue"].toMap();
if (venue["lng"].isValid() && venue["lat"].isValid()) {
if (valid_latlng) {
writer.writeStartElement("img");
QString maps_url = QString(kStaticMapUrl).arg(
venue["lat"].toString(),
@ -171,3 +194,7 @@ void SongkickConcerts::InjectImage(
reply->request().url(),
QVariant(image));
}
void SongkickConcerts::GeolocateFinished(Geolocator::LatLng latlng) {
latlng_ = latlng;
}

View File

@ -21,6 +21,7 @@
#include "songinfoprovider.h"
#include "core/network.h"
#include "internet/geolocator.h"
class QNetworkReply;
class SongInfoTextView;
@ -36,11 +37,13 @@ class SongkickConcerts : public SongInfoProvider {
void ArtistSearchFinished(QNetworkReply* reply, int id);
void CalendarRequestFinished(QNetworkReply* reply, int id);
void InjectImage(QNetworkReply* reply, SongInfoTextView* text_view);
void GeolocateFinished(Geolocator::LatLng latlng);
private:
void FetchSongkickCalendar(const QString& artist_id, int id);
NetworkAccessManager network_;
Geolocator::LatLng latlng_;
static const char* kSongkickArtistBucket;
static const char* kSongkickArtistCalendarUrl;