1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

OP-37 GCS/MapPlugin cleaning and bug hunting

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@704 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
zedamota 2010-06-02 20:22:31 +00:00 committed by zedamota
parent 59250845ea
commit f31cd81a8d
6 changed files with 597 additions and 577 deletions

View File

@ -27,611 +27,617 @@
*/ */
#include "core.h" #include "core.h"
#ifdef DEBUG_CORE
qlonglong internals::Core::debugcounter=0; qlonglong internals::Core::debugcounter=0;
#endif
using namespace projections; using namespace projections;
namespace internals { namespace internals {
Core::Core():currentPosition(0,0),currentPositionPixel(0,0),LastLocationInBounds(-1,-1),sizeOfMapArea(0,0) Core::Core():currentPosition(0,0),currentPositionPixel(0,0),LastLocationInBounds(-1,-1),sizeOfMapArea(0,0)
,minOfTiles(0,0),maxOfTiles(0,0),isDragging(false),started(false),MouseWheelZooming(false),TooltipTextPadding(10,10),zoom(0),loaderLimit(5) ,minOfTiles(0,0),maxOfTiles(0,0),isDragging(false),started(false),MouseWheelZooming(false),TooltipTextPadding(10,10),zoom(0),loaderLimit(5)
{
mousewheelzoomtype=MouseWheelZoomType::MousePositionAndCenter;
SetProjection(new MercatorProjection());
this->setAutoDelete(false);
renderOffset=Point(0,0);
dragPoint=Point(0,0);
CanDragMap=true;
}
void Core::run()
{
qlonglong debug;
Mdebug.lock();
debug=++debugcounter;
Mdebug.unlock();
#ifdef DEBUG_CORE
qDebug()<<"core:run"<<" ID="<<debug;
#endif //DEBUG_CORE
bool last = false;
LoadTask task;
MtileLoadQueue.lock();
{ {
if(tileLoadQueue.count() > 0) mousewheelzoomtype=MouseWheelZoomType::MousePositionAndCenter;
{ SetProjection(new MercatorProjection());
task = tileLoadQueue.dequeue(); this->setAutoDelete(false);
{ ProcessLoadTaskCallback.setMaxThreadCount(10);
last = tileLoadQueue.count() == 0; renderOffset=Point(0,0);
#ifdef DEBUG_CORE dragPoint=Point(0,0);
qDebug()<<"TileLoadQueue: " << tileLoadQueue.count()<<" Point:"<<task.Pos.ToString()<<" ID="<<debug;; CanDragMap=true;
#endif //DEBUG_CORE
}
}
} }
MtileLoadQueue.unlock(); void Core::run()
if(loaderLimit.tryAcquire(1,OPMaps::Instance()->Timeout))
{ {
#ifdef DEBUG_CORE #ifdef DEBUG_CORE
qDebug()<<"loadLimit semaphore aquired "<<loaderLimit.available()<<" ID="<<debug<<" TASK="<<task.Pos.ToString()<<" "<<task.Zoom; qlonglong debug;
Mdebug.lock();
debug=++debugcounter;
Mdebug.unlock();
qDebug()<<"core:run"<<" ID="<<debug;
#endif //DEBUG_CORE #endif //DEBUG_CORE
if(task.HasValue()) bool last = false;
{
#ifdef DEBUG_CORE
qDebug()<<"task as value, begining get"<<" ID="<<debug;;
#endif //DEBUG_CORE
{
Tile* m = Matrix.TileAt(task.Pos);
if(m==0 || m->Overlays.count() == 0) LoadTask task;
{
#ifdef DEBUG_CORE
qDebug()<<"Fill empty TileMatrix: " + task.ToString()<<" ID="<<debug;;
#endif //DEBUG_CORE
Tile* t = new Tile(task.Zoom, task.Pos);
QVector<MapType::Types> layers= OPMaps::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 = OPMaps::Instance()->GetImageFrom(tl, Point(task.Pos.X(), maxOfTiles.Height() - task.Pos.Y()), task.Zoom);
}
else // ok
{
qDebug()<<"start getting image"<<" ID="<<debug;
img = OPMaps::Instance()->GetImageFrom(tl, task.Pos, task.Zoom);
#ifdef DEBUG_CORE
qDebug()<<"Core::run:gotimage size:"<<img.count()<<" ID="<<debug;
#endif //DEBUG_CORE
}
if(img.length()!=0)
{
Moverlays.lock();
{
t->Overlays.append(img);
#ifdef DEBUG_CORE
qDebug()<<"Core::run append img:"<<img.length()<<" to tile:"<<t->GetPos().ToString()<<" now has "<<t->Overlays.count()<<" overlays"<<" ID="<<debug;
#endif //DEBUG_CORE
}
Moverlays.unlock();
break;
}
else if(OPMaps::Instance()->RetryLoadTile > 0)
{
#ifdef DEBUG_CORE
qDebug()<<"ProcessLoadTask: " << task.ToString()<< " -> empty tile, retry " << retry<<" ID="<<debug;;
#endif //DEBUG_CORE
{
QWaitCondition wait;
QMutex m;
m.lock();
wait.wait(&m,1111);
}
}
}
while(++retry < OPMaps::Instance()->RetryLoadTile);
}
if(t->Overlays.count() > 0)
{
Matrix.SetTileAt(task.Pos,t);
emit OnNeedInvalidation();
#ifdef DEBUG_CORE
qDebug()<<"Core::run add tile "<<t->GetPos().ToString()<<" to matrix index "<<task.Pos.ToString()<<" ID="<<debug;
qDebug()<<"Core::run matrix index "<<task.Pos.ToString()<<" as tile with "<<Matrix.TileAt(task.Pos)->Overlays.count()<<" ID="<<debug;
#endif //DEBUG_CORE
}
else
{
delete t;
t = 0;
}
// layers = null;
}
}
{
// last buddy cleans stuff ;}
if(last)
{
OPMaps::Instance()->kiberCacheLock.lockForWrite();
OPMaps::Instance()->TilesInMemory.RemoveMemoryOverload();
OPMaps::Instance()->kiberCacheLock.unlock();
MtileDrawingList.lock();
{
Matrix.ClearPointsNotIn(tileDrawingList);
}
MtileDrawingList.unlock();
emit OnTileLoadComplete();
emit OnNeedInvalidation();
}
}
}
qDebug()<<"loaderLimit release:"+loaderLimit.available()<<" ID="<<debug;
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")
{
SetProjection(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")
{
SetProjection(new LKS94Projection());
}
}
break;
case MapType::PergoTurkeyMap:
{
if(Projection()->Type()!="PlateCarreeProjectionPergo")
{
SetProjection(new PlateCarreeProjectionPergo());
}
}
break;
case MapType::YandexMapRu:
{
if(Projection()->Type()!="MercatorProjectionYandex")
{
SetProjection(new MercatorProjectionYandex());
}
}
break;
default:
{
if(Projection()->Type()!="MercatorProjection")
{
SetProjection(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 = OPMaps::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 <= OPMaps::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)
{
#ifdef DEBUG_CORE
qDebug()<<"------------------";
#endif //DEBUG_CORE
MtileLoadQueue.lock(); MtileLoadQueue.lock();
{ {
tileLoadQueue.clear(); if(tileLoadQueue.count() > 0)
{
task = tileLoadQueue.dequeue();
{
last = tileLoadQueue.count() == 0;
#ifdef DEBUG_CORE
qDebug()<<"TileLoadQueue: " << tileLoadQueue.count()<<" Point:"<<task.Pos.ToString()<<" ID="<<debug;;
#endif //DEBUG_CORE
}
}
} }
MtileLoadQueue.unlock(); MtileLoadQueue.unlock();
Matrix.Clear(); if(loaderLimit.tryAcquire(1,OPMaps::Instance()->Timeout))
{
#ifdef DEBUG_CORE
qDebug()<<"loadLimit semaphore aquired "<<loaderLimit.available()<<" ID="<<debug<<" TASK="<<task.Pos.ToString()<<" "<<task.Zoom;
#endif //DEBUG_CORE
if(task.HasValue())
{
#ifdef DEBUG_CORE
qDebug()<<"task as value, begining get"<<" ID="<<debug;;
#endif //DEBUG_CORE
{
Tile* m = Matrix.TileAt(task.Pos);
if(m==0 || m->Overlays.count() == 0)
{
#ifdef DEBUG_CORE
qDebug()<<"Fill empty TileMatrix: " + task.ToString()<<" ID="<<debug;;
#endif //DEBUG_CORE
Tile* t = new Tile(task.Zoom, task.Pos);
QVector<MapType::Types> layers= OPMaps::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 = OPMaps::Instance()->GetImageFrom(tl, Point(task.Pos.X(), maxOfTiles.Height() - task.Pos.Y()), task.Zoom);
}
else // ok
{
#ifdef DEBUG_CORE
qDebug()<<"start getting image"<<" ID="<<debug;
#endif //DEBUG_CORE
img = OPMaps::Instance()->GetImageFrom(tl, task.Pos, task.Zoom);
#ifdef DEBUG_CORE
qDebug()<<"Core::run:gotimage size:"<<img.count()<<" ID="<<debug<<" time="<<t.elapsed();
#endif //DEBUG_CORE
}
if(img.length()!=0)
{
Moverlays.lock();
{
t->Overlays.append(img);
#ifdef DEBUG_CORE
qDebug()<<"Core::run append img:"<<img.length()<<" to tile:"<<t->GetPos().ToString()<<" now has "<<t->Overlays.count()<<" overlays"<<" ID="<<debug;
#endif //DEBUG_CORE
}
Moverlays.unlock();
break;
}
else if(OPMaps::Instance()->RetryLoadTile > 0)
{
#ifdef DEBUG_CORE
qDebug()<<"ProcessLoadTask: " << task.ToString()<< " -> empty tile, retry " << retry<<" ID="<<debug;;
#endif //DEBUG_CORE
{
QWaitCondition wait;
QMutex m;
m.lock();
wait.wait(&m,1111);
}
}
}
while(++retry < OPMaps::Instance()->RetryLoadTile);
}
if(t->Overlays.count() > 0)
{
Matrix.SetTileAt(task.Pos,t);
emit OnNeedInvalidation();
#ifdef DEBUG_CORE
qDebug()<<"Core::run add tile "<<t->GetPos().ToString()<<" to matrix index "<<task.Pos.ToString()<<" ID="<<debug;
qDebug()<<"Core::run matrix index "<<task.Pos.ToString()<<" as tile with "<<Matrix.TileAt(task.Pos)->Overlays.count()<<" ID="<<debug;
#endif //DEBUG_CORE
}
else
{
delete t;
t = 0;
}
// layers = null;
}
}
{
// last buddy cleans stuff ;}
if(last)
{
OPMaps::Instance()->kiberCacheLock.lockForWrite();
OPMaps::Instance()->TilesInMemory.RemoveMemoryOverload();
OPMaps::Instance()->kiberCacheLock.unlock();
MtileDrawingList.lock();
{
Matrix.ClearPointsNotIn(tileDrawingList);
}
MtileDrawingList.unlock();
emit OnTileLoadComplete();
emit OnNeedInvalidation();
}
}
}
#ifdef DEBUG_CORE
qDebug()<<"loaderLimit release:"+loaderLimit.available()<<" ID="<<debug;
#endif
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")
{
SetProjection(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")
{
SetProjection(new LKS94Projection());
}
}
break;
case MapType::PergoTurkeyMap:
{
if(Projection()->Type()!="PlateCarreeProjectionPergo")
{
SetProjection(new PlateCarreeProjectionPergo());
}
}
break;
case MapType::YandexMapRu:
{
if(Projection()->Type()!="MercatorProjectionYandex")
{
SetProjection(new MercatorProjectionYandex());
}
}
break;
default:
{
if(Projection()->Type()!="MercatorProjection")
{
SetProjection(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 = OPMaps::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 <= OPMaps::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(); emit OnNeedInvalidation();
} }
} void Core::ReloadMap()
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) if(started)
{ {
#ifdef DEBUG_CORE
qDebug()<<"------------------";
#endif //DEBUG_CORE
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)); Point pt = Point(-(GetcurrentPositionGPixel().X() - Width/2), -(GetcurrentPositionGPixel().Y() - Height/2));
renderOffset.SetX(pt.X() - dragPoint.X()); renderOffset.SetX(pt.X() - dragPoint.X());
renderOffset.SetY(pt.Y() - dragPoint.Y()); 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)); 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.SetX(pt.X() - dragPoint.X());
renderOffset.SetY(pt.Y() - dragPoint.Y()); renderOffset.SetY(pt.Y() - dragPoint.Y());
}
UpdateCenterTileXYLocation(); UpdateCenterTileXYLocation();
}
void Core::DragOffset(Point const& offset)
{
renderOffset.Offset(offset);
UpdateCenterTileXYLocation(); if(centerTileXYLocation != centerTileXYLocationLast)
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)
{
ProcessLoadTaskCallback.waitForDone();
MtileLoadQueue.lock();
{ {
tileLoadQueue.clear(); centerTileXYLocationLast = centerTileXYLocation;
UpdateBounds();
} }
MtileLoadQueue.unlock();
// ProcessLoadTaskCallback.waitForDone();
}
}
void Core::UpdateBounds()
{
MtileDrawingList.lock();
{
FindTilesAround(tileDrawingList);
#ifdef DEBUG_CORE if(IsDragging())
qDebug()<<"OnTileLoadStart: " << tileDrawingList.count() << " tiles to load at zoom " << Zoom() << ", time: " << QDateTime::currentDateTime().date();
#endif //DEBUG_CORE
emit OnTileLoadStart();
foreach(Point p,tileDrawingList)
{ {
LoadTask task = LoadTask(p, Zoom()); LastLocationInBounds = CurrentPosition();
SetCurrentPosition(FromLocalToLatLng((int) Width/2, (int) Height/2));
}
emit OnNeedInvalidation();
emit OnMapDrag();
}
void Core::CancelAsyncTasks()
{
if(started)
{
ProcessLoadTaskCallback.waitForDone();
MtileLoadQueue.lock();
{ {
MtileLoadQueue.lock(); tileLoadQueue.clear();
{
if(!tileLoadQueue.contains(task))
{
tileLoadQueue.enqueue(task);
#ifdef DEBUG_CORE
qDebug()<<"Core::UpdateBounds new Task"<<task.Pos.ToString();
#endif //DEBUG_CORE
ProcessLoadTaskCallback.start(this);
}
}
MtileLoadQueue.unlock();
} }
MtileLoadQueue.unlock();
// ProcessLoadTaskCallback.waitForDone();
} }
} }
MtileDrawingList.unlock(); void Core::UpdateBounds()
UpdateGroundResolution(); {
} MtileDrawingList.lock();
void Core::FindTilesAround(QList<Point> &list) {
{ FindTilesAround(tileDrawingList);
list.clear();;
for(int i = -sizeOfMapArea.Width(); i <= sizeOfMapArea.Width(); i++) #ifdef DEBUG_CORE
{ qDebug()<<"OnTileLoadStart: " << tileDrawingList.count() << " tiles to load at zoom " << Zoom() << ", time: " << QDateTime::currentDateTime().date();
#endif //DEBUG_CORE
emit OnTileLoadStart();
foreach(Point p,tileDrawingList)
{
LoadTask task = LoadTask(p, Zoom());
{
MtileLoadQueue.lock();
{
if(!tileLoadQueue.contains(task))
{
tileLoadQueue.enqueue(task);
#ifdef DEBUG_CORE
qDebug()<<"Core::UpdateBounds new Task"<<task.Pos.ToString();
#endif //DEBUG_CORE
ProcessLoadTaskCallback.start(this);
}
}
MtileLoadQueue.unlock();
}
}
}
MtileDrawingList.unlock();
UpdateGroundResolution();
}
void Core::FindTilesAround(QList<Point> &list)
{
list.clear();;
for(int i = -sizeOfMapArea.Width(); i <= sizeOfMapArea.Width(); i++)
{
for(int j = -sizeOfMapArea.Height(); j <= sizeOfMapArea.Height(); j++) for(int j = -sizeOfMapArea.Height(); j <= sizeOfMapArea.Height(); j++)
{ {
Point p = centerTileXYLocation; Point p = centerTileXYLocation;
p.SetX(p.X() + i); p.SetX(p.X() + i);
p.SetY(p.Y() + j); p.SetY(p.Y() + j);
//if(p.X < minOfTiles.Width) //if(p.X < minOfTiles.Width)
//{ //{
// p.X += (maxOfTiles.Width + 1); // p.X += (maxOfTiles.Width + 1);
//} //}
//if(p.X > maxOfTiles.Width) //if(p.X > maxOfTiles.Width)
//{ //{
// p.X -= (maxOfTiles.Width + 1); // p.X -= (maxOfTiles.Width + 1);
//} //}
if(p.X() >= minOfTiles.Width() && p.Y() >= minOfTiles.Height() && p.X() <= maxOfTiles.Width() && p.Y() <= maxOfTiles.Height()) if(p.X() >= minOfTiles.Width() && p.Y() >= minOfTiles.Height() && p.X() <= maxOfTiles.Width() && p.Y() <= maxOfTiles.Height())
{ {
if(!list.contains(p)) if(!list.contains(p))
{ {
list.append(p); list.append(p);
} }
} }
} }
} }
} }
void Core::UpdateGroundResolution() void Core::UpdateGroundResolution()
{ {
double rez = Projection()->GetGroundResolution(Zoom(), CurrentPosition().Lat()); double rez = Projection()->GetGroundResolution(Zoom(), CurrentPosition().Lat());
pxRes100m = (int) (100.0 / rez); // 100 meters pxRes100m = (int) (100.0 / rez); // 100 meters
pxRes1000m = (int) (1000.0 / rez); // 1km pxRes1000m = (int) (1000.0 / rez); // 1km
pxRes10km = (int) (10000.0 / rez); // 10km pxRes10km = (int) (10000.0 / rez); // 10km
pxRes100km = (int) (100000.0 / rez); // 100km pxRes100km = (int) (100000.0 / rez); // 100km
pxRes1000km = (int) (1000000.0 / rez); // 1000km pxRes1000km = (int) (1000000.0 / rez); // 1000km
pxRes5000km = (int) (5000000.0 / rez); // 5000km pxRes5000km = (int) (5000000.0 / rez); // 5000km
} }
} }

View File

@ -28,9 +28,7 @@
#ifndef CORE_H #ifndef CORE_H
#define CORE_H #define CORE_H
#define DEBUG_CORE #include "debugheader.h"
//#define DEBUG_TILE
//#define DEBUG_TILEMATRIX
#include "../internals/PointLatlng.h" #include "../internals/PointLatlng.h"
#include "mousewheelzoomtype.h" #include "mousewheelzoomtype.h"
@ -56,11 +54,16 @@
//#include <QObject> //#include <QObject>
namespace mapcontrol
{
class OPMapControl;
}
namespace internals { namespace internals {
class Core:public QObject,public QRunnable class Core:public QObject,public QRunnable
{ {
Q_OBJECT Q_OBJECT
friend class mapcontrol::OPMapControl;
public: public:
Core(); Core();
void run(); void run();
@ -179,12 +182,7 @@ public:
TileMatrix Matrix; TileMatrix Matrix;
Rectangle tileRect;
Point mouseDown;
bool CanDragMap;
Point mouseCurrent;
PointLatLng LastLocationInBounds;
Point mouseLastZoom;
signals: signals:
void OnCurrentPositionChanged(PointLatLng point); void OnCurrentPositionChanged(PointLatLng point);
void OnTileLoadComplete(); void OnTileLoadComplete();
@ -197,14 +195,19 @@ signals:
private: private:
static qlonglong debugcounter;
PointLatLng currentPosition; PointLatLng currentPosition;
Point currentPositionPixel; Point currentPositionPixel;
Point renderOffset; Point renderOffset;
Point centerTileXYLocation; Point centerTileXYLocation;
Point centerTileXYLocationLast; Point centerTileXYLocationLast;
Point dragPoint; Point dragPoint;
Rectangle tileRect;
Point mouseDown;
bool CanDragMap;
Point mouseCurrent;
PointLatLng LastLocationInBounds;
Point mouseLastZoom;
MouseWheelZoomType::Types mousewheelzoomtype; MouseWheelZoomType::Types mousewheelzoomtype;
@ -233,9 +236,10 @@ private:
QMutex Moverlays; QMutex Moverlays;
QMutex MtileDrawingList; QMutex MtileDrawingList;
#ifdef DEBUG_CORE
QMutex Mdebug; QMutex Mdebug;
static qlonglong debugcounter;
#endif
Size TooltipTextPadding; Size TooltipTextPadding;
MapType::Types mapType; MapType::Types mapType;

View File

@ -0,0 +1,8 @@
#ifndef DEBUGHEADER_H
#define DEBUGHEADER_H
//#define DEBUG_CORE
//#define DEBUG_TILE
//#define DEBUG_TILEMATRIX
#endif // DEBUGHEADER_H

View File

@ -9,7 +9,8 @@ HEADERS += core.h \
pureprojection.h \ pureprojection.h \
pointlatlng.h \ pointlatlng.h \
rectlatlng.h \ rectlatlng.h \
sizelatlng.h sizelatlng.h \
debugheader.h
SOURCES += core.cpp \ SOURCES += core.cpp \
rectangle.cpp \ rectangle.cpp \
tile.cpp \ tile.cpp \
@ -19,7 +20,7 @@ SOURCES += core.cpp \
sizelatlng.cpp \ sizelatlng.cpp \
pointlatlng.cpp \ pointlatlng.cpp \
loadtask.cpp \ loadtask.cpp \
MouseWheelZoomType.cpp mousewheelzoomtype.cpp
HEADERS += ./projections/lks94projection.h \ HEADERS += ./projections/lks94projection.h \
./projections/mercatorprojection.h \ ./projections/mercatorprojection.h \
./projections/mercatorprojectionyandex.h \ ./projections/mercatorprojectionyandex.h \

View File

@ -33,6 +33,7 @@
#include "../core/point.h" #include "../core/point.h"
#include <QMutex> #include <QMutex>
#include <QDebug> #include <QDebug>
#include "debugheader.h"
using namespace core; using namespace core;
namespace internals namespace internals
{ {

View File

@ -32,7 +32,7 @@
#include "tile.h" #include "tile.h"
#include <QList> #include <QList>
#include "../core/point.h" #include "../core/point.h"
#include "debugheader.h"
namespace internals { namespace internals {
class TileMatrix class TileMatrix
{ {