288 lines
8.8 KiB
C++
288 lines
8.8 KiB
C++
|
|
/**
|
||
|
|
******************************************************************************
|
||
|
|
*
|
||
|
|
* @file OPMaps.cpp
|
||
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||
|
|
* @brief
|
||
|
|
* @see The GNU Public License (GPL) Version 3
|
||
|
|
* @defgroup OPMapWidget
|
||
|
|
* @{
|
||
|
|
*
|
||
|
|
*****************************************************************************/
|
||
|
|
/*
|
||
|
|
* This program is free software; you can redistribute it and/or modify
|
||
|
|
* it under the terms of the GNU General Public License as published by
|
||
|
|
* the Free Software Foundation; either version 3 of the License, or
|
||
|
|
* (at your option) any later version.
|
||
|
|
*
|
||
|
|
* This program is distributed in the hope that it will be useful, but
|
||
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||
|
|
* for more details.
|
||
|
|
*
|
||
|
|
* You should have received a copy of the GNU General Public License along
|
||
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
|
*/
|
||
|
|
#include "opmaps.h"
|
||
|
|
|
||
|
|
|
||
|
|
namespace core {
|
||
|
|
OPMaps *OPMaps::m_pInstance = 0;
|
||
|
|
|
||
|
|
OPMaps *OPMaps::Instance()
|
||
|
|
{
|
||
|
|
if (!m_pInstance) {
|
||
|
|
m_pInstance = new OPMaps;
|
||
|
|
}
|
||
|
|
return m_pInstance;
|
||
|
|
}
|
||
|
|
OPMaps::OPMaps() : RetryLoadTile(2), useMemoryCache(true)
|
||
|
|
{
|
||
|
|
accessmode = AccessMode::ServerAndCache;
|
||
|
|
Language = LanguageType::PortuguesePortugal;
|
||
|
|
LanguageStr = LanguageType().toShortString(Language);
|
||
|
|
Cache::Instance();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
OPMaps::~OPMaps()
|
||
|
|
{
|
||
|
|
TileDBcacheQueue.wait();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
QByteArray OPMaps::GetImageFrom(const MapType::Types &type, const Point &pos, const int &zoom)
|
||
|
|
{
|
||
|
|
#ifdef DEBUG_TIMINGS
|
||
|
|
QTime time;
|
||
|
|
time.restart();
|
||
|
|
#endif
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Entered GetImageFrom";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
QByteArray ret;
|
||
|
|
|
||
|
|
if (useMemoryCache) {
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Try Tile from memory:Size=" << TilesInMemory.MemoryCacheSize();
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
ret = GetTileFromMemoryCache(RawTile(type, pos, zoom));
|
||
|
|
if (!ret.isEmpty()) {
|
||
|
|
errorvars.lock();
|
||
|
|
++diag.tilesFromMem;
|
||
|
|
errorvars.unlock();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (ret.isEmpty()) {
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Tile not in memory";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
if (accessmode != (AccessMode::ServerOnly)) {
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Try tile from DataBase";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
ret = Cache::Instance()->ImageCache.GetImageFromCache(type, pos, zoom);
|
||
|
|
if (!ret.isEmpty()) {
|
||
|
|
errorvars.lock();
|
||
|
|
++diag.tilesFromDB;
|
||
|
|
errorvars.unlock();
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Tile found in Database";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
if (useMemoryCache) {
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Add Tile to memory";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
AddTileToMemoryCache(RawTile(type, pos, zoom), ret);
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (accessmode != AccessMode::CacheOnly) {
|
||
|
|
QEventLoop q;
|
||
|
|
QNetworkReply *reply;
|
||
|
|
QNetworkRequest qheader;
|
||
|
|
QNetworkAccessManager network;
|
||
|
|
QTimer tT;
|
||
|
|
tT.setSingleShot(true);
|
||
|
|
connect(&network, SIGNAL(finished(QNetworkReply *)),
|
||
|
|
&q, SLOT(quit()));
|
||
|
|
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
|
||
|
|
network.setProxy(Proxy);
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Try Tile from the Internet";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
#ifdef DEBUG_TIMINGS
|
||
|
|
qDebug() << "opmaps before make image url" << time.elapsed();
|
||
|
|
#endif
|
||
|
|
QString url = MakeImageUrl(type, pos, zoom, LanguageStr);
|
||
|
|
#ifdef DEBUG_TIMINGS
|
||
|
|
qDebug() << "opmaps after make image url" << time.elapsed();
|
||
|
|
#endif // url "http://vec02.maps.yandex.ru/tiles?l=map&v=2.10.2&x=7&y=5&z=3" string
|
||
|
|
// "http://map3.pergo.com.tr/tile/02/000/000/007/000/000/002.png"
|
||
|
|
qheader.setUrl(QUrl(url));
|
||
|
|
qheader.setRawHeader("User-Agent", UserAgent);
|
||
|
|
qheader.setRawHeader("Accept", "*/*");
|
||
|
|
switch (type) {
|
||
|
|
case MapType::GoogleMap:
|
||
|
|
case MapType::GoogleSatellite:
|
||
|
|
case MapType::GoogleLabels:
|
||
|
|
case MapType::GoogleTerrain:
|
||
|
|
case MapType::GoogleHybrid:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "http://maps.google.com/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MapType::GoogleMapChina:
|
||
|
|
case MapType::GoogleSatelliteChina:
|
||
|
|
case MapType::GoogleLabelsChina:
|
||
|
|
case MapType::GoogleTerrainChina:
|
||
|
|
case MapType::GoogleHybridChina:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "http://ditu.google.cn/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MapType::BingHybrid:
|
||
|
|
case MapType::BingMap:
|
||
|
|
case MapType::BingSatellite:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "http://www.bing.com/maps/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MapType::BingChina:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "https://cn.bing.com/maps");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
|
||
|
|
case MapType::YahooHybrid:
|
||
|
|
case MapType::YahooLabels:
|
||
|
|
case MapType::YahooMap:
|
||
|
|
case MapType::YahooSatellite:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "http://maps.yahoo.com/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MapType::ArcGIS_MapsLT_Map_Labels:
|
||
|
|
case MapType::ArcGIS_MapsLT_Map:
|
||
|
|
case MapType::ArcGIS_MapsLT_OrtoFoto:
|
||
|
|
case MapType::ArcGIS_MapsLT_Map_Hybrid:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "http://www.maps.lt/map_beta/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MapType::OpenStreetMapSurfer:
|
||
|
|
case MapType::OpenStreetMapSurferTerrain:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "http://www.mapsurfer.net/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MapType::OpenStreetMap:
|
||
|
|
case MapType::OpenStreetOsm:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "http://www.openstreetmap.org/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MapType::YandexMapRu:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "http://maps.yandex.ru/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
|
||
|
|
case MapType::BaiduMap:
|
||
|
|
case MapType::BaiduSatellite:
|
||
|
|
{
|
||
|
|
qheader.setRawHeader("Referrer", "https://map.baidu.com/");
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
reply = network.get(qheader);
|
||
|
|
tT.start(Timeout);
|
||
|
|
q.exec();
|
||
|
|
|
||
|
|
if (!tT.isActive()) {
|
||
|
|
errorvars.lock();
|
||
|
|
++diag.timeouts;
|
||
|
|
errorvars.unlock();
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
tT.stop();
|
||
|
|
if ((reply->error() != QNetworkReply::NoError)) {
|
||
|
|
errorvars.lock();
|
||
|
|
++diag.networkerrors;
|
||
|
|
errorvars.unlock();
|
||
|
|
reply->deleteLater();
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
ret = reply->readAll();
|
||
|
|
reply->deleteLater(); // TODO can't this be global??
|
||
|
|
if (ret.isEmpty()) {
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Invalid Tile";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
errorvars.lock();
|
||
|
|
++diag.emptytiles;
|
||
|
|
errorvars.unlock();
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Received Tile from the Internet";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
errorvars.lock();
|
||
|
|
++diag.tilesFromNet;
|
||
|
|
errorvars.unlock();
|
||
|
|
if (useMemoryCache) {
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Add Tile to memory cache";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
AddTileToMemoryCache(RawTile(type, pos, zoom), ret);
|
||
|
|
}
|
||
|
|
if (accessmode != AccessMode::ServerOnly) {
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Add tile to DataBase";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
CacheItemQueue *item = new CacheItemQueue(type, pos, ret, zoom);
|
||
|
|
TileDBcacheQueue.EnqueueCacheTask(item);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#ifdef DEBUG_GMAPS
|
||
|
|
qDebug() << "Entered GetImageFrom";
|
||
|
|
#endif // DEBUG_GMAPS
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool OPMaps::ExportToGMDB(const QString &file)
|
||
|
|
{
|
||
|
|
return Cache::Instance()->ImageCache.ExportMapDataToDB(Cache::Instance()->ImageCache.GtileCache() + QDir::separator() + "Data.qmdb", file);
|
||
|
|
}
|
||
|
|
bool OPMaps::ImportFromGMDB(const QString &file)
|
||
|
|
{
|
||
|
|
return Cache::Instance()->ImageCache.ExportMapDataToDB(file, Cache::Instance()->ImageCache.GtileCache() + QDir::separator() + "Data.qmdb");
|
||
|
|
}
|
||
|
|
|
||
|
|
diagnostics OPMaps::GetDiagnostics()
|
||
|
|
{
|
||
|
|
diagnostics i;
|
||
|
|
|
||
|
|
errorvars.lock();
|
||
|
|
i = diag;
|
||
|
|
errorvars.unlock();
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
}
|