Subversion Repositories Projects

Rev

Rev 391 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
305 KeyOz 1
/*
2
*
3
* This file is part of QMapControl,
4
* an open-source cross-platform map widget
5
*
6
* Copyright (C) 2007 - 2008 Kai Winter
7
*
8
* This program is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU Lesser General Public License as published by
10
* the Free Software Foundation, either version 3 of the License, or
11
* (at your option) any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
* GNU Lesser General Public License for more details.
17
*
18
* You should have received a copy of the GNU Lesser General Public License
19
* along with QMapControl. If not, see <http://www.gnu.org/licenses/>.
20
*
21
* Contact e-mail: kaiwinter@gmx.de
22
* Program URL   : http://qmapcontrol.sourceforge.net/
23
*
24
*/
25
 
26
#include "mapcontrol.h"
27
namespace qmapcontrol
28
{
29
    MapControl::MapControl(QSize size, MouseMode mousemode)
30
        : size(size), mymousemode(mousemode), scaleVisible(false)
31
    {
32
        layermanager = new LayerManager(this, size);
33
        screen_middle = QPoint(size.width()/2, size.height()/2);
34
 
35
        mousepressed = false;
36
 
37
        connect(ImageManager::instance(), SIGNAL(imageReceived()),
38
                this, SLOT(updateRequestNew()));
39
 
40
        connect(ImageManager::instance(), SIGNAL(loadingFinished()),
41
                this, SLOT(loadingFinished()));
42
 
43
        this->setMaximumSize(size.width()+1, size.height()+1);
44
    }
45
 
46
    MapControl::~MapControl()
47
    {
48
        delete layermanager;
49
    }
50
 
51
    QPointF MapControl::currentCoordinate() const
52
    {
53
        return layermanager->currentCoordinate();
54
    }
55
 
56
    Layer* MapControl::layer(const QString& layername) const
57
    {
58
        return layermanager->layer(layername);
59
    }
60
 
61
    QList<QString> MapControl::layers() const
62
    {
63
        return layermanager->layers();
64
    }
65
 
66
    int MapControl::numberOfLayers() const
67
    {
68
        return layermanager->layers().size();
69
    }
70
 
71
    void MapControl::followGeometry(const Geometry* geom) const
72
    {
73
        connect(geom, SIGNAL(positionChanged(Geometry*)),
74
                this, SLOT(positionChanged(Geometry*)));
75
    }
76
 
77
    void MapControl::positionChanged(Geometry* geom)
78
    {
79
        QPoint start = layermanager->layer()->mapadapter()->coordinateToDisplay(currentCoordinate());
80
        QPoint dest = layermanager->layer()->mapadapter()->coordinateToDisplay(((Point*)geom)->coordinate());
81
 
82
        QPoint step = (dest-start);
83
 
84
        layermanager->scrollView(step);
85
 
86
        // setView(geom);
87
        update();
88
    }
89
 
90
    void MapControl::moveTo(QPointF coordinate)
91
    {
92
        target = coordinate;
93
        steps = 25;
94
        if (moveMutex.tryLock())
95
        {
96
            QTimer::singleShot(40, this, SLOT(tick()));
97
        }
98
        else
99
        {
100
            // stopMove(coordinate);
101
        }
102
    }
103
    void MapControl::tick()
104
    {
105
        QPoint start = layermanager->layer()->mapadapter()->coordinateToDisplay(currentCoordinate());
106
        QPoint dest = layermanager->layer()->mapadapter()->coordinateToDisplay(target);
107
 
108
        QPoint step = (dest-start)/steps;
109
        QPointF next = currentCoordinate()- step;
110
 
111
        // setView(Coordinate(next.x(), next.y()));
112
        layermanager->scrollView(step);
113
 
114
        update();
115
        steps--;
116
        if (steps>0)
117
        {
118
            QTimer::singleShot(40, this, SLOT(tick()));
119
        }
120
        else
121
        {
122
            moveMutex.unlock();
123
        }
124
    }
125
 
126
    void MapControl::paintEvent(QPaintEvent* evnt)
127
    {
128
        QWidget::paintEvent(evnt);
129
        QPainter painter(this);
130
 
131
        // painter.translate(150,190);
132
        // painter.scale(0.5,0.5);
133
 
134
        // painter.setClipRect(0,0, size.width(), size.height());
135
 
136
        // painter.setViewport(10000000000,0,size.width(),size.height());
137
 
138
        /*
139
        // rotating
140
            rotation = 45;
141
            painter.translate(256,256);
142
            painter.rotate(rotation);
143
            painter.translate(-256,-256);
144
        */
145
 
146
        layermanager->drawImage(&painter);
147
        layermanager->drawGeoms(&painter);
148
 
149
        // added by wolf
150
        // draw scale
151
        if (scaleVisible)
152
        {
153
            QList<double> distanceList;
154
            distanceList<<5000000<<2000000<<1000000<<1000000<<1000000<<100000<<100000<<50000<<50000<<10000<<10000<<10000<<1000<<1000<<500<<200<<100<<50<<25;
155
            if (currentZoom() >= 0 && distanceList.size() > currentZoom())
156
            {
157
                double line;
158
                line = distanceList.at( currentZoom() ) / pow(2, 18-currentZoom() ) / 0.597164;
159
 
160
                // draw the scale
161
                painter.setPen(Qt::black);
162
                QPoint p1(10,size.height()-20);
163
                QPoint p2((int)line,size.height()-20);
164
                painter.drawLine(p1,p2);
165
 
166
                painter.drawLine(10,size.height()-15, 10,size.height()-25);
167
                painter.drawLine((int)line,size.height()-15, (int)line,size.height()-25);
168
 
169
                QString distance;
170
                if (distanceList.at(currentZoom()) >= 1000)
171
                {
172
                    distance = QVariant( distanceList.at(currentZoom())/1000 )  .toString()+ " km";
173
                }
174
                else
175
                {
176
                    distance = QVariant( distanceList.at(currentZoom()) ).toString() + " m";
177
                }
178
 
179
                painter.drawText(QPoint((int)line+10,size.height()-15), distance);
180
            }
181
        }
182
 
183
        painter.drawLine(screen_middle.x(), screen_middle.y()-10,
184
                         screen_middle.x(), screen_middle.y()+10); // |
185
        painter.drawLine(screen_middle.x()-10, screen_middle.y(),
186
                         screen_middle.x()+10, screen_middle.y()); // -
187
 
188
        // int cross_x = int(layermanager->getMapmiddle_px().x())%256;
189
        // int cross_y = int(layermanager->getMapmiddle_px().y())%256;
190
        // painter.drawLine(screen_middle.x()-cross_x+cross_x, screen_middle.y()-cross_y+0,
191
        //   screen_middle.x()-cross_x+cross_x, screen_middle.y()-cross_y+256); // |
192
        // painter.drawLine(screen_middle.x()-cross_x+0, screen_middle.y()-cross_y+cross_y,
193
        //   screen_middle.x()-cross_x+256, screen_middle.y()-cross_y+cross_y); // -
194
 
195
        painter.drawRect(0,0, size.width(), size.height());
196
        /*
197
        // rotating
198
          painter.setMatrix(painter.matrix().inverted());
199
        //qt = painter.transform();
200
           qm = painter.combinedMatrix();
201
        */
202
 
203
        if (mousepressed && mymousemode == Dragging)
204
        {
205
            QRect rect = QRect(pre_click_px, current_mouse_pos);
206
            painter.drawRect(rect);
207
        }
208
        emit viewChanged(currentCoordinate(), currentZoom());
209
    }
210
 
211
    // mouse events
212
    void MapControl::mousePressEvent(QMouseEvent* evnt)
213
    {
214
        //rotating (experimental)
215
        // QMouseEvent* me = new QMouseEvent(evnt->type(), qm.map(QPoint(evnt->x(),evnt->y())), evnt->button(), evnt->buttons(), evnt->modifiers());
216
        // evnt = me;
217
        // qDebug() << "evnt: " << evnt->x() << ", " << evnt->y() << ", " << evnt->pos();
218
 
219
        layermanager->mouseEvent(evnt);
220
 
221
        if (layermanager->layers().size()>0)
222
        {
223
            if (evnt->button() == 1)
224
            {
225
                mousepressed = true;
226
                pre_click_px = QPoint(evnt->x(), evnt->y());
227
            }
228
            else if (evnt->button() == 2 && mymousemode != None) // zoom in
229
            {
230
                zoomIn();
231
            } else if  (evnt->button() == 4 && mymousemode != None) // zoom out
232
            {
233
                zoomOut();
234
            }
235
        }
236
 
237
        // emit(mouseEvent(evnt));
238
        emit(mouseEventCoordinate(evnt, clickToWorldCoordinate(evnt->pos())));
239
    }
240
 
241
    void MapControl::mouseReleaseEvent(QMouseEvent* evnt)
242
    {
243
        mousepressed = false;
244
        if (mymousemode == Dragging)
245
        {
246
            QPointF ulCoord = clickToWorldCoordinate(pre_click_px);
247
            QPointF lrCoord = clickToWorldCoordinate(current_mouse_pos);
248
 
249
            QRectF coordinateBB = QRectF(ulCoord, QSizeF( (lrCoord-ulCoord).x(), (lrCoord-ulCoord).y()));
250
 
251
            emit(boxDragged(coordinateBB));
252
        }
253
 
254
        emit(mouseEventCoordinate(evnt, clickToWorldCoordinate(evnt->pos())));
255
    }
256
 
257
    void MapControl::mouseMoveEvent(QMouseEvent* evnt)
258
    {
259
        // emit(mouseEvent(evnt));
260
 
261
        /*
262
        // rotating
263
           QMouseEvent* me = new QMouseEvent(evnt->type(), qm.map(QPoint(evnt->x(),evnt->y())), evnt->button(), evnt->buttons(), evnt->modifiers());
264
           evnt = me;
265
        */
266
        if (mousepressed && mymousemode == Panning)
267
        {
268
            QPoint offset = pre_click_px - QPoint(evnt->x(), evnt->y());
269
            layermanager->scrollView(offset);
270
            pre_click_px = QPoint(evnt->x(), evnt->y());
271
        }
272
        else if (mousepressed && mymousemode == Dragging)
273
        {
274
            current_mouse_pos = QPoint(evnt->x(), evnt->y());
275
        }
276
        // emit(mouseEventCoordinate(evnt, clickToWorldCoordinate(evnt->pos())));
277
 
278
        update();
279
        // emit(mouseEventCoordinate(evnt, clickToWorldCoordinate(evnt->pos())));
280
    }
281
 
282
    QPointF MapControl::clickToWorldCoordinate(QPoint click)
283
    {
284
        // click coordinate to image coordinate
285
        QPoint displayToImage= QPoint(click.x()-screen_middle.x()+layermanager->getMapmiddle_px().x(),
286
                                      click.y()-screen_middle.y()+layermanager->getMapmiddle_px().y());
287
        // image coordinate to world coordinate
288
        return layermanager->layer()->mapadapter()->displayToCoordinate(displayToImage);
289
    }
290
 
291
    void MapControl::updateRequest(QRect rect)
292
    {
293
        update(rect);
294
    }
295
    void MapControl::updateRequestNew()
296
    {
297
        // qDebug() << "MapControl::updateRequestNew()";
298
        layermanager->forceRedraw();
299
        update();
300
    }
301
    // slots
302
    void MapControl::zoomIn()
303
    {
304
        layermanager->zoomIn();
305
        update();
306
    }
307
    void MapControl::zoomOut()
308
    {
309
        layermanager->zoomOut();
310
        update();
311
    }
312
    void MapControl::setZoom(int zoomlevel)
313
    {
314
        layermanager->setZoom(zoomlevel);
315
        update();
316
    }
317
    int MapControl::currentZoom() const
318
    {
319
        return layermanager->currentZoom();
320
    }
321
    void MapControl::scrollLeft(int pixel)
322
    {
323
        layermanager->scrollView(QPoint(-pixel,0));
324
        update();
325
    }
326
    void MapControl::scrollRight(int pixel)
327
    {
328
        layermanager->scrollView(QPoint(pixel,0));
329
        update();
330
    }
331
    void MapControl::scrollUp(int pixel)
332
    {
333
        layermanager->scrollView(QPoint(0,-pixel));
334
        update();
335
    }
336
    void MapControl::scrollDown(int pixel)
337
    {
338
        layermanager->scrollView(QPoint(0,pixel));
339
        update();
340
    }
341
    void MapControl::scroll(const QPoint scroll)
342
    {
343
        layermanager->scrollView(scroll);
344
        update();
345
    }
346
 
347
    void MapControl::setView(const QPointF& coordinate) const
348
    {
349
        layermanager->setView(coordinate);
350
    }
351
 
352
    void MapControl::setView(const QList<QPointF> coordinates) const
353
    {
354
        layermanager->setView(coordinates);
355
    }
356
 
357
    void MapControl::setViewAndZoomIn(const QList<QPointF> coordinates) const
358
    {
359
        layermanager->setViewAndZoomIn(coordinates);
360
    }
361
 
362
    void MapControl::setView(const Point* point) const
363
    {
364
        layermanager->setView(point->coordinate());
365
    }
366
 
367
    void MapControl::loadingFinished()
368
    {
369
        // qDebug() << "MapControl::loadingFinished()";
370
        layermanager->removeZoomImage();
371
    }
372
    void MapControl::addLayer(Layer* layer)
373
    {
374
        layermanager->addLayer(layer);
375
    }
376
 
377
    void MapControl::setMouseMode(MouseMode mousemode)
378
    {
379
        mymousemode = mousemode;
380
    }
381
    MapControl::MouseMode MapControl::mouseMode()
382
    {
383
        return mymousemode;
384
    }
385
 
386
    void MapControl::stopFollowing(Geometry* geom)
387
    {
388
        geom->disconnect(SIGNAL(positionChanged(Geometry*)));
389
    }
390
 
391
    void MapControl::enablePersistentCache(const QDir& path)
392
    {
393
        ImageManager::instance()->setCacheDir(path);
394
    }
395
 
396
    void MapControl::setProxy(QString host, int port)
397
    {
398
        ImageManager::instance()->setProxy(host, port);
399
    }
400
 
401
    void MapControl::showScale(bool show)
402
    {
403
        scaleVisible = show;
404
    }
405
 
406
    void MapControl::resize(const QSize newSize)
407
    {
408
        this->size = newSize;
409
        screen_middle = QPoint(newSize.width()/2, newSize.height()/2);
410
 
411
        this->setMaximumSize(newSize.width()+1, newSize.height()+1);
412
        layermanager->resize(newSize);
413
    }
414
}