1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-18 08:54:15 +01:00

OP-37 GCS/MapPlugin Some fixes to core, fixed sqlite multi-thread access, changed some things from being created on the stack to the heap (I'm starting to sound like a C++ developer...lol)

Continued work on the widget stuff

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@678 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
zedamota 2010-05-28 19:39:51 +00:00 committed by zedamota
parent 1cd94e7b31
commit ab34bbfa7a
20 changed files with 216 additions and 121 deletions

View File

@ -41,6 +41,7 @@ CacheItemQueue& CacheItemQueue::operator =(const CacheItemQueue &cSource)
pos=cSource.pos;
type=cSource.type;
zoom=cSource.zoom;
return *this;
}
bool CacheItemQueue::operator ==(const CacheItemQueue &cSource)
{

View File

@ -12,7 +12,6 @@ SOURCES += gmaps.cpp \
alllayersoftype.cpp \
urlfactory.cpp \
placemark.cpp \
threadpool.cpp \
point.cpp \
size.cpp \
kibertilecache.cpp
@ -33,6 +32,5 @@ HEADERS += gmaps.h \
urlfactory.h \
geodecoderstatus.h \
placemark.h \
threadpool.h \
point.h \
kibertilecache.h

View File

@ -10,10 +10,10 @@ GMaps* GMaps::Instance()
}
GMaps::GMaps():useMemoryCache(true),MaxZoom(19),RetryLoadTile(2)
{
accessmode=AccessMode::ServerOnly;
accessmode=AccessMode::ServerAndCache;
Language=LanguageType::PortuguesePortugal;
LanguageStr=LanguageType().toString(Language);
Cache::Instance()->ImageCache=PureImageCache();
// Cache::Instance()->ImageCache=PureImageCache();
}

View File

@ -24,6 +24,7 @@ bool PureImageCache::CreateEmptyDB(const QString &file)
QDir dir=File.absoluteDir();
QString path=dir.absolutePath();
QString filename=File.fileName();
if(File.exists()) QFile(filename).remove();
if(!dir.exists())
{
qDebug()<<"CreateEmptyDB: Cache path doesn't exist, try to create";
@ -35,7 +36,7 @@ bool PureImageCache::CreateEmptyDB(const QString &file)
}
QSqlDatabase db;
db = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("MapsConnection"));
db = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("CreateConn"));
db.setDatabaseName(file);
if (!db.open())
{
@ -99,14 +100,14 @@ bool PureImageCache::CreateEmptyDB(const QString &file)
db.close();
return true;
}
bool PureImageCache::PutImageToCache(const QByteArray &tile, const MapType::Types &type,const Point &pos,const int &zoom) const
bool PureImageCache::PutImageToCache(const QByteArray &tile, const MapType::Types &type,const Point &pos,const int &zoom)
{
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;
qDebug()<<"PutImageToCache Cache dir="<<dir<<" Try to PUT:"<<pos.ToString();
if(!d.exists(dir))
{
d.mkdir(dir);
@ -122,10 +123,10 @@ bool PureImageCache::PutImageToCache(const QByteArray &tile, const MapType::Type
if(ret)
{
QSqlDatabase cn;
if (QSqlDatabase::contains(QLatin1String("MapsConnection")))
cn = QSqlDatabase::database(QLatin1String("MapsConnection"));
else
cn = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("MapsConnection"));
Mcounter.lock();
qlonglong id=++ConnCounter;
Mcounter.unlock();
cn = QSqlDatabase::addDatabase("QSQLITE",QString::number(id));
cn.setDatabaseName(db);
if(cn.open())
@ -170,10 +171,10 @@ QByteArray PureImageCache::GetImageFromCache(MapType::Types type, Point pos, int
if(ret)
{
QSqlDatabase cn;
if (QSqlDatabase::contains(QLatin1String("MapsConnection")))
cn = QSqlDatabase::database(QLatin1String("MapsConnection"));
else
cn = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("MapsConnection"));
Mcounter.lock();
qlonglong id=++ConnCounter;
Mcounter.unlock();
cn = QSqlDatabase::addDatabase("QSQLITE",QString::number(id));
cn.setDatabaseName(db);
if(cn.open())
{

View File

@ -14,19 +14,25 @@
#include <QVariant>
#include "pureimage.h"
#include <QList>
#include <QMutex>
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;
bool PutImageToCache(const QByteArray &tile,const MapType::Types &type,const Point &pos, const int &zoom);
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;
QMutex Mcounter;
};
static qlonglong ConnCounter=0;
#endif // PUREIMAGECACHE_H

View File

@ -1,39 +0,0 @@
#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

@ -1,28 +0,0 @@
#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

@ -16,6 +16,7 @@ class TileCacheQueue:public QThread
Q_OBJECT
public:
TileCacheQueue();
void EnqueueCacheTask(CacheItemQueue &task);
protected:

View File

@ -17,7 +17,6 @@
#include "../core/alllayersoftype.h"
#include "geodecoderstatus.h"
//#include "QTest"
#include "threadpool.h"
#include "../internals/core.h"
#include "../core/size.h"
#include "../internals/rectangle.h"
@ -30,6 +29,7 @@
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PureImageCache* p=new PureImageCache();
QPixmap pixmap;
//Tile Polling test
pixmap=PureImageProxy::FromStream(GMaps::Instance()->GetImageFrom(MapType::GoogleSatellite,Point(1,0),1));

View File

@ -4,10 +4,14 @@ Core::Core():currentPosition(0,0),currentPositionPixel(0,0),LastLocationInBounds
,minOfTiles(0,0),maxOfTiles(0,0),started(false),isDragging(false),TooltipTextPadding(10,10),MouseWheelZooming(false),loaderLimit(5)
{
mousewheelzoomtype=MouseWheelZoomType::MousePositionAndCenter;
SetProjection(new MercatorProjection());
this->setAutoDelete(false);
renderOffset=Point(0,0);
dragPoint=Point(0,0);
}
void Core::run()
{
qDebug()<<"core:run";
bool last = false;
LoadTask task;
@ -19,24 +23,25 @@ void Core::run()
task = tileLoadQueue.dequeue();
{
last = tileLoadQueue.count() == 0;
qDebug()<<"TileLoadQueue: " << tileLoadQueue.count();
qDebug()<<"TileLoadQueue: " << tileLoadQueue.count()<<" Point:"<<task.Pos.ToString();
}
}
}
MtileLoadQueue.unlock();
if(loaderLimit.tryAcquire(1,GMaps::Instance()->Timeout))
{
if(task.HasValue())
{
qDebug()<<"AKI";
{
Tile m = Matrix.TileAt(task.Pos);
Tile* m = Matrix.TileAt(task.Pos);
if(m.Overlays.count() == 0)
if(m==0 || m->Overlays.count() == 0)
{
qDebug()<<"Fill empty TileMatrix: " + task.ToString();
Tile t = Tile(task.Zoom, task.Pos);
Tile* t = new Tile(task.Zoom, task.Pos);
QVector<MapType::Types> layers= GMaps::Instance()->GetAllLayersOfType(GetMapType());
foreach(MapType::Types tl,layers)
@ -54,14 +59,17 @@ void Core::run()
else // ok
{
img = GMaps::Instance()->GetImageFrom(tl, task.Pos, task.Zoom);
qDebug()<<"Core::run:gotimage size:"<<img.count();
}
if(img.length()!=0)
{
Moverlays.lock();
{
t.Overlays.append(img);
}
t->Overlays.append(img);
qDebug()<<"Core::run append img:"<<img.length()<<" to tile:"<<t->GetPos().ToString()<<" now has "<<t->Overlays.count()<<" overlays";
}
Moverlays.unlock();
break;
}
@ -79,14 +87,16 @@ void Core::run()
while(++retry < GMaps::Instance()->RetryLoadTile);
}
if(t.Overlays.count() > 0)
if(t->Overlays.count() > 0)
{
Matrix.SetTileAt(task.Pos,t);
qDebug()<<"Core::run add tile "<<t->GetPos().ToString()<<" to matrix index "<<task.Pos.ToString();
qDebug()<<"Core::run matrix index "<<task.Pos.ToString()<<" as tile with "<<Matrix.TileAt(task.Pos)->Overlays.count();
}
else
{
t.Clear();
//t = null;
delete t;
t = 0;
}
// layers = null;
@ -185,7 +195,7 @@ void Core::SetMapType(const MapType::Types &value)
{
if(Projection()->Type()!="PlateCarreeProjection")
{
projection = new PlateCarreeProjection();
SetProjection(new PlateCarreeProjection());
}
}
break;
@ -197,7 +207,7 @@ void Core::SetMapType(const MapType::Types &value)
{
if(Projection()->Type()!="LKS94Projection")
{
projection = new LKS94Projection();
SetProjection(new LKS94Projection());
}
}
break;
@ -206,7 +216,7 @@ void Core::SetMapType(const MapType::Types &value)
{
if(Projection()->Type()!="PlateCarreeProjectionPergo")
{
projection = new PlateCarreeProjectionPergo();
SetProjection(new PlateCarreeProjectionPergo());
}
}
break;
@ -215,7 +225,7 @@ void Core::SetMapType(const MapType::Types &value)
{
if(Projection()->Type()!="MercatorProjectionYandex")
{
projection = new MercatorProjectionYandex();
SetProjection(new MercatorProjectionYandex());
}
}
break;
@ -224,7 +234,7 @@ void Core::SetMapType(const MapType::Types &value)
{
if(Projection()->Type()!="MercatorProjection")
{
projection = new MercatorProjection();
SetProjection(new MercatorProjection());
}
}
break;
@ -476,6 +486,7 @@ void Core::CancelAsyncTasks()
tileLoadQueue.clear();
}
MtileLoadQueue.unlock();
ProcessLoadTaskCallback.waitForDone();
}
}
void Core::UpdateBounds()

View File

@ -143,6 +143,10 @@ public:
void FindTilesAround(QList<Point> &list);
void UpdateGroundResolution();
TileMatrix Matrix;
Rectangle tileRect;
signals:
void OnCurrentPositionChanged(PointLatLng point);
void OnTileLoadComplete();
@ -171,13 +175,12 @@ private:
Size minOfTiles;
Size maxOfTiles;
Rectangle tileRect;
Point tilePoint;
Rectangle CurrentRegion;
TileMatrix Matrix;
QQueue<LoadTask> tileLoadQueue;

View File

@ -24,7 +24,7 @@ struct LoadTask
}
bool HasValue()
{
return Zoom==-1;
return !(Zoom==-1);
}
QString ToString()const

View File

@ -24,5 +24,6 @@ Tile& Tile::operator =(const Tile &cSource)
{
this->zoom=cSource.zoom;
this->pos=cSource.pos;
return *this;
}

View File

@ -22,6 +22,7 @@ public:
this->zoom=cSource.zoom;
this->pos=cSource.pos;
}
bool HasValue(){return !(zoom==0);}
QList<QByteArray> Overlays;
protected:

View File

@ -6,9 +6,10 @@ TileMatrix::TileMatrix()
void TileMatrix::Clear()
{
mutex.lock();
foreach(Tile t,matrix.values())
foreach(Tile* t,matrix.values())
{
t.Clear();
delete t;
t=0;
}
matrix.clear();
mutex.unlock();
@ -28,12 +29,12 @@ void TileMatrix::ClearPointsNotIn(QList<Point>list)
mutex.unlock();
foreach(Point p,removals)
{
Tile t=TileAt(p);
if(t.GetZoom()!=0)
Tile* t=TileAt(p);
if(t!=0)
{
mutex.lock();
t.Clear();
t.SetZoom(NULL);
delete t;
t=0;
matrix.remove(p);
mutex.unlock();
}
@ -41,15 +42,16 @@ void TileMatrix::ClearPointsNotIn(QList<Point>list)
}
removals.clear();
}
Tile TileMatrix::TileAt(const Point &p)
Tile* TileMatrix::TileAt(const Point &p)
{
Tile ret;
qDebug()<<"TileMatrix:TileAt:"<<p.ToString();
Tile* ret;
mutex.lock();
ret=matrix.value(p);
ret=matrix.value(p,0);
mutex.unlock();
return ret;
}
void TileMatrix::SetTileAt(const Point &p, const Tile &tile)
void TileMatrix::SetTileAt(const Point &p, Tile* tile)
{
mutex.lock();
matrix.insert(p,tile);

View File

@ -11,10 +11,10 @@ public:
TileMatrix();
void Clear();
void ClearPointsNotIn(QList<Point> list);
Tile TileAt(const Point &p);
void SetTileAt(const Point &p,const Tile &tile);
Tile* TileAt(const Point &p);
void SetTileAt(const Point &p,Tile* tile);
protected:
QHash<Point,Tile> matrix;
QHash<Point,Tile*> matrix;
QList<Point> removals;
QMutex mutex;
};

View File

@ -1,14 +1,124 @@
#include "opmapcontrol.h"
OPMapControl::OPMapControl(QWidget *parent):QWidget(parent)
OPMapControl::OPMapControl(QWidget *parent):QWidget(parent),MapRenderTransform(1)
{
EmptytileBrush = Qt::blue;
MissingDataFont =QFont ("Times",10,QFont::Bold);
EmptyTileText = "We are sorry, but we don't\nhave imagery at this zoom\nlevel for this region.";
EmptyTileBorders = QPen(Qt::white);
ShowTileGridLines=true;
core.SetCurrentRegion(Rectangle(-50, -50, this->width()+100, this->height()+100));
core.SetMapType(MapType::GoogleMap);
resize();
core.SetZoom(2);
connect(&core,SIGNAL(OnNeedInvalidation()),this,SLOT(Core_OnNeedInvalidation()));
core.StartSystem();
}
void OPMapControl::Core_OnNeedInvalidation()
{
this->repaint();
}
void OPMapControl::paintEvent(QPaintEvent* evnt)
{
QWidget::paintEvent(evnt);
QPainter painter(this);
if(MapRenderTransform!=1)
{
QTransform transform;
transform.scale(MapRenderTransform,MapRenderTransform);
painter.setWorldTransform(transform);
{
DrawMap2D(painter);
}
painter.resetTransform();
}
else
{
DrawMap2D(painter);
}
painter.drawText(10,10,"TESTE");
}
void OPMapControl::DrawMap2D(QPainter &painter)
{
painter.drawText(10,10,"TESTE");
for(int i = -core.GetsizeOfMapArea().Width(); i <= core.GetsizeOfMapArea().Width(); i++)
{
for(int j = -core.GetsizeOfMapArea().Height(); j <= core.GetsizeOfMapArea().Height(); j++)
{
core.SettilePoint (core.GetcenterTileXYLocation());
core.SettilePoint(Point(core.GettilePoint().X()+ i,core.GettilePoint().Y()+j));
{
Tile* t = core.Matrix.TileAt(core.GettilePoint());
//qDebug()<<"OPMapControl::DrawMap2D tile:"<<t->GetPos().ToString()<<" as "<<t->Overlays.count()<<" overlays";
//Tile t = Core.Matrix[tileToDraw];
if(t!=0)
{
qDebug()<< "opmapcontrol:draw2d TileHasValue:"<<t->GetPos().ToString();
core.tileRect.SetX(core.GettilePoint().X()*core.tileRect.Width());
core.tileRect.SetY(core.GettilePoint().Y()*core.tileRect.Height());
core.tileRect.Offset(core.GetrenderOffset());
if(core.GetCurrentRegion().IntersectsWith(core.tileRect))
{
bool found = false;
// render tile
//lock(t.Overlays)
{
foreach(QByteArray img,t->Overlays)
{
if(img.count()!=0)
{
if(!found)
found = true;
{
painter.drawPixmap(core.tileRect.X(), core.tileRect.Y(), core.tileRect.Width(), core.tileRect.Height(),PureImageProxy::FromStream(img));
}
}
}
}
if(ShowTileGridLines)
{
painter.setPen(EmptyTileBorders);
painter.drawRect(core.tileRect.X(), core.tileRect.Y(), core.tileRect.Width(), core.tileRect.Height());
{
painter.setFont(MissingDataFont);
painter.setPen(Qt::red);
painter.drawText(QRectF(core.tileRect.X(), core.tileRect.Y(), core.tileRect.Width(), core.tileRect.Height()),Qt::AlignCenter,(core.GettilePoint() == core.GetcenterTileXYLocation()? "CENTER: " :"TILE: ")+core.GettilePoint().ToString());
}
}
// add text if tile is missing
if(!found)
{
painter.fillRect(QRectF(core.tileRect.X(), core.tileRect.Y(), core.tileRect.Width(), core.tileRect.Height()),EmptytileBrush);
painter.setFont(MissingDataFont);
painter.drawText(QRectF(core.tileRect.X(), core.tileRect.Y(), core.tileRect.Width(), core.tileRect.Height()),EmptyTileText);
painter.setPen(EmptyTileBorders);
painter.drawRect(core.tileRect.X(), core.tileRect.Y(), core.tileRect.Width(), core.tileRect.Height());
// raise error
}
}
}
}
}
}
}
void OPMapControl::mousePressEvent ( QMouseEvent* evnt )
@ -25,3 +135,18 @@ void OPMapControl::mouseMoveEvent ( QMouseEvent* evnt )
{
}
void OPMapControl::resizeEvent ( QResizeEvent * event )
{
QWidget::resizeEvent(event);
resize();
}
void OPMapControl::resize()
{
core.OnMapSizeChanged(this->width(),this->height());
core.SetCurrentRegion(Rectangle(-50, -50, this->width()+100, this->height()+100));
if(isVisible())
{
core.GoToCurrentPosition();
}
}

View File

@ -3,22 +3,34 @@
#include "../internals/core.h"
#include <QtGui>
#include <QTransform>
#include <QWidget>
#include <QBrush>
#include <QFont>
class OPMapControl:public QWidget
{
Q_OBJECT
public:
OPMapControl(QWidget *parent=0);
QBrush EmptytileBrush;
QString EmptyTileText;
QPen EmptyTileBorders;
bool ShowTileGridLines;
protected:
void paintEvent ( QPaintEvent* evnt );
void mousePressEvent ( QMouseEvent* evnt );
void mouseReleaseEvent ( QMouseEvent* evnt );
void mouseMoveEvent ( QMouseEvent* evnt );
void resizeEvent ( QResizeEvent * event );
private:
Core core;
qreal MapRenderTransform;
void DrawMap2D(QPainter &painter);
QFont MissingDataFont;
void resize();
private slots:
void Core_OnNeedInvalidation();
};
#endif // OPMAPCONTROL_H

View File

@ -16,7 +16,6 @@
#include "../core/alllayersoftype.h"
#include "geodecoderstatus.h"
//#include "QTest"
#include "threadpool.h"
#include "../internals/core.h"
#include "../core/size.h"
#include "../internals/rectangle.h"

View File

@ -6,8 +6,9 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
map * mw = new map();
mw->resize(400,590);
// mw->resize(400,590);
mw->setWindowTitle("Map");
mw->adjustSize();
mw->show();
return app.exec();
}