StelLocationMgr.cpp   StelLocationMgr.cpp 
skipping to change at line 20 skipping to change at line 20
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelCore.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "StelLocationMgr.hpp" #include "StelLocationMgr.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
#include <QStringListModel> #include <QStringListModel>
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#include <QDir> #include <QDir>
#include <QtNetwork/QNetworkInterface>
#include <QtNetwork/QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QUrlQuery>
#include <QSettings>
StelLocationMgr::StelLocationMgr() StelLocationMgr::StelLocationMgr()
: networkReply(NULL)
{ {
QSettings* conf = StelApp::getInstance().getSettings();
// The line below allows to re-generate the location file, you still need to gunzip it manually afterward. // The line below allows to re-generate the location file, you still need to gunzip it manually afterward.
// generateBinaryLocationFile("data/base_locations.txt", false, "dat a/base_locations.bin"); // generateBinaryLocationFile("data/base_locations.txt", false, "dat a/base_locations.bin");
locations = loadCitiesBin("data/base_locations.bin.gz"); locations = loadCitiesBin("data/base_locations.bin.gz");
locations.unite(loadCities("data/user_locations.txt", true)); locations.unite(loadCities("data/user_locations.txt", true));
modelAllLocation = new QStringListModel(this); modelAllLocation = new QStringListModel(this);
modelAllLocation->setStringList(locations.keys()); modelAllLocation->setStringList(locations.keys());
modelPickedLocation = new QStringListModel(this); // keep empty for now.
// Init to Paris France because it's the center of the world. // Init to Paris France because it's the center of the world.
lastResortLocation = locationForString("Paris, France"); lastResortLocation = locationForString(conf->value("init_location/la st_location", "Paris, France").toString());
} }
void StelLocationMgr::generateBinaryLocationFile(const QString& fileName, b ool isUserLocation, const QString& binFilePath) const void StelLocationMgr::generateBinaryLocationFile(const QString& fileName, b ool isUserLocation, const QString& binFilePath) const
{ {
const QMap<QString, StelLocation>& cities = loadCities(fileName, isU serLocation); const QMap<QString, StelLocation>& cities = loadCities(fileName, isU serLocation);
QFile binfile(binFilePath); QFile binfile(binFilePath);
if(binfile.open(QIODevice::WriteOnly)) if(binfile.open(QIODevice::WriteOnly))
{ {
QDataStream out(&binfile); QDataStream out(&binfile);
out.setVersion(QDataStream::Qt_4_6); out.setVersion(QDataStream::Qt_4_6);
skipping to change at line 147 skipping to change at line 159
{ {
locations.insert(locId, loc); locations.insert(locId, loc);
} }
} }
sourcefile.close(); sourcefile.close();
return locations; return locations;
} }
StelLocationMgr::~StelLocationMgr() StelLocationMgr::~StelLocationMgr()
{ {
delete modelPickedLocation;
modelPickedLocation=NULL;
delete modelAllLocation;
modelAllLocation=NULL;
} }
static float parseAngle(const QString& s, bool* ok) static float parseAngle(const QString& s, bool* ok)
{ {
float ret; float ret;
// First try normal decimal value. // First try normal decimal value.
ret = s.toFloat(ok); ret = s.toFloat(ok);
if (*ok) return ret; if (*ok) return ret;
// Try GPS coordinate like +121°33'38.28" // Try GPS coordinate like +121°33'38.28"
QRegExp reg("([+-]?[\\d.]+)°(?:([\\d.]+)')?(?:([\\d.]+)\")?"); QRegExp reg("([+-]?[\\d.]+)°(?:([\\d.]+)')?(?:([\\d.]+)\")?");
skipping to change at line 310 skipping to change at line 326
{ {
if (iter.value().isUserLocation) if (iter.value().isUserLocation)
{ {
outstream << iter.value().serializeToLine() << '\n'; outstream << iter.value().serializeToLine() << '\n';
} }
} }
sourcefile.close(); sourcefile.close();
return true; return true;
} }
// lookup location from IP address.
void StelLocationMgr::locationFromIP()
{
QNetworkRequest req( QUrl( QString("http://freegeoip.net/csv/") ) );
networkReply=StelApp::getInstance().getNetworkAccessManager()->get(r
eq);
connect(networkReply, SIGNAL(finished()), this, SLOT(changeLocationF
romNetworkLookup()));
}
// slot that receives IP-based location data from the network.
void StelLocationMgr::changeLocationFromNetworkLookup()
{
StelLocation location;
StelCore *core=StelApp::getInstance().getCore();
if (networkReply->error() == QNetworkReply::NoError) {
//success
// Tested with and without working network connection.
QByteArray answer=networkReply->readAll();
// answer/splitline example: "222.222.222.222","AT","Austria
","","","","","47.3333","13.3333","",""
// The parts from freegeoip are: ip,country_code,country_nam
e,region_code,region_name,city,zipcode,latitude,longitude,metro_code,area_c
ode
// longitude and latitude should always be filled.
// A few tests:
if ((answer.count('"') != 22 ) || (answer.count(',') != 10 )
)
{
qDebug() << "StelLocationMgr: Malformatted answer in
IP-based location lookup: \n\t" << answer;
qDebug() << "StelLocationMgr: Will not change locati
on.";
networkReply->deleteLater();
return;
}
const QStringList& splitline = QString(answer).split(",");
if (splitline.count() != 11 )
{
qDebug() << "StelLocationMgr: Unexpected answer in I
P-based location lookup: \n\t" << answer;
qDebug() << "StelLocationMgr: Will not change locati
on.";
networkReply->deleteLater();
return;
}
if ((splitline.at(7)=="\"\"") || (splitline.at(8)=="\"\""))
// empty coordinates?
{
qDebug() << "StelLocationMgr: Invalid coordinates fr
om IP-based lookup. Ignoring: \n\t" << answer;
networkReply->deleteLater();
return;
}
float latitude=splitline.at(7).mid(1, splitline.at(7).length
()-2).toFloat();
float longitude=splitline.at(8).mid(1, splitline.at(8).lengt
h()-2).toFloat();
QString locLine= // we re-pack into a new line that will be
parsed back by StelLocation...
QString("%1\t%2\t%3\t%4\t%5\t%6\t%7\t0")
.arg(splitline.at(5).length()>2 ? splitline.
at(5).mid(1, splitline.at(5).length()-2) : QString("IP%1").arg(splitline.a
t(0).mid(1, splitline.at(0).length()-2)))
.arg(splitline.at(4).length()>2 ? splitline.
at(4).mid(1, splitline.at(4).length()-2) : "IPregion")
.arg(splitline.at(2).length()>2 ? splitline.
at(2).mid(1, splitline.at(2).length()-2) : "IPcountry") // country
.arg("X") // role: X=user-defined
.arg(0) // population: unknown
.arg(latitude<0 ? QString("%1S").arg(-latitu
de, 0, 'f', 6) : QString("%1N").arg(latitude, 0, 'f', 6))
.arg(longitude<0 ? QString("%1W").arg(-longi
tude, 0, 'f', 6) : QString("%1E").arg(longitude, 0, 'f', 6));
location=StelLocation::createFromLine(locLine); // in lack o
f a regular constructor ;-)
core->moveObserverTo(location, 0.0f, 0.0f);
QSettings* conf = StelApp::getInstance().getSettings();
conf->setValue("init_location/last_location", QString("%1, %
2").arg(latitude).arg(longitude));
}
else
{
qDebug() << "Failure getting IP-based location: \n\t" <<netw
orkReply->errorString();
core->moveObserverTo(lastResortLocation, 0.0f, 0.0f);
}
networkReply->deleteLater();
}
void StelLocationMgr::pickLocationsNearby(const QString planetName, const f
loat longitude, const float latitude, const float radiusDegrees)
{
pickedLocations.clear();
QMapIterator<QString, StelLocation> iter(locations);
while (iter.hasNext())
{
iter.next();
const StelLocation *loc=&iter.value();
if ( (loc->planetName == planetName) &&
(StelLocation::distanceDegrees(longitude, la
titude, loc->longitude, loc->latitude) <= radiusDegrees) )
{
pickedLocations.insert(iter.key(), iter.value());
}
}
modelPickedLocation->setStringList(pickedLocations.keys());
}
void StelLocationMgr::pickLocationsInCountry(const QString country)
{
pickedLocations.clear();
QMapIterator<QString, StelLocation> iter(locations);
while (iter.hasNext())
{
iter.next();
const StelLocation *loc=&iter.value();
if (loc->country == country)
{
pickedLocations.insert(iter.key(), iter.value());
}
}
modelPickedLocation->setStringList(pickedLocations.keys());
}
 End of changes. 8 change blocks. 
1 lines changed or deleted 17 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/