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 3

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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