1 /* 2 * Copyright (C) 2008 Fabien Chereau 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (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, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. 17 */ 18 19 #ifndef STELLOCATIONMGR_HPP 20 #define STELLOCATIONMGR_HPP 21 22 #include "StelLocation.hpp" 23 #include <QString> 24 #include <QObject> 25 #include <QMetaType> 26 #include <QMap> 27 28 typedef QList<StelLocation> LocationList; 29 typedef QMap<QString,StelLocation> LocationMap; 30 typedef QMap<QByteArray,QByteArray> TimezoneNameMap; 31 32 typedef struct 33 { 34 int code; 35 QString regionName; 36 QString countries; 37 QString planet; 38 } GeoRegion; 39 40 class GPSLookupHelper; 41 42 //! @class StelLocationMgr 43 //! Manage the list of available location. 44 class StelLocationMgr : public QObject 45 { 46 Q_OBJECT 47 48 public: 49 //! Default constructor which loads the list of locations from the base and user location files. 50 StelLocationMgr(); 51 ~StelLocationMgr(); 52 53 //! Construct a StelLocationMgr which uses the locations given instead of loading them from the files. 54 StelLocationMgr(const LocationList& locations); 55 56 //! Replaces the loaded location list 57 void setLocations(const LocationList& locations); 58 59 //! Return the list of all loaded locations getAll() const60 LocationList getAll() const {return locations.values();} 61 62 //! Returns a map of all loaded locations. The key is the location ID, suitable for a list view. getAllMap() const63 LocationMap getAllMap() const { return locations; } 64 65 //! Return the StelLocation from a CLI 66 const StelLocation locationFromCLI() const; 67 68 //! Return a valid location when no valid one was found. getLastResortLocation() const69 const StelLocation& getLastResortLocation() const {return lastResortLocation;} 70 71 //! Get whether a location can be permanently added to the list of user locations 72 //! The main constraint is that the small string must be unique 73 bool canSaveUserLocation(const StelLocation& loc) const; 74 75 //! Add permanently a location to the list of user locations 76 //! It is later identified by its small string 77 bool saveUserLocation(const StelLocation& loc); 78 79 //! Get whether a location can be deleted from the list of user locations 80 //! If the location comes from the base read only list, it cannot be deleted 81 //! @param id the location ID 82 bool canDeleteUserLocation(const QString& id) const; 83 84 //! Delete permanently the given location from the list of user locations 85 //! If the location comes from the base read only list, it cannot be deleted and false is returned 86 //! @param id the location ID 87 bool deleteUserLocation(const QString& id); 88 89 //! Find list of locations within @param radiusDegrees of selected (usually screen-clicked) coordinates. 90 LocationMap pickLocationsNearby(const QString planetName, const float longitude, const float latitude, const float radiusDegrees); 91 //! Find list of locations in a particular region only. 92 LocationMap pickLocationsInRegion(const QString region); 93 94 //! return a QStringList of region names by planet (return all list of regions if planet name is empty) 95 QStringList getRegionNames(const QString& planet = "") const; 96 97 //! Pick region name from ISO 3166-1 two-letter country codes 98 static QString pickRegionFromCountryCode(const QString countryCode); 99 //! Pick region name from country English name 100 static QString pickRegionFromCountry(const QString country); 101 //! Pick region name from region code 102 static QString pickRegionFromCode(int regionCode); 103 104 public slots: 105 //! Return the StelLocation for a given string 106 //! Can match location name, or coordinates 107 const StelLocation locationForString(const QString& s) const; 108 109 //! Find location via online lookup of IP address 110 void locationFromIP(); 111 112 //! return a QStringList of valid timezone names in Stellarium's location database. 113 QStringList getAllTimezoneNames() const; 114 115 #ifdef ENABLE_GPS 116 //! Try to get a location from GPS lookup. 117 //! This prefers GPSD on non-Windows platforms, and uses Qt positioning with a NMEA serial device otherwise 118 //! Use the gpsResult() signal to determine if the location was set successfully. 119 //! With argument 0, this always signals true. 120 //! @note When using GPSD not on localhost, don't forget the -G switch when starting gpsd there! 121 //! @param interval set negative to just fetch one position, mseconds to start periodic query, or 0 to stop those. 122 //! It may be better to leave it running to observe incoming data, then switch off when fix seems good. 123 //! When disabled, the NMEA device and its serial connection is released. 124 void locationFromGPS(int interval=-1); 125 #endif 126 127 //! Check timezone string and return either the same or one that we use in the Stellarium location database. 128 //! If timezone name starts with "UTC", always return unchanged. 129 //! This is required to store timezone names exactly as we know them, and not mix ours and current-IANA spelling flavour. 130 static QString sanitizeTimezoneStringForLocationDB(QString tzString); 131 //! Attempt to translate a timezone name from those used in Stellarium's location database to a name which is known 132 //! to Qt at runtime as result of QTimeZone::availableTimeZoneIds(). That list may be updated by OS anytime and is known to differ 133 //! between OSes. Some spellings may be different, or in some cases some names get simply translated to "UTC+HH:MM" style. 134 //! The empty string gets translated to "UTC". 135 static QString sanitizeTimezoneStringFromLocationDB(QString dbString); 136 137 signals: 138 //! Can be used to detect changes to the full location list 139 //! i.e. when the user added or removed locations 140 void locationListChanged(); 141 142 #ifdef ENABLE_GPS 143 //! emitted when GPS location query and setting location either succeed or fail. 144 //! @param success true if successful, false in case of any error (no device, timeout, bad fix, ...). 145 void gpsQueryFinished(bool success); 146 #endif 147 private slots: 148 //! Process answer from online lookup of IP address 149 void changeLocationFromNetworkLookup(); 150 #ifdef ENABLE_GPS 151 void changeLocationFromGPSQuery(const StelLocation& loc); 152 void gpsQueryError(const QString& err); 153 #endif 154 private: 155 void loadRegions(); 156 void loadCountries(); 157 void generateBinaryLocationFile(const QString& txtFile, bool isUserLocation, const QString& binFile) const; 158 159 //! Load cities from a file 160 static LocationMap loadCities(const QString& fileName, bool isUserLocation); 161 static LocationMap loadCitiesBin(const QString& fileName); 162 163 //! The list of all loaded locations 164 LocationMap locations; 165 //! A Map which has to be used to replace, system- and Qt-version dependent, 166 //! timezone names from our location database to the code names currently used by Qt. 167 //! Required to avoid https://bugs.launchpad.net/stellarium/+bug/1662132, 168 //! details on IANA names with Qt at http://doc.qt.io/qt-5/qtimezone.html. 169 //! This has nothing to do with the Windows timezone names! 170 //! Key: TZ name as used in our database. 171 //! Value: TZ name as may be available instead in the currently running version of Qt. 172 //! The list has to be maintained based on empirical observations. 173 //! @todo Make it load from a configurable external file. 174 static TimezoneNameMap locationDBToIANAtranslations; 175 176 static QList<GeoRegion> regions; 177 static QMap<QString, QString> countryCodeToRegionMap; 178 static QMap<QString, QString> countryNameToCodeMap; 179 180 StelLocation lastResortLocation; 181 182 GPSLookupHelper *nmeaHelper,*libGpsHelper; 183 }; 184 185 #endif // STELLOCATIONMGR_HPP 186