0,0 → 1,307 |
/* |
* |
* This file is part of QMapControl, |
* an open-source cross-platform map widget |
* |
* Copyright (C) 2007 - 2008 Kai Winter |
* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU Lesser General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU Lesser General Public License for more details. |
* |
* You should have received a copy of the GNU Lesser General Public License |
* along with QMapControl. If not, see <http://www.gnu.org/licenses/>. |
* |
* Contact e-mail: kaiwinter@gmx.de |
* Program URL : http://qmapcontrol.sourceforge.net/ |
* |
*/ |
|
#include "layer.h" |
namespace qmapcontrol |
{ |
Layer::Layer(QString layername, MapAdapter* mapadapter, enum LayerType layertype, bool takeevents) |
:visible(true), mylayername(layername), mylayertype(layertype), mapAdapter(mapadapter), takeevents(takeevents), myoffscreenViewport(QRect(0,0,0,0)) |
{ |
//qDebug() << "creating new Layer: " << layername << ", type: " << contents; |
//qDebug() << this->layertype; |
} |
|
Layer::~Layer() |
{ |
delete mapAdapter; |
} |
|
void Layer::setSize(QSize size) |
{ |
this->size = size; |
screenmiddle = QPoint(size.width()/2, size.height()/2); |
//QMatrix mat; |
//mat.translate(480/2, 640/2); |
//mat.rotate(45); |
//mat.translate(-480/2,-640/2); |
//screenmiddle = mat.map(screenmiddle); |
} |
|
QString Layer::layername() const |
{ |
return mylayername; |
} |
|
const MapAdapter* Layer::mapadapter() const |
{ |
return mapAdapter; |
} |
|
void Layer::setVisible(bool visible) |
{ |
this->visible = visible; |
emit(updateRequest()); |
} |
|
void Layer::addGeometry(Geometry* geom) |
{ |
//qDebug() << geom->getName() << ", " << geom->getPoints().at(0)->getWidget(); |
|
geometries.append(geom); |
emit(updateRequest(geom->boundingBox())); |
//a geometry can request a redraw, e.g. when its position has been changed |
connect(geom, SIGNAL(updateRequest(QRectF)), |
this, SIGNAL(updateRequest(QRectF))); |
} |
void Layer::removeGeometry(Geometry* geometry) |
{ |
for (int i=0; i<geometries.count(); i++) |
{ |
if (geometry == geometries.at(i)) |
{ |
disconnect(geometry); |
geometries.removeAt(i); |
//delete geometry; |
} |
} |
} |
|
void Layer::clearGeometries() |
{ |
foreach(Geometry *geometry, geometries){ |
disconnect(geometry); |
} |
geometries.clear(); |
} |
|
bool Layer::isVisible() const |
{ |
return visible; |
} |
void Layer::zoomIn() const |
{ |
mapAdapter->zoom_in(); |
} |
void Layer::zoomOut() const |
{ |
mapAdapter->zoom_out(); |
} |
|
void Layer::mouseEvent(const QMouseEvent* evnt, const QPoint mapmiddle_px) |
{ |
if (takesMouseEvents()) |
{ |
if (evnt->button() == Qt::LeftButton && evnt->type() == QEvent::MouseButtonPress) |
{ |
// check for collision |
QPointF c = mapAdapter->displayToCoordinate(QPoint(evnt->x()-screenmiddle.x()+mapmiddle_px.x(), |
evnt->y()-screenmiddle.y()+mapmiddle_px.y())); |
Point* tmppoint = new Point(c.x(), c.y()); |
for (int i=0; i<geometries.count(); i++) |
{ |
if (geometries.at(i)->isVisible() && geometries.at(i)->Touches(tmppoint, mapAdapter)) |
|
//if (geometries.at(i)->Touches(c, mapAdapter)) |
{ |
emit(geometryClicked(geometries.at(i), QPoint(evnt->x(), evnt->y()))); |
} |
} |
delete tmppoint; |
} |
} |
} |
|
bool Layer::takesMouseEvents() const |
{ |
return takeevents; |
} |
|
void Layer::drawYourImage(QPainter* painter, const QPoint mapmiddle_px) const |
{ |
if (mylayertype == MapLayer) |
{ |
//qDebug() << ":: " << mapmiddle_px; |
//QMatrix mat; |
//mat.translate(480/2, 640/2); |
//mat.rotate(45); |
//mat.translate(-480/2,-640/2); |
|
//mapmiddle_px = mat.map(mapmiddle_px); |
//qDebug() << ":: " << mapmiddle_px; |
_draw(painter, mapmiddle_px); |
} |
|
drawYourGeometries(painter, QPoint(mapmiddle_px.x()-screenmiddle.x(), mapmiddle_px.y()-screenmiddle.y()), myoffscreenViewport); |
} |
void Layer::drawYourGeometries(QPainter* painter, const QPoint mapmiddle_px, QRect viewport) const |
{ |
QPoint offset; |
if (mylayertype == MapLayer) |
offset = mapmiddle_px; |
else |
offset = mapmiddle_px-screenmiddle; |
|
painter->translate(-mapmiddle_px+screenmiddle); |
for (int i=0; i<geometries.count(); i++) |
{ |
geometries.at(i)->draw(painter, mapAdapter, viewport, offset); |
} |
painter->translate(mapmiddle_px-screenmiddle); |
|
} |
void Layer::_draw(QPainter* painter, const QPoint mapmiddle_px) const |
{ |
// screen middle rotieren... |
|
int tilesize = mapAdapter->tilesize(); |
int cross_x = int(mapmiddle_px.x())%tilesize; // position on middle tile |
int cross_y = int(mapmiddle_px.y())%tilesize; |
//qDebug() << screenmiddle << " - " << cross_x << ", " << cross_y; |
|
// calculate how many surrounding tiles have to be drawn to fill the display |
int space_left = screenmiddle.x() - cross_x; |
int tiles_left = space_left/tilesize; |
if (space_left>0) |
tiles_left+=1; |
|
int space_above = screenmiddle.y() - cross_y; |
int tiles_above = space_above/tilesize; |
if (space_above>0) |
tiles_above+=1; |
|
int space_right = screenmiddle.x() - (tilesize-cross_x); |
int tiles_right = space_right/tilesize; |
if (space_right>0) |
tiles_right+=1; |
|
int space_bottom = screenmiddle.y() - (tilesize-cross_y); |
int tiles_bottom = space_bottom/tilesize; |
if (space_bottom>0) |
tiles_bottom+=1; |
|
//int tiles_displayed = 0; |
int mapmiddle_tile_x = mapmiddle_px.x()/tilesize; |
int mapmiddle_tile_y = mapmiddle_px.y()/tilesize; |
|
const QPoint from = QPoint((-tiles_left+mapmiddle_tile_x)*tilesize, (-tiles_above+mapmiddle_tile_y)*tilesize); |
const QPoint to = QPoint((tiles_right+mapmiddle_tile_x+1)*tilesize, (tiles_bottom+mapmiddle_tile_y+1)*tilesize); |
|
myoffscreenViewport = QRect(from, to); |
|
// for the EmptyMapAdapter no tiles should be loaded and painted. |
if (mapAdapter->host() == "") |
{ |
return; |
} |
|
if (mapAdapter->isValid(mapmiddle_tile_x, mapmiddle_tile_y, mapAdapter->currentZoom())) |
{ |
painter->drawPixmap(-cross_x+size.width(), |
-cross_y+size.height(), |
ImageManager::instance()->getImage(mapAdapter->host(), mapAdapter->query(mapmiddle_tile_x, mapmiddle_tile_y, mapAdapter->currentZoom()))); |
} |
|
for (int i=-tiles_left+mapmiddle_tile_x; i<=tiles_right+mapmiddle_tile_x; i++) |
{ |
for (int j=-tiles_above+mapmiddle_tile_y; j<=tiles_bottom+mapmiddle_tile_y; j++) |
{ |
// check if image is valid |
if (!(i==mapmiddle_tile_x && j==mapmiddle_tile_y)) |
if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
{ |
|
painter->drawPixmap(((i-mapmiddle_tile_x)*tilesize)-cross_x+size.width(), |
((j-mapmiddle_tile_y)*tilesize)-cross_y+size.height(), |
ImageManager::instance()->getImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom()))); |
//if (QCoreApplication::hasPendingEvents()) |
// QCoreApplication::processEvents(); |
} |
} |
} |
|
|
// PREFETCHING |
int upper = mapmiddle_tile_y-tiles_above-1; |
int right = mapmiddle_tile_x+tiles_right+1; |
int left = mapmiddle_tile_x-tiles_right-1; |
int lower = mapmiddle_tile_y+tiles_bottom+1; |
|
int j = upper; |
for (int i=left; i<=right; i++) |
{ |
if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
ImageManager::instance()->prefetchImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom())); |
} |
j = lower; |
for (int i=left; i<=right; i++) |
{ |
if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
ImageManager::instance()->prefetchImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom())); |
} |
int i = left; |
for (int j=upper+1; j<=lower-1; j++) |
{ |
if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
ImageManager::instance()->prefetchImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom())); |
} |
i = right; |
for (int j=upper+1; j<=lower-1; j++) |
{ |
if (mapAdapter->isValid(i, j, mapAdapter->currentZoom())) |
ImageManager::instance()->prefetchImage(mapAdapter->host(), mapAdapter->query(i, j, mapAdapter->currentZoom())); |
} |
} |
|
QRect Layer::offscreenViewport() const |
{ |
return myoffscreenViewport; |
} |
|
void Layer::moveWidgets(const QPoint mapmiddle_px) const |
{ |
for (int i=0; i<geometries.count(); i++) |
{ |
const Geometry* geom = geometries.at(i); |
if (geom->GeometryType == "Point") |
{ |
if (((Point*)geom)->widget()!=0) |
{ |
QPoint topleft_relative = QPoint(mapmiddle_px-screenmiddle); |
((Point*)geom)->drawWidget(mapAdapter, topleft_relative); |
} |
} |
} |
} |
Layer::LayerType Layer::layertype() const |
{ |
return mylayertype; |
} |
|
void Layer::setMapAdapter(MapAdapter* mapadapter) |
{ |
|
mapAdapter = mapadapter; |
} |
} |