OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [gui_plugin/] [GnssWidgets/] [StreetMapObject.cpp] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 sergeykhbr
#include "StreetMapObject.h"
2
#include "moc_StreetMapObject.h"
3
 
4
#include <QtWidgets/QtWidgets>
5
#include <QtCore/QDateTime>
6
#include <QtNetwork/QtNetwork>
7
#include <math.h>
8
 
9
#ifndef M_PI
10
#define M_PI 3.14159265358979323846
11
#endif
12
 
13
/** This hash function must be placed into global namespace,
14
 *  otherwise QHash<QPoint, QPixmap> will generate errors
15
 */
16
static uint qHash(const QPoint& p) {
17
    return p.x() * 17 ^ p.y();
18
}
19
 
20
namespace debugger {
21
 
22
// tile size in pixels
23
static const int TILE_SIZE = 256;
24
 
25
static QPointF tileForCoordinate(qreal lat, qreal lng, int zoom) {
26
    qreal zn = static_cast<qreal>(1 << zoom);
27
    qreal tx = (lng + 180.0) / 360.0;
28
    qreal ty = (1.0 - log(tan(lat * M_PI / 180.0) +
29
                          1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0;
30
    return QPointF(tx * zn, ty * zn);
31
}
32
 
33
static qreal longitudeFromTile(qreal tx, int zoom) {
34
    qreal zn = static_cast<qreal>(1 << zoom);
35
    qreal lat = tx / zn * 360.0 - 180.0;
36
    return lat;
37
}
38
 
39
static qreal latitudeFromTile(qreal ty, int zoom) {
40
    qreal zn = static_cast<qreal>(1 << zoom);
41
    qreal n = M_PI - 2 * M_PI * ty / zn;
42
    qreal lng = 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
43
    return lng;
44
}
45
 
46
 
47
// Zoom: 1=world map
48
//       12 = 0.5 of Moscow
49
//       15 = default
50
StreetMap::StreetMap(QObject *parent, int zoom_)
51
    : QObject(parent) {
52 3 sergeykhbr
    width = 400;
53
    height = 300;
54
    zoom = zoom_;
55
 
56
    latitude = 0;
57
    longitude = 0;
58 4 sergeykhbr
 
59
    m_request.setRawHeader("User-Agent", "sergeykhbr (RISC-V debugger)");
60
    m_emptyTile = QPixmap(TILE_SIZE, TILE_SIZE);
61
    m_emptyTile.fill(Qt::lightGray);
62
 
63
#if 0
64
    m_proxy.setType(QNetworkProxy::HttpProxy);
65
    m_proxy.setHostName(tr("http://proxy.server.com"));
66
    m_proxy.setPort(911);
67
    m_manager.setProxy(m_proxy);
68
#endif
69
 
70
    QNetworkDiskCache *cache = new QNetworkDiskCache;
71
    cache->setCacheDirectory(
72
        QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
73
    m_manager.setCache(cache);
74
    connect(&m_manager, SIGNAL(finished(QNetworkReply*)),
75
            this, SLOT(handleNetworkData(QNetworkReply*)));
76
}
77
 
78
StreetMap::~StreetMap() {
79
}
80
 
81
QPoint StreetMap::coordToPixpos(QPointF coord) {
82
    QPointF f = tileForCoordinate(coord.x(), coord.y(), zoom);
83
    f -= ct;
84
    f *= TILE_SIZE;
85
    int x = width/2 + (int)(f.x() + 0.5);
86
    int y = height/2 + (int)((int)f.y() + 0.5);
87
    return QPoint(x, y);
88
}
89
 
90
QRect StreetMap::coordToPixpos(QRectF coord) {
91
    QRect ret;
92
    QPoint c = coordToPixpos(coord.topLeft());
93
    ret.setTopLeft(c);
94
    c = coordToPixpos(coord.bottomRight());
95
    ret.setBottomRight(c);
96
    return ret;
97
}
98
 
99
QRectF StreetMap::getBorderCoord() {
100
    QRectF ret;
101
    qreal x0 = ct.x() - 0.5*double(width)/TILE_SIZE;
102
    qreal x1 = ct.x() + 0.5*double(width)/TILE_SIZE;
103
    ret.setTop(longitudeFromTile(x0, zoom));
104
    ret.setBottom(longitudeFromTile(x1, zoom));
105
 
106
    qreal y0 = ct.y() - 0.5*double(height)/TILE_SIZE;
107
    qreal y1 = ct.y() + 0.5*double(height)/TILE_SIZE;
108
    ret.setLeft(latitudeFromTile(y0, zoom));
109
    ret.setRight(latitudeFromTile(y1, zoom));
110
    return ret;
111
}
112
 
113
 
114
void StreetMap::setCenterCoord(QPointF coord) {
115
    if (width <= 0 || height <= 0)
116
        return;
117
 
118
    latitude = coord.x();
119
    longitude = coord.y();
120
 
121
    // Normalize lat/lon to range (0.0...1.0)*(1<<scale)
122
    // It means that full world map will be splitted on (1<<scale) x (1<<scale) rectangles.
123
    // If scale =12, then full map 4096 x 4096 tiles
124
    ct = tileForCoordinate(latitude, longitude, zoom);
125
    qreal tx = ct.x();
126
    qreal ty = ct.y();
127
 
128
    // Each tile 256x256 size:
129
    double centertile_x = (tx - (double)((int)tx)) * TILE_SIZE;
130
    double centertile_y = (ty - (double)((int)ty)) * TILE_SIZE;
131
 
132
    // top-left corner of the center tile
133
    int xp = width / 2 - centertile_x;
134
    int yp = height / 2 - centertile_y;
135
 
136
    // first tile vertical and horizontal
137
    int beforetile_x = (xp + TILE_SIZE - 1) / TILE_SIZE;
138
    int beforetile_y = (yp + TILE_SIZE - 1) / TILE_SIZE;
139
    int xs = static_cast<int>(tx) - beforetile_x;
140
    int ys = static_cast<int>(ty) - beforetile_y;
141
 
142
 
143
    // offset for top-left tile
144
    m_offset = QPoint(xp - beforetile_x * TILE_SIZE,
145
                      yp - beforetile_y * TILE_SIZE);
146
 
147
    // last tile vertical and horizontal
148
    int aftertile_x = (width - xp - 1) / TILE_SIZE;
149
    int aftertile_y = (height - yp - 1) / TILE_SIZE;
150
    int xe = static_cast<int>(tx) + aftertile_x;
151
    int ye = static_cast<int>(ty) + aftertile_y;
152
 
153
    // build a rect
154
    m_tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1);
155
}
156
 
157
QPointF StreetMap::getCenterCoord() {
158
    return QPointF(latitude, longitude);
159
}
160
 
161
void StreetMap::resize(int w, int h) {
162
    width = w;
163
    height = h;
164
    setCenterCoord(QPointF(latitude, longitude));
165
}
166
 
167
void StreetMap::render(QPainter *p, const QRect &rect) {
168
    for (int x = 0; x <= m_tilesRect.width(); ++x) {
169
        for (int y = 0; y <= m_tilesRect.height(); ++y) {
170
            QPoint tp(x + m_tilesRect.left(), y + m_tilesRect.top());
171
            QRect box = tileRect(tp);
172
            if (rect.intersects(box)) {
173
                if (m_tilePixmaps.contains(tp)) {
174
                    p->drawPixmap(box, m_tilePixmaps.value(tp));
175
                } else {
176
                    p->drawPixmap(box, m_emptyTile);
177
                }
178
            }
179
        }
180
    }
181
}
182
 
183
void StreetMap::pan(const QPoint &delta) {
184
    QPointF dx = QPointF(delta) / qreal(TILE_SIZE);
185
    QPointF center = tileForCoordinate(latitude, longitude, zoom) - dx;
186
    qreal lat = latitudeFromTile(center.y(), zoom);
187
    qreal lon = longitudeFromTile(center.x(), zoom);
188
    setCenterCoord(QPointF(lat, lon));
189
}
190
 
191
void StreetMap::slotRequestNetworkData() {
192
    download();
193
}
194
 
195
void StreetMap::handleNetworkData(QNetworkReply *reply) {
196
    QImage img;
197
    QPoint tp = reply->request().attribute(QNetworkRequest::User).toPoint();
198
    QUrl url = reply->url();
199
    if (!reply->error()) {
200
        if (!img.load(reply, 0)) {
201
            img = QImage();
202
        }
203
    }
204
    reply->deleteLater();
205
    if (img.isNull()) {
206
        m_tilePixmaps[tp] = m_emptyTile;
207
    } else {
208
        m_tilePixmaps[tp] = QPixmap::fromImage(img);
209
    }
210
 
211
    emit signalTilesUpdated(tileRect(tp));
212
 
213
    // purge unused spaces
214
    QRect bound = m_tilesRect.adjusted(-2, -2, 2, 2);
215
    foreach(QPoint tp, m_tilePixmaps.keys())
216
    if (!bound.contains(tp)) {
217
        m_tilePixmaps.remove(tp);
218
    }
219
 
220
    download();
221
}
222
 
223
void StreetMap::download() {
224
    QPoint grab(0, 0);
225
    for (int x = 0; x <= m_tilesRect.width(); ++x) {
226
        for (int y = 0; y <= m_tilesRect.height(); ++y) {
227
            QPoint tp = m_tilesRect.topLeft() + QPoint(x, y);
228
            if (!m_tilePixmaps.contains(tp)) {
229
                grab = tp;
230
                break;
231
            }
232
        }
233
    }
234
    if (grab == QPoint(0, 0)) {
235
        m_url = QUrl();
236
        emit signalTilesUpdated(QRect());
237
        return;
238
    }
239
 
240
    QString path = "http://tile.openstreetmap.org/%1/%2/%3.png";
241
    m_url = QUrl(path.arg(zoom).arg(grab.x()).arg(grab.y()));
242
    m_request.setUrl(m_url);
243
    QVariant arg(grab);
244
    m_request.setAttribute(QNetworkRequest::User, arg);
245
    m_manager.get(m_request);
246
}
247
 
248
QRect StreetMap::tileRect(const QPoint &tp) {
249
    QPoint t = tp - m_tilesRect.topLeft();
250
    int x = t.x() * TILE_SIZE + m_offset.x();
251
    int y = t.y() * TILE_SIZE + m_offset.y();
252
    return QRect(x, y, TILE_SIZE, TILE_SIZE);
253
}
254
 
255
}  // namespace debugger

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.