Subversion Repositories Projects

Rev

Go to most recent revision | Details | 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 "point.h"
27
namespace qmapcontrol
28
{
29
    Point::Point()
30
    {}
31
    Point::Point(const Point& point)
32
        :Geometry(point.name()), X(point.longitude()), Y(point.latitude())
33
    {
34
        visible = point.isVisible();
35
        mywidget = 0;
36
        mypixmap = 0;
37
        mypen = point.mypen;
38
        homelevel = -1;
39
        minsize = QSize(-1,-1);
40
        maxsize = QSize(-1,-1);
41
    }
42
 
43
    Point::Point(qreal x, qreal y, QString name, enum Alignment alignment)
44
        : Geometry(name), X(x), Y(y), myalignment(alignment)
45
    {
46
        GeometryType = "Point";
47
        mywidget = 0;
48
        mypixmap = 0;
49
        visible = true;
50
        homelevel = -1;
51
        minsize = QSize(-1,-1);
52
        maxsize = QSize(-1,-1);
53
    }
54
 
55
    Point::Point(qreal x, qreal y, QWidget* widget, QString name, enum Alignment alignment)
56
        : Geometry(name), X(x), Y(y), mywidget(widget), myalignment(alignment)
57
    {
58
        // Point(x, y, name, alignment);
59
        GeometryType = "Point";
60
        mypixmap = 0;
61
        visible = true;
62
        size = widget->size();
63
        homelevel = -1;
64
        minsize = QSize(-1,-1);
65
        maxsize = QSize(-1,-1);
66
        mywidget->show();
67
    }
68
    Point::Point(qreal x, qreal y, QPixmap* pixmap, QString name, enum Alignment alignment)
69
        : Geometry(name), X(x), Y(y), mypixmap(pixmap), myalignment(alignment)
70
    {
71
        GeometryType = "Point";
72
        mywidget = 0;
73
        visible = true;
74
        size = pixmap->size();
75
        homelevel = -1;
76
        minsize = QSize(-1,-1);
77
        maxsize = QSize(-1,-1);
78
    }
79
    /*
80
        Point& Point::operator=(const Point& rhs)
81
        {
82
        if (this == &rhs)
83
        return *this;
84
        else
85
        {
86
        X = rhs.X;
87
        Y = rhs.Y;
88
        size = rhs.size;
89
 
90
        mywidget = rhs.mywidget;
91
        mypixmap = rhs.mypixmap;
92
        alignment = rhs.alignment;
93
        homelevel = rhs.homelevel;
94
        minsize = rhs.minsize;
95
        maxsize = rhs.maxsize;
96
}
97
}
98
*/
99
    Point::~Point()
100
    {
101
        delete mywidget;
102
        delete mypixmap;
103
    }
104
 
105
    void Point::setVisible(bool visible)
106
    {
107
        this->visible = visible;
108
        if (mywidget !=0)
109
        {
110
            mywidget->setVisible(visible);
111
        }
112
    }
113
 
114
    QRectF Point::boundingBox()
115
    {
116
        //TODO: have to be calculated in relation to alignment...
117
        return QRectF(QPointF(X, Y), displaysize);
118
    }
119
 
120
    qreal Point::longitude() const
121
    {
122
        return X;
123
    }
124
    qreal Point::latitude() const
125
    {
126
        return Y;
127
    }
128
    QPointF Point::coordinate() const
129
    {
130
        return QPointF(X, Y);
131
    }
132
 
133
    void Point::draw(QPainter* painter, const MapAdapter* mapadapter, const QRect &viewport, const QPoint offset)
134
    {
135
        if (!visible)
136
            return;
137
 
138
        if (homelevel > 0)
139
        {
140
 
141
            int currentzoom = mapadapter->maxZoom() < mapadapter->minZoom() ? mapadapter->minZoom() - mapadapter->currentZoom() : mapadapter->currentZoom();
142
 
143
            // int currentzoom = mapadapter->getZoom();
144
            int diffzoom = homelevel-currentzoom;
145
            int viewheight = size.height();
146
            int viewwidth = size.width();
147
            viewheight = int(viewheight / pow(2, diffzoom));
148
            viewwidth = int(viewwidth / pow(2, diffzoom));
149
 
150
            if (minsize.height()!= -1 && viewheight < minsize.height())
151
                viewheight = minsize.height();
152
            else if (maxsize.height() != -1 && viewheight > maxsize.height())
153
                viewheight = maxsize.height();
154
 
155
 
156
            if (minsize.width()!= -1 && viewwidth < minsize.width())
157
                viewwidth = minsize.width();
158
            else if (maxsize.width() != -1 && viewwidth > maxsize.width())
159
                viewwidth = maxsize.width();
160
 
161
 
162
            displaysize = QSize(viewwidth, viewheight);
163
        }
164
        else
165
        {
166
            displaysize = size;
167
        }
168
 
169
 
170
        if (mypixmap !=0)
171
        {
172
            const QPointF c = QPointF(X, Y);
173
            QPoint point = mapadapter->coordinateToDisplay(c);
174
 
175
            if (viewport.contains(point))
176
            {
177
                QPoint alignedtopleft = alignedPoint(point);
178
                painter->drawPixmap(alignedtopleft.x(), alignedtopleft.y(), displaysize.width(), displaysize.height(), *mypixmap);
179
            }
180
 
181
        }
182
        else if (mywidget!=0)
183
        {
184
            drawWidget(mapadapter, offset);
185
        }
186
 
187
    }
188
 
189
    void Point::drawWidget(const MapAdapter* mapadapter, const QPoint offset)
190
    {
191
        const QPointF c = QPointF(X, Y);
192
        QPoint point = mapadapter->coordinateToDisplay(c);
193
        point -= offset;
194
 
195
        QPoint alignedtopleft = alignedPoint(point);
196
        mywidget->setGeometry(alignedtopleft.x(), alignedtopleft.y(), displaysize.width(), displaysize.height());
197
    }
198
 
199
    QPoint Point::alignedPoint(const QPoint point) const
200
    {
201
        QPoint alignedtopleft;
202
        if (myalignment == Middle)
203
        {
204
            alignedtopleft.setX(point.x()-displaysize.width()/2);
205
            alignedtopleft.setY(point.y()-displaysize.height()/2);
206
        }
207
        else if (myalignment == TopLeft)
208
        {
209
            alignedtopleft.setX(point.x());
210
            alignedtopleft.setY(point.y());
211
        }
212
        else if (myalignment == TopRight)
213
        {
214
            alignedtopleft.setX(point.x()-displaysize.width());
215
            alignedtopleft.setY(point.y());
216
        }
217
        else if (myalignment == BottomLeft)
218
        {
219
            alignedtopleft.setX(point.x());
220
            alignedtopleft.setY(point.y()-displaysize.height());
221
        }
222
        else if (myalignment == BottomRight)
223
        {
224
            alignedtopleft.setX(point.x()-displaysize.width());
225
            alignedtopleft.setY(point.y()-displaysize.height());
226
        }
227
        return alignedtopleft;
228
    }
229
 
230
 
231
    bool Point::Touches(Point* p, const MapAdapter* mapadapter)
232
    {
233
        if (this->isVisible() == false)
234
            return false;
235
        if (mypixmap == 0)
236
            return false;
237
 
238
        QPointF c = p->coordinate();
239
        // coordinate to pixel
240
        QPoint pxOfPoint = mapadapter->coordinateToDisplay(c);
241
        // size/2 Pixel toleranz aufaddieren
242
        QPoint p1;
243
        QPoint p2;
244
 
245
        switch (myalignment)
246
        {
247
                        case Middle:
248
            p1 = pxOfPoint - QPoint(displaysize.width()/2,displaysize.height()/2);
249
            p2 = pxOfPoint + QPoint(displaysize.width()/2,displaysize.height()/2);
250
            break;
251
                        case TopLeft:
252
            p1 = pxOfPoint - QPoint(displaysize.width(),displaysize.height());
253
            p2 = pxOfPoint;
254
            break;
255
                        case TopRight:
256
            p1 = pxOfPoint - QPoint(0, displaysize.height());
257
            p2 = pxOfPoint + QPoint(displaysize.width(),0);
258
            break;
259
                        case BottomLeft:
260
            p1 = pxOfPoint - QPoint(displaysize.width(), 0);
261
            p2 = pxOfPoint + QPoint(0, displaysize.height());
262
            break;
263
                        case BottomRight:
264
            p1 = pxOfPoint;
265
            p2 = pxOfPoint + QPoint(displaysize.width(), displaysize.height());
266
            break;
267
        }
268
 
269
        // calculate "Bounding Box" in coordinates
270
        QPointF c1 = mapadapter->displayToCoordinate(p1);
271
        QPointF c2 = mapadapter->displayToCoordinate(p2);
272
 
273
 
274
        if(this->longitude()>=c1.x() && this->longitude()<=c2.x())
275
        {
276
            if (this->latitude()<=c1.y() && this->latitude()>=c2.y())
277
            {
278
                emit(geometryClicked(this, QPoint(0,0)));
279
                return true;
280
            }
281
        }
282
        return false;
283
    }
284
 
285
    void Point::setCoordinate(QPointF point)
286
    {
287
        // emit(updateRequest(this));
288
        // emit(updateRequest(QRectF(X, Y, size.width(), size.height())));
289
        X = point.x();
290
        Y = point.y();
291
        // emit(updateRequest(this));
292
        emit(updateRequest(QRectF(X, Y, size.width(), size.height())));
293
 
294
        emit(positionChanged(this));
295
    }
296
    QList<Point*> Point::points()
297
    {
298
        //TODO: assigning temp?!
299
        QList<Point*> points;
300
        points.append(this);
301
        return points;
302
    }
303
 
304
    QWidget* Point::widget()
305
    {
306
        return mywidget;
307
    }
308
 
309
    QPixmap* Point::pixmap()
310
    {
311
        return mypixmap;
312
    }
313
 
314
    void Point::setBaselevel(int zoomlevel)
315
    {
316
        homelevel = zoomlevel;
317
    }
318
    void Point::setMinsize(QSize minsize)
319
    {
320
        this->minsize = minsize;
321
    }
322
    void Point::setMaxsize(QSize maxsize)
323
    {
324
        this->maxsize = maxsize;
325
    }
326
    Point::Alignment Point::alignment() const
327
    {
328
        return myalignment;
329
    }
330
}