Ticket #10286: mythweather-worldweathermap.2.patch
| File mythweather-worldweathermap.2.patch, 20.5 KB (added by , 15 years ago) |
|---|
-
new file mythplugins/mythweather/mythweather/location.cpp
From aac5f990a792e985ca1add517d633d3b3ca0e8b8 Mon Sep 17 00:00:00 2001 From: Joachim Langenbach <joachim.langenbach@engsas.de> Date: Fri, 27 Jan 2012 19:44:01 +0100 Subject: [PATCH] Added a screenw which displays weather for defined locations on a world map- The map is taken from NASA blue marble project --- mythplugins/mythweather/mythweather/location.cpp | 140 +++++++++++++ mythplugins/mythweather/mythweather/location.h | 63 ++++++ .../mythweather/mythweather/mythweather.pro | 10 +- .../mythweather/mythweather/weatherScreen.cpp | 4 +- .../mythweather/mythweather/weatherUtils.cpp | 8 + .../mythweather/mythweather/worldweatherscreen.cpp | 213 ++++++++++++++++++++ .../mythweather/mythweather/worldweatherscreen.h | 101 +++++++++ .../mythweather/theme/default-wide/weather-ui.xml | 6 + .../mythweather/theme/default/weather-ui.xml | 6 + 9 files changed, 547 insertions(+), 4 deletions(-) create mode 100644 mythplugins/mythweather/mythweather/location.cpp create mode 100644 mythplugins/mythweather/mythweather/location.h create mode 100644 mythplugins/mythweather/mythweather/worldweatherscreen.cpp create mode 100644 mythplugins/mythweather/mythweather/worldweatherscreen.h diff --git a/mythplugins/mythweather/mythweather/location.cpp b/mythplugins/mythweather/mythweather/location.cpp new file mode 100644 index 0000000..25a374f
- + 1 /* 2 Copyright (C) 2012 EngSaS - Engineering Solutions and Services Langenbach. All rights reserved. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 */ 18 19 20 #include "location.h" 21 22 #include <mythimage.h> 23 #include <mythmainwindow.h> 24 25 #include <QStringList> 26 #include <QPainter> 27 #include <QPixmap> 28 #include <QFont> 29 #include <QFontMetrics> 30 31 // Location::Location(qreal latitude, qreal longitude, QString station, QString name) 32 // { 33 // init(); 34 // // myCoordinates = QtMobility::QGeoCoordinate(latitude, longitude); 35 // myStation = station; 36 // myName = name; 37 // } 38 39 void Location::setName(QString name) 40 { 41 myName = name; 42 } 43 44 QString Location::name() const 45 { 46 return myName; 47 } 48 49 // void Location::setCoordinate(QtMobility::QGeoCoordinate coordinates) 50 // { 51 // myCoordinates = coordinates; 52 // } 53 54 // QString Location::latitude() const 55 // { 56 // // Format: 27° 28' 3.2" S, 153° 1' 40.4" E, 28.1m 57 // QString myValues = myCoordinates.toString(QtMobility::QGeoCoordinate::DegreesMinutesSecondsWithHemisphere); 58 // return myValues.split(", ")[0]; 59 // } 60 // 61 // QString Location::longitude() const 62 // { 63 // // Format: 27° 28' 3.2" S, 153° 1' 40.4" E, 28.1m 64 // QString myValues = myCoordinates.toString(QtMobility::QGeoCoordinate::DegreesMinutesSecondsWithHemisphere); 65 // return myValues.split(", ")[1]; 66 // } 67 68 void Location::setCurrentTemperatur(QString temperature) 69 { 70 myCurrentTemperature = temperature; 71 } 72 73 QString Location::currentTemperature() const 74 { 75 return myCurrentTemperature; 76 } 77 78 void Location::setCurrentWeatherIcon(QString icon) 79 { 80 if(!icon.startsWith(":/weathermap/") && !icon.startsWith(":")) 81 icon = ":/weathermap/"+ icon; 82 myCurrentWeatherIcon = icon; 83 } 84 85 QString Location::currentWeatherIcon() const 86 { 87 return myCurrentWeatherIcon; 88 } 89 90 // QtMobility::QGeoCoordinate Location::toCoordinate() const 91 // { 92 // return myCoordinates; 93 // } 94 95 bool Location::addToMap(MythImage* map, QPoint position) 96 { 97 if(!map) 98 return false; 99 100 // load weather icon 101 MythImage *weatherIcon = GetMythMainWindow()->GetCurrentPainter()->GetFormatImage(); 102 weatherIcon->Load(currentWeatherIcon()); 103 if(weatherIcon->isNull()) 104 weatherIcon->Load("unknown.png"); 105 106 // add the temperature value 107 QFont iconFont; 108 iconFont.setPixelSize(40); 109 QFontMetrics metrics(iconFont); 110 QString text = QObject::tr("%1: %2 C").arg(name()).arg(currentTemperature()); 111 int iconWidth = weatherIcon->size().width(); 112 if(iconWidth < metrics.width(text)) 113 iconWidth = metrics.width(text); 114 115 QPixmap icon(iconWidth, weatherIcon->size().height() + 1.2 * float(metrics.height())); 116 icon.fill(Qt::transparent); 117 QPainter painter; 118 painter.begin(&icon); 119 painter.setFont(iconFont); 120 painter.setPen(Qt::white); 121 // remember: iconWidth = weatherIcon.width() 122 painter.drawImage((icon.width() - iconWidth)/2, 0, *weatherIcon); 123 painter.drawText(float(icon.width() - metrics.width(text)) / 2.0, weatherIcon->height() + painter.fontMetrics().height(), text); 124 painter.end(); 125 126 icon = icon.scaled(iconWidth, 80, Qt::KeepAspectRatio); 127 // set offset 128 position.setX(position.x() - icon.width()/2); 129 position.setY(position.y() - 40); 130 painter.begin(map); 131 painter.drawPixmap(position.x(), position.y(), icon); 132 painter.end(); 133 134 return true; 135 } 136 137 void Location::init() 138 { 139 myCurrentWeatherIcon = "unknown.png"; 140 } -
new file mythplugins/mythweather/mythweather/location.h
diff --git a/mythplugins/mythweather/mythweather/location.h b/mythplugins/mythweather/mythweather/location.h new file mode 100644 index 0000000..52b1fd8
- + 1 /* 2 Copyright (C) 2012 EngSaS - Engineering Solutions and Services Langenbach. All rights reserved. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 */ 18 19 20 #ifndef LOCATION_H 21 #define LOCATION_H 22 23 // #include <QGeoCoordinate> 24 25 class MythImage; 26 27 #include <QMetaType> 28 29 /** 30 * @brief Represents a location with its coordinates and weather. 31 */ 32 class Location 33 { 34 public: 35 inline Location(){ init(); } 36 // Location(qreal latitude, qreal longitude, QString station, QString name); 37 38 void setName(QString name); 39 QString name() const; 40 // void setCoordinate(QtMobility::QGeoCoordinate coordinates); 41 // QString latitude() const; 42 // QString longitude() const; 43 void setCurrentTemperatur(QString temperature); 44 QString currentTemperature() const; 45 void setCurrentWeatherIcon(QString icon); 46 QString currentWeatherIcon() const; 47 // QtMobility::QGeoCoordinate toCoordinate() const; 48 bool addToMap(MythImage *map, QPoint position); 49 50 51 private: 52 void init(); 53 54 // QtMobility::QGeoCoordinate myCoordinates; 55 QString myName, myStation, myCurrentWeatherIcon; 56 QString myCurrentTemperature; 57 }; 58 59 typedef QList<Location*> Locations; 60 61 Q_DECLARE_METATYPE(Location) 62 63 #endif // LOCATION_H -
mythplugins/mythweather/mythweather/mythweather.pro
diff --git a/mythplugins/mythweather/mythweather/mythweather.pro b/mythplugins/mythweather/mythweather/mythweather.pro index a96087b..5255354 100644
a b include ( ../../settings.pro ) 3 3 include ( ../../programs-libs.pro ) 4 4 5 5 QT += sql xml 6 CONFIG += mobility 7 MOBILITY += location 6 8 7 9 TEMPLATE = lib 8 10 CONFIG += plugin thread debug … … datafiles.path = $${PREFIX}/share/mythtv/mythweather/ 20 22 datafiles.files = weather-screens.xml 21 23 installscripts.path = $${PREFIX}/share/mythtv/mythweather/scripts 22 24 installscripts.files = scripts/* 23 INSTALLS += datafiles installscripts 25 installmaps.path = $${PREFIX}/share/mythtv/mythweather/bluemarble 26 installmaps.files = bluemarble/*.png 27 INSTALLS += datafiles installscripts installmaps 24 28 25 29 # Input 26 30 27 31 HEADERS += weather.h weatherSource.h sourceManager.h weatherScreen.h dbcheck.h 28 HEADERS += weatherSetup.h weatherUtils.h 32 HEADERS += weatherSetup.h weatherUtils.h worldweatherscreen.h location.h 29 33 SOURCES += main.cpp weather.cpp weatherSource.cpp sourceManager.cpp weatherScreen.cpp 30 SOURCES += dbcheck.cpp weatherSetup.cpp weatherUtils.cpp 34 SOURCES += dbcheck.cpp weatherSetup.cpp weatherUtils.cpp worldweatherscreen.cpp location.cpp 31 35 32 36 include ( ../../libs-targetfix.pro ) -
mythplugins/mythweather/mythweather/weatherScreen.cpp
diff --git a/mythplugins/mythweather/mythweather/weatherScreen.cpp b/mythplugins/mythweather/mythweather/weatherScreen.cpp index 9dcbded..0f25c20 100644
a b using namespace std; 8 8 // MythWeather headers 9 9 #include "weather.h" 10 10 #include "weatherScreen.h" 11 #include "worldweatherscreen.h" 11 12 12 13 WeatherScreen *WeatherScreen::loadScreen(MythScreenStack *parent, 13 14 ScreenListInfo *screenDefn, int id) 14 15 { 16 if(screenDefn->name == "World Weather") 17 return new WorldWeatherScreen(parent, screenDefn, id); 15 18 return new WeatherScreen(parent, screenDefn, id); 16 19 } 17 20 … … WeatherScreen::WeatherScreen(MythScreenStack *parent, 24 27 m_prepared(false), 25 28 m_id(id) 26 29 { 27 28 30 QStringList types = m_screenDefn->dataTypes; 29 31 30 32 for (int i = 0; i < types.size(); ++i) -
mythplugins/mythweather/mythweather/weatherUtils.cpp
diff --git a/mythplugins/mythweather/mythweather/weatherUtils.cpp b/mythplugins/mythweather/mythweather/weatherUtils.cpp index 3a5ed90..f3e4b64 100644
a b 8 8 9 9 // MythWeather headers 10 10 #include "weatherUtils.h" 11 #include "worldweatherscreen.h" 11 12 12 13 static QString getScreenTitle(const QString &screenName) 13 14 { … … ScreenListMap loadScreens() 33 34 { 34 35 ScreenListMap screens; 35 36 QList<QString> searchpath = GetMythUI()->GetThemeSearchPath(); 37 38 ScreenListInfo info = WorldWeatherScreen::info(); 39 screens[info.name].multiLoc = false; 40 screens[info.name].name = info.name; 41 screens[info.name].title = info.title; 42 screens[info.name].hasUnits = true; 43 screens[info.name].dataTypes = info.dataTypes; 36 44 37 45 // Check the theme first if it has its own weather-screens.xml 38 46 -
new file mythplugins/mythweather/mythweather/worldweatherscreen.cpp
diff --git a/mythplugins/mythweather/mythweather/worldweatherscreen.cpp b/mythplugins/mythweather/mythweather/worldweatherscreen.cpp new file mode 100644 index 0000000..10e1fc5
- + 1 /* 2 Copyright (C) 2012 EngSaS - Engineering Solutions and Services Langenbach. All rights reserved. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 */ 18 19 20 #include "worldweatherscreen.h" 21 22 #include "location.h" 23 24 #include <QGeoSearchManager> 25 #include <QGeoServiceProvider> 26 #include <QGeoCoordinate> 27 #include <QGeoAddress> 28 29 #include <mythimage.h> 30 #include <mythuiimage.h> 31 #include <mythmainwindow.h> 32 #include <mythdirs.h> 33 34 #include <cmath> 35 36 using namespace QtMobility; 37 38 #include <QDebug> 39 40 WorldWeatherScreen::WorldWeatherScreen(MythScreenStack* parent, ScreenListInfo* screenDefn, int id) 41 : WeatherScreen(parent, screenDefn, id) 42 { 43 map = NULL; 44 geoProvider = NULL; 45 geoSearch = NULL; 46 // manager = NULL; 47 } 48 49 WorldWeatherScreen::~WorldWeatherScreen() 50 { 51 if(geoProvider) 52 delete geoProvider; 53 } 54 55 ScreenListInfo WorldWeatherScreen::info() 56 { 57 ScreenListInfo info; 58 info.name = "World Weather"; 59 info.title = tr("World Weather"); 60 info.hasUnits = false; 61 // seems to be ignored right now 62 info.multiLoc = true; 63 info.dataTypes << "cclocation" << "c1location" << "temp" << "weather" << "weather_icon" << "copyright"; 64 return info; 65 } 66 67 bool WorldWeatherScreen::Create(void ) 68 { 69 bool foundtheme = false; 70 71 // Load the theme for this screen 72 foundtheme = LoadWindowFromXML("weather-ui.xml", "World Weather", this); 73 74 if (!foundtheme) 75 return false; 76 77 bool err = false; 78 79 UIUtilE::Assign(this, m_mapImage, "map_image", &err); 80 81 if (err) 82 { 83 VERBOSE(VB_IMPORTANT, "Window World Weather is missing required elements."); 84 return false; 85 } 86 87 if (!prepareScreen(true)) 88 return false; 89 90 return true; 91 } 92 93 void WorldWeatherScreen::newData(QString loc, units_t units, DataMap data) 94 { 95 Location *location = new Location(); 96 QGeoAddress address; 97 foreach(QString key, data.uniqueKeys()){ 98 qDebug() << "WorldWeather::newData: "+ key +": "+ data.value(key); 99 if(key.endsWith("location")){ 100 QStringList names = data.value(key).split(", "); 101 if(names.size() < 2) 102 return; 103 location->setName(names[0]); 104 address.setCity(names[0]); 105 address.setCountry(names[1]); 106 } 107 if(key == "temp") 108 location->setCurrentTemperatur(data.value(key)); 109 if(key == "weather_icon") 110 location->setCurrentWeatherIcon(data.value(key)); 111 } 112 if(address.isEmpty()) 113 return; 114 locations << location; 115 QGeoSearchReply *reply = geoSearch->geocode(address); 116 connect(reply, SIGNAL(finished()), this, SLOT(geocodingFinished())); 117 } 118 119 bool WorldWeatherScreen::prepareScreen(bool checkOnly) 120 { 121 // setup provider and scene 122 if(!geoProvider) 123 geoProvider = new QGeoServiceProvider("nokia"); 124 if(!geoProvider) 125 return false; 126 if(!geoSearch) 127 geoSearch = geoProvider->searchManager(); 128 if(!geoSearch) 129 return false; 130 131 if(!map || map->isNull()) 132 if(!loadMap(SatelliteMapDay)) 133 return false; 134 135 // draw empty map 136 m_mapImage->SetImage(map); 137 138 return true; 139 } 140 141 void WorldWeatherScreen::geocodingFinished() 142 { 143 qDebug() << "geocoding finished"; 144 QGeoSearchReply *reply = qobject_cast<QGeoSearchReply*>(sender()); 145 if(!reply) 146 return; 147 if(!reply->error() != QGeoSearchReply::NoError){ 148 qDebug() << "Network error"; 149 // return; 150 } 151 if(locations.size() < 1) 152 return; 153 154 Location *location = locations.first(); 155 foreach(QGeoPlace place, reply->places()){ 156 qDebug() << "trying "+ place.address().city() +" --> "+ location->name(); 157 if(place.address().city() == location->name()){ 158 qDebug() << "add "+ place.address().city() +" to the map"; 159 if(!location->addToMap(map, coordinateToWorldReferencePosition(place.coordinate()))) 160 qDebug() << "drawing weathericon has failed"; 161 locations.removeFirst(); 162 delete location; 163 if(locations.size() < 1) 164 break; 165 location = locations.first(); 166 } 167 } 168 169 emit screenReady(this); 170 } 171 172 bool WorldWeatherScreen::loadMap(MapType type) 173 { 174 if(!map) 175 map = GetMythMainWindow()->GetCurrentPainter()->GetFormatImage(); 176 177 if(type == SatelliteMapNight) 178 map->Load(QString("%1/mythweather/bluemarble/land_ocean_ice_lights_8192.png").arg(GetShareDir())); 179 else 180 map->Load(QString("%1/mythweather/bluemarble/land_shallow_topo_8192.png").arg(GetShareDir())); 181 return !map->isNull(); 182 } 183 184 QPoint WorldWeatherScreen::coordinateToWorldReferencePosition(const QGeoCoordinate& coordinate) const 185 { 186 double longitude = coordinate.longitude(); 187 double latitude = coordinate.latitude(); 188 189 int x = floor(longitude * mLongitude() + nLongitude()); 190 int y = floor(latitude * mLatitude() + nLatitude()); 191 192 return QPoint(x, y); 193 } 194 195 qreal WorldWeatherScreen::mLongitude() const 196 { 197 return qreal(map->size().width())/360.0; 198 } 199 200 qreal WorldWeatherScreen::mLatitude() const 201 { 202 return qreal(map->size().height())/-180.0; 203 } 204 205 qreal WorldWeatherScreen::nLongitude() const 206 { 207 return qreal(map->size().width())/2.0; 208 } 209 210 qreal WorldWeatherScreen::nLatitude() const 211 { 212 return qreal(map->size().height()) + mLatitude() * 90.0; 213 } -
new file mythplugins/mythweather/mythweather/worldweatherscreen.h
diff --git a/mythplugins/mythweather/mythweather/worldweatherscreen.h b/mythplugins/mythweather/mythweather/worldweatherscreen.h new file mode 100644 index 0000000..99e4929
- + 1 /* 2 Copyright (C) 2012 EngSaS - Engineering Solutions and Services Langenbach. All rights reserved. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 */ 18 19 20 #ifndef WORLDWEATHERSCREEN_H 21 #define WORLDWEATHERSCREEN_H 22 23 #include "weatherScreen.h" 24 #include "weatherUtils.h" 25 26 class Location; 27 28 #include <QGeoCoordinate> 29 30 namespace QtMobility{ 31 class QGeoServiceProvider; 32 class QGeoSearchManager; 33 }; 34 35 class MythImage; 36 37 class WorldWeatherScreen : public WeatherScreen 38 { 39 Q_OBJECT 40 public: 41 /** 42 * @brief List of supported maps. 43 */ 44 enum MapType{ 45 SatelliteMapDay, /**< Day map */ 46 SatelliteMapNight /**< Night map */ 47 }; 48 49 WorldWeatherScreen(MythScreenStack *parent, ScreenListInfo *screenDefn, int id); 50 ~WorldWeatherScreen(); 51 52 static ScreenListInfo info(); 53 54 bool Create(void); 55 56 public slots: 57 void newData(QString loc, units_t units, DataMap data); 58 59 protected: 60 bool prepareScreen(bool checkOnly = false); 61 62 private slots: 63 void geocodingFinished(); 64 65 private: 66 /** 67 * @brief Loads the map of @p type type. 68 */ 69 bool loadMap(MapType type); 70 /** 71 * @brief Converts the coordinate \a coordinate to a pixel position on the entire map at the maximum zoom level. 72 * 73 * @note Do not check for longitude between -180 and 180 and latitude between 74 * -90 and 90, because the map starts over after 180 and -180 and so on. 75 */ 76 QPoint coordinateToWorldReferencePosition(const QtMobility::QGeoCoordinate &coordinate) const; 77 /** 78 * @brief pixel/Deg for longitude. 79 */ 80 qreal mLongitude() const; 81 /** 82 * @brief pixel/deg for latitude. 83 */ 84 qreal mLatitude() const; 85 /** 86 * @brief pixel of greenwich meridian. 87 */ 88 qreal nLongitude() const; 89 /** 90 * @brief pixel of equator. 91 */ 92 qreal nLatitude() const; 93 94 MythImage *map; 95 MythUIImage *m_mapImage; 96 QtMobility::QGeoServiceProvider *geoProvider; 97 QtMobility::QGeoSearchManager *geoSearch; 98 QList<Location*> locations; 99 }; 100 101 #endif // WORLDWEATHERSCREEN_H -
mythplugins/mythweather/theme/default-wide/weather-ui.xml
diff --git a/mythplugins/mythweather/theme/default-wide/weather-ui.xml b/mythplugins/mythweather/theme/default-wide/weather-ui.xml index 5823fc4..174970d 100644
a b 45 45 </textarea> 46 46 </window> 47 47 48 <window name="World Weather"> 49 <imagetype name="map_image"> 50 <area>0,65,1280,640</area> 51 </imagetype> 52 </window> 53 48 54 <window name="Current Conditions"> 49 55 50 56 <shape name="background1"> -
mythplugins/mythweather/theme/default/weather-ui.xml
diff --git a/mythplugins/mythweather/theme/default/weather-ui.xml b/mythplugins/mythweather/theme/default/weather-ui.xml index 4b4a80d..bbc774f 100644
a b 45 45 </textarea> 46 46 </window> 47 47 48 <window name="World Weather"> 49 <imagetype name="map_image"> 50 <area>30,80,760,380</area> 51 </imagetype> 52 </window> 53 48 54 <window name="Current Conditions"> 49 55 50 56 <shape name="background1">
