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 2

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

powered by: WebSVN 2.1.0

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