1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

OP-37 GCS/MapPlugin First Commit, NOT fully functional.

Standalone compilation, not included on the top level project. 

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@661 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
zedamota 2010-05-24 19:53:44 +00:00 committed by zedamota
parent ec40618664
commit 630c1325d8
76 changed files with 5954 additions and 0 deletions

View File

@ -0,0 +1,8 @@
TEMPLATE = subdirs
SUBDIRS = core
SUBDIRS += internals
CONFIG += ordered
SUBDIRS +=teste
SUBDIRS +=gettilestest

View File

@ -0,0 +1,15 @@
DESTDIR = ../build
QT += network
QT += sql
INCLUDEPATH += . ..
WARNINGS += -Wall
#CONFIG += console
#CONFIG -= app_bundle
CONFIG += dll
TEMPLATE = lib
UI_DIR = uics
MOC_DIR = mocs
OBJECTS_DIR = objs

View File

@ -0,0 +1,29 @@
#ifndef ACCESSMODE_H
#define ACCESSMODE_H
struct AccessMode
{
public:
enum Types
{
/// <summary>
/// access only server
/// </summary>
ServerOnly,
/// <summary>
/// access first server and caches localy
/// </summary>
ServerAndCache,
/// <summary>
/// access only cache
/// </summary>
CacheOnly,
};
};
#endif // ACCESSMODE_H

View File

@ -0,0 +1,61 @@
#include "alllayersoftype.h"
AllLayersOfType::AllLayersOfType()
{
}
QVector<MapType::Types> AllLayersOfType::GetAllLayersOfType(const MapType::Types &type)
{
QVector<MapType::Types> types;
{
switch(type)
{
case MapType::GoogleHybrid:
{
types.append(MapType::GoogleSatellite);
types.append(MapType::GoogleLabels);
}
break;
case MapType::GoogleHybridChina:
{
types.append(MapType::GoogleSatelliteChina);
types.append(MapType::GoogleLabelsChina);
}
break;
case MapType::GoogleHybridKorea:
{
types.append(MapType::GoogleSatelliteKorea);
types.append(MapType::GoogleLabelsKorea);
}
break;
case MapType::YahooHybrid:
{
types.append(MapType::YahooSatellite);
types.append(MapType::YahooLabels);
}
break;
case MapType::ArcGIS_MapsLT_Map_Hybrid:
{
types.append(MapType::ArcGIS_MapsLT_OrtoFoto);
types.append(MapType::ArcGIS_MapsLT_Map_Labels);
}
break;
default:
{
types.append(type);
}
break;
}
}
return types;
}

View File

@ -0,0 +1,14 @@
#ifndef ALLLAYERSOFTYPE_H
#define ALLLAYERSOFTYPE_H
#include "maptype.h"
#include <QList>
#include <QVector>
class AllLayersOfType
{
public:
AllLayersOfType();
QVector<MapType::Types> GetAllLayersOfType(const MapType::Types &type);
};
#endif // ALLLAYERSOFTYPE_H

View File

@ -0,0 +1,127 @@
#include "cache.h"
Cache* Cache::m_pInstance=0;
Cache* Cache::Instance()
{
if(!m_pInstance)
m_pInstance=new Cache;
return m_pInstance;
}
void Cache::setCacheLocation(const QString& value)
{
cache=value;
routeCache = cache + "RouteCache" + QDir::separator();
geoCache = cache + "GeocoderCache"+ QDir::separator();
placemarkCache = cache + "PlacemarkCache" + QDir::separator();
ImageCache.setGtileCache(value);
}
QString Cache::CacheLocation()
{
return cache;
}
Cache::Cache()
{
if(cache.isNull()|cache.isEmpty())
{
cache=QDir::currentPath()+QDir::separator()+"mapscache"+QDir::separator();
setCacheLocation(cache);
}
}
QString Cache::GetGeocoderFromCache(const QString &urlEnd)
{
qDebug()<<"Entered GetGeocoderFromCache";
QString ret=QString::null;
QString filename=geoCache+QString(urlEnd)+".geo";
qDebug()<<"GetGeocoderFromCache: Does file exist?:"<<filename;
QFileInfo File(filename);
if (File .exists())
{
qDebug()<<"GetGeocoderFromCache:File exists!!";
QFile file(filename);
if (file.open(QIODevice::ReadOnly))
{
QTextStream stream(&file);
stream.setCodec("UTF-8");
stream>>ret;
}
}
qDebug()<<"GetGeocoderFromCache:Returning:"<<ret;
return ret;
}
void Cache::CacheGeocoder(const QString &urlEnd, const QString &content)
{
QString ret=QString::null;
QString filename=geoCache+QString(urlEnd)+".geo";
qDebug()<<"CacheGeocoder: Filename:"<<filename;
QFileInfo File(filename);;
QDir dir=File.absoluteDir();
QString path=dir.absolutePath();
qDebug()<<"CacheGeocoder: Path:"<<path;
if(!dir.exists())
{
qDebug()<<"CacheGeocoder: Cache path doesn't exist, try to create";
if(!dir.mkpath(path))
{
qDebug()<<"GetGeocoderFromCache: Could not create path";
}
}
qDebug()<<"CacheGeocoder: OpenFile:"<<filename;
QFile file(filename);
if (file.open(QIODevice::WriteOnly))
{
qDebug()<<"CacheGeocoder: File Opened!!!:"<<filename;
QTextStream stream(&file);
stream.setCodec("UTF-8");
stream<<content;
}
}
QString Cache::GetPlacemarkFromCache(const QString &urlEnd)
{
qDebug()<<"Entered GetPlacemarkFromCache";
QString ret=QString::null;
QString filename=placemarkCache+QString(urlEnd)+".plc";
qDebug()<<"GetPlacemarkFromCache: Does file exist?:"<<filename;
QFileInfo File(filename);
if (File .exists())
{
qDebug()<<"GetPlacemarkFromCache:File exists!!";
QFile file(filename);
if (file.open(QIODevice::ReadOnly))
{
QTextStream stream(&file);
stream.setCodec("UTF-8");
stream>>ret;
}
}
qDebug()<<"GetPlacemarkFromCache:Returning:"<<ret;
return ret;
}
void Cache::CachePlacemark(const QString &urlEnd, const QString &content)
{
QString ret=QString::null;
QString filename=placemarkCache+QString(urlEnd)+".plc";
qDebug()<<"CachePlacemark: Filename:"<<filename;
QFileInfo File(filename);;
QDir dir=File.absoluteDir();
QString path=dir.absolutePath();
qDebug()<<"CachePlacemark: Path:"<<path;
if(!dir.exists())
{
qDebug()<<"CachePlacemark: Cache path doesn't exist, try to create";
if(!dir.mkpath(path))
{
qDebug()<<"CachePlacemark: Could not create path";
}
}
qDebug()<<"CachePlacemark: OpenFile:"<<filename;
QFile file(filename);
if (file.open(QIODevice::WriteOnly))
{
qDebug()<<"CachePlacemark: File Opened!!!:"<<filename;
QTextStream stream(&file);
stream.setCodec("UTF-8");
stream<<content;
}
}

View File

@ -0,0 +1,33 @@
#ifndef CACHE_H
#define CACHE_H
#include "pureimagecache.h"
class Cache
{
public:
static Cache* Instance();
PureImageCache ImageCache;
QString CacheLocation();
void setCacheLocation(const QString& value);
void CacheGeocoder(const QString &urlEnd,const QString &content);
QString GetGeocoderFromCache(const QString &urlEnd);
void CachePlacemark(const QString &urlEnd,const QString &content);
QString GetPlacemarkFromCache(const QString &urlEnd);
void CacheRoute(const QString &urlEnd,const QString &content);
QString GetRouteFromCache(const QString &urlEnd);
private:
Cache();
Cache(Cache const&){};
Cache& operator=(Cache const&){};
static Cache* m_pInstance;
QString cache;
QString routeCache;
QString geoCache;
QString placemarkCache;
};
#endif // CACHE_H

View File

@ -0,0 +1,49 @@
#include "cacheitemqueue.h"
CacheItemQueue::CacheItemQueue(const MapType::Types &Type, const Point &Pos, const QByteArray &Img, const int &Zoom)
{
type=Type;
pos=Pos;
img=Img;
zoom=Zoom;
}
QByteArray CacheItemQueue::GetImg()
{
return img;
}
MapType::Types CacheItemQueue::GetMapType()
{
return type;
}
Point CacheItemQueue::GetPosition()
{
return pos;
}
void CacheItemQueue::SetImg(const QByteArray &value)
{
img=value;
}
void CacheItemQueue::SetMapType(const MapType::Types &value)
{
type=value;
}
void CacheItemQueue::SetPosition(const Point &value)
{
pos=value;
}
CacheItemQueue& CacheItemQueue::operator =(const CacheItemQueue &cSource)
{
img=cSource.img;
pos=cSource.pos;
type=cSource.type;
zoom=cSource.zoom;
}
bool CacheItemQueue::operator ==(const CacheItemQueue &cSource)
{
bool b=(img==cSource.img)&& (pos==cSource.pos) && (type==cSource.type) && (zoom==cSource.zoom);
return b;
}

View File

@ -0,0 +1,40 @@
#ifndef CACHEITEMQUEUE_H
#define CACHEITEMQUEUE_H
#include "maptype.h"
#include "point.h"
#include <QByteArray>
class CacheItemQueue
{
public:
CacheItemQueue(const MapType::Types &Type,const Point &Pos,const QByteArray &Img,const int &Zoom);
CacheItemQueue(){};
CacheItemQueue(const CacheItemQueue &cSource)
{
img=cSource.img;
pos=cSource.pos;
type=cSource.type;
zoom=cSource.zoom;
}
CacheItemQueue& operator= (const CacheItemQueue &cSource);
bool operator== (const CacheItemQueue &cSource);
void SetMapType(const MapType::Types &value);
void SetPosition(const Point &value);
void SetImg(const QByteArray &value);
MapType::Types GetMapType();
Point GetPosition();
QByteArray GetImg();
int GetZoom(){return zoom;};
void SetZoom(const int &value) {zoom=value;};
private:
MapType::Types type;
Point pos;
QByteArray img;
int zoom;
};
#endif // CACHEITEMQUEUE_H

View File

@ -0,0 +1,5 @@
#include "core.h"
Core::Core()
{
}

View File

@ -0,0 +1,38 @@
include (../common.pri)
SOURCES += gmaps.cpp \
pureimagecache.cpp \
pureimage.cpp \
rawtile.cpp \
memorycache.cpp \
cache.cpp \
languagetype.cpp \
providerstrings.cpp \
cacheitemqueue.cpp \
tilecachequeue.cpp \
alllayersoftype.cpp \
urlfactory.cpp \
placemark.cpp \
threadpool.cpp \
point.cpp \
size.cpp \
kibertilecache.cpp
HEADERS += gmaps.h \
size.h \
maptype.h \
pureimagecache.h \
pureimage.h \
rawtile.h \
memorycache.h \
cache.h \
accessmode.h \
languagetype.h \
providerstrings.h \
cacheitemqueue.h \
tilecachequeue.h \
alllayersoftype.h \
urlfactory.h \
geodecoderstatus.h \
placemark.h \
threadpool.h \
point.h \
kibertilecache.h

View File

@ -0,0 +1,71 @@
#ifndef GEODECODERSTATUS_H
#define GEODECODERSTATUS_H
struct GeoCoderStatusCode
{
enum Types
{
/// <summary>
/// unknow response
/// </summary>
Unknow = -1,
/// <summary>
/// No errors occurred; the address was successfully parsed and its geocode has been returned.
/// </summary>
G_GEO_SUCCESS=200,
/// <summary>
/// A directions request could not be successfully parsed.
/// For example, the request may have been rejected if it contained more than the maximum number of waypoints allowed.
/// </summary>
G_GEO_BAD_REQUEST=400,
/// <summary>
/// A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.
/// </summary>
G_GEO_SERVER_ERROR=500,
/// <summary>
/// The HTTP q parameter was either missing or had no value.
/// For geocoding requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.
/// </summary>
G_GEO_MISSING_QUERY=601,
/// <summary>
/// Synonym for G_GEO_MISSING_QUERY.
/// </summary>
G_GEO_MISSING_ADDRESS=601,
/// <summary>
/// No corresponding geographic location could be found for the specified address.
/// This may be due to the fact that the address is relatively new, or it may be incorrect.
/// </summary>
G_GEO_UNKNOWN_ADDRESS=602,
/// <summary>
/// The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.
/// </summary>
G_GEO_UNAVAILABLE_ADDRESS=603,
/// <summary>
/// The GDirections object could not compute directions between the points mentioned in the query.
/// This is usually because there is no route available between the two points, or because we do not have data for routing in that region.
/// </summary>
G_GEO_UNKNOWN_DIRECTIONS=604,
/// <summary>
/// The given key is either invalid or does not match the domain for which it was given.
/// </summary>
G_GEO_BAD_KEY=610,
/// <summary>
/// The given key has gone over the requests limit in the 24 hour period or has submitted too many requests in too short a period of time.
/// If you're sending multiple requests in parallel or in a tight loop, use a timer or pause in your code to make sure you don't send the requests too quickly.
/// </summary>
G_GEO_TOO_MANY_QUERIES=620,
};
};
#endif // GEODECODERSTATUS_H

View File

@ -0,0 +1,184 @@
#include "gmaps.h"
GMaps* GMaps::m_pInstance=0;
GMaps* GMaps::Instance()
{
if(!m_pInstance)
m_pInstance=new GMaps;
return m_pInstance;
}
GMaps::GMaps():useMemoryCache(true),MaxZoom(19),RetryLoadTile(2)
{
accessmode=AccessMode::ServerOnly;
Language=LanguageType::PortuguesePortugal;
LanguageStr=LanguageType().toString(Language);
Cache::Instance()->ImageCache=PureImageCache();
}
GMaps::~GMaps()
{
//delete Proxy;
}
QByteArray GMaps::GetImageFrom(const MapType::Types &type,const Point &pos,const int &zoom)
{
qDebug()<<"Entered GetImageFrom";
QByteArray ret;
if(useMemoryCache)
{
qDebug()<<"Try Tile from memory:Size="<<TilesInMemory.MemoryCacheSize();
ret=GetTileFromMemoryCache(RawTile(type,pos,zoom));
}
if(ret.isEmpty())
{
qDebug()<<"Tile not in memory";
if(accessmode != (AccessMode::ServerOnly))
{
qDebug()<<"Try tile from DataBase";
ret=Cache::Instance()->ImageCache.GetImageFromCache(type,pos,zoom);
if(!ret.isEmpty())
{
qDebug()<<"Tile found in Database";
if(useMemoryCache)
{
qDebug()<<"Add Tile to memory";
AddTileToMemoryCache(RawTile(type,pos,zoom),ret);
}
return ret;
}
}
if(accessmode!=AccessMode::CacheOnly)
{
QNetworkReply *reply;
QNetworkRequest qheader;
QNetworkAccessManager network;
network.setProxy(Proxy);
qDebug()<<"Try Tile from the Internet";
QString url=MakeImageUrl(type,pos,zoom,LanguageStr);
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::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;
default:
break;
}
reply=network.get(qheader);
qDebug()<<"Starting get response ";//<<pos.X()+","+pos.Y();
QTime time;
time.start();
while( !(reply->isFinished() | time.elapsed()>(6*Timeout)) ){QCoreApplication::processEvents(QEventLoop::AllEvents);}
qDebug()<<"Finished?"<<reply->error()<<" abort?"<<(time.elapsed()>Timeout*6);
if( (reply->error()!=QNetworkReply::NoError) | (time.elapsed()>Timeout*6))
{
qDebug()<<"Request timed out ";//<<pos.x+","+pos.y;
return ret;
}
qDebug()<<"Response OK ";//<<pos.x+","+pos.y;
ret=reply->readAll();
reply->deleteLater();//TODO can't this be global??
if(ret.isEmpty())
{
qDebug()<<"Invalid Tile";
return ret;
}
qDebug()<<"Received Tile from the Internet";
if (useMemoryCache)
{
qDebug()<<"Add Tile to memory cache";
AddTileToMemoryCache(RawTile(type,pos,zoom),ret);
}
if(accessmode!=AccessMode::ServerOnly)
{
qDebug()<<"Add tile to DataBase";
CacheItemQueue item(type,pos,ret,zoom);
TileDBcacheQueue.EnqueueCacheTask(item);
}
}
}
qDebug()<<"Entered GetImageFrom";
return ret;
}
bool GMaps::ExportToGMDB(const QString &file)
{
return Cache::Instance()->ImageCache.ExportMapDataToDB(Cache::Instance()->ImageCache.GtileCache()+QDir::separator()+"Data.qmdb",file);
}
bool GMaps::ImportFromGMDB(const QString &file)
{
return Cache::Instance()->ImageCache.ExportMapDataToDB(file,Cache::Instance()->ImageCache.GtileCache()+QDir::separator()+"Data.qmdb");
}

View File

@ -0,0 +1,66 @@
#ifndef GMAPS_H
#define GMAPS_H
#include "memorycache.h"
#include "rawtile.h"
#include "cache.h"
#include "accessmode.h"
#include "languagetype.h"
#include "cacheitemqueue.h"
#include "tilecachequeue.h"
#include "pureimagecache.h"
#include "alllayersoftype.h"
#include "urlfactory.h"
//#include "point.h"
class GMaps: public MemoryCache,public AllLayersOfType,public UrlFactory
{
public:
~GMaps();
static GMaps* Instance();
bool ImportFromGMDB(const QString &file);
bool ExportToGMDB(const QString &file);
/// <summary>
/// timeout for map connections
/// </summary>
QByteArray GetImageFrom(const MapType::Types &type,const Point &pos,const int &zoom);
bool UseMemoryCache();//TODO
void setUseMemoryCache(const bool& value);//TODO
void setLanguage(const LanguageType::Types& language);//TODO
LanguageType::Types GetLanguage();//TODO
AccessMode GetAccessMode();
void setAccessMode(const AccessMode& mode);
int MaxZoom;
int RetryLoadTile;
private:
bool useMemoryCache;
LanguageType::Types Language;
AccessMode::Types accessmode;
// PureImageCache ImageCacheLocal;//TODO Criar acesso Get Set
TileCacheQueue TileDBcacheQueue;
GMaps();
GMaps(GMaps const&){};
GMaps& operator=(GMaps const&){};
static GMaps* m_pInstance;
protected:
// MemoryCache TilesInMemory;
};
#endif // GMAPS_H

View File

@ -0,0 +1,34 @@
#include "kibertilecache.h"
//TODO add readwrite lock
KiberTileCache::KiberTileCache()
{
memoryCacheSize = 0;
_MemoryCacheCapacity = 22;
}
void KiberTileCache::setMemoryCacheCapacity(const int &value)
{
kiberCacheLock.lockForWrite();
_MemoryCacheCapacity=value;
kiberCacheLock.unlock();
}
int KiberTileCache::MemoryCacheCapacity()
{
kiberCacheLock.lockForRead();
return _MemoryCacheCapacity;
kiberCacheLock.unlock();
}
void KiberTileCache::RemoveMemoryOverload()
{
while(memoryCacheSize>MemoryCacheCapacity())
{
if(cachequeue.count()>0 && list.count()>0)
{
RawTile first=list.dequeue();
memoryCacheSize-=cachequeue.value(first).length();
cachequeue.remove(first);
}
}
}

View File

@ -0,0 +1,33 @@
#ifndef KIBERTILECACHE_H
#define KIBERTILECACHE_H
#include <QPixmapCache>
#include "rawtile.h"
#include <QMutex>
#include <QReadWriteLock>
#include <QQueue>
class KiberTileCache
{
public:
KiberTileCache();
void setMemoryCacheCapacity(const int &value);
int MemoryCacheCapacity();
double MemoryCacheSize(){return memoryCacheSize/1048576.0;}
void RemoveMemoryOverload();
QReadWriteLock kiberCacheLock;
QHash <RawTile,QByteArray> cachequeue;
QQueue <RawTile> list;
long memoryCacheSize;
private:
int _MemoryCacheCapacity;
// QPixmapCache TilesInMemory;
};
#endif // KIBERTILECACHE_H

View File

@ -0,0 +1,71 @@
#include "languagetype.h"
LanguageType::LanguageType()
{
list
<<"ar"
<<"bg"
<<"bn"
<<"ca"
<<"cs"
<<"da"
<<"de"
<<"el"
<<"en"
<<"en-AU"
<<"en-GB"
<<"es"
<<"eu"
<<"fi"
<<"fil"
<<"fr"
<<"gl"
<<"gu"
<<"hi"
<<"hr"
<<"hu"
<<"id"
<<"it"
<<"iw"
<<"ja"
<<"kn"
<<"ko"
<<"lt"
<<"lv"
<<"ml"
<<"mr"
<<"nl"
<<"nn"
<<"no"
<<"or"
<<"pl"
<<"pt"
<<"pt-BR"
<<"pt-PT"
<<"rm"
<<"ro"
<<"ru"
<<"sk"
<<"sl"
<<"sr"
<<"sv"
<<"ta"
<<"te"
<<"th"
<<"tr"
<<"uk"
<<"vi"
<<"zh-CN"
<<"zh-TW";
}
QString LanguageType::toString(Types type)
{
return list[type];
}
LanguageType::~LanguageType()
{
list.clear();
}

View File

@ -0,0 +1,78 @@
#ifndef LANGUAGETYPE_H
#define LANGUAGETYPE_H
#include <QString>
#include <QStringList>
class LanguageType
{
public:
enum Types
{
Arabic,
Bulgarian,
Bengali,
Catalan,
Czech,
Danish,
German,
Greek,
English,
EnglishAustralian,
EnglishGreatBritain,
Spanish,
Basque,
Finnish,
Filipino,
French,
Galician,
Gujarati,
Hindi,
Croatian,
Hungarian,
Indonesian,
Italian,
Hebrew,
Japanese,
Kannada,
Korean,
Lithuanian,
Latvian,
Malayalam,
Marathi,
Dutch,
NorwegianNynorsk,
Norwegian,
Oriya,
Polish,
Portuguese,
PortugueseBrazil,
PortuguesePortugal,
Romansch,
Romanian,
Russian,
Slovak,
Slovenian,
Serbian,
Swedish,
Tamil,
Telugu,
Thai,
Turkish,
Ukrainian,
Vietnamese,
ChineseSimplified,
ChineseTraditional,
};
QString toString(Types type);
LanguageType();
~LanguageType();
private:
QStringList list;
};
#endif // LANGUAGETYPE_H

View File

@ -0,0 +1,69 @@
#ifndef MAPTYPE_H
#define MAPTYPE_H
struct MapType
{
enum Types
{
GoogleMap=1,
GoogleSatellite=4,
GoogleLabels=8,
GoogleTerrain=16,
GoogleHybrid=20,
GoogleMapChina=22,
GoogleSatelliteChina=24,
GoogleLabelsChina=26,
GoogleTerrainChina=28,
GoogleHybridChina=29,
OpenStreetMap=32,
OpenStreetOsm=33,
OpenStreetMapSurfer=34,
OpenStreetMapSurferTerrain=35,
YahooMap=64,
YahooSatellite=128,
YahooLabels=256,
YahooHybrid=333,
BingMap=444,
BingSatellite=555,
BingHybrid=666,
ArcGIS_Map=777,
ArcGIS_Satellite=788,
ArcGIS_ShadedRelief=799,
ArcGIS_Terrain=811,
// use these numbers to clean up old stuff
//ArcGIS_MapsLT_Map_Old= 877,
//ArcGIS_MapsLT_OrtoFoto_Old = 888,
//ArcGIS_MapsLT_Map_Labels_Old = 890,
//ArcGIS_MapsLT_Map_Hybrid_Old = 899,
//ArcGIS_MapsLT_Map=977,
//ArcGIS_MapsLT_OrtoFoto=988,
//ArcGIS_MapsLT_Map_Labels=990,
//ArcGIS_MapsLT_Map_Hybrid=999,
//ArcGIS_MapsLT_Map=978,
//ArcGIS_MapsLT_OrtoFoto=989,
//ArcGIS_MapsLT_Map_Labels=991,
//ArcGIS_MapsLT_Map_Hybrid=998,
ArcGIS_MapsLT_Map=1000,
ArcGIS_MapsLT_OrtoFoto=1001,
ArcGIS_MapsLT_Map_Labels=1002,
ArcGIS_MapsLT_Map_Hybrid=1003,
PergoTurkeyMap = 2001,
SigPacSpainMap = 3001,
GoogleMapKorea=4001,
GoogleSatelliteKorea=4002,
GoogleLabelsKorea=4003,
GoogleHybridKorea=4005,
YandexMapRu = 5000,
};
};
#endif // MAPTYPE_H

View File

@ -0,0 +1,28 @@
#include "memorycache.h"
//TODO add readwrite lock
MemoryCache::MemoryCache()
{
}
QByteArray MemoryCache::GetTileFromMemoryCache(const RawTile &tile)
{
kiberCacheLock.lockForRead();
QByteArray pic;
pic=TilesInMemory.cachequeue.value(tile);
// TilesInMemory.find(key,&pic);
kiberCacheLock.unlock();
return pic;
}
void MemoryCache::AddTileToMemoryCache(const RawTile &tile, const QByteArray &pic)
{
kiberCacheLock.lockForWrite();
// QPixmapCache::Key key=TilesInMemory.insert(pic);
TilesInMemory.memoryCacheSize +=pic.count();
TilesInMemory.cachequeue.insert(tile,pic);
TilesInMemory.list.enqueue(tile);
kiberCacheLock.unlock();
}

View File

@ -0,0 +1,23 @@
#ifndef MEMORYCACHE_H
#define MEMORYCACHE_H
#include <QPixmapCache>
#include "rawtile.h"
#include <QMutex>
#include <QReadWriteLock>
#include <QQueue>
#include "kibertilecache.h"
class MemoryCache
{
public:
MemoryCache();
KiberTileCache TilesInMemory;
QByteArray GetTileFromMemoryCache(const RawTile &tile);
void AddTileToMemoryCache(const RawTile &tile, const QByteArray &pic);
QReadWriteLock kiberCacheLock;
};
#endif // MEMORYCACHE_H

View File

@ -0,0 +1,2 @@
#include "placemark.h"

View File

@ -0,0 +1,25 @@
#ifndef PLACEMARK_H
#define PLACEMARK_H
#include <QString>
class Placemark
{
public:
Placemark(const QString &address)
{
this->address = address;
}
QString Address(){return address;}
int Accuracy(){return accuracy;}
void SetAddress(const QString &adr){address=adr;}
void SetAccuracy(const int &value){accuracy=value;}
private:
QString address;
int accuracy;
protected:
};
#endif // PLACEMARK_H

View File

@ -0,0 +1,42 @@
#include "point.h"
#include "size.h"
Point::Point(int dw)
{
this->x=(short)Point::LOWORD(dw);
this->y=(short)Point::HIWORD(dw);
}
Point::Point(Size sz)
{
this->x=sz.Width();
this->y=sz.Height();
}
Point::Point(int x, int y)
{
this->x=x;
this->y=y;
}
Point::Point():x(-1),y(-1)
{}
uint qHash(Point const& point)
{
return point.x^point.y;
}
bool operator==(Point const &lhs,Point const &rhs)
{
return (lhs.x==rhs.x && lhs.y==rhs.y);
}
bool operator!=(Point const &lhs,Point const &rhs)
{
return !(lhs==rhs);
}
int Point::HIWORD(int n)
{
return (n >> 16) & 0xffff;
}
int Point::LOWORD(int n)
{
return n & 0xffff;
}
Point Point::Empty=Point();

View File

@ -0,0 +1,46 @@
#ifndef POINT_H
#define POINT_H
#include "QString"
//#include "size.h"
struct Size;
struct Point
{
friend uint qHash(Point const& point);
friend bool operator==(Point const& lhs,Point const& rhs);
friend bool operator!=(Point const& lhs,Point const& rhs);
public:
Point();
Point(int x,int y);
Point(Size sz);
Point(int dw);
bool IsEmpty(){return (x==-1 && y==-1);}
int X()const{return this->x;}
int Y()const{return this->y;}
void SetX(const int &value){x=value;}
void SetY(const int &value){y=value;}
QString ToString()const{return "{"+QString::number(x)+","+QString::number(y)+"}";}
static Point Empty;
void Offset(const int &dx,const int &dy)
{
x += dx;
y += dy;
}
void Offset(Point p)
{
Offset(p.x, p.y);
}
static int HIWORD(int n);
static int LOWORD(int n);
private:
int x;
int y;
};
#endif // POINT_H

View File

@ -0,0 +1,53 @@
#include "providerstrings.h"
const QString ProviderStrings::levelsForSigPacSpainMap[] = {"0", "1", "2", "3", "4",
"MTNSIGPAC",
"MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000",
"MTN200", "MTN200", "MTN200",
"MTN25", "MTN25",
"ORTOFOTOS","ORTOFOTOS","ORTOFOTOS","ORTOFOTOS"};
ProviderStrings::ProviderStrings()
{
// Google version strings
VersionGoogleMap = "m@123";
VersionGoogleSatellite = "59";
VersionGoogleLabels = "h@123";
VersionGoogleTerrain = "t@108,r@123";
SecGoogleWord = "Galileo";
// Google (China) version strings
VersionGoogleMapChina = "m@123";
VersionGoogleSatelliteChina = "s@59";
VersionGoogleLabelsChina = "h@123";
VersionGoogleTerrainChina = "t@108,r@123";
// Google (Korea) version strings
VersionGoogleMapKorea = "kr1.12";
VersionGoogleSatelliteKorea = "59";
VersionGoogleLabelsKorea = "kr1t.12";
/// <summary>
/// Google Maps API generated using http://greatmaps.codeplex.com/
/// from http://code.google.com/intl/en-us/apis/maps/signup.html
/// </summary>
GoogleMapsAPIKey = "ABQIAAAAWaQgWiEBF3lW97ifKnAczhRAzBk5Igf8Z5n2W3hNnMT0j2TikxTLtVIGU7hCLLHMAuAMt-BO5UrEWA";
// Yahoo version strings
VersionYahooMap = "4.3";
VersionYahooSatellite = "1.9";
VersionYahooLabels = "4.3";
// BingMaps
VersionBingMaps = "452";
// YandexMap
VersionYandexMap = "2.10.2";
/// <summary>
/// Bing Maps Customer Identification, more info here
/// http://msdn.microsoft.com/en-us/library/bb924353.aspx
/// </summary>
BingMapsClientToken = "";
}

View File

@ -0,0 +1,56 @@
#ifndef PROVIDERSTRINGS_H
#define PROVIDERSTRINGS_H
#include <QString>
class ProviderStrings
{
public:
ProviderStrings();
static const QString levelsForSigPacSpainMap[];
QString GoogleMapsAPIKey;
// Google version strings
QString VersionGoogleMap;
QString VersionGoogleSatellite;
QString VersionGoogleLabels;
QString VersionGoogleTerrain;
QString SecGoogleWord;
// Google (China) version strings
QString VersionGoogleMapChina;
QString VersionGoogleSatelliteChina;
QString VersionGoogleLabelsChina;
QString VersionGoogleTerrainChina;
// Google (Korea) version strings
QString VersionGoogleMapKorea;
QString VersionGoogleSatelliteKorea;
QString VersionGoogleLabelsKorea;
/// <summary>
/// Google Maps API generated using http://greatmaps.codeplex.com/
/// from http://code.google.com/intl/en-us/apis/maps/signup.html
/// </summary>
// Yahoo version strings
QString VersionYahooMap;
QString VersionYahooSatellite;
QString VersionYahooLabels;
// BingMaps
QString VersionBingMaps;
// YandexMap
QString VersionYandexMap;
/// <summary>
/// Bing Maps Customer Identification, more info here
/// http://msdn.microsoft.com/en-us/library/bb924353.aspx
/// </summary>
QString BingMapsClientToken;
};
#endif // PROVIDERSTRINGS_H

View File

@ -0,0 +1,17 @@
#include "pureimage.h"
PureImageProxy::PureImageProxy()
{
}
QPixmap PureImageProxy::FromStream(const QByteArray &array)
{
return QPixmap::fromImage(QImage::fromData(array));
}
bool PureImageProxy::Save(const QByteArray &array, QPixmap &pic)
{
pic=QPixmap::fromImage(QImage::fromData(array));
return true;
}

View File

@ -0,0 +1,15 @@
#ifndef PUREIMAGE_H
#define PUREIMAGE_H
#include <QPixmap>
#include <QByteArray>
class PureImageProxy
{
public:
PureImageProxy();
static QPixmap FromStream(const QByteArray &array);
static bool Save(const QByteArray &array,QPixmap &pic);
};
#endif // PUREIMAGE_H

View File

@ -0,0 +1,245 @@
#include "pureimagecache.h"
PureImageCache::PureImageCache()
{
gtilecache=QDir::currentPath()+QDir::separator()+"mapscache"+QDir::separator();
}
void PureImageCache::setGtileCache(const QString &value)
{
gtilecache=value;
}
QString PureImageCache::GtileCache()
{
return gtilecache;
}
bool PureImageCache::CreateEmptyDB(const QString &file)
{
qDebug()<<"Create database at:"<<file;
bool ret=true;
QFileInfo File(file);
QDir dir=File.absoluteDir();
QString path=dir.absolutePath();
QString filename=File.fileName();
if(!dir.exists())
{
qDebug()<<"CreateEmptyDB: Cache path doesn't exist, try to create";
if(!dir.mkpath(path))
{
qDebug()<<"CreateEmptyDB: Could not create path";
return false;
}
}
QSqlDatabase db;
db = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("MapsConnection"));
db.setDatabaseName(file);
if (!db.open())
{
qDebug()<<"CreateEmptyDB: Unable to create database";
return false;
}
QSqlQuery query(db);
query.exec("CREATE TABLE IF NOT EXISTS Tiles (id INTEGER NOT NULL PRIMARY KEY, X INTEGER NOT NULL, Y INTEGER NOT NULL, Zoom INTEGER NOT NULL, Type INTEGER NOT NULL)");
if(query.numRowsAffected()==-1)
{
qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
db.close();
return false;
}
query.exec("CREATE TABLE IF NOT EXISTS TilesData (id INTEGER NOT NULL PRIMARY KEY CONSTRAINT fk_Tiles_id REFERENCES Tiles(id) ON DELETE CASCADE, Tile BLOB NULL)");
if(query.numRowsAffected()==-1)
{
qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
db.close();
return false;
}
query.exec(
"CREATE TRIGGER fki_TilesData_id_Tiles_id "
"BEFORE INSERT ON [TilesData] "
"FOR EACH ROW BEGIN "
"SELECT RAISE(ROLLBACK, 'insert on table TilesData violates foreign key constraint fki_TilesData_id_Tiles_id') "
"WHERE (SELECT id FROM Tiles WHERE id = NEW.id) IS NULL; "
"END");
if(query.numRowsAffected()==-1)
{
qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
db.close();
return false;
}
query.exec(
"CREATE TRIGGER fku_TilesData_id_Tiles_id "
"BEFORE UPDATE ON [TilesData] "
"FOR EACH ROW BEGIN "
"SELECT RAISE(ROLLBACK, 'update on table TilesData violates foreign key constraint fku_TilesData_id_Tiles_id') "
"WHERE (SELECT id FROM Tiles WHERE id = NEW.id) IS NULL; "
"END");
if(query.numRowsAffected()==-1)
{
qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
db.close();
return false;
}
query.exec(
"CREATE TRIGGER fkdc_TilesData_id_Tiles_id "
"BEFORE DELETE ON Tiles "
"FOR EACH ROW BEGIN "
"DELETE FROM TilesData WHERE TilesData.id = OLD.id; "
"END");
if(query.numRowsAffected()==-1)
{
qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
db.close();
return false;
}
db.close();
return true;
}
bool PureImageCache::PutImageToCache(const QByteArray &tile, const MapType::Types &type,const Point &pos,const int &zoom) const
{
qDebug()<<"PutImageToCache Start:";//<<pos;
bool ret=true;
QDir d;
QString dir=gtilecache;
qDebug()<<"PutImageToCache Cache dir="<<dir;
qDebug()<<"PutImageToCache Cache dir="<<dir<<" Try to PUT:";//<<pos;
if(!d.exists(dir))
{
d.mkdir(dir);
qDebug()<<"Create Cache directory";
}
{
QString db=dir+"Data.qmdb";
if(!QFileInfo(db).exists())
{
qDebug()<<"Try to create EmptyDB";
ret=CreateEmptyDB(db);
}
if(ret)
{
QSqlDatabase cn;
if (QSqlDatabase::contains(QLatin1String("MapsConnection")))
cn = QSqlDatabase::database(QLatin1String("MapsConnection"));
else
cn = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("MapsConnection"));
cn.setDatabaseName(db);
if(cn.open())
{
{
QSqlQuery query(cn);
query.prepare("INSERT INTO Tiles(X, Y, Zoom, Type) VALUES(?, ?, ?, ?)");
query.addBindValue(pos.X());
query.addBindValue(pos.Y());
query.addBindValue(zoom);
query.addBindValue((int)type);
query.exec();
}
{
QSqlQuery query(cn);
query.prepare("INSERT INTO TilesData(id, Tile) VALUES((SELECT last_insert_rowid()), ?)");
query.addBindValue(tile);
query.exec();
}
cn.close();
}
else return false;
}
else
{
qDebug()<<"PutImageToCache Could not create DB";
return false;
}
}
return true;
}
QByteArray PureImageCache::GetImageFromCache(MapType::Types type, Point pos, int zoom)
{
bool ret=true;
QByteArray ar;
QString dir=gtilecache;
qDebug()<<"Cache dir="<<dir<<" Try to GET:"<<pos.X()+","+pos.Y();
{
QString db=dir+"Data.qmdb";
ret=QFileInfo(db).exists();
if(ret)
{
QSqlDatabase cn;
if (QSqlDatabase::contains(QLatin1String("MapsConnection")))
cn = QSqlDatabase::database(QLatin1String("MapsConnection"));
else
cn = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("MapsConnection"));
cn.setDatabaseName(db);
if(cn.open())
{
{
QSqlQuery query(cn);
query.exec(QString("SELECT Tile FROM TilesData WHERE id = (SELECT id FROM Tiles WHERE X=%1 AND Y=%2 AND Zoom=%3 AND Type=%4)").arg(pos.X()).arg(pos.Y()).arg(zoom).arg((int) type));
query.next();
ar=query.value(0).toByteArray();
}
cn.close();
}
}
}
return ar;
}
// PureImageCache::ExportMapDataToDB("C:/Users/Xapo/Documents/mapcontrol/debug/mapscache/data.qmdb","C:/Users/Xapo/Documents/mapcontrol/debug/mapscache/data2.qmdb");
bool PureImageCache::ExportMapDataToDB(QString sourceFile, QString destFile)
{
bool ret=true;
QList<long> add;
if(!QFileInfo(destFile).exists())
{
qDebug()<<"Try to create EmptyDB";
ret=CreateEmptyDB(destFile);
}
if(!ret) return false;
QSqlDatabase ca = QSqlDatabase::addDatabase("QSQLITE","ca");
ca.setDatabaseName(sourceFile);
if(ca.open())
{
QSqlDatabase cb = QSqlDatabase::addDatabase("QSQLITE","cb");
cb.setDatabaseName(destFile);
if(cb.open())
{
QSqlQuery queryb(cb);
queryb.exec(QString("ATTACH DATABASE \"%1\" AS Source").arg(sourceFile));
QSqlQuery querya(ca);
querya.exec("SELECT id, X, Y, Zoom, Type FROM Tiles");
while(querya.next())
{
long id=querya.value(0).toLongLong();
queryb.exec(QString("SELECT id FROM Tiles WHERE X=%1 AND Y=%2 AND Zoom=%3 AND Type=%4;").arg(querya.value(1).toLongLong()).arg(querya.value(2).toLongLong()).arg(querya.value(3).toLongLong()).arg(querya.value(4).toLongLong()));
if(!queryb.next())
{
add.append(id);
}
}
long f;
foreach(f,add)
{
queryb.exec(QString("INSERT INTO Tiles(X, Y, Zoom, Type) SELECT X, Y, Zoom, Type FROM Source.Tiles WHERE id=%1").arg(f));
queryb.exec(QString("INSERT INTO TilesData(id, Tile) Values((SELECT last_insert_rowid()), (SELECT Tile FROM Source.TilesData WHERE id=%1))").arg(f));
}
add.clear();
ca.close();
cb.close();
}
else return false;
}
else return false;
return true;
}

View File

@ -0,0 +1,32 @@
#ifndef PUREIMAGECACHE_H
#define PUREIMAGECACHE_H
#include <QSqlDatabase>
#include <QString>
#include <QDir>
#include <QDebug>
#include <QFileInfo>
#include <QSqlQuery>
#include <QSqlError>
#include <QBuffer>
#include "maptype.h"
#include "point.h"
#include <QVariant>
#include "pureimage.h"
#include <QList>
class PureImageCache
{
public:
PureImageCache();
static bool CreateEmptyDB(const QString &file);
bool PutImageToCache(const QByteArray &tile,const MapType::Types &type,const Point &pos, const int &zoom) const;
QByteArray GetImageFromCache(MapType::Types type, Point pos, int zoom);
QString GtileCache();
void setGtileCache(const QString &value);
static bool ExportMapDataToDB(QString sourceFile, QString destFile);
private:
QString gtilecache;
};
#endif // PUREIMAGECACHE_H

View File

@ -0,0 +1,47 @@
#include "rawtile.h"
RawTile::RawTile(const MapType::Types &Type, const Point &Pos, const int &Zoom)
{
zoom=Zoom;
type=Type;
pos=Pos;
}
QString RawTile::ToString()
{
return QString("%1 at zoom %2, pos:%3,%4").arg(type).arg(zoom).arg(pos.X()).arg(pos.Y());
}
Point RawTile::Pos()
{
return pos;
}
MapType::Types RawTile::Type()
{
return type;
}
int RawTile::Zoom()
{
return zoom;
}
void RawTile::setType(const MapType::Types &value)
{
type=value;
}
void RawTile::setPos(const Point &value)
{
pos=value;
}
void RawTile::setZoom(const int &value)
{
zoom=value;
}
uint qHash(RawTile const& tile)
{
// RawTile tile=tilee;
quint64 tmp=(((quint64)(tile.zoom))<<54)+(((int)(tile.type))<<36)+(((quint64)(tile.pos.X()))<<18)+(((quint64)(tile.pos.Y())));
// quint64 tmp5=tmp+tmp2+tmp3+tmp4;
return ::qHash(tmp);
}
bool operator==(RawTile const &lhs,RawTile const &rhs)
{
return (lhs.pos==rhs.pos && lhs.zoom==rhs.zoom && lhs.type==rhs.type);
}

View File

@ -0,0 +1,30 @@
#ifndef RAWTILE_H
#define RAWTILE_H
#include "maptype.h"
#include "point.h"
#include <QString>
#include <QHash>
class RawTile
{
friend uint qHash(RawTile const& tile);
friend bool operator==(RawTile const& lhs,RawTile const& rhs);
public:
RawTile(const MapType::Types &Type,const Point &Pos,const int &Zoom);
QString ToString(void);
MapType::Types Type();
Point Pos();
int Zoom();
void setType(const MapType::Types &value);
void setPos(const Point &value);
void setZoom(const int &value);
private:
MapType::Types type;
Point pos;
int zoom;
};
//uint qHash(RawTile const& tile);
//bool operator==(RawTile const& lhs,RawTile const& rhs);
#endif // RAWTILE_H

View File

@ -0,0 +1,4 @@
#include "size.h"
Size::Size():width(0),height(0)
{}

View File

@ -0,0 +1,33 @@
#ifndef SIZE_H
#define SIZE_H
#include "point.h"
#include <QString>
#include <QHash>
struct Size
{
public:
Size();
Size(Point pt){width=pt.X(); height=pt.Y();};
Size(int Width,int Height){width=Width; height=Height;};
friend uint qHash(Size const& size);
// friend bool operator==(Size const& lhs,Size const& rhs);
Size operator-(const Size &sz1){return Size(width-sz1.width,height-sz1.height);}
Size operator+(const Size &sz1){return Size(sz1.width+width,sz1.height+height);}
int GetHashCode(){return width^height;}
uint qHash(Size const& rect){return width^height;}
QString ToString(){return "With="+QString::number(width)+" ,Height="+QString::number(height);}
int Width()const {return width;}
int Height()const {return height;}
void SetWidth(int const& value){width=value;}
void SetHeight(int const& value){height=value;}
private:
int width;
int height;
Point p;
};
//bool operator==(Size const& lhs,Size const& rhs){return (lhs.width==rhs.width && lhs.height==rhs.height);}
#endif // SIZE_H

View File

@ -0,0 +1,39 @@
#include "threadpool.h"
threadpool::threadpool()
{
// m.lock();
threadpool::count=0;
mm.lock();
count2=0;
mm.unlock();
// qDebug()<<"Thread constructor";
// m.unlock();
}
void threadpool::run()
{
mm.lock();
++count2;
int countt=count2;
mm.unlock();
QByteArray tmp;
QImage im;
qDebug()<<"Thread start";
tmp=GMaps::Instance()->GetImageFrom(MapType::GoogleMap,Point(1,0),2);
// im.load("C:/Users/Xapo/Pictures/x.jpg");
//tmp=QPixmap::fromImage(im);
// qDebug()<<"WWWWWWWW="<<im.width();
mm.lock();
pix.append(tmp);
// ++threadpool::count;
mm.unlock();
}
QByteArray threadpool::GetPic(int i)
{
m.lock();
QByteArray p=pix.last();
m.unlock();
return p;
}

View File

@ -0,0 +1,28 @@
#ifndef THREADPOOL_H
#define THREADPOOL_H
#include "QThreadPool"
#include <QDebug>
#include "gmaps.h"
#include <QList>
class threadpool: public QRunnable
{
public:
threadpool();
QList <QByteArray> pix;
QByteArray GetPic(int i);
int count;
int count2;
QMutex m;
private:
void run();
QMutex mm;
QPixmap temp;
};
#endif // THREADPOOL_H

View File

@ -0,0 +1,64 @@
#include "tilecachequeue.h"
TileCacheQueue::TileCacheQueue()
{
}
void TileCacheQueue::EnqueueCacheTask(CacheItemQueue &task)
{
qDebug()<<"DB Do I EnqueueCacheTask"<<task.GetPosition().X()<<","<<task.GetPosition().Y();
if(!tileCacheQueue.contains(task))
{
qDebug()<<"EnqueueCacheTask"<<task.GetPosition().X()<<","<<task.GetPosition().Y();
mutex.lock();
tileCacheQueue.enqueue(task);
mutex.unlock();
if(this->isRunning())
{
qDebug()<<"Wake Thread";
wait.wakeOne();
}
else
{
qDebug()<<"Start Thread";
this->start(QThread::LowestPriority);
}
}
}
void TileCacheQueue::run()
{
qDebug()<<"Cache Engine Start";
while(true)
{
CacheItemQueue task;
qDebug()<<"Cache";
if(tileCacheQueue.count()>0)
{
mutex.lock();
task=tileCacheQueue.dequeue();
mutex.unlock();
qDebug()<<"Cache engine Put:"<<task.GetPosition().X()<<","<<task.GetPosition().Y();
Cache::Instance()->ImageCache.PutImageToCache(task.GetImg(),task.GetMapType(),task.GetPosition(),task.GetZoom());
QThread::usleep(44);
}
else
{
waitmutex.lock();
if(!wait.wait(&waitmutex,4444))
{
qDebug()<<"Cache Engine TimeOut";
if(tileCacheQueue.count()==0) break;
}
waitmutex.unlock();
}
}
qDebug()<<"Cache Engine Stopped";
}

View File

@ -0,0 +1,35 @@
#ifndef TILECACHEQUEUE_H
#define TILECACHEQUEUE_H
#include <QQueue>
#include "cacheitemqueue.h"
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QObject>
#include <QMutexLocker>
#include "pureimagecache.h"
#include "cache.h"
class TileCacheQueue:public QThread
{
Q_OBJECT
public:
TileCacheQueue();
void EnqueueCacheTask(CacheItemQueue &task);
protected:
QQueue<CacheItemQueue> tileCacheQueue;
private:
void run();
QMutex mutex;
QMutex waitmutex;
QWaitCondition wait;
};
#endif // TILECACHEQUEUE_H

View File

@ -0,0 +1,676 @@
#include "urlfactory.h"
UrlFactory::UrlFactory()
{
/// <summary>
/// timeout for map connections
/// </summary>
Proxy.setType(QNetworkProxy::NoProxy);
/// <summary>
/// Gets or sets the value of the User-agent HTTP header.
/// </summary>
UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7";
Timeout = 30 * 1000;
CorrectGoogleVersions=true;
isCorrectedGoogleVersions = false;
UseGeocoderCache=true;
UsePlacemarkCache=true;
// timer.setSingleShot(true);
}
UrlFactory::~UrlFactory()
{
}
QString UrlFactory::TileXYToQuadKey(const int &tileX,const int &tileY,const int &levelOfDetail) const
{
QString quadKey;
for(int i = levelOfDetail; i > 0; i--)
{
char digit = '0';
int mask = 1 << (i - 1);
if((tileX & mask) != 0)
{
digit++;
}
if((tileY & mask) != 0)
{
digit++;
digit++;
}
quadKey.append(digit);
}
return quadKey;
}
int UrlFactory::GetServerNum(const Point &pos,const int &max) const
{
return (pos.X() + 2 * pos.Y()) % max;
}
void UrlFactory::setIsCorrectGoogleVersions(bool value)
{
isCorrectedGoogleVersions=value;
}
bool UrlFactory::IsCorrectGoogleVersions()
{
return isCorrectedGoogleVersions;
}
void UrlFactory::TryCorrectGoogleVersions()
{
if(CorrectGoogleVersions && !IsCorrectGoogleVersions())
{
QNetworkReply *reply;
QNetworkRequest qheader;
QNetworkAccessManager network;
network.setProxy(Proxy);
qDebug()<<"Correct GoogleVersion";
setIsCorrectGoogleVersions(true);
QString url = "http://maps.google.com";
qheader.setUrl(QUrl(url));
qheader.setRawHeader("User-Agent",UserAgent);
reply=network.get(qheader);
QTime time;
time.start();
while( !(reply->isFinished() | time.elapsed()>(6*Timeout)) ){QCoreApplication::processEvents(QEventLoop::AllEvents);}
qDebug()<<"Finished?"<<reply->error()<<" abort?"<<(time.elapsed()>Timeout*6);
if( (reply->error()!=QNetworkReply::NoError) | (time.elapsed()>Timeout*6))
{
qDebug()<<"Try corrected version network error:";
return;
}
{
qDebug()<<"Try corrected version withou abort or error:"<<reply->errorString();
QString html=QString(reply->readAll());
// find it
// apiCallback(["http://mt0.google.com/vt/v\x3dw2.106\x26hl\x3dlt\x26","http://mt1.google.com/vt/v\x3dw2.106\x26hl\x3dlt\x26","http://mt2.google.com/vt/v\x3dw2.106\x26hl\x3dlt\x26","http://mt3.google.com/vt/v\x3dw2.106\x26hl\x3dlt\x26"],
// ["http://khm0.google.com/kh/v\x3d45\x26","http://khm1.google.com/kh/v\x3d45\x26","http://khm2.google.com/kh/v\x3d45\x26","http://khm3.google.com/kh/v\x3d45\x26"],
// ["http://mt0.google.com/vt/v\x3dw2t.106\x26hl\x3dlt\x26","http://mt1.google.com/vt/v\x3dw2t.106\x26hl\x3dlt\x26","http://mt2.google.com/vt/v\x3dw2t.106\x26hl\x3dlt\x26","http://mt3.google.com/vt/v\x3dw2t.106\x26hl\x3dlt\x26"],
// "","","",false,"G",opts,["http://mt0.google.com/vt/v\x3dw2p.106\x26hl\x3dlt\x26","http://mt1.google.com/vt/v\x3dw2p.106\x26hl\x3dlt\x26","http://mt2.google.com/vt/v\x3dw2p.106\x26hl\x3dlt\x26","http://mt3.google.com/vt/v\x3dw2p.106\x26hl\x3dlt\x26"],jslinker,pageArgs);
int id = html.lastIndexOf("apiCallback([");
if(id > 0)
{
int idEnd = html.indexOf("jslinker,pageArgs", id);
if(idEnd > id)
{
QString api = html.mid(id, idEnd - id);
if(!(api.isNull()|api.isEmpty()))
{
int i = 0;
QStringList opts = api.split("["); //"[\""
QString opt;
foreach( opt ,opts)
{
if(opt.contains("http://"))
{
int start = opt.indexOf("x3d");
if(start > 0)
{
int end = opt.indexOf("\\x26", start);
if(end > start)
{
start += 3;
QString u = opt.mid(start, end - start);
if(i == 0)
{
if(u.startsWith("m@"))
{
qDebug()<<("TryCorrectGoogleVersions[map]: " + u);
VersionGoogleMap = u;
}
else
{
qDebug()<<("TryCorrectGoogleVersions[map FAILED]: " + u);
}
}
else
if(i == 1)
{
// 45
if(u[0].isDigit())
{
qDebug()<<("TryCorrectGoogleVersions[satelite]: " + u);
VersionGoogleSatellite = u;
}
else
{
qDebug()<<("TryCorrectGoogleVersions[satelite FAILED]: " + u);
}
}
else
if(i == 2)
{
if(u.startsWith("h@"))
{
qDebug()<<("TryCorrectGoogleVersions[labels]: " + u);
VersionGoogleLabels = u;
}
else
{
qDebug()<<("TryCorrectGoogleVersions[labels FAILED]: " + u);
}
}
else
if(i == 3)
{
// t@108,r@120
if(u.startsWith("t@"))
{
qDebug()<<("TryCorrectGoogleVersions[terrain]: " + u);
VersionGoogleTerrain = u;
VersionGoogleTerrainChina = u;
}
else
{
qDebug()<<("TryCorrectGoogleVersions[terrain FAILED]: " + u);
}
break;
}
i++;
}
}
}
}
}
}
}
}
reply->deleteLater();
}
}
QString UrlFactory::MakeImageUrl(const MapType::Types &type,const Point &pos,const int &zoom,const QString &language)
{
qDebug()<<"Entered MakeImageUrl";
switch(type)
{
case MapType::GoogleMap:
{
QString server = "mt";
QString request = "vt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
TryCorrectGoogleVersions();
return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMap).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleSatellite:
{
QString server = "khm";
QString request = "kh";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
TryCorrectGoogleVersions();
return QString("http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatellite).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleLabels:
{
QString server = "mt";
QString request = "vt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
TryCorrectGoogleVersions();
return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabels).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleTerrain:
{
QString server = "mt";
QString request = "vt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
TryCorrectGoogleVersions();
return QString("http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleTerrain).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleMapChina:
{
QString server = "mt";
QString request = "vt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
TryCorrectGoogleVersions();
// http://mt0.google.cn/vt/v=w2.101&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga
return QString("http://%1%2.google.cn/%3/lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMapChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleSatelliteChina:
{
QString server = "mt";
QString request = "vt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
// TryCorrectGoogleVersions();
// http://khm0.google.cn/kh/v=46&x=12&y=6&z=4&s=Ga
return QString("http://%1%2.google.cn/%3/lyrs=%4&gl=cn&x=%5%6&y=%7&z=%8&s=%9").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatelliteChina).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleLabelsChina:
{
QString server = "mt";
QString request = "vt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
TryCorrectGoogleVersions();
// http://mt0.google.cn/vt/v=w2t.110&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga
return QString("http://%1%2.google.cn/%3/imgtp=png32&lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabelsChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleTerrainChina:
{
QString server = "mt";
QString request = "vt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
TryCorrectGoogleVersions();
// http://mt0.google.cn/vt/v=w2p.110&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga
return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleTerrainChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleMapKorea:
{
QString server = "mt";
QString request = "mt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
//http://mt3.gmaptiles.co.kr/mt/v=kr1.11&hl=lt&x=109&y=49&z=7&s=
QString ret = QString("http://%1%2.gmaptiles.co.kr/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMapKorea).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
return ret;
}
break;
case MapType::GoogleSatelliteKorea:
{
QString server = "khm";
QString request = "kh";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
// http://khm1.google.co.kr/kh/v=54&x=109&y=49&z=7&s=
return QString("http://%1%2.google.co.kr/%3/v=%4&x=%5%6&y=%7&z=%8&s=%9").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatelliteKorea).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::GoogleLabelsKorea:
{
QString server = "mt";
QString request = "mt";
QString sec1 = ""; // after &x=...
QString sec2 = ""; // after &zoom=...
GetSecGoogleWords(pos, sec1, sec2);
// http://mt1.gmaptiles.co.kr/mt/v=kr1t.11&hl=lt&x=109&y=50&z=7&s=G
return QString("http://%1%2.gmaptiles.co.kr/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabelsKorea).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2);
}
break;
case MapType::YahooMap:
{
return QString("http://maps%1.yimg.com/hx/tl?v=%2&.intl=%3&x=%4&y=%5&z=%6&r=1").arg(((GetServerNum(pos, 2)) + 1)).arg(VersionYahooMap).arg(language).arg(pos.X()).arg((((1 << zoom) >> 1) - 1 - pos.Y())).arg((zoom + 1));
}
case MapType::YahooSatellite:
{
return QString("http://maps%1.yimg.com/ae/ximg?v=%2&t=a&s=256&.intl=%3&x=%4&y=%5&z=%6&r=1").arg("3").arg(VersionYahooSatellite).arg(language).arg(pos.X()).arg(((1 << zoom) >> 1) - 1 - pos.Y()).arg(zoom + 1);
}
break;
case MapType::YahooLabels:
{
return QString("http://maps%1.yimg.com/hx/tl?v=%2&t=h&.intl=%3&x=%4&y=%5&z=%6&r=1").arg("1").arg(VersionYahooLabels).arg(language).arg(pos.X()).arg(((1 << zoom) >> 1) - 1 - pos.Y()).arg(zoom + 1);
}
break;
case MapType::OpenStreetMap:
{
char letter= "abc"[GetServerNum(pos, 3)];
return QString("http://%1.tile.openstreetmap.org/%2/%3/%4.png").arg(letter).arg(zoom).arg(pos.X()).arg(pos.Y());
}
break;
case MapType::OpenStreetOsm:
{
char letter = "abc"[GetServerNum(pos, 3)];
return QString("http://%1.tah.openstreetmap.org/Tiles/tile/%2/%3/%4.png").arg(letter).arg(zoom).arg(pos.X()).arg(pos.Y());
}
break;
case MapType::OpenStreetMapSurfer:
{
// http://tiles1.mapsurfer.net/tms_r.ashx?x=37378&y=20826&z=16
return QString("http://tiles1.mapsurfer.net/tms_r.ashx?x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom);
}
break;
case MapType::OpenStreetMapSurferTerrain:
{
// http://tiles2.mapsurfer.net/tms_t.ashx?x=9346&y=5209&z=14
return QString("http://tiles2.mapsurfer.net/tms_t.ashx?x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom);
}
break;
case MapType::BingMap:
{
QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom);
return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/r%2.png?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString(""));
}
break;
case MapType::BingSatellite:
{
QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom);
return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/a%2.jpeg?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString(""));
}
break;
case MapType::BingHybrid:
{
QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom);
return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/h%2.jpeg?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString(""));
}
case MapType::ArcGIS_Map:
{
// http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/tile/0/0/0.jpg
return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X());
}
break;
case MapType::ArcGIS_Satellite:
{
// http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer/tile/1/0/1.jpg
return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X());
}
break;
case MapType::ArcGIS_ShadedRelief:
{
// http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_ShadedRelief_World_2D/MapServer/tile/1/0/1.jpg
return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_ShadedRelief_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X());
}
break;
case MapType::ArcGIS_Terrain:
{
// http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer/tile/4/3/15
return QString("http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X());
}
break;
case MapType::ArcGIS_MapsLT_OrtoFoto:
{
// http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L02/R0000001b/C00000028.jpg
// http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/0/9/13
// return string.Format("http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L{0:00}/R{1:x8}/C{2:x8}.jpg", zoom, pos.Y(), pos.X());
// http://dc1.maps.lt/cache/mapslt_ortofoto_512/map/_alllayers/L03/R0000001c/C00000029.jpg
// return string.Format("http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/{0}/{1}/{2}", zoom, pos.Y(), pos.X());
// http://dc1.maps.lt/cache/mapslt_ortofoto_512/map/_alllayers/L03/R0000001d/C0000002a.jpg
//TODO verificar
return QString("http://dc1.maps.lt/cache/mapslt_ortofoto/map/_alllayers/L%1/R%2/C%3.jpg").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0');
}
break;
case MapType::ArcGIS_MapsLT_Map:
{
// http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L02/R0000001b/C00000028.jpg
// http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/0/9/13
// return string.Format("http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L{0:00}/R{1:x8}/C{2:x8}.jpg", zoom, pos.Y(), pos.X());
// http://arcgis.maps.lt/ArcGIS/rest/services/mapslt/MapServer/tile/7/1162/1684.png
// http://dc1.maps.lt/cache/mapslt_512/map/_alllayers/L03/R0000001b/C00000029.png
//TODO verificar
// http://dc1.maps.lt/cache/mapslt/map/_alllayers/L02/R0000001c/C00000029.png
return QString("http://dc1.maps.lt/cache/mapslt/map/_alllayers/L%1/R%2/C%3.png").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0');
}
break;
case MapType::ArcGIS_MapsLT_Map_Labels:
{
//http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto_overlay/MapServer/tile/0/9/13
//return string.Format("http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto_overlay/MapServer/tile/{0}/{1}/{2}", zoom, pos.Y(), pos.X());
//http://dc1.maps.lt/cache/mapslt_ortofoto_overlay_512/map/_alllayers/L03/R0000001d/C00000029.png
//TODO verificar
return QString("http://dc1.maps.lt/cache/mapslt_ortofoto_overlay/map/_alllayers/L%1/R%2/C%3.png").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0');
}
break;
case MapType::PergoTurkeyMap:
{
// http://{domain}/{layerName}/{zoomLevel}/{first3LetterOfTileX}/{second3LetterOfTileX}/{third3LetterOfTileX}/{first3LetterOfTileY}/{second3LetterOfTileY}/{third3LetterOfTileXY}.png
// http://map3.pergo.com.tr/tile/00/000/000/001/000/000/000.png
// That means: Zoom Level: 0 TileX: 1 TileY: 0
// http://domain/tile/14/000/019/371/000/011/825.png
// That means: Zoom Level: 14 TileX: 19371 TileY:11825
// string x = pos.X().ToString("000000000").Insert(3, "/").Insert(7, "/"); // - 000/000/001
// string y = pos.Y().ToString("000000000").Insert(3, "/").Insert(7, "/"); // - 000/000/000
QString x=QString("%1").arg(pos.X(),9,(QChar)'0');
x.insert(3,"/").insert(7,"/");
QString y=QString("%1").arg(pos.X(),9,(QChar)'0');
y.insert(3,"/").insert(7,"/");
return QString("http://map%1.pergo.com.tr/tile/%2/%3/%4.png").arg(GetServerNum(pos, 4),2,10,(QChar)'0').arg(zoom).arg(x).arg(y);
}
break;
case MapType::SigPacSpainMap:
{
return QString("http://sigpac.mapa.es/kmlserver/raster/%1@3785/%2.%3.%4.img").arg(levelsForSigPacSpainMap[zoom]).arg(zoom).arg(pos.X()).arg((2 << (zoom - 1)) - pos.Y() - 1);
}
break;
case MapType::YandexMapRu:
{
QString server = "vec";
//http://vec01.maps.yandex.ru/tiles?l=map&v=2.10.2&x=1494&y=650&z=11
return QString("http://%10%2.maps.yandex.ru/tiles?l=map&v=%3&x=%4&y=%5&z=%6").arg(server).arg(GetServerNum(pos, 4)+1).arg(VersionYandexMap).arg(pos.X()).arg(pos.Y()).arg(zoom);
}
break;
default:
break;
}
return QString::null;
}
void UrlFactory::GetSecGoogleWords(const Point &pos, QString &sec1, QString &sec2)
{
sec1 = ""; // after &x=...
sec2 = ""; // after &zoom=...
int seclen = ((pos.X() * 3) + pos.Y()) % 8;
sec2 = SecGoogleWord.left(seclen);
if(pos.Y() >= 10000 && pos.Y() < 100000)
{
sec1 = "&s=";
}
}
QString UrlFactory::MakeGeocoderUrl(QString keywords)
{
QString key = keywords.replace(' ', '+');
return QString("http://maps.google.com/maps/geo?q=%1&output=csv&key=%2").arg(key).arg(GoogleMapsAPIKey);
}
QString UrlFactory::MakeReverseGeocoderUrl(PointLatLng &pt,const QString &language)
{
return QString("http://maps.google.com/maps/geo?hl=%1&ll=%2,%3&output=csv&key=%4").arg(language).arg(QString::number(pt.Lat())).arg(QString::number(pt.Lng())).arg(GoogleMapsAPIKey);
}
PointLatLng UrlFactory::GetLatLngFromGeodecoder(const QString &keywords, GeoCoderStatusCode::Types &status)
{
return GetLatLngFromGeocoderUrl(MakeGeocoderUrl(keywords),UseGeocoderCache,status);
}
PointLatLng UrlFactory::GetLatLngFromGeocoderUrl(const QString &url, const bool &useCache, GeoCoderStatusCode::Types &status)
{
qDebug()<<"Entered GetLatLngFromGeocoderUrl:";
status = GeoCoderStatusCode::Unknow;
PointLatLng ret(0,0);
QString urlEnd = url.right(url.indexOf("geo?q="));
urlEnd.replace( QRegExp(
"[^"
"A-Z,a-z,0-9,"
"\\^,\\&,\\',\\@,"
"\\{,\\},\\[,\\],"
"\\,,\\$,\\=,\\!,"
"\\-,\\#,\\(,\\),"
"\\%,\\.,\\+,\\~,\\_"
"]"), "_" );
QString geo = useCache ? Cache::Instance()->GetGeocoderFromCache(urlEnd) : "";
if(geo.isNull()|geo.isEmpty())
{
qDebug()<<"GetLatLngFromGeocoderUrl:Not in cache going internet";
QNetworkReply *reply;
QNetworkRequest qheader;
QNetworkAccessManager network;
network.setProxy(Proxy);
qheader.setUrl(QUrl(url));
qheader.setRawHeader("User-Agent",UserAgent);
reply=network.get(qheader);
qDebug()<<"GetLatLngFromGeocoderUrl:URL="<<url;
QTime time;
time.start();
while( !(reply->isFinished() | time.elapsed()>(6*Timeout)) ){QCoreApplication::processEvents(QEventLoop::AllEvents);}
qDebug()<<"Finished?"<<reply->error()<<" abort?"<<(time.elapsed()>Timeout*6);
if( (reply->error()!=QNetworkReply::NoError) | (time.elapsed()>Timeout*6))
{
qDebug()<<"GetLatLngFromGeocoderUrl::Network error";
return PointLatLng(0,0);
}
{
qDebug()<<"GetLatLngFromGeocoderUrl:Reply ok";
geo=reply->readAll();
// cache geocoding
if(useCache && geo.startsWith("200"))
{
Cache::Instance()->CacheGeocoder(urlEnd, geo);
}
}
reply->deleteLater();
}
// parse values
// true : 200,4,56.1451640,22.0681787
// false: 602,0,0,0
{
QStringList values = geo.split(',');
if(values.count() == 4)
{
status = (GeoCoderStatusCode::Types) QString(values[0]).toInt();
if(status == GeoCoderStatusCode::G_GEO_SUCCESS)
{
double lat = QString(values[2]).toDouble();
double lng = QString(values[3]).toDouble();
ret = PointLatLng(lat, lng);
qDebug()<<"Lat="<<lat<<" Lng="<<lng;
}
}
}
return ret;
}
Placemark UrlFactory::GetPlacemarkFromGeocoder(PointLatLng location)
{
return GetPlacemarkFromReverseGeocoderUrl(MakeReverseGeocoderUrl(location, LanguageStr), UsePlacemarkCache);
}
Placemark UrlFactory::GetPlacemarkFromReverseGeocoderUrl(const QString &url, const bool &useCache)
{
Placemark ret("");
qDebug()<<"Entered GetPlacemarkFromReverseGeocoderUrl:";
// status = GeoCoderStatusCode::Unknow;
QString urlEnd = url.right(url.indexOf("geo?hl="));
urlEnd.replace( QRegExp(
"[^"
"A-Z,a-z,0-9,"
"\\^,\\&,\\',\\@,"
"\\{,\\},\\[,\\],"
"\\,,\\$,\\=,\\!,"
"\\-,\\#,\\(,\\),"
"\\%,\\.,\\+,\\~,\\_"
"]"), "_" );
QString reverse = useCache ? Cache::Instance()->GetPlacemarkFromCache(urlEnd) : "";
if(reverse.isNull()|reverse.isEmpty())
{
qDebug()<<"GetLatLngFromGeocoderUrl:Not in cache going internet";
QNetworkReply *reply;
QNetworkRequest qheader;
QNetworkAccessManager network;
network.setProxy(Proxy);
qheader.setUrl(QUrl(url));
qheader.setRawHeader("User-Agent",UserAgent);
reply=network.get(qheader);
qDebug()<<"GetLatLngFromGeocoderUrl:URL="<<url;
QTime time;
time.start();
while( !(reply->isFinished() | time.elapsed()>(6*Timeout)) ){QCoreApplication::processEvents(QEventLoop::AllEvents);}
qDebug()<<"Finished?"<<reply->error()<<" abort?"<<(time.elapsed()>Timeout*6);
if( (reply->error()!=QNetworkReply::NoError) | (time.elapsed()>Timeout*6))
{
qDebug()<<"GetLatLngFromGeocoderUrl::Network error";
return ret;
}
{
qDebug()<<"GetLatLngFromGeocoderUrl:Reply ok";
QByteArray a=(reply->readAll());
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
reverse = codec->toUnicode(a);
qDebug()<<reverse;
// cache geocoding
if(useCache && reverse.startsWith("200"))
{
Cache::Instance()->CachePlacemark(urlEnd, reverse);
}
}
reply->deleteLater();
}
// parse values
// true : 200,4,56.1451640,22.0681787
// false: 602,0,0,0
if(reverse.startsWith("200"))
{
QString acc = reverse.left(reverse.indexOf('\"'));
ret = Placemark(reverse.remove(reverse.indexOf('\"')));
ret.SetAccuracy ((int) (( (QString) acc.split(',')[1]).toInt()) );
}
return ret;
}
double UrlFactory::GetDistance(PointLatLng p1, PointLatLng p2)
{
double dLat1InRad = p1.Lat() * (M_PI / 180);
double dLong1InRad = p1.Lng() * (M_PI / 180);
double dLat2InRad = p2.Lat() * (M_PI / 180);
double dLong2InRad = p2.Lng() * (M_PI / 180);
double dLongitude = dLong2InRad - dLong1InRad;
double dLatitude = dLat2InRad - dLat1InRad;
double a = pow(sin(dLatitude / 2), 2) + cos(dLat1InRad) * cos(dLat2InRad) * pow(sin(dLongitude / 2), 2);
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
double dDistance = EarthRadiusKm * c;
return dDistance;
}

View File

@ -0,0 +1,60 @@
#ifndef URLFACTORY_H
#define URLFACTORY_H
#include <QNetworkProxy>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTimer>
#include <QCoreApplication>
#include "providerstrings.h"
#include "pureimagecache.h"
#include "../internals/pointlatlng.h"
#include "geodecoderstatus.h"
#include <QTime>
#include "cache.h"
#include "placemark.h"
#include <QTextCodec>
#include "cmath"
class UrlFactory: public QObject,public ProviderStrings
{
Q_OBJECT
public:
/// <summary>
/// Gets or sets the value of the User-agent HTTP header.
/// </summary>
QByteArray UserAgent;
QNetworkProxy Proxy;
UrlFactory();
~UrlFactory();
QString MakeImageUrl(const MapType::Types &type,const Point &pos,const int &zoom,const QString &language);
PointLatLng GetLatLngFromGeodecoder(const QString &keywords,GeoCoderStatusCode::Types &status);
Placemark GetPlacemarkFromGeocoder(PointLatLng location);
int Timeout;
private:
void GetSecGoogleWords(const Point &pos, QString &sec1, QString &sec2);
int GetServerNum(const Point &pos,const int &max) const;
void TryCorrectGoogleVersions();
bool isCorrectedGoogleVersions;
QString TileXYToQuadKey(const int &tileX,const int &tileY,const int &levelOfDetail) const;
bool CorrectGoogleVersions;
bool UseGeocoderCache; //TODO GetSet
bool UsePlacemarkCache;//TODO GetSet
static const double EarthRadiusKm = 6378.137; // WGS-84
double GetDistance(PointLatLng p1,PointLatLng p2);
protected:
static short timelapse;
QString LanguageStr;
bool IsCorrectGoogleVersions();
void setIsCorrectGoogleVersions(bool value);
QString MakeGeocoderUrl(QString keywords);
QString MakeReverseGeocoderUrl(PointLatLng &pt,const QString &language);
PointLatLng GetLatLngFromGeocoderUrl(const QString &url,const bool &useCache, GeoCoderStatusCode::Types &status);
Placemark GetPlacemarkFromReverseGeocoderUrl(const QString &url,const bool &useCache);
};
#endif // URLFACTORY_H

View File

@ -0,0 +1,12 @@
DESTDIR = ../build
PROJECT = gettilestest
TEMPLATE = app
QT += network
QT += sql
CONFIG += console
CONFIG -= app_bundle
DEPENDPATH += .
INCLUDEPATH += ../core
SOURCES += main.cpp
LIBS += -L../build -lcore -linternals

View File

@ -0,0 +1,44 @@
#include <QApplication>
#include "gmaps.h"
#include <QDebug>
#include "../core/pureimagecache.h"
#include "QPixmap"
#include "QPicture"
#include <QIODevice>
#include <QtGui/QLabel>
#include "../core/pureimage.h"
#include "../core/rawtile.h"
#include "../core/cache.h"
#include "../core/languagetype.h"
#include "../core/tilecachequeue.h"
#include "../core/cacheitemqueue.h"
#include "../core/maptype.h"
#include "../core/alllayersoftype.h"
#include "geodecoderstatus.h"
//#include "QTest"
#include "threadpool.h"
#include "../internals/core.h"
#include "../core/size.h"
#include "../internals/rectangle.h"
#include "../internals/tile.h"
#include "../internals/tilematrix.h"
#include "../core/point.h"
#include "../core/size.h"
#include "../internals/copyrightstrings.h"
#include "../internals/projections/lks94projection.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPixmap pixmap;
//Tile Polling test
pixmap=PureImageProxy::FromStream(GMaps::Instance()->GetImageFrom(MapType::GoogleSatellite,Point(1,0),1));
QLabel label;
label.setPixmap(pixmap);
label.show();
//Geocoding Test
GeoCoderStatusCode::Types status;
qDebug()<<"Lisbon Coordinates:"<<GMaps::Instance()->GetLatLngFromGeodecoder("lisbon",status).ToString();
return a.exec();
}

View File

@ -0,0 +1,12 @@
#ifndef COPYRIGHTSTRINGS_H
#define COPYRIGHTSTRINGS_H
#include <QString>
#include <QDateTime>
static const QString googleCopyright = QString("©%1 Google - Map data ©%1 Tele Atlas, Imagery ©%1 TerraMetrics").arg(QDate::currentDate().year());
static const QString openStreetMapCopyright = QString("© OpenStreetMap - Map data ©%1 OpenStreetMap").arg(QDate::currentDate().year());
static const QString yahooMapCopyright = QString("© Yahoo! Inc. - Map data & Imagery ©%1 NAVTEQ").arg(QDate::currentDate().year());
static const QString virtualEarthCopyright = QString("©%1 Microsoft Corporation, ©%1 NAVTEQ, ©%1 Image courtesy of NASA").arg(QDate::currentDate().year());
static const QString arcGisCopyright = QString("©%1 ESRI - Map data ©%1 ArcGIS").arg(QDate::currentDate().year());
#endif // COPYRIGHTSTRINGS_H

View File

@ -0,0 +1,508 @@
#include "core.h"
Core::Core():currentPosition(0,0),currentPositionPixel(0,0),LastLocationInBounds(-1,-1),sizeOfMapArea(0,0)
,minOfTiles(0,0),maxOfTiles(0,0),started(false),isDragging(false),TooltipTextPadding(10,10),MouseWheelZooming(false),loaderLimit(5)
{
mousewheelzoomtype=MouseWheelZoomType::MousePositionAndCenter;
}
void Core::run()
{
bool last = false;
LoadTask task;
MtileLoadQueue.lock();
{
if(tileLoadQueue.count() > 0)
{
task = tileLoadQueue.dequeue();
{
last = tileLoadQueue.count() == 0;
//Debug.WriteLine("TileLoadQueue: " + tileLoadQueue.Count);
}
}
}
MtileLoadQueue.unlock();
if(loaderLimit.tryAcquire(1,GMaps::Instance()->Timeout))
{
if(task.HasValue())
{
{
Tile m = Matrix.TileAt(task.Pos);
if(m.Overlays.count() == 0)
{
qDebug()<<"Fill empty TileMatrix: " + task.ToString();
Tile t = Tile(task.Zoom, task.Pos);
QVector<MapType::Types> layers= GMaps::Instance()->GetAllLayersOfType(GetMapType());
foreach(MapType::Types tl,layers)
{
int retry = 0;
do
{
QByteArray img;
// tile number inversion(BottomLeft -> TopLeft) for pergo maps
if(tl == MapType::PergoTurkeyMap)
{
img = GMaps::Instance()->GetImageFrom(tl, Point(task.Pos.X(), maxOfTiles.Height() - task.Pos.Y()), task.Zoom);
}
else // ok
{
img = GMaps::Instance()->GetImageFrom(tl, task.Pos, task.Zoom);
}
if(img.length()!=0)
{
Moverlays.lock();
{
t.Overlays.append(img);
}
Moverlays.unlock();
break;
}
else if(GMaps::Instance()->RetryLoadTile > 0)
{
qDebug()<<"ProcessLoadTask: " << task.ToString()<< " -> empty tile, retry " << retry;
{
//QThread::usleep(1111);
}
}
}
while(++retry < GMaps::Instance()->RetryLoadTile);
}
if(t.Overlays.count() > 0)
{
Matrix.SetTileAt(task.Pos,t);
}
else
{
t.Clear();
//t = null;
}
// layers = null;
}
}
{
// last buddy cleans stuff ;}
if(last)
{
GMaps::Instance()->kiberCacheLock.lockForWrite();
GMaps::Instance()->TilesInMemory.RemoveMemoryOverload();
GMaps::Instance()->kiberCacheLock.unlock();
MtileDrawingList.lock();
{
Matrix.ClearPointsNotIn(tileDrawingList);
}
MtileDrawingList.unlock();
emit OnTileLoadComplete();
emit OnNeedInvalidation();
}
}
loaderLimit.release();
}
}
}
void Core::SetZoom(const int &value)
{
if (zoom!=value && !isDragging)
{
zoom=value;
minOfTiles=Projection()->GetTileMatrixMinXY(value);
maxOfTiles=Projection()->GetTileMatrixMaxXY(value);
currentPositionPixel=Projection()->FromLatLngToPixel(currentPosition,value);
if(started)
{
MtileLoadQueue.lock();
tileLoadQueue.clear();
MtileLoadQueue.unlock();
Matrix.Clear();
GoToCurrentPositionOnZoom();
UpdateBounds();
emit OnMapDrag();
emit OnMapZoomChanged();
emit OnNeedInvalidation();
}
}
}
void Core::SetCurrentPosition(const PointLatLng &value)
{
if(!IsDragging())
{
currentPosition = value;
SetCurrentPositionGPixel(Projection()->FromLatLngToPixel(value, Zoom()));
if(started)
{
GoToCurrentPosition();
emit OnCurrentPositionChanged(currentPosition);
}
}
else
{
currentPosition = value;
SetCurrentPositionGPixel(Projection()->FromLatLngToPixel(value, Zoom()));
if(started)
{
emit OnCurrentPositionChanged(currentPosition);
}
}
}
void Core::SetMapType(const MapType::Types &value)
{
if(value != GetMapType())
{
mapType = value;
switch(value)
{
case MapType::ArcGIS_Map:
case MapType::ArcGIS_Satellite:
case MapType::ArcGIS_ShadedRelief:
case MapType::ArcGIS_Terrain:
{
if(Projection()->Type()!="PlateCarreeProjection")
{
projection = new PlateCarreeProjection();
}
}
break;
case MapType::ArcGIS_MapsLT_Map_Hybrid:
case MapType::ArcGIS_MapsLT_Map_Labels:
case MapType::ArcGIS_MapsLT_Map:
case MapType::ArcGIS_MapsLT_OrtoFoto:
{
if(Projection()->Type()!="LKS94Projection")
{
projection = new LKS94Projection();
}
}
break;
case MapType::PergoTurkeyMap:
{
if(Projection()->Type()!="PlateCarreeProjectionPergo")
{
projection = new PlateCarreeProjectionPergo();
}
}
break;
case MapType::YandexMapRu:
{
if(Projection()->Type()!="MercatorProjectionYandex")
{
projection = new MercatorProjectionYandex();
}
}
break;
default:
{
if(Projection()->Type()!="MercatorProjection")
{
projection = new MercatorProjection();
}
}
break;
}
minOfTiles = Projection()->GetTileMatrixMinXY(Zoom());
maxOfTiles = Projection()->GetTileMatrixMaxXY(Zoom());
SetCurrentPositionGPixel(Projection()->FromLatLngToPixel(CurrentPosition(), Zoom()));
if(started)
{
CancelAsyncTasks();
OnMapSizeChanged(Width, Height);
GoToCurrentPosition();
ReloadMap();
emit OnMapTypeChanged(value);
}
}
}
void Core::StartSystem()
{
if(!started)
{
started = true;
ReloadMap();
GoToCurrentPosition();
}
}
void Core::UpdateCenterTileXYLocation()
{
PointLatLng center = FromLocalToLatLng(Width/2, Height/2);
Point centerPixel = Projection()->FromLatLngToPixel(center, Zoom());
centerTileXYLocation = Projection()->FromPixelToTileXY(centerPixel);
}
void Core::OnMapSizeChanged(int const& width, int const& height)
{
Width = width;
Height = height;
sizeOfMapArea.SetWidth(1 + (Width/Projection()->TileSize().Width())/2);
sizeOfMapArea.SetHeight(1 + (Height/Projection()->TileSize().Height())/2);
UpdateCenterTileXYLocation();
if(started)
{
UpdateBounds();
emit OnCurrentPositionChanged(currentPosition);
}
}
void Core::OnMapClose()
{
// if(waitOnEmptyTasks != null)
// {
// try
// {
// waitOnEmptyTasks.Set();
// waitOnEmptyTasks.Close();
// }
// catch
// {
// }
// }
CancelAsyncTasks();
}
GeoCoderStatusCode::Types Core::SetCurrentPositionByKeywords(QString const& keys)
{
GeoCoderStatusCode::Types status = GeoCoderStatusCode::Unknow;
PointLatLng pos = GMaps::Instance()->GetLatLngFromGeodecoder(keys, status);
if(pos.IsEmpty() && status == GeoCoderStatusCode::G_GEO_SUCCESS)
{
SetCurrentPosition(pos);
}
return status;
}
RectLatLng Core::CurrentViewArea()
{
PointLatLng p = Projection()->FromPixelToLatLng(-renderOffset.X(), -renderOffset.Y(), Zoom());
double rlng = Projection()->FromPixelToLatLng(-renderOffset.X() + Width, -renderOffset.Y(), Zoom()).Lng();
double blat = Projection()->FromPixelToLatLng(-renderOffset.X(), -renderOffset.Y() + Height, Zoom()).Lat();
return RectLatLng::FromLTRB(p.Lng(), p.Lat(), rlng, blat);
}
PointLatLng Core::FromLocalToLatLng(int const& x, int const& y)
{
return Projection()->FromPixelToLatLng(Point(x - renderOffset.X(), y - renderOffset.Y()), Zoom());
}
Point Core::FromLatLngToLocal(PointLatLng const& latlng)
{
Point pLocal = Projection()->FromLatLngToPixel(latlng, Zoom());
pLocal.Offset(renderOffset);
return pLocal;
}
int Core::GetMaxZoomToFitRect(RectLatLng const& rect)
{
int zoom = 0;
for(int i = 1; i <= GMaps::Instance()->MaxZoom; i++)
{
Point p1 = Projection()->FromLatLngToPixel(rect.LocationTopLeft(), i);
Point p2 = Projection()->FromLatLngToPixel(rect.Bottom(), rect.Right(), i);
if(((p2.X() - p1.X()) <= Width+10) && (p2.Y() - p1.Y()) <= Height+10)
{
zoom = i;
}
else
{
break;
}
}
return zoom;
}
void Core::BeginDrag(Point const& pt)
{
dragPoint.SetX(pt.X() - renderOffset.X());
dragPoint.SetY(pt.Y() - renderOffset.Y());
isDragging = true;
}
void Core::EndDrag()
{
isDragging = false;
emit OnNeedInvalidation();
}
void Core::ReloadMap()
{
if(started)
{
qDebug()<<"------------------";
MtileLoadQueue.lock();
{
tileLoadQueue.clear();
}
MtileLoadQueue.unlock();
Matrix.Clear();
emit OnNeedInvalidation();
}
}
void Core::GoToCurrentPosition()
{
// reset stuff
renderOffset = Point::Empty;
centerTileXYLocationLast = Point::Empty;
dragPoint = Point::Empty;
// goto location
Drag(Point(-(GetcurrentPositionGPixel().X() - Width/2), -(GetcurrentPositionGPixel().Y() - Height/2)));
}
void Core::GoToCurrentPositionOnZoom()
{
// reset stuff
renderOffset = Point::Empty;
centerTileXYLocationLast = Point::Empty;
dragPoint = Point::Empty;
// goto location and centering
if(MouseWheelZooming)
{
if(mousewheelzoomtype != MouseWheelZoomType::MousePositionWithoutCenter)
{
Point pt = Point(-(GetcurrentPositionGPixel().X() - Width/2), -(GetcurrentPositionGPixel().Y() - Height/2));
renderOffset.SetX(pt.X() - dragPoint.X());
renderOffset.SetY(pt.Y() - dragPoint.Y());
}
else // without centering
{
renderOffset.SetX(-GetcurrentPositionGPixel().X() - dragPoint.X());
renderOffset.SetY(-GetcurrentPositionGPixel().Y() - dragPoint.Y());
renderOffset.Offset(mouseLastZoom);
}
}
else // use current map center
{
mouseLastZoom = Point::Empty;
Point pt = Point(-(GetcurrentPositionGPixel().X() - Width/2), -(GetcurrentPositionGPixel().Y() - Height/2));
renderOffset.SetX(pt.X() - dragPoint.X());
renderOffset.SetY(pt.Y() - dragPoint.Y());
}
UpdateCenterTileXYLocation();
}
void Core::DragOffset(Point const& offset)
{
renderOffset.Offset(offset);
UpdateCenterTileXYLocation();
if(centerTileXYLocation != centerTileXYLocationLast)
{
centerTileXYLocationLast = centerTileXYLocation;
UpdateBounds();
}
{
LastLocationInBounds = CurrentPosition();
SetCurrentPosition (FromLocalToLatLng((int) Width/2, (int) Height/2));
}
emit OnNeedInvalidation();
emit OnMapDrag();
}
void Core::Drag(Point const& pt)
{
renderOffset.SetX(pt.X() - dragPoint.X());
renderOffset.SetY(pt.Y() - dragPoint.Y());
UpdateCenterTileXYLocation();
if(centerTileXYLocation != centerTileXYLocationLast)
{
centerTileXYLocationLast = centerTileXYLocation;
UpdateBounds();
}
if(IsDragging())
{
LastLocationInBounds = CurrentPosition();
SetCurrentPosition(FromLocalToLatLng((int) Width/2, (int) Height/2));
}
emit OnNeedInvalidation();
emit OnMapDrag();
}
void Core::CancelAsyncTasks()
{
if(started)
{
MtileLoadQueue.lock();
{
tileLoadQueue.clear();
}
MtileLoadQueue.unlock();
}
}
void Core::UpdateBounds()
{
MtileDrawingList.lock();
{
//FindTilesAround(tileDrawingList);
qDebug()<<"OnTileLoadStart: " << tileDrawingList.count() << " tiles to load at zoom " << Zoom() << ", time: " << QDateTime::currentDateTime().date();
emit OnTileLoadStart();
foreach(Point p,tileDrawingList)
{
LoadTask task = LoadTask(p, Zoom());
{
MtileLoadQueue.lock();
{
if(!tileLoadQueue.contains(task))
{
tileLoadQueue.enqueue(task);
//this->.QueueUserWorkItem(ProcessLoadTaskCallback);
}
}
MtileLoadQueue.unlock();
}
}
}
//UpdateGroundResolution();
}

View File

@ -0,0 +1,215 @@
#ifndef CORE_H
#define CORE_H
#include "../internals/PointLatlng.h"
#include "mousewheelzoomtype.h"
#include "../core/size.h"
#include "../core/maptype.h"
#include "rectangle.h"
#include "QThreadPool"
#include "tilematrix.h"
#include <QQueue>
#include "loadtask.h"
#include "copyrightstrings.h"
#include "rectlatlng.h"
#include "../internals/projections/lks94projection.h"
#include "../internals/projections/mercatorprojection.h"
#include "../internals/projections/mercatorprojectionyandex.h"
#include "../internals/projections/platecarreeprojection.h"
#include "../internals/projections/platecarreeprojectionpergo.h"
#include "../core/geodecoderstatus.h"
#include "../core/gmaps.h"
#include <QSemaphore>
#include <QThread>
#include <QDateTime>
//#include <QObject>
class Core:public QObject,public QRunnable
{
Q_OBJECT
public:
Core();
void run();
PointLatLng CurrentPosition(){return currentPosition;};
void SetCurrentPosition(const PointLatLng &value);
Point GetcurrentPositionGPixel(){return currentPositionPixel;};
void SetcurrentPositionGPixel(const Point &value){currentPositionPixel=value;};
Point GetrenderOffset(){return renderOffset;};
void SetrenderOffset(const Point &value){renderOffset=value;};
Point GetcenterTileXYLocation(){return centerTileXYLocation;};
void SetcenterTileXYLocation(const Point &value){centerTileXYLocation=value;};
Point GetcenterTileXYLocationLast(){return centerTileXYLocationLast;};
void SetcenterTileXYLocationLast(const Point &value){centerTileXYLocationLast=value;};
Point GetdragPoint(){return dragPoint;};
void SetdragPoint(const Point &value){dragPoint=value;};
Point GetmouseDown(){return mouseDown;};
void SetmouseDown(const Point &value){mouseDown=value;};
Point GetmouseCurrent(){return mouseCurrent;};
void SetmouseCurrent(const Point &value){mouseCurrent=value;};
Point GetmouseLastZoom(){return mouseLastZoom;};
void SetmouseLastZoom(const Point &value){mouseLastZoom=value;};
MouseWheelZoomType::Types GetMouseWheelZoomType(){return mousewheelzoomtype;};
void SetMouseWheelZoomType(const MouseWheelZoomType::Types &value){mousewheelzoomtype=value;};
PointLatLng GetLastLocationInBounds(){return LastLocationInBounds;}
void SetLastLocationInBounds(const PointLatLng &value){LastLocationInBounds=value;}
Size GetsizeOfMapArea(){return sizeOfMapArea;}
void SetsizeOfMapArea(const Size &value){sizeOfMapArea=value;}
Size GetminOfTiles(){return minOfTiles;}
void SetminOfTiles(const Size &value){minOfTiles=value;}
Size GetmaxOfTiles(){return maxOfTiles;}
void SetmaxOfTiles(const Size &value){maxOfTiles=value;}
Rectangle GettileRect(){return tileRect;}
void SettileRect(const Rectangle &value){tileRect=value;}
Point GettilePoint(){return tilePoint;}
void SettilePoint(const Point &value){tilePoint=value;}
Rectangle GetCurrentRegion(){return CurrentRegion;}
void SetCurrentRegion(const Rectangle &value){CurrentRegion=value;}
QList<Point> tileDrawingList;
PureProjection* Projection()
{
return projection;
}
void SetProjection(PureProjection* value)
{
projection=value;
tileRect=Rectangle(Point(0,0),value->TileSize());
}
bool IsDragging(){return isDragging;}
int Zoom(){return zoom;}
void SetZoom(int const& value);
void UpdateBounds();
MapType::Types GetMapType(){return mapType;}
void SetMapType(MapType::Types const& value);
void StartSystem();
void UpdateCenterTileXYLocation();
void OnMapSizeChanged(int const& width, int const& height);//TODO had as slot
void OnMapClose();//TODO had as slot
GeoCoderStatusCode::Types SetCurrentPositionByKeywords(QString const& keys);
RectLatLng CurrentViewArea();
PointLatLng FromLocalToLatLng(int const& x, int const& y);
Point FromLatLngToLocal(PointLatLng const& latlng);
int GetMaxZoomToFitRect(RectLatLng const& rect);
void BeginDrag(Point const& pt);
void EndDrag();
void ReloadMap();
void GoToCurrentPosition();
bool MouseWheelZooming;
void DragOffset(Point const& offset);
void Drag(Point const& pt);
void CancelAsyncTasks();
signals:
void OnCurrentPositionChanged(PointLatLng point);
void OnTileLoadComplete();
void OnTileLoadStart();
void OnMapDrag();
void OnMapZoomChanged();
void OnMapTypeChanged(MapType::Types type);
void OnEmptyTileError(int zoom, Point pos);
void OnNeedInvalidation();
private:
PointLatLng currentPosition;
Point currentPositionPixel;
Point renderOffset;
Point centerTileXYLocation;
Point centerTileXYLocationLast;
Point dragPoint;
Point mouseDown;
Point mouseCurrent;
Point mouseLastZoom;
MouseWheelZoomType::Types mousewheelzoomtype;
PointLatLng LastLocationInBounds;
Size sizeOfMapArea;
Size minOfTiles;
Size maxOfTiles;
Rectangle tileRect;
Point tilePoint;
Rectangle CurrentRegion;
TileMatrix Matrix;
QQueue<LoadTask> tileLoadQueue;
int zoom;
PureProjection* projection;
bool isDragging;
QMutex MtileLoadQueue;
QMutex Moverlays;
QMutex MtileDrawingList;
Size TooltipTextPadding;
MapType::Types mapType;
QSemaphore loaderLimit;
protected:
bool started;
int Width;
int Height;
int pxRes100m; // 100 meters
int pxRes1000m; // 1km
int pxRes10km; // 10km
int pxRes100km; // 100km
int pxRes1000km; // 1000km
int pxRes5000km; // 5000km
void SetCurrentPositionGPixel(Point const& value){currentPositionPixel = value;}
void GoToCurrentPositionOnZoom();
};
#endif // CORE_H

View File

@ -0,0 +1,33 @@
include (../common.pri)
HEADERS += core.h \
mousewheelzoomtype.h \
rectangle.h \
tile.h \
tilematrix.h \
loadtask.h \
copyrightstrings.h \
pureprojection.h \
pointlatlng.h \
rectlatlng.h \
sizelatlng.h
SOURCES += core.cpp \
rectangle.cpp \
tile.cpp \
tilematrix.cpp \
pureprojection.cpp \
rectlatlng.cpp \
sizelatlng.cpp \
pointlatlng.cpp \
loadtask.cpp
HEADERS += ./projections/lks94projection.h \
./projections/mercatorprojection.h \
./projections/mercatorprojectionyandex.h \
./projections/platecarreeprojection.h \
./projections/platecarreeprojectionpergo.h
SOURCES += ./projections/lks94projection.cpp \
./projections/mercatorprojection.cpp \
./projections/mercatorprojectionyandex.cpp \
./projections/platecarreeprojection.cpp \
./projections/platecarreeprojectionpergo.cpp
LIBS += -L../build \
-lcore \

View File

@ -0,0 +1,6 @@
#include "loadtask.h"
bool operator==(LoadTask const& lhs,LoadTask const& rhs)
{
return ((lhs.Pos==rhs.Pos)&&(lhs.Zoom==rhs.Zoom));
}

View File

@ -0,0 +1,35 @@
#ifndef LOADTASK_H
#define LOADTASK_H
#include <QString>
#include "../core/point.h"
struct LoadTask
{
friend bool operator==(LoadTask const& lhs,LoadTask const& rhs);
public:
Point Pos;
int Zoom;
LoadTask(Point pos, int zoom)
{
Pos = pos;
Zoom = zoom;
}
LoadTask()
{
Pos=Point(-1,-1);
Zoom=-1;
}
bool HasValue()
{
return Zoom==-1;
}
QString ToString()const
{
return QString::number(Zoom) + " - " + Pos.ToString();
}
};
#endif // LOADTASK_H

View File

@ -0,0 +1,26 @@
#ifndef MOUSEWHEELZOOMTYPE_H
#define MOUSEWHEELZOOMTYPE_H
struct MouseWheelZoomType
{
enum Types
{
/// <summary>
/// zooms map to current mouse position and makes it map center
/// </summary>
MousePositionAndCenter,
/// <summary>
/// zooms to current mouse position, but doesn't make it map center,
/// google/bing style ;}
/// </summary>
MousePositionWithoutCenter,
/// <summary>
/// zooms map to current view center
/// </summary>
ViewCenter,
};
};
#endif // MOUSEWHEELZOOMTYPE_H

View File

@ -0,0 +1,26 @@
#include "pointlatlng.h"
PointLatLng PointLatLng::Empty=PointLatLng();
PointLatLng::PointLatLng():lat(0),lng(0)
{
}
bool operator==(PointLatLng const& lhs,PointLatLng const& rhs)
{
return ((lhs.Lng() == rhs.Lng()) && (lhs.Lat() == rhs.Lat()));
}
bool operator!=(PointLatLng const& left, PointLatLng const& right)
{
return !(left == right);
}
PointLatLng operator+(PointLatLng pt, SizeLatLng sz)
{
return PointLatLng::Add(pt, sz);
}
PointLatLng operator-(PointLatLng pt, SizeLatLng sz)
{
return PointLatLng::Subtract(pt, sz);
}

View File

@ -0,0 +1,98 @@
#ifndef POINTLATLNG_H
#define POINTLATLNG_H
#include <QHash>
#include <QString>
#include "sizelatlng.h"
struct PointLatLng
{
//friend uint qHash(PointLatLng const& point);
friend bool operator==(PointLatLng const& lhs,PointLatLng const& rhs);
friend bool operator!=(PointLatLng const& left, PointLatLng const& right);
friend PointLatLng operator+(PointLatLng pt, SizeLatLng sz);
friend PointLatLng operator-(PointLatLng pt, SizeLatLng sz);
//TODO Sizelatlng friend PointLatLng operator+(PointLatLng pt, SizeLatLng sz);
private:
double lat;
double lng;
public:
PointLatLng();
static PointLatLng Empty;
PointLatLng(const double &lat,const double &lng)
{
this->lat = lat;
this->lng = lng;
}
bool IsEmpty()
{
return ((this->lng == 0) && (this->lat == 0));
}
double Lat()const
{
return this->lat;
}
void SetLat(const double &value)
{
this->lat = value;
}
double Lng()const
{
return this->lng;
}
void SetLng(const double &value)
{
this->lng = value;
}
static PointLatLng Add(PointLatLng const& pt, SizeLatLng const& sz)
{
return PointLatLng(pt.Lat() - sz.HeightLat(), pt.Lng() + sz.WidthLng());
}
static PointLatLng Subtract(PointLatLng const& pt, SizeLatLng const& sz)
{
return PointLatLng(pt.Lat() + sz.HeightLat(), pt.Lng() - sz.WidthLng());
}
void Offset(PointLatLng const& pos)
{
this->Offset(pos.Lat(), pos.Lng());
}
void Offset(double const& lat, double const& lng)
{
this->lng += lng;
this->lat -= lat;
}
QString ToString()const
{
return QString("{Lat=%1, Lng=%2}").arg(this->lat).arg(this->lng);
}
//// static PointLatLng()
//// {
//// Empty = new PointLatLng();
//// }
};
//
#endif // POINTLATLNG_H

View File

@ -0,0 +1,757 @@
#include "lks94projection.h"
LKS94Projection::LKS94Projection():MinLatitude (53.33 ), MaxLatitude (56.55 ), MinLongitude (20.22 ),
MaxLongitude (27.11 ), orignX (5122000 ), orignY (10000100 ),tileSize(256, 256)
{
}
Size LKS94Projection::TileSize() const
{
return tileSize;
}
double LKS94Projection::Axis() const
{
return 6378137;
}
double LKS94Projection::Flattening() const
{
return (1.0 / 298.257222101);
}
Point LKS94Projection::FromLatLngToPixel(double lat, double lng, int const& zoom)
{
Point ret;
lat = Clip(lat, MinLatitude, MaxLatitude);
lng = Clip(lng, MinLongitude, MaxLongitude);
QVector <double> lks(3);
lks[0]=lng;
lks[1]=lat;
lks = DTM10(lks);
lks = MTD10(lks);
lks = DTM00(lks);
double res = GetTileMatrixResolution(zoom);
ret.SetX((int) floor((lks[0] + orignX) / res));
ret.SetY((int) floor((orignY - lks[1]) / res));
return ret;
}
PointLatLng LKS94Projection::FromPixelToLatLng(int const& x, int const& y, int const& zoom)
{
PointLatLng ret;// = PointLatLng::Empty;
double res = GetTileMatrixResolution(zoom);
QVector <double> lks(2);
lks[0]=(x * res) - orignX;
lks[1]=-(y * res) + orignY;
lks = MTD11(lks);
lks = DTM10(lks);
lks = MTD10(lks);
ret.SetLat(Clip(lks[1], MinLatitude, MaxLatitude));
ret.SetLng(Clip(lks[0], MinLongitude, MaxLongitude));
return ret;
}
QVector <double> LKS94Projection::DTM10(const QVector <double>& lonlat)
{
double es; // Eccentricity squared : (a^2 - b^2)/a^2
double semiMajor = 6378137.0; // major axis
double semiMinor = 6356752.3142451793; // minor axis
double ab; // Semi_major / semi_minor
double ba; // Semi_minor / semi_major
double ses; // Second eccentricity squared : (a^2 - b^2)/b^2
es = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor); //e^2
ses = (pow(semiMajor, 2) - pow(semiMinor, 2)) / pow(semiMinor, 2);
ba = semiMinor / semiMajor;
ab = semiMajor / semiMinor;
// ...
double lon = DegreesToRadians(lonlat[0]);
double lat = DegreesToRadians(lonlat[1]);
double h = lonlat.count() < 3 ? 0 : std::isnan(lonlat[2]) ? 0 : lonlat[2];//TODO NAN
double v = semiMajor / sqrt(1 - es * pow(sin(lat), 2));
double x = (v + h) * cos(lat) * cos(lon);
double y = (v + h) * cos(lat) * sin(lon);
double z = ((1 - es) * v + h) * sin(lat);
QVector <double> ret(3);
ret[0]=x;
ret[1]=y;
ret[2]=z;
return ret;
}
QVector <double> LKS94Projection::MTD10(QVector <double>& pnt)
{
QVector <double> ret(3);
const double COS_67P5 = 0.38268343236508977; // cosine of 67.5 degrees
const double AD_C = 1.0026000; // Toms region 1 constant
double es; // Eccentricity squared : (a^2 - b^2)/a^2
double semiMajor = 6378137.0; // major axis
double semiMinor = 6356752.3141403561; // minor axis
double ab; // Semi_major / semi_minor
double ba; // Semi_minor / semi_major
double ses; // Second eccentricity squared : (a^2 - b^2)/b^2
es = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor); //e^2
ses = (pow(semiMajor, 2) - pow(semiMinor, 2)) / pow(semiMinor, 2);
ba = semiMinor / semiMajor;
ab = semiMajor / semiMinor;
// ...
bool AtPole = false; // is location in polar region
double Z = pnt.count() < 3 ? 0 : std::isnan(pnt[2]) ? 0 : pnt[2];//TODO NaN
double lon = 0;
double lat = 0;
double Height = 0;
if(pnt[0] != 0.0)
{
lon = atan2(pnt[1], pnt[0]);
}
else
{
if(pnt[1] > 0)
{
lon = M_PI / 2;
}
else
if(pnt[1] < 0)
{
lon = -M_PI * 0.5;
}
else
{
AtPole = true;
lon = 0.0;
if(Z > 0.0) // north pole
{
lat = M_PI * 0.5;
}
else
if(Z < 0.0) // south pole
{
lat = -M_PI * 0.5;
}
else // center of earth
{
ret[0]=RadiansToDegrees(lon);
ret[1]=RadiansToDegrees(M_PI * 0.5);
ret[2]=-semiMinor;
return ret;
}
}
}
double W2 = pnt[0] * pnt[0] + pnt[1] * pnt[1]; // Square of distance from Z axis
double W = sqrt(W2); // distance from Z axis
double T0 = Z * AD_C; // initial estimate of vertical component
double S0 = sqrt(T0 * T0 + W2); // initial estimate of horizontal component
double Sin_B0 = T0 / S0; // sin(B0), B0 is estimate of Bowring aux variable
double Cos_B0 = W / S0; // cos(B0)
double Sin3_B0 = pow(Sin_B0, 3);
double T1 = Z + semiMinor * ses * Sin3_B0; // corrected estimate of vertical component
double Sum = W - semiMajor * es * Cos_B0 * Cos_B0 * Cos_B0; // numerator of cos(phi1)
double S1 = sqrt(T1 * T1 + Sum * Sum); // corrected estimate of horizontal component
double Sin_p1 = T1 / S1; // sin(phi1), phi1 is estimated latitude
double Cos_p1 = Sum / S1; // cos(phi1)
double Rn = semiMajor / sqrt(1.0 - es * Sin_p1 * Sin_p1); // Earth radius at location
if(Cos_p1 >= COS_67P5)
{
Height = W / Cos_p1 - Rn;
}
else
if(Cos_p1 <= -COS_67P5)
{
Height = W / -Cos_p1 - Rn;
}
else
{
Height = Z / Sin_p1 + Rn * (es - 1.0);
}
if(!AtPole)
{
lat = atan(Sin_p1 / Cos_p1);
}
ret[0]=RadiansToDegrees(lon);
ret[1]=RadiansToDegrees(lat);
ret[2]=Height;
return ret;
}
QVector <double> LKS94Projection::DTM00(QVector <double>& lonlat)
{
double scaleFactor = 0.9998; // scale factor
double centralMeridian = 0.41887902047863912; // Center qlonglongitude (projection center) */
double latOrigin = 0.0; // center latitude
double falseNorthing = 0.0; // y offset in meters
double falseEasting = 500000.0; // x offset in meters
double semiMajor = 6378137.0; // major axis
double semiMinor = 6356752.3141403561; // minor axis
double metersPerUnit = 1.0;
double e0, e1, e2, e3; // eccentricity constants
double e, es, esp; // eccentricity constants
double ml0; // small value m
es = 1.0 - pow(semiMinor / semiMajor, 2);
e = sqrt(es);
e0 = e0fn(es);
e1 = e1fn(es);
e2 = e2fn(es);
e3 = e3fn(es);
ml0 = semiMajor * mlfn(e0, e1, e2, e3, latOrigin);
esp = es / (1.0 - es);
// ...
double lon = DegreesToRadians(lonlat[0]);
double lat = DegreesToRadians(lonlat[1]);
double delta_lon = 0.0; // Delta qlonglongitude (Given qlonglongitude - center)
double sin_phi, cos_phi; // sin and cos value
double al, als; // temporary values
double c, t, tq; // temporary values
double con, n, ml; // cone constant, small m
delta_lon = LKS94Projection::AdjustLongitude(lon - centralMeridian);
LKS94Projection::SinCos(lat, sin_phi, cos_phi);
al = cos_phi * delta_lon;
als = pow(al, 2);
c = pow(cos_phi, 2);
tq = tan(lat);
t = pow(tq, 2);
con = 1.0 - es * pow(sin_phi, 2);
n = semiMajor / sqrt(con);
ml = semiMajor * mlfn(e0, e1, e2, e3, lat);
double x = scaleFactor * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als / 20.0 *
(5.0 - 18.0 * t + pow(t, 2) + 72.0 * c - 58.0 * esp))) + falseEasting;
double y = scaleFactor * (ml - ml0 + n * tq * (als * (0.5 + als / 24.0 *
(5.0 - t + 9.0 * c + 4.0 * pow(c, 2) + als / 30.0 * (61.0 - 58.0 * t
+ pow(t, 2) + 600.0 * c - 330.0 * esp))))) + falseNorthing;
if(lonlat.count() < 3)
{
QVector <double> ret(2);
ret[0]= x / metersPerUnit;
ret[1]= y / metersPerUnit;
return ret;
}
else
{
QVector <double> ret(3);
ret[0]= x / metersPerUnit;
ret[1]= y / metersPerUnit;
ret[2]=lonlat[2];
return ret;
}
}
QVector <double> LKS94Projection::DTM01(QVector <double>& lonlat)
{
double es; // Eccentricity squared : (a^2 - b^2)/a^2
double semiMajor = 6378137.0; // major axis
double semiMinor = 6356752.3141403561; // minor axis
double ab; // Semi_major / semi_minor
double ba; // Semi_minor / semi_major
double ses; // Second eccentricity squared : (a^2 - b^2)/b^2
es = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor);
ses = (pow(semiMajor, 2) -pow(semiMinor, 2)) / pow(semiMinor, 2);
ba = semiMinor / semiMajor;
ab = semiMajor / semiMinor;
// ...
double lon = DegreesToRadians(lonlat[0]);
double lat = DegreesToRadians(lonlat[1]);
double h = lonlat.count() < 3 ? 0 : std::isnan(lonlat[2]) ? 0 : lonlat[2];//TODO NaN
double v = semiMajor / sqrt(1 - es * pow(sin(lat), 2));
double x = (v + h) * cos(lat) * cos(lon);
double y = (v + h) * cos(lat) * sin(lon);
double z = ((1 - es) * v + h) * sin(lat);
QVector <double> ret(3);
ret[0]=x;
ret[1]=y;
ret[2]=z;
return ret;
}
QVector <double> LKS94Projection::MTD01(QVector <double>& pnt)
{
const double COS_67P5 = 0.38268343236508977; // cosine of 67.5 degrees
const double AD_C = 1.0026000; // Toms region 1 constant
double es; // Eccentricity squared : (a^2 - b^2)/a^2
double semiMajor = 6378137.0; // major axis
double semiMinor = 6356752.3142451793; // minor axis
double ab; // Semi_major / semi_minor
double ba; // Semi_minor / semi_major
double ses; // Second eccentricity squared : (a^2 - b^2)/b^2
es = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor);
ses = (pow(semiMajor, 2) - pow(semiMinor, 2)) / pow(semiMinor, 2);
ba = semiMinor / semiMajor;
ab = semiMajor / semiMinor;
// ...
bool At_Pole = false; // is location in polar region
double Z = pnt.count() < 3 ? 0 : std::isnan(pnt[2]) ? 0 : pnt[2];//TODO NaN
double lon = 0;
double lat = 0;
double Height = 0;
if(pnt[0] != 0.0)
{
lon = atan2(pnt[1], pnt[0]);
}
else
{
if(pnt[1] > 0)
{
lon = M_PI / 2;
}
else
if(pnt[1] < 0)
{
lon = -M_PI * 0.5;
}
else
{
At_Pole = true;
lon = 0.0;
if(Z > 0.0) // north pole
{
lat = M_PI * 0.5;
}
else
if(Z < 0.0) // south pole
{
lat = -M_PI * 0.5;
}
else // center of earth
{
QVector<double> ret(3);
ret[0]=RadiansToDegrees(lon);
ret[1]=RadiansToDegrees(M_PI * 0.5);
ret[2]=-semiMinor;
return ret;
}
}
}
double W2 = pnt[0] * pnt[0] + pnt[1] * pnt[1]; // Square of distance from Z axis
double W = sqrt(W2); // distance from Z axis
double T0 = Z * AD_C; // initial estimate of vertical component
double S0 = sqrt(T0 * T0 + W2); //initial estimate of horizontal component
double Sin_B0 = T0 / S0; // sin(B0), B0 is estimate of Bowring aux variable
double Cos_B0 = W / S0; // cos(B0)
double Sin3_B0 = pow(Sin_B0, 3);
double T1 = Z + semiMinor * ses * Sin3_B0; //corrected estimate of vertical component
double Sum = W - semiMajor * es * Cos_B0 * Cos_B0 * Cos_B0; // numerator of cos(phi1)
double S1 = sqrt(T1 * T1 + Sum * Sum); // corrected estimate of horizontal component
double Sin_p1 = T1 / S1; // sin(phi1), phi1 is estimated latitude
double Cos_p1 = Sum / S1; // cos(phi1)
double Rn = semiMajor / sqrt(1.0 - es * Sin_p1 * Sin_p1); // Earth radius at location
if(Cos_p1 >= COS_67P5)
{
Height = W / Cos_p1 - Rn;
}
else
if(Cos_p1 <= -COS_67P5)
{
Height = W / -Cos_p1 - Rn;
}
else
{
Height = Z / Sin_p1 + Rn * (es - 1.0);
}
if(!At_Pole)
{
lat = atan(Sin_p1 / Cos_p1);
}
QVector<double> ret(3);
ret[0]=RadiansToDegrees(lon);
ret[1]=RadiansToDegrees(lat);
ret[2]=Height;
return ret;
}
QVector <double> LKS94Projection::MTD11(QVector <double>& p)
{
double scaleFactor = 0.9998; // scale factor
double centralMeridian = 0.41887902047863912; // Center qlonglongitude (projection center)
double latOrigin = 0.0; // center latitude
double falseNorthing = 0.0; // y offset in meters
double falseEasting = 500000.0; // x offset in meters
double semiMajor = 6378137.0; // major axis
double semiMinor = 6356752.3141403561; // minor axis
double metersPerUnit = 1.0;
double e0, e1, e2, e3; // eccentricity constants
double e, es, esp; // eccentricity constants
double ml0; // small value m
es =(semiMinor * semiMinor) / (semiMajor * semiMajor);
es=1.0-es;
e = sqrt(es);
e0 = e0fn(es);
e1 = e1fn(es);
e2 = e2fn(es);
e3 = e3fn(es);
ml0 = semiMajor * mlfn(e0, e1, e2, e3, latOrigin);
esp = es / (1.0 - es);
// ...
double con, phi;
double delta_phi;
qlonglong i;
double sin_phi, cos_phi, tan_phi;
double c, cs, t, ts, n, r, d, ds;
qlonglong max_iter = 6;
double x = p[0] * metersPerUnit - falseEasting;
double y = p[1] * metersPerUnit - falseNorthing;
con = (ml0 + y / scaleFactor) / semiMajor;
phi = con;
for(i = 0; ; i++)
{
delta_phi = ((con + e1 * sin(2.0 * phi) - e2 * sin(4.0 * phi) + e3 * sin(6.0 * phi)) / e0) - phi;
phi += delta_phi;
if(fabs(delta_phi) <= EPSLoN)
break;
if(i >= max_iter)
throw "Latitude failed to converge";
}
if(fabs(phi) < HALF_PI)
{
SinCos(phi, sin_phi, cos_phi);
tan_phi = tan(phi);
c = esp * pow(cos_phi, 2);
cs = pow(c, 2);
t = pow(tan_phi, 2);
ts = pow(t, 2);
con = 1.0 - es * pow(sin_phi, 2);
n = semiMajor / sqrt(con);
r = n * (1.0 - es) / con;
d = x / (n * scaleFactor);
ds = pow(d, 2);
double lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t +
10.0 * c - 4.0 * cs - 9.0 * esp - ds / 30.0 * (61.0 + 90.0 * t +
298.0 * c + 45.0 * ts - 252.0 * esp - 3.0 * cs)));
double lon = AdjustLongitude(centralMeridian + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t +
c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * esp +
24.0 * ts))) / cos_phi));
if(p.count() < 3)
{
QVector<double> ret(2);
ret[0]= RadiansToDegrees(lon);
ret[1]= RadiansToDegrees(lat);
return ret;
}
else
{
QVector<double> ret(3);
ret[0]= RadiansToDegrees(lon);
ret[1]= RadiansToDegrees(lat);
ret[2]=p[2];
return ret;
//return new double[] { RadiansToDegrees(lon), RadiansToDegrees(lat), p[2] };
}
}
else
{
if(p.count() < 3)
{
QVector<double> ret(2);
ret[0]= RadiansToDegrees(HALF_PI * Sign(y));
ret[1]= RadiansToDegrees(centralMeridian);
return ret;
}
else
{
QVector<double> ret(3);
ret[0]= RadiansToDegrees(HALF_PI * Sign(y));
ret[1]= RadiansToDegrees(centralMeridian);
ret[2]=p[2];
return ret;
}
}
}
double LKS94Projection::Clip(double const& n, double const& minValue, double const& maxValue)
{
return qMin(qMax(n, minValue), maxValue);
}
double LKS94Projection::GetTileMatrixResolution(int const& zoom)
{
double ret = 0;
switch(zoom)
{
case 0:
{
ret = 1587.50317500635;
}
break;
case 1:
{
ret = 793.751587503175;
}
break;
case 2:
{
ret = 529.167725002117;
}
break;
case 3:
{
ret = 264.583862501058;
}
break;
case 4:
{
ret = 132.291931250529;
}
break;
case 5:
{
ret = 52.9167725002117;
}
break;
case 6:
{
ret = 26.4583862501058;
}
break;
case 7:
{
ret = 13.2291931250529;
}
break;
case 8:
{
ret = 6.61459656252646;
}
break;
case 9:
{
ret = 2.64583862501058;
}
break;
case 10:
{
ret = 1.32291931250529;
}
break;
case 11:
{
ret = 0.529167725002117;
}
break;
}
return ret;
}
double LKS94Projection::GetGroundResolution(int const& zoom, double const& latitude)
{
return GetTileMatrixResolution(zoom);
}
Size LKS94Projection::GetTileMatrixMinXY(int const& zoom)
{
Size ret;
switch(zoom)
{
case 0:
{
ret = Size(12, 8);
}
break;
case 1:
{
ret = Size(24, 17);
}
break;
case 2:
{
ret = Size(37, 25);
}
break;
case 3:
{
ret = Size(74, 51);
}
break;
case 4:
{
ret = Size(149, 103);
}
break;
case 5:
{
ret = Size(374, 259);
}
break;
case 6:
{
ret = Size(749, 519);
}
break;
case 7:
{
ret = Size(1594, 1100);
}
break;
case 8:
{
ret = Size(3188, 2201);
}
break;
case 9:
{
ret = Size(7971, 5502);
}
break;
case 10:
{
ret = Size(15943, 11005);
}
break;
case 11:
{
ret = Size(39858, 27514);
}
break;
}
return ret;
}
Size LKS94Projection::GetTileMatrixMaxXY(int const& zoom)
{
Size ret;
switch(zoom)
{
case 0:
{
ret = Size(14, 10);
}
break;
case 1:
{
ret = Size(30, 20);
}
break;
case 2:
{
ret = Size(45, 31);
}
break;
case 3:
{
ret = Size(90, 62);
}
break;
case 4:
{
ret = Size(181, 125);
}
break;
case 5:
{
ret = Size(454, 311);
}
break;
case 6:
{
ret = Size(903, 623);
}
break;
case 7:
{
ret = Size(1718, 1193);
}
break;
case 8:
{
ret = Size(3437, 2386);
}
break;
case 9:
{
ret = Size(8594, 5966);
}
break;
case 10:
{
ret = Size(17189, 11932);
}
break;
case 11:
{
ret = Size(42972, 29831);
}
break;
}
return ret;
}

View File

@ -0,0 +1,43 @@
#ifndef LKS94PROJECTION_H
#define LKS94PROJECTION_H
#include <QVector>
#include "cmath"
#include "../internals/pureprojection.h"
class LKS94Projection:public PureProjection
{
public:
LKS94Projection();
double GetTileMatrixResolution(int const& zoom);
virtual QString Type(){return "LKS94Projection";}
virtual Size TileSize() const;
virtual double Axis() const;
virtual double Flattening() const;
virtual Point FromLatLngToPixel(double lat, double lng, int const& zoom);
virtual PointLatLng FromPixelToLatLng(int const& x, int const& y, int const& zoom);
virtual double GetGroundResolution(int const& zoom, double const& latitude);
virtual Size GetTileMatrixMinXY(int const& zoom);
virtual Size GetTileMatrixMaxXY(int const& zoom);
private:
const double MinLatitude;
const double MaxLatitude;
const double MinLongitude;
const double MaxLongitude;
const double orignX;
const double orignY;
Size tileSize;
QVector <double> DTM10(const QVector <double>& lonlat);
QVector <double> MTD10(QVector <double>& pnt);
QVector <double> DTM00(QVector <double>& lonlat);
QVector <double> DTM01(QVector <double>& lonlat);
QVector <double> MTD01(QVector <double>& pnt);
QVector <double> MTD11(QVector <double>& p);
double Clip(double const& n, double const& minValue, double const& maxValue);
};
#endif // LKS94PROJECTION_H

View File

@ -0,0 +1,67 @@
#include "mercatorprojection.h"
MercatorProjection::MercatorProjection():MinLatitude(-85.05112878), MaxLatitude(85.05112878),MinLongitude(-177),
MaxLongitude(177), tileSize(256, 256)
{
}
Point MercatorProjection::FromLatLngToPixel(double lat, double lng, const int &zoom)
{
Point ret;// = Point.Empty;
lat = Clip(lat, MinLatitude, MaxLatitude);
lng = Clip(lng, MinLongitude, MaxLongitude);
double x = (lng + 180) / 360;
double sinLatitude = sin(lat * M_PI / 180);
double y = 0.5 - log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * M_PI);
Size s = GetTileMatrixSizePixel(zoom);
int mapSizeX = s.Width();
int mapSizeY = s.Height();
ret.SetX((int) Clip(x * mapSizeX + 0.5, 0, mapSizeX - 1));
ret.SetY((int) Clip(y * mapSizeY + 0.5, 0, mapSizeY - 1));
return ret;
}
PointLatLng MercatorProjection::FromPixelToLatLng(const int &x, const int &y, const int &zoom)
{
PointLatLng ret;// = PointLatLng.Empty;
Size s = GetTileMatrixSizePixel(zoom);
double mapSizeX = s.Width();
double mapSizeY = s.Height();
double xx = (Clip(x, 0, mapSizeX - 1) / mapSizeX) - 0.5;
double yy = 0.5 - (Clip(y, 0, mapSizeY - 1) / mapSizeY);
ret.SetLat(90 - 360 * atan(exp(-yy * 2 * M_PI)) / M_PI);
ret.SetLng(360 * xx);
return ret;
}
double MercatorProjection::Clip(const double &n, const double &minValue, const double &maxValue) const
{
return qMin(qMax(n, minValue), maxValue);
}
Size MercatorProjection::TileSize() const
{
return tileSize;
}
double MercatorProjection::Axis() const
{
return 6378137;
}
double MercatorProjection::Flattening() const
{
return (1.0 / 298.257223563);
}
Size MercatorProjection::GetTileMatrixMaxXY(const int &zoom)
{
int xy = (1 << zoom);
return Size(xy - 1, xy - 1);
}
Size MercatorProjection::GetTileMatrixMinXY(const int &zoom)
{
return Size(0, 0);
}

View File

@ -0,0 +1,25 @@
#ifndef MERCATORPROJECTION_H
#define MERCATORPROJECTION_H
#include "../internals/pureprojection.h"
class MercatorProjection:public PureProjection
{
public:
MercatorProjection();
virtual QString Type(){return "MercatorProjection";}
virtual Size TileSize() const;
virtual double Axis() const;
virtual double Flattening()const;
virtual Point FromLatLngToPixel(double lat, double lng, int const& zoom);
virtual PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom);
virtual Size GetTileMatrixMinXY(const int &zoom);
virtual Size GetTileMatrixMaxXY(const int &zoom);
private:
const double MinLatitude;
const double MaxLatitude;
const double MinLongitude;
const double MaxLongitude;
double Clip(double const& n, double const& minValue, double const& maxValue)const;
Size tileSize;
};
#endif // MERCATORPROJECTION_H

View File

@ -0,0 +1,82 @@
#include "mercatorprojectionyandex.h"
MercatorProjectionYandex::MercatorProjectionYandex():MinLatitude(-85.05112878), MaxLatitude(85.05112878),MinLongitude(-177),
MaxLongitude(177), tileSize(256, 256),RAD_DEG(180 / M_PI),DEG_RAD(M_PI / 180), MathPiDiv4(M_PI / 4)
{
}
Point MercatorProjectionYandex::FromLatLngToPixel(double lat, double lng, const int &zoom)
{
lat = Clip(lat, MinLatitude, MaxLatitude);
lng = Clip(lng, MinLongitude, MaxLongitude);
double rLon = lng * DEG_RAD; // Math.PI / 180;
double rLat = lat * DEG_RAD; // Math.PI / 180;
double a = 6378137;
double k = 0.0818191908426;
double z = tan(MathPiDiv4 + rLat / 2) / pow((tan(MathPiDiv4 + asin(k * sin(rLat)) / 2)), k);
double z1 = pow(2, 23 - zoom);
double DX = ((20037508.342789 + a * rLon) * 53.5865938 / z1);
double DY = ((20037508.342789 - a * log(z)) * 53.5865938 / z1);
Point ret;// = Point.Empty;
ret.SetX((int) DX);
ret.SetY((int) DY);
return ret;
}
PointLatLng MercatorProjectionYandex::FromPixelToLatLng(const int &x, const int &y, const int &zoom)
{
Size s = GetTileMatrixSizePixel(zoom);
double mapSizeX = s.Width();
double mapSizeY = s.Height();
double a = 6378137;
double c1 = 0.00335655146887969;
double c2 = 0.00000657187271079536;
double c3 = 0.00000001764564338702;
double c4 = 0.00000000005328478445;
double z1 = (23 - zoom);
double mercX = (x * pow(2, z1)) / 53.5865938 - 20037508.342789;
double mercY = 20037508.342789 - (y *pow(2, z1)) / 53.5865938;
double g = M_PI /2 - 2 *atan(1 / exp(mercY /a));
double z = g + c1 * sin(2 * g) + c2 * sin(4 * g) + c3 * sin(6 * g) + c4 * sin(8 * g);
PointLatLng ret;// = PointLatLng.Empty;
ret.SetLat(z * RAD_DEG);
ret.SetLng (mercX / a * RAD_DEG);
return ret;
}
double MercatorProjectionYandex::Clip(const double &n, const double &minValue, const double &maxValue) const
{
return qMin(qMax(n, minValue), maxValue);
}
Size MercatorProjectionYandex::TileSize() const
{
return tileSize;
}
double MercatorProjectionYandex::Axis() const
{
return 6356752.3142;
}
double MercatorProjectionYandex::Flattening() const
{
return (1.0 / 298.257223563);
}
Size MercatorProjectionYandex::GetTileMatrixMaxXY(const int &zoom)
{
int xy = (1 << zoom);
return Size(xy - 1, xy - 1);
}
Size MercatorProjectionYandex::GetTileMatrixMinXY(const int &zoom)
{
return Size(0, 0);
}

View File

@ -0,0 +1,30 @@
#ifndef MERCATORPROJECTIONYANDEX_H
#define MERCATORPROJECTIONYANDEX_H
#include "../internals/pureprojection.h"
class MercatorProjectionYandex:public PureProjection
{
public:
MercatorProjectionYandex();
virtual QString Type(){return "MercatorProjectionYandex";}
virtual Size TileSize() const;
virtual double Axis() const;
virtual double Flattening()const;
virtual Point FromLatLngToPixel(double lat, double lng, int const& zoom);
virtual PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom);
virtual Size GetTileMatrixMinXY(const int &zoom);
virtual Size GetTileMatrixMaxXY(const int &zoom);
private:
const double MinLatitude;
const double MaxLatitude;
const double MinLongitude;
const double MaxLongitude;
const double RAD_DEG;
const double DEG_RAD;
const double MathPiDiv4;
double Clip(double const& n, double const& minValue, double const& maxValue)const;
Size tileSize;
};
#endif // MERCATORPROJECTIONYANDEX_H

View File

@ -0,0 +1,67 @@
#include "platecarreeprojection.h"
PlateCarreeProjection::PlateCarreeProjection():MinLatitude(-85.05112878), MaxLatitude(85.05112878),MinLongitude(-180),
MaxLongitude(180), tileSize(512, 512)
{
}
Point PlateCarreeProjection::FromLatLngToPixel(double lat, double lng, const int &zoom)
{
Point ret;// = Point.Empty;
lat = Clip(lat, MinLatitude, MaxLatitude);
lng = Clip(lng, MinLongitude, MaxLongitude);
Size s = GetTileMatrixSizePixel(zoom);
double mapSizeX = s.Width();
double mapSizeY = s.Height();
double scale = 360.0 / mapSizeX;
ret.SetY((int) ((90.0 - lat) / scale));
ret.SetX((int) ((lng + 180.0) / scale));
return ret;
}
PointLatLng PlateCarreeProjection::FromPixelToLatLng(const int &x, const int &y, const int &zoom)
{
PointLatLng ret;// = PointLatLng.Empty;
Size s = GetTileMatrixSizePixel(zoom);
double mapSizeX = s.Width();
double mapSizeY = s.Height();
double scale = 360.0 / mapSizeX;
ret.SetLat(90 - (y * scale));
ret.SetLng((x * scale) - 180);
return ret;
}
double PlateCarreeProjection::Clip(const double &n, const double &minValue, const double &maxValue) const
{
return qMin(qMax(n, minValue), maxValue);
}
Size PlateCarreeProjection::TileSize() const
{
return tileSize;
}
double PlateCarreeProjection::Axis() const
{
return 6378137;
}
double PlateCarreeProjection::Flattening() const
{
return (1.0 / 298.257223563);
}
Size PlateCarreeProjection::GetTileMatrixMaxXY(const int &zoom)
{
int y = (int) pow(2, zoom);
return Size((2*y) - 1, y - 1);
}
Size PlateCarreeProjection::GetTileMatrixMinXY(const int &zoom)
{
return Size(0, 0);
}

View File

@ -0,0 +1,27 @@
#ifndef PLATECARREEPROJECTION_H
#define PLATECARREEPROJECTION_H
#include "../internals/pureprojection.h"
class PlateCarreeProjection:public PureProjection
{
public:
PlateCarreeProjection();
virtual QString Type(){return "PlateCarreeProjection";}
virtual Size TileSize() const;
virtual double Axis() const;
virtual double Flattening()const;
virtual Point FromLatLngToPixel(double lat, double lng, int const& zoom);
virtual PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom);
virtual Size GetTileMatrixMinXY(const int &zoom);
virtual Size GetTileMatrixMaxXY(const int &zoom);
private:
const double MinLatitude;
const double MaxLatitude;
const double MinLongitude;
const double MaxLongitude;
double Clip(double const& n, double const& minValue, double const& maxValue)const;
Size tileSize;
};
#endif // PLATECARREEPROJECTION_H

View File

@ -0,0 +1,66 @@
#include "platecarreeprojectionpergo.h"
PlateCarreeProjectionPergo::PlateCarreeProjectionPergo():MinLatitude(-85.05112878), MaxLatitude(85.05112878),MinLongitude(-180),
MaxLongitude(180), tileSize(256, 256)
{
}
Point PlateCarreeProjectionPergo::FromLatLngToPixel(double lat, double lng, const int &zoom)
{
Point ret;// = Point.Empty;
lat = Clip(lat, MinLatitude, MaxLatitude);
lng = Clip(lng, MinLongitude, MaxLongitude);
Size s = GetTileMatrixSizePixel(zoom);
double mapSizeX = s.Width();
double mapSizeY = s.Height();
double scale = 360.0 / mapSizeX;
ret.SetY((int) ((90.0 - lat) / scale));
ret.SetX((int) ((lng + 180.0) / scale));
return ret;
}
PointLatLng PlateCarreeProjectionPergo::FromPixelToLatLng(const int &x, const int &y, const int &zoom)
{
PointLatLng ret;// = PointLatLng.Empty;
Size s = GetTileMatrixSizePixel(zoom);
double mapSizeX = s.Width();
double mapSizeY = s.Height();
double scale = 360.0 / mapSizeX;
ret.SetLat(90 - (y * scale));
ret.SetLng((x * scale) - 180);
return ret;
}
double PlateCarreeProjectionPergo::Clip(const double &n, const double &minValue, const double &maxValue) const
{
return qMin(qMax(n, minValue), maxValue);
}
Size PlateCarreeProjectionPergo::TileSize() const
{
return tileSize;
}
double PlateCarreeProjectionPergo::Axis() const
{
return 6378137;
}
double PlateCarreeProjectionPergo::Flattening() const
{
return (1.0 / 298.257223563);
}
Size PlateCarreeProjectionPergo::GetTileMatrixMaxXY(const int &zoom)
{
int y = (int) pow(2, zoom);
return Size((2*y) - 1, y - 1);
}
Size PlateCarreeProjectionPergo::GetTileMatrixMinXY(const int &zoom)
{
return Size(0, 0);
}

View File

@ -0,0 +1,27 @@
#ifndef PLATECARREEPROJECTIONPERGO_H
#define PLATECARREEPROJECTIONPERGO_H
#include "../internals/pureprojection.h"
class PlateCarreeProjectionPergo:public PureProjection
{
public:
PlateCarreeProjectionPergo();
virtual QString Type(){return "PlateCarreeProjectionPergo";}
virtual Size TileSize() const;
virtual double Axis() const;
virtual double Flattening()const;
virtual Point FromLatLngToPixel(double lat, double lng, int const& zoom);
virtual PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom);
virtual Size GetTileMatrixMinXY(const int &zoom);
virtual Size GetTileMatrixMaxXY(const int &zoom);
private:
const double MinLatitude;
const double MaxLatitude;
const double MinLongitude;
const double MaxLongitude;
double Clip(double const& n, double const& minValue, double const& maxValue)const;
Size tileSize;
};
#endif // PLATECARREEPROJECTIONPERGO_H

View File

@ -0,0 +1,178 @@
#include "pureprojection.h"
Point PureProjection::FromLatLngToPixel(const PointLatLng::PointLatLng &p,const int &zoom)
{
return FromLatLngToPixel(p.Lat(), p.Lng(), zoom);
}
PointLatLng PureProjection::FromPixelToLatLng(const Point &p,const int &zoom)
{
return FromPixelToLatLng(p.X(), p.Y(), zoom);
}
Point PureProjection::FromPixelToTileXY(const Point &p)
{
return Point((int) (p.X() / TileSize().Width()), (int) (p.Y() / TileSize().Height()));
}
Point PureProjection::FromTileXYToPixel(const Point &p)
{
return Point((p.X() * TileSize().Width()), (p.Y() * TileSize().Height()));
}
Size PureProjection::GetTileMatrixSizeXY(const int &zoom)
{
Size sMin = GetTileMatrixMinXY(zoom);
Size sMax = GetTileMatrixMaxXY(zoom);
return Size(sMax.Width() - sMin.Width() + 1, sMax.Height() - sMin.Height() + 1);
}
int PureProjection::GetTileMatrixItemCount(const int &zoom)
{
Size s = GetTileMatrixSizeXY(zoom);
return (s.Width() * s.Height());
}
Size PureProjection::GetTileMatrixSizePixel(const int &zoom)
{
Size s = GetTileMatrixSizeXY(zoom);
return Size(s.Width() * TileSize().Width(), s.Height() * TileSize().Height());
}
QList<Point> PureProjection::GetAreaTileList(const RectLatLng &rect,const int &zoom,const int &padding)
{
QList<Point> ret;
Point topLeft = FromPixelToTileXY(FromLatLngToPixel(rect.LocationTopLeft(), zoom));
Point rightBottom = FromPixelToTileXY(FromLatLngToPixel(rect.Bottom(), rect.Right(), zoom));
for(int x = (topLeft.X() - padding); x <= (rightBottom.X() + padding); x++)
{
for(int y = (topLeft.Y() - padding); y <= (rightBottom.Y() + padding); y++)
{
Point p = Point(x, y);
if(!ret.contains(p) && p.X() >= 0 && p.Y() >= 0)
{
ret.append(p);
}
}
}
//ret.TrimExcess();
return ret;
}
double PureProjection::GetGroundResolution(const int &zoom,const double &latitude)
{
return (cos(latitude * (PI / 180)) * 2 * PI * Axis()) / GetTileMatrixSizePixel(zoom).Width();
}
double PureProjection::Sign(const double &x)
{
if(x < 0.0)
return (-1);
else
return (1);
}
double PureProjection::AdjustLongitude(double x)
{
qlonglong count = 0;
while(true)
{
if(qAbs(x) <= PI)
break;
else
if(((qlonglong) qAbs(x / PI)) < 2)
x = x - (Sign(x) * TWO_PI);
else
if(((qlonglong) qAbs(x / TWO_PI)) < MAXLONG)
{
x = x - (((qlonglong) (x / TWO_PI)) * TWO_PI);
}
else
if(((qlonglong) qAbs(x / (MAXLONG * TWO_PI))) < MAXLONG)
{
x = x - (((qlonglong) (x / (MAXLONG * TWO_PI))) * (TWO_PI * MAXLONG));
}
else
if(((qlonglong) qAbs(x / (DBLLONG * TWO_PI))) < MAXLONG)
{
x = x - (((qlonglong) (x / (DBLLONG * TWO_PI))) * (TWO_PI * DBLLONG));
}
else
x = x - (Sign(x) * TWO_PI);
count++;
if(count > MAX_VAL)
break;
}
return (x);
}
void PureProjection::SinCos(const double &val, double &si, double &co)
{
si = sin(val);
co = cos(val);
}
double PureProjection::e0fn(const double &x)
{
return (1.0 - 0.25 * x * (1.0 + x / 16.0 * (3.0 + 1.25 * x)));
}
double PureProjection::e1fn(const double &x)
{
return (0.375 * x * (1.0 + 0.25 * x * (1.0 + 0.46875 * x)));
}
double PureProjection::e2fn(const double &x)
{
return (0.05859375 * x * x * (1.0 + 0.75 * x));
}
double PureProjection::e3fn(const double &x)
{
return (x * x * x * (35.0 / 3072.0));
}
double PureProjection::mlfn(const double &e0,const double &e1,const double &e2,const double &e3,const double &phi)
{
return (e0 * phi - e1 * sin(2.0 * phi) + e2 * sin(4.0 * phi) - e3 * sin(6.0 * phi));
}
qlonglong PureProjection::GetUTMzone(const double &lon)
{
return ((qlonglong) (((lon + 180.0) / 6.0) + 1.0));
}
void PureProjection::FromGeodeticToCartesian(double Lat,double Lng,const double &Height, double &X, double &Y, double &Z)
{
Lat = (PI / 180) * Lat;
Lng = (PI / 180) * Lng;
double B = Axis() * (1.0 - Flattening());
double ee = 1.0 - (B / Axis()) * (B / Axis());
double N = (Axis() / sqrt(1.0 - ee * sin(Lat) * sin(Lat)));
X = (N + Height) * cos(Lat) * cos(Lng);
Y = (N + Height) * cos(Lat) * sin(Lng);
Z = (N * (B / Axis()) * (B / Axis()) + Height) * sin(Lat);
}
void PureProjection::FromCartesianTGeodetic(const double &X,const double &Y,const double &Z, double &Lat, double &Lng)
{
double E = Flattening() * (2.0 - Flattening());
Lng = atan2(Y, X);
double P = sqrt(X * X + Y * Y);
double Theta = atan2(Z, (P * (1.0 - Flattening())));
double st = sin(Theta);
double ct = cos(Theta);
Lat = atan2(Z + E / (1.0 - Flattening()) * Axis() * st * st * st, P - E * Axis() * ct * ct * ct);
Lat /= (PI / 180);
Lng /= (PI / 180);
}

View File

@ -0,0 +1,78 @@
#ifndef PUREPROJECTION_H
#define PUREPROJECTION_H
#include "../core/size.h"
#include "../core/point.h"
#include "../internals/pointlatlng.h"
#include "pointlatlng.h"
#include "cmath"
#include "rectlatlng.h"
class PureProjection
{
public:
virtual Size TileSize()const=0;
virtual double Axis()const=0;
virtual double Flattening()const=0;
virtual Point FromLatLngToPixel(double lat, double lng, int const& zoom)=0;
virtual PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom)=0;
virtual QString Type(){return "PureProjection";}
Point FromLatLngToPixel(const PointLatLng &p,const int &zoom);
PointLatLng FromPixelToLatLng(const Point &p,const int &zoom);
virtual Point FromPixelToTileXY(const Point &p);
virtual Point FromTileXYToPixel(const Point &p);
virtual Size GetTileMatrixMinXY(const int &zoom)=0;
virtual Size GetTileMatrixMaxXY(const int &zoom)=0;
virtual Size GetTileMatrixSizeXY(const int &zoom);
int GetTileMatrixItemCount(const int &zoom);
virtual Size GetTileMatrixSizePixel(const int &zoom);
QList<Point> GetAreaTileList(const RectLatLng &rect,const int &zoom,const int &padding);
virtual double GetGroundResolution(const int &zoom,const double &latitude);
double DegreesToRadians(const double &deg)const
{
return (D2R * deg);
}
double RadiansToDegrees(const double &rad)const
{
return (R2D * rad);
}
void FromGeodeticToCartesian(double Lat,double Lng,const double &Height, double &X, double &Y, double &Z);
void FromCartesianTGeodetic(const double &X,const double &Y,const double &Z, double &Lat, double &Lng);
protected:
static const double PI = M_PI;
static const double HALF_PI = (M_PI * 0.5);
static const double TWO_PI= (M_PI * 2.0);
static const double EPSLoN= 1.0e-10;
static const double MAX_VAL= 4;
static const double MAXLONG= 2147483647;
static const double DBLLONG= 4.61168601e18;
static const double R2D=180/M_PI;
static const double D2R=M_PI/180;
static double Sign(const double &x);
static double AdjustLongitude(double x);
static void SinCos(const double &val, double &sin, double &cos);
static double e0fn(const double &x);
static double e1fn(const double &x);
static double e2fn(const double &x);
static double e3fn(const double &x);
static double mlfn(const double &e0,const double &e1,const double &e2,const double &e3,const double &phi);
static qlonglong GetUTMzone(const double &lon);
};
#endif // PUREPROJECTION_H

View File

@ -0,0 +1,51 @@
#include "rectangle.h"
Rectangle Rectangle::Empty=Rectangle();
Rectangle Rectangle::FromLTRB(int left, int top, int right, int bottom)
{
return Rectangle(left,
top,
right - left,
bottom - top);
}
Rectangle Rectangle::Inflate(Rectangle rect, int x, int y)
{
Rectangle r = rect;
r.Inflate(x, y);
return r;
}
Rectangle Rectangle::Intersect(Rectangle a, Rectangle b)
{
int x1 = std::max(a.X(), b.X());
int x2 = std::min(a.X() + a.Width(), b.X() + b.Width());
int y1 = std::max(a.Y(), b.Y());
int y2 = std::min(a.Y() + a.Height(), b.Y() + b.Height());
if(x2 >= x1
&& y2 >= y1)
{
return Rectangle(x1, y1, x2 - x1, y2 - y1);
}
return Rectangle::Empty;
}
Rectangle Rectangle::Union(const Rectangle &a,const Rectangle &b)
{
int x1 = std::min(a.x, b.x);
int x2 = std::max(a.x + a.width, b.x + b.width);
int y1 = std::min(a.y, b.y);
int y2 = std::max(a.y + a.height, b.y + b.height);
return Rectangle(x1, y1, x2 - x1, y2 - y1);
}
bool operator==(Rectangle const& lhs,Rectangle const& rhs)
{
return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.width == rhs.width && lhs.height == rhs.height);
}
uint qHash(Rectangle const& rect)
{
return (int) ((quint32) rect.x ^
(((quint32) rect.y << 13) | ((quint32) rect.y >> 19)) ^
(((quint32) rect.width << 26) | ((quint32) rect.width >> 6)) ^
(((quint32) rect.height << 7) | ((quint32) rect.height >> 25)));
}

View File

@ -0,0 +1,129 @@
#ifndef RECTANGLE_H
#define RECTANGLE_H
//#include <point.h>
#include "../core/size.h"
#include "math.h"
struct Rectangle
{
friend uint qHash(Rectangle const& rect);
friend bool operator==(Rectangle const& lhs,Rectangle const& rhs);
public:
static Rectangle Empty;
static Rectangle FromLTRB(int left, int top, int right, int bottom);
Rectangle(){x=0; y=0; width=0; height=0; };
Rectangle(int x, int y, int width, int height)
{
this->x = x;
this->y = y;
this->width = width;
this->height = height;
}
Rectangle(Point location, Size size)
{
this->x = location.X();
this->y = location.Y();
this->width = size.Width();
this->height = size.Height();
}
Point GetLocation() {
return Point(x, y);
}
void SetLocation(const Point &value)
{
x = value.X();
y = value.Y();
}
int X(){return x;}
int Y(){return y;}
void SetX(const int &value){x=value;}
void SetY(const int &value){y=value;}
int Width(){return width;}
void SetWidth(const int &value){width=value;}
int Height(){return height;}
void SetHeight(const int &value){height=value;}
int Left(){return x;}
int Top(){return y;}
int Right(){return x+width;}
int Bottom(){return y+height;}
bool IsEmpty(){return (height==0 && width==0 && x==0 && y==0);}
bool operator==(const Rectangle &cSource)
{
return (cSource.x == x && cSource.y == y && cSource.width == width && cSource.height == height);
}
bool operator!=(const Rectangle &cSource){return !(*this==cSource);}
bool Contains(const int &x,const int &y)
{
return this->x<=x && x<this->x+this->width && this->y<=y && y<this->y+this->height;
}
bool Contains(const Point &pt)
{
return Contains(pt.X(),pt.Y());
}
bool Contains(const Rectangle &rect)
{
return (this->x <= rect.x) &&
((rect.x + rect.width) <= (this->x + this->width)) &&
(this->y <= rect.y) &&
((rect.y + rect.height) <= (this->y + this->height));
}
void Inflate(const int &width,const int &height)
{
this->x -= width;
this->y -= height;
this->width += 2*width;
this->height += 2*height;
}
void Inflate(Size &size)
{
Inflate(size.Width(), size.Height());
}
static Rectangle Inflate(Rectangle rect, int x, int y);
void Intersect(const Rectangle &rect)
{
Rectangle result = Rectangle::Intersect(rect, *this);
this->x = result.X();
this->y = result.Y();
this->width = result.Width();
this->height = result.Height();
}
static Rectangle Intersect(Rectangle a, Rectangle b);
bool IntersectsWith(const Rectangle &rect)
{
return (rect.x < this->x + this->width) &&
(this->x < (rect.x + rect.width)) &&
(rect.y < this->y + this->height) &&
(this->y < rect.y + rect.height);
}
static Rectangle Union(const Rectangle &a,const Rectangle &b);
void Offset(const Point &pos)
{
Offset(pos.X(), pos.Y());
}
void Offset(const int &x,const int &y)
{
this->x += x;
this->y += y;
}
QString ToString()
{
return "{X=" + QString::number(x) + ",Y=" + QString::number(y) +
",Width=" + QString::number(width) +
",Height=" +QString::number(height) +"}";
}
private:
int x;
int y;
int width;
int height;
};
#endif // RECTANGLE_H

View File

@ -0,0 +1,21 @@
#include "rectlatlng.h"
RectLatLng::RectLatLng():lng(0),lat(0),widthLng(0),heightLat(0)
{
}
RectLatLng RectLatLng::Empty=RectLatLng();
uint qHash(RectLatLng const& rect)
{
return (int) (((((uint) rect.Lng()) ^ ((((uint) rect.Lat()) << 13) | (((uint) rect.Lat()) >> 0x13))) ^ ((((uint) rect.WidthLng()) << 0x1a) | (((uint) rect.WidthLng()) >> 6))) ^ ((((uint) rect.HeightLat()) << 7) | (((uint) rect.HeightLat()) >> 0x19)));
}
bool operator==(RectLatLng const& left,RectLatLng const& right)
{
return ((((left.Lng() == right.Lng()) && (left.Lat() == right.Lat())) && (left.WidthLng() == right.WidthLng())) && (left.HeightLat() == right.HeightLat()));
}
bool operator!=(RectLatLng const& left,RectLatLng const& right)
{
return !(left == right);
}

View File

@ -0,0 +1,222 @@
#ifndef RECTLATLNG_H
#define RECTLATLNG_H
//#include "pointlatlng.h"
#include "../internals/pointlatlng.h"
#include "math.h"
#include <QString>
#include "sizelatlng.h"
struct RectLatLng
{
public:
RectLatLng();
static RectLatLng Empty;
friend uint qHash(RectLatLng const& rect);
friend bool operator==(RectLatLng const& left,RectLatLng const& right);
friend bool operator!=(RectLatLng const& left,RectLatLng const& right);
RectLatLng(double const& lat, double const& lng, double const& widthLng, double const& heightLat)
{
this->lng = lng;
this->lat = lat;
this->widthLng = widthLng;
this->heightLat = heightLat;
}
RectLatLng(PointLatLng const& location, SizeLatLng const& size)
{
this->lng = location.Lng();
this->lat = location.Lat();
this->widthLng = size.WidthLng();
this->heightLat = size.HeightLat();
}
static RectLatLng FromLTRB(double const& lng, double const& lat, double const& rightLng, double const& bottomLat)
{
return RectLatLng(lat, lng, rightLng - lng, lat - bottomLat);
}
PointLatLng LocationTopLeft()const
{
return PointLatLng(this->lat, this->lng);
}
void SetLocationTopLeft(PointLatLng const& value)
{
this->lng = value.Lng();
this->lat = value.Lat();
}
PointLatLng LocationRightBottom()
{
PointLatLng ret = PointLatLng(this->lat, this->lng);
ret.Offset(HeightLat(), WidthLng());
return ret;
}
SizeLatLng Size()
{
return SizeLatLng(this->HeightLat(), this->WidthLng());
}
void SetSize(SizeLatLng const& value)
{
this->widthLng = value.WidthLng();
this->heightLat = value.HeightLat();
}
double Lng()const
{
return this->lng;
}
void SetLng(double const& value)
{
this->lng = value;
}
double Lat()const
{
return this->lat;
}
void SetLat(double const& value)
{
this->lat = value;
}
double WidthLng()const
{
return this->widthLng;
}
void SetWidthLng(double const& value)
{
this->widthLng = value;
}
double HeightLat()const
{
return this->heightLat;
}
void SetHeightLat(double const& value)
{
this->heightLat = value;
}
double Left()const
{
return this->Lng();
}
double Top()const
{
return this->Lat();
}
double Right()const
{
return (this->Lng() + this->WidthLng());
}
double Bottom()const
{
return (this->Lat() - this->HeightLat());
}
bool IsEmpty()const
{
if(this->WidthLng() > 0)
{
return (this->HeightLat() <= 0);
}
return true;
}
bool Contains(double const& lat, double const& lng)
{
return ((((this->Lng() <= lng) && (lng < (this->Lng() + this->WidthLng()))) && (this->Lat() >= lat)) && (lat > (this->Lat() - this->HeightLat())));
}
bool Contains(PointLatLng const& pt)
{
return this->Contains(pt.Lat(), pt.Lng());
}
bool Contains(RectLatLng const& rect)
{
return ((((this->Lng() <= rect.Lng()) && ((rect.Lng() + rect.WidthLng()) <= (this->Lng() + this->WidthLng()))) && (this->Lat() >= rect.Lat())) && ((rect.Lat() - rect.HeightLat()) >= (this->Lat() - this->HeightLat())));
}
void Inflate(double const& lat, double const& lng)
{
this->lng -= lng;
this->lat += lat;
this->widthLng += (double)2 * lng;
this->heightLat +=(double)2 * lat;
}
void Inflate(SizeLatLng const& size)
{
this->Inflate(size.HeightLat(), size.WidthLng());
}
static RectLatLng Inflate(RectLatLng const& rect, double const& lat, double const& lng)
{
RectLatLng ef = rect;
ef.Inflate(lat, lng);
return ef;
}
void Intersect(RectLatLng const& rect)
{
RectLatLng ef = Intersect(rect, *this);
this->lng = ef.Lng();
this->lat = ef.Lat();
this->widthLng = ef.WidthLng();
this->heightLat = ef.HeightLat();
}
static RectLatLng Intersect(RectLatLng const& a, RectLatLng const& b)
{
double lng = std::max(a.Lng(), b.Lng());
double num2 = std::min((double) (a.Lng() + a.WidthLng()), (double) (b.Lng() + b.WidthLng()));
double lat = std::max(a.Lat(), b.Lat());
double num4 = std::min((double) (a.Lat() + a.HeightLat()), (double) (b.Lat() + b.HeightLat()));
if((num2 >= lng) && (num4 >= lat))
{
return RectLatLng(lng, lat, num2 - lng, num4 - lat);
}
return Empty;
}
bool IntersectsWith(RectLatLng const& rect)
{
return ((((rect.Lng() < (this->Lng() + this->WidthLng())) && (this->Lng() < (rect.Lng() + rect.WidthLng()))) && (rect.Lat() < (this->Lat() + this->HeightLat()))) && (this->Lat() < (rect.Lat() + rect.HeightLat())));
}
static RectLatLng Union(RectLatLng const& a, RectLatLng const& b)
{
double lng = std::min(a.Lng(), b.Lng());
double num2 = std::max((double) (a.Lng() + a.WidthLng()), (double) (b.Lng() + b.WidthLng()));
double lat = std::min(a.Lat(), b.Lat());
double num4 = std::max((double) (a.Lat() + a.HeightLat()), (double) (b.Lat() + b.HeightLat()));
return RectLatLng(lng, lat, num2 - lng, num4 - lat);
}
void Offset(PointLatLng const& pos)
{
this->Offset(pos.Lat(), pos.Lng());
}
void Offset(double const& lat, double const& lng)
{
this->lng += lng;
this->lat -= lat;
}
QString ToString() const
{
return ("{Lat=" + QString::number(this->Lat()) + ",Lng=" + QString::number(this->Lng()) + ",WidthLng=" + QString::number(this->WidthLng()) + ",HeightLat=" + QString::number(this->HeightLat()) + "}");
}
private:
double lng;
double lat;
double widthLng;
double heightLat;
};
#endif // RECTLATLNG_H
// static RectLatLng()
// {
// Empty = new RectLatLng();
// }
// }

View File

@ -0,0 +1,31 @@
#include "sizelatlng.h"
#include "pointlatlng.h"
SizeLatLng::SizeLatLng():heightLat(0),widthLng(0)
{
}
SizeLatLng::SizeLatLng(PointLatLng const& pt)
{
this->heightLat = pt.Lat();
this->widthLng = pt.Lng();
}
SizeLatLng operator+(SizeLatLng const& sz1, SizeLatLng const& sz2)
{
return SizeLatLng::Add(sz1, sz2);
}
SizeLatLng operator-(SizeLatLng const& sz1, SizeLatLng const& sz2)
{
return SizeLatLng::Subtract(sz1, sz2);
}
bool operator==(SizeLatLng const& sz1, SizeLatLng const& sz2)
{
return ((sz1.WidthLng() == sz2.WidthLng()) && (sz1.HeightLat() == sz2.HeightLat()));
}
bool operator!=(SizeLatLng const& sz1, SizeLatLng const& sz2)
{
return !(sz1 == sz2);
}
SizeLatLng SizeLatLng::Empty=SizeLatLng();

View File

@ -0,0 +1,107 @@
#ifndef SIZELATLNG_H
#define SIZELATLNG_H
#include <QString>
struct PointLatLng;
struct SizeLatLng
{
public:
SizeLatLng();
static SizeLatLng Empty;
SizeLatLng(SizeLatLng const& size)
{
this->widthLng = size.widthLng;
this->heightLat = size.heightLat;
}
SizeLatLng(PointLatLng const& pt);
SizeLatLng(double const& heightLat, double const& widthLng)
{
this->heightLat = heightLat;
this->widthLng = widthLng;
}
friend SizeLatLng operator+(SizeLatLng const& sz1, SizeLatLng const& sz2);
friend SizeLatLng operator-(SizeLatLng const& sz1, SizeLatLng const& sz2);
friend bool operator==(SizeLatLng const& sz1, SizeLatLng const& sz2);
friend bool operator!=(SizeLatLng const& sz1, SizeLatLng const& sz2);
// static explicit operator PointLatLng(SizeLatLng size)
// {
// return new PointLatLng(size.HeightLat(), size.WidthLng());
// }
bool IsEmpty()const
{
return ((this->widthLng == 0) && (this->heightLat == 0));
}
double WidthLng()const
{
return this->widthLng;
}
void SetWidthLng(double const& value)
{
this->widthLng = value;
}
double HeightLat()const
{
return this->heightLat;
}
void SetHeightLat(double const& value)
{
this->heightLat = value;
}
static SizeLatLng Add(SizeLatLng const& sz1, SizeLatLng const& sz2)
{
return SizeLatLng(sz1.HeightLat() + sz2.HeightLat(), sz1.WidthLng() + sz2.WidthLng());
}
static SizeLatLng Subtract(SizeLatLng const& sz1, SizeLatLng const& sz2)
{
return SizeLatLng(sz1.HeightLat() - sz2.HeightLat(), sz1.WidthLng() - sz2.WidthLng());
}
// override bool Equals(object obj)
// {
// if(!(obj is SizeLatLng))
// {
// return false;
// }
// SizeLatLng ef = (SizeLatLng) obj;
// return (((ef.WidthLng == this->WidthLng) && (ef.HeightLat == this->HeightLat)) && ef.GetType().Equals(base.GetType()));
// }
// override int GetHashCode()
// {
// return base.GetHashCode();
// }
// PointLatLng ToPointLatLng()
// {
// return (PointLatLng) this;
// }
QString ToString()
{
return ("{WidthLng=" + QString::number(this->widthLng) + ", HeightLng=" + QString::number(this->heightLat) + "}");
}
private:
double heightLat;
double widthLng;
};
#endif // SIZELATLNG_H

View File

@ -0,0 +1,28 @@
#include "tile.h"
Tile::Tile(int zoom, Point pos)
{
this->zoom=zoom;
this->pos=pos;
}
void Tile::Clear()
{
qDebug()<<"Tile:Clear Overlays";
mutex.lock();
foreach(QByteArray img, Overlays)
{
img.~QByteArray();
}
Overlays.clear();
mutex.unlock();
}
Tile::Tile():zoom(0),pos(0,0)
{
}
Tile& Tile::operator =(const Tile &cSource)
{
this->zoom=cSource.zoom;
this->pos=cSource.pos;
}

View File

@ -0,0 +1,36 @@
#ifndef TILE_H
#define TILE_H
#include "QList"
#include <QImage>
#include "../core/point.h"
#include <QMutex>
#include <QDebug>
class Tile
{
public:
Tile(int zoom,Point pos);
Tile();
void Clear();
int GetZoom(){return zoom;}
Point GetPos(){return pos;}
void SetZoom(const int &value){zoom=value;}
void SetPos(const Point &value){pos=value;}
Tile& operator= (const Tile &cSource);
Tile(const Tile &cSource)
{
this->zoom=cSource.zoom;
this->pos=cSource.pos;
}
QList<QByteArray> Overlays;
protected:
QMutex mutex;
private:
int zoom;
Point pos;
};
#endif // TILE_H

View File

@ -0,0 +1,57 @@
#include "tilematrix.h"
TileMatrix::TileMatrix()
{
}
void TileMatrix::Clear()
{
mutex.lock();
foreach(Tile t,matrix.values())
{
t.Clear();
}
matrix.clear();
mutex.unlock();
}
void TileMatrix::ClearPointsNotIn(QList<Point>list)
{
removals.clear();
mutex.lock();
foreach(Point p, matrix.keys())
{
if(!list.contains(p))
{
removals.append(p);
}
}
mutex.unlock();
foreach(Point p,removals)
{
Tile t=TileAt(p);
if(t.GetZoom()!=0)
{
mutex.lock();
t.Clear();
t.SetZoom(NULL);
matrix.remove(p);
mutex.unlock();
}
}
removals.clear();
}
Tile TileMatrix::TileAt(const Point &p)
{
Tile ret;
mutex.lock();
ret=matrix.value(p);
mutex.unlock();
return ret;
}
void TileMatrix::SetTileAt(const Point &p, const Tile &tile)
{
mutex.lock();
matrix.insert(p,tile);
mutex.unlock();
}

View File

@ -0,0 +1,22 @@
#ifndef TILEMATRIX_H
#define TILEMATRIX_H
#include <QHash>
#include "tile.h"
#include <QList>
#include "../core/point.h"
class TileMatrix
{
public:
TileMatrix();
void Clear();
void ClearPointsNotIn(QList<Point> list);
Tile TileAt(const Point &p);
void SetTileAt(const Point &p,const Tile &tile);
protected:
QHash<Point,Tile> matrix;
QList<Point> removals;
QMutex mutex;
};
#endif // TILEMATRIX_H

View File

@ -0,0 +1,151 @@
#include <QApplication>
#include "gmaps.h"
#include <QDebug>
#include "../core/pureimagecache.h"
#include "QPixmap"
#include <QIODevice>
#include <QtGui/QLabel>
#include "../core/pureimage.h"
#include "../core/rawtile.h"
#include "../core/cache.h"
#include "../core/languagetype.h"
#include "../core/tilecachequeue.h"
#include "../core/cacheitemqueue.h"
#include "../core/maptype.h"
#include "../core/alllayersoftype.h"
#include "geodecoderstatus.h"
//#include "QTest"
#include "threadpool.h"
#include "../internals/core.h"
#include "../core/size.h"
#include "../internals/rectangle.h"
#include "../internals/tile.h"
#include "../internals/tilematrix.h"
#include "../core/point.h"
#include "../core/size.h"
#include "../internals/copyrightstrings.h"
#include "../internals/projections/lks94projection.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// GMaps g;
// qDebug()<<g.GoogleMapsAPIKey;
// qDebug()<<QString(g.levelsForSigPacSpainMap[2]);
// qDebug()<<g.MakeImageUrl(GoogleMap,Point(18,10),5,QString("en"));
// qDebug()<<g.MakeImageUrl(GoogleMap,Point(5,7),3,QString("en"));
// qDebug()<<"DB creation="<<PureImageCache::CreateEmptyDB("C:/Users/Xapo/Documents/QT/QMapControlXx/main.cpp");
// qDebug()<<"end";
PureImageCache p;
PureImageProxy proxy;
QPixmap pixmap("C:/Users/Xapo/Pictures/x.jpg");
QPixmap pixmapb;
QByteArray ba;
QByteArray bb;
QBuffer buffer( &ba );
buffer.open(QIODevice::WriteOnly);
pixmap.save( &buffer, "PNG" ); // writes pixmap into ba in PNG format
//pixmapb=Cache::Instance()->ImageCache.GetImageFromCache(GoogleMap,Point(1,2),3);
// pixmapb=p.GetImageFromCache(GoogleMap,Point(1,2),3);
// RawTile r(GoogleMap,Point(1,2),3);
// g.AddTileToMemoryCache(r,pixmapb);
//pixmap=QPixmap("C:/Users/Xapo/Pictures/y.jpg");
//g.AddTileToMemoryCache(RawTile(GoogleMap,Point(2,2),3),pixmap);
//
// //pixmapb= QPixmap::fromImage(QImage::fromData(bb, "png"));;
// qDebug()<<pixmapb.width();
// // pixmapb=proxy.FromStream(bb);
// bb.clear();
// QLabel label;
QLabel labell;
// pixmapb=QPixmap();
// pixmapb=g.GetTileFromMemoryCache(r);
// label.setPixmap(pixmapb);
//
// label.show();
// pixmapb=g.GetTileFromMemoryCache(RawTile(GoogleMap,Point(4,2),3));
// LanguageType::Types l;//=LanguageType::English;
// l=LanguageType::PortuguesePortugal;
// qDebug()<<LanguageType().toString(LanguageType::PortuguesePortugal);
//qDebug()<<(l==LanguageType::Arabic);
//// TileCacheQueue queue(&p);
////for(int x=0;x<10;++x)
////{
//// CacheItemQueue item(GoogleMap,Point(69,79),QByteArray(),x);
//// // QTest::qsleep(200);
//// queue.EnqueueCacheTask(item);
////}
//pixmapb=PureImageProxy::FromStream(GMaps::Instance()->GetImageFrom(MapType::GoogleMap,Point(7,5),8));
//qDebug()<<"WITH"<<pixmapb.width();
labell.setPixmap(pixmapb);
////
labell.show();
// QCoreApplication::processEvents(QEventLoop::AllEvents);
////pixmapb=GMaps::Instance()->GetImageFrom(MapType::GoogleSatellite,Point(1,0),1);
////labell.setPixmap(pixmapb);
////GeoCoderStatusCode::Types f;
////qDebug()<<"LAT"<<GMaps::Instance()->GetLatLngFromGeodecoder("lisbon",f).Lat();
////QString s=GMaps::Instance()->GetPlacemarkFromGeocoder(GMaps::Instance()->GetLatLngFromGeodecoder("lisbon",f)).Address();
////labell.show();
////labell.setText(s);
//threadpool *g=new threadpool();
// ;
//QThreadPool tp;
//g->setAutoDelete(false);
////tp.tryStart(new threadpool());
////tp.tryStart(new threadpool());
////tp.tryStart(new threadpool());
//int i=10;
//while(i>0)
//{
// tp.tryStart(g);
// tp.tryStart(g);
// //tp.tryStart(g);
// // qDebug()<<tp.activeThreadCount();
// // qDebug()<<"IDEAL"<<QThread::idealThreadCount();
// // while(tp.activeThreadCount()!=1){}
// while(tp.activeThreadCount()!=0){}
// --i;
//}
//foreach(QByteArray arr,g->pix)
// {
// QLabel *lab=new QLabel();
// QPixmap p;
//
// p=PureImageProxy::FromStream(arr);
// lab->setPixmap(p);
// lab->show();
//
// }
// //QCoreApplication::processEvents(QEventLoop::AllEvents);
// // QCoreApplication::processEvents(QEventLoop::AllEvents);
// //while (tp.activeThreadCount()!=0)
// // qDebug()<<tp.activeThreadCount();
//
Core c;
c.SetCurrentPosition(PointLatLng(10,20));
//qDebug()<<"GetLatLng:"<<c.GetCurrentPosition().Lat();
Size s(Point(10,10));
Size ss(5,5);
Point ppp(2,3);
//Point pp(1,2);
Rectangle rt(0,0,10,11);
Rectangle rtt(0,0,10,12);
qDebug()<<"+"<<(s+ss).Height()<<" "<<(s+ss).Width();
Point pp(1,2);
RawTile r(MapType::ArcGIS_Map,Point(1,1),2);
RawTile rr(MapType::ArcGIS_Map,Point(1,1),3);
qDebug()<<pp.X()<<","<<pp.Y()<<qHash(r)<<qHash(rr)<<qHash(rt)<<qHash(rtt)<<qHash(pp)<<qHash(ppp);
Tile ttt;
qDebug()<<ttt.GetZoom();
qDebug()<<googleCopyright;
LKS94Projection lp;
PointLatLng point=lp.FromPixelToLatLng(210, 200,2);
Point pointp=lp.FromLatLngToPixel(point.Lat(),point.Lng(),1);
Size size=lp.TileSize();
qDebug()<<point.ToString()<<" "<<size.ToString()<<pointp.ToString();
return a.exec();
}

View File

@ -0,0 +1,12 @@
DESTDIR = ../build
PROJECT = teste
TEMPLATE = app
QT += network
QT += sql
CONFIG += console
CONFIG -= app_bundle
DEPENDPATH += .
INCLUDEPATH += ../core
SOURCES += main.cpp
LIBS += -L../build -lcore -linternals