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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [gui_plugin/] [GnssWidgets/] [MapWidget.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 "MapWidget.h"
2
#include "moc_MapWidget.h"
3
#include <math.h>
4
 
5
namespace debugger {
6
 
7
/** Start marker of GNSS raw measurements that receiver generates in JSON
8
 *  format.
9
 */
10
const Reg64Type MAGIC_GNSS = {"{'Epoch"};
11
 
12
/** Test points that will shown even if no position availbale */
13
QPointF defaultPos[] = {
14
    {55.929967, 37.516868},     // MIPT, Dolgoprudniy (Moscow area)
15
    {37.871853, -122.258423},   // University of California, Berkely
16
    {59.336187, 18.068777}      // Sweden, Gaisler (Leon3) office location
17
};
18
 
19
MapWidget::MapWidget(IGui *igui, QWidget *parent)
20
    : QWidget(parent) {
21
    igui_ = igui;
22
    gnssIsParsing_ = false;
23
    bNewDataAvailable = true;
24
    pressed = false;
25
    invert = false;
26
 
27
    m_normalMap = new StreetMap(this, 17);
28
    m_miniMap = new StreetMap(this, 12);
29
    // This signal force redrawing when new data were downloaded
30
    connect(m_normalMap, SIGNAL(signalTilesUpdated(QRect)),
31
            this, SLOT(slotTilesUpdated(QRect)));
32
    connect(m_miniMap, SIGNAL(signalTilesUpdated(QRect)),
33
            this, SLOT(slotTilesUpdated(QRect)));
34
 
35
    connect(this, SIGNAL(signalRequestNetworkData()),
36
            m_normalMap, SLOT(slotRequestNetworkData()));
37
    connect(this, SIGNAL(signalRequestNetworkData()),
38
            m_miniMap, SLOT(slotRequestNetworkData()));
39
 
40
    setFocusPolicy(Qt::ClickFocus);
41
 
42
    contextMenu = new QMenu(this);
43
    contextMenu->addAction(tr("Clear"), this, SLOT(slotActionClear()));
44
    contextMenu->addAction(tr("Nightmode"), this, SLOT(slotActionNightMode()));
45
 
46
    setContextMenuPolicy(Qt::CustomContextMenu);
47
    connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
48
                  SLOT(slotRightClickMenu(const QPoint &)));
49
 
50
    connect(this, SIGNAL(signalUpdateGnssRaw()),
51
                  SLOT(slotUpdateGnssRaw()));
52
 
53
    setWindowTitle(tr("Map"));
54
 
55
    posinfoSize = QSize(340, 200);
56
    posinfoPixmap = QPixmap(posinfoSize);
57
 
58
    AttributeType serial_name;
59
    igui_->getWidgetsAttribute("Serial", &serial_name);
60
    if (serial_name.is_string()) {
61
        uart_ = static_cast<ISerial *>
62
            (RISCV_get_service_iface(serial_name.to_string(), IFACE_SERIAL));
63
        if (uart_) {
64
            uart_->registerRawListener(static_cast<IRawListener *>(this));
65
        }
66
    }
67
 
68
    QDateTime sd = QDateTime::currentDateTime();
69
    qsrand(sd.toTime_t());
70
    int pos_init_idx =
71
        qrand() % static_cast<int>(sizeof(defaultPos)/sizeof(QPointF));
72
 
73
    m_normalMap->setCenterCoord(defaultPos[pos_init_idx]);
74
    m_miniMap->setCenterCoord(defaultPos[pos_init_idx]);
75
}
76
 
77
MapWidget::~MapWidget() {
78
    if (uart_) {
79
        uart_->unregisterRawListener(static_cast<IRawListener *>(this));
80
    }
81
}
82
 
83
void MapWidget::updateData(const char *buf, int buflen) {
84
    for (int i = 0; i < buflen; i++) {
85
        gnssMagicNumber_.buf[7] = buf[i];
86
        gnssMagicNumber_.val >>= 8;
87
        if (!gnssIsParsing_) {
88
            if (gnssMagicNumber_.val == MAGIC_GNSS.val) {
89
                memcpy(gnssBuf_, MAGIC_GNSS.buf, 8);
90
                gnssBufCnt_ = 7;
91
                gnssBraceCnt_ = 1;
92
                gnssIsParsing_ = true;
93
            }
94
            continue;
95
        }
96
        gnssBuf_[gnssBufCnt_++] = buf[i];
97
        gnssBuf_[gnssBufCnt_] = '\0';
98
        if (buf[i] == '{') {
99
            gnssBraceCnt_++;
100
            continue;
101
        }
102
        if (buf[i] != '}') {
103
            continue;
104
        }
105
        if (--gnssBraceCnt_ == 0) {
106
            gnssIsParsing_ = false;
107
            gnssRawMeas_.from_config(gnssBuf_);
108
            emit signalUpdateGnssRaw();
109
        }
110
    }
111
}
112
 
113
void MapWidget::slotUpdateGnssRaw() {
114
    if (!gnssRawMeas_.is_dict()) {
115
        return;
116
    }
117
    AttributeType &gps = gnssRawMeas_["GPS"];
118
    if (!gps.is_dict()) {
119
        return;
120
    }
121
    AttributeType &lms = gps["LMS"];
122
    if (!lms.is_list() || lms.size() < 8) {
123
        return;
124
    }
125
    double lat, lon;
126
    lat = static_cast<double>(lms[1].to_int());
127
    lat += lms[2].to_float() / 60.0;
128
    if (lms[3].is_equal("S")) {
129
        lat = -lat;
130
    }
131
 
132
    lon = static_cast<double>(lms[4].to_int());
133
    lon += lms[5].to_float() / 60.0;
134
    if (lms[6].is_equal("W")) {
135
        lon = -lon;
136
    }
137
    if (lat == 0 || lon == 0) {
138
        return;
139
    }
140
    gpsLat_.put(lat);
141
    gpsLon_.put(lon);
142
 
143
    if (!pressed) {
144
        QPointF coord(gpsLat_.get_avg(), gpsLon_.get_avg());
145
        m_normalMap->setCenterCoord(coord);
146
        m_miniMap->setCenterCoord(coord);
147
    }
148
    emit signalRequestNetworkData();
149
}
150
 
151
 
152
void MapWidget::slotTilesUpdated(QRect rect) {
153
    renderAll();
154
    update();
155
}
156
 
157
void MapWidget::slotActionClear() {
158
    //for (int i=0; i<DataTotal; i++) {
159
        //pPosTrack[i]->clear();
160
    //}
161
    renderAll();
162
    update();
163
}
164
 
165
void MapWidget::slotActionNightMode() {
166
    invert = !invert;
167
    renderAll();
168
    update();
169
}
170
 
171
void MapWidget::slotRightClickMenu(const QPoint &p) {
172
    QPoint globalPos = mapToGlobal(p);
173
    //contextMenu->exec(globalPos);
174
    contextMenu->popup(globalPos);
175
}
176
 
177
void MapWidget::resizeEvent(QResizeEvent *ev) {
178
    if (ev->size().height() == 0 || ev->size().width() == 0) {
179
        // Warning: When window inactive the height=0
180
        return;
181
    }
182
    mainmapSize = ev->size();
183
    int w = mainmapSize.width();
184
    int h = mainmapSize.height();
185
    m_normalMap->resize(w, h);
186
 
187
 
188
    int square_sz = qMin((2*w)/5, (2*h)/5);
189
    minimapSize = QSize(square_sz, square_sz);
190
    m_miniMap->resize(square_sz, square_sz);
191
 
192
    renderAll();
193
    update();
194
 
195
    if (bNewDataAvailable) {
196
        bNewDataAvailable = false;
197
        emit signalRequestNetworkData();
198
    }
199
}
200
 
201
void MapWidget::renderAll() {
202
    renderMinimap();
203
    renderMainMap();      // Rendering of the mainMap will cause update signal
204
}
205
 
206
void MapWidget::renderMainMap() {
207
    // only set the dimension to the magnified portion
208
    if (mainmapPixmap.size() != mainmapSize) {
209
        mainmapPixmap = QPixmap(mainmapSize);
210
        mainmapPixmap.fill(Qt::lightGray);
211
    }
212
 
213
    QPainter p_map(&mainmapPixmap);
214
    m_normalMap->render(&p_map, QRect(QPoint(0,0), mainmapSize));
215
    p_map.setPen(Qt::black);
216
    p_map.drawText(rect(),  Qt::AlignBottom | Qt::TextWordWrap,
217
                tr("Map data CCBYSA 2017 OpenStreetMap.org contributors"));
218
 
219
    // Draw Position track:
220
    p_map.translate(20,20);
221
    fontPos.setPixelSize(16);
222
    p_map.setFont(fontPos);
223
 
224
    renderTrack(0, p_map);
225
 
226
    p_map.end();
227
}
228
 
229
void MapWidget::renderTrack(int trkIdx, QPainter &p) {
230
    // Draw semi-transparent background for coordinates output:
231
    QColor trackLineColor(tr("#008F8F"));
232
    QColor trackPointColor(tr("#004848"));
233
    QColor trackTextColor;
234
    QPen pointPen(trackPointColor, 0, Qt::SolidLine, Qt::RoundCap);
235
    trackLineColor.setAlpha(0xa0);
236
    trackPointColor.setAlpha(0xa0);
237
    QPen linePen = QPen(trackLineColor, 0, Qt::SolidLine, Qt::RoundCap);
238
 
239
    p.setPen(pointPen);
240
    p.setRenderHint(QPainter::Antialiasing);
241
 
242
    QPoint xy;
243
    double lat = gpsLat_.getp()[0];
244
    double lon = gpsLon_.getp()[0];
245
    QPoint xy0 = m_normalMap->coordToPixpos(QPointF(lat, lon));
246
    p.drawLine(xy0.x() - 2, xy0.y(), xy0.x() + 2, xy0.y());
247
    p.drawLine(xy0.x(), xy0.y() + 2, xy0.x(), xy0.y() - 2);
248
 
249
    for (int i = 0; i < gpsLat_.size(); i++) {
250
        lat = gpsLat_.getp()[i];
251
        lon = gpsLon_.getp()[i];
252
        xy = m_normalMap->coordToPixpos(QPointF(lat, lon));
253
        p.setPen(linePen);
254
        p.drawLine(xy0.x(), xy0.y(), xy.x(), xy.y());
255
        xy0 = xy;
256
 
257
        p.setPen(pointPen);
258
        p.drawLine(xy0.x() - 2, xy0.y(), xy0.x() + 2, xy0.y());
259
        p.drawLine(xy0.x(), xy0.y() + 2, xy0.x(), xy0.y() - 2);
260
    }
261
 
262
    QString strPosition;
263
    strPosition.sprintf("GPS LMS: Lat %.4f; Lon %.4f", lat, lon);
264
    int h = p.fontMetrics().size(Qt::TextSingleLine, strPosition).height();
265
 
266
    QRect rect = QRect(QPoint(0, trkIdx * (h + 5)),
267
                       QPoint(340, (trkIdx + 1) * (h + 5)));
268
    p.fillRect(rect, QBrush(QColor(128, 128, 128, 128)));
269
    // Draw axis line template:
270
    int marginy = trkIdx*(h + 5)/2;
271
    int startx = 5;
272
    int starty = marginy + (h + 5)/2;
273
    int endx = 30;
274
    int endy = marginy + (h + 5)/2;
275
    p.setPen(linePen);
276
    p.drawLine(startx, starty, endx, endy);
277
    p.setPen(pointPen);
278
    p.drawLine(startx - 2, starty, startx + 2, starty);
279
    p.drawLine(startx, starty + 2, startx, starty - 2);
280
    p.drawLine(endx - 2, endy, endx + 2, endy);
281
    p.drawLine(endx, endy + 2, endx, endy - 2);
282
 
283
    trackTextColor.setRgb(0xff, 0xff, 0xff, 0xc0);
284
    p.drawText(endx + 6, h + trkIdx*(h + 5) + 1, strPosition);
285
    trackTextColor.setRgb(0x20, 0x20, 0x20, 0xff);
286
    p.setPen(trackTextColor);
287
    p.drawText(endx + 5, h + trkIdx*(h + 5), strPosition);
288
}
289
 
290
void MapWidget::renderPosInfo(QPainter &p)
291
{
292
    QString info, strTmp;
293
    /*for (int i=0; i<POS_Total; i++) {
294
        if (PosTrack[i].ena == false) continue;
295
        strTmp.sprintf("%s: \n", PosTrack[i].name.c_str());
296
        info += strTmp;
297
    }*/
298
 
299
    QSize infoSize = p.fontMetrics().size(Qt::TextDontClip, info);
300
    QPoint infoPos = QPoint(10, 10);
301
    QRect infoRect = QRect(infoPos, infoSize);
302
 
303
    p.fillRect(infoRect, QBrush(QColor(0xff, 0xef, 0xd5, 0x80)));
304
    /*
305
    int sz = pPosTrack[type]->size();
306
    QColor clr = getDataColor(type);
307
 
308
    p.setPen(QPen(clr, 2, Qt::SolidLine, Qt::RoundCap));
309
    p.setRenderHint(QPainter::Antialiasing);
310
    */
311
}
312
 
313
 
314
void MapWidget::renderMinimap() {
315
    if (minimapSize.width() == 0 || minimapSize.height() == 0) {
316
        // At the beging there occurs strange resizeEvent()
317
        return;
318
    }
319
 
320
    // 1/2 x 1/2 of the main screen width:
321
    int w = mainmapSize.width();
322
    int h = mainmapSize.height();
323
    if (w == 0 || h == 0)
324
        return;
325
 
326
    int square_sz = m_miniMap->getWidth();     // always square: height = width
327
    minimapRadius = square_sz/2;     //
328
    minimapInnerRadius = minimapRadius - 15;
329
    minimapSize = QSize(square_sz, square_sz);
330
    minimapPosition = QPoint(w - square_sz, h - square_sz);
331
    minimapCenter = minimapPosition + QPoint(minimapRadius, minimapRadius);
332
 
333
 
334
    // reupdate our mask
335
    if (minimapPixmapMask.size() != minimapSize) {
336
        minimapPixmapMask = QPixmap(minimapSize);
337
        minimapPixmapMask.fill(Qt::transparent);
338
 
339
        QRadialGradient g;
340
        g.setCenter(minimapRadius, minimapRadius);
341
        g.setFocalPoint(minimapRadius, minimapRadius);
342
        g.setRadius(minimapRadius);
343
        g.setColorAt(1.0, QColor(255, 255, 255, 0));
344
        g.setColorAt(0.5, QColor(128, 128, 128, 255));
345
 
346
        QPainter mask(&minimapPixmapMask);
347
        mask.setRenderHint(QPainter::Antialiasing);
348
        mask.setCompositionMode(QPainter::CompositionMode_Source);
349
        mask.setBrush(g);
350
        mask.setPen(Qt::NoPen);
351
        mask.drawRect(minimapPixmapMask.rect());
352
        mask.setBrush(QColor(Qt::transparent));
353
        mask.drawEllipse(g.center(), minimapInnerRadius, minimapInnerRadius);
354
        mask.end();
355
    }
356
 
357
    // only set the dimension to the magnified portion
358
    if (minimapPixmap.size() != minimapSize) {
359
        minimapPixmap = QPixmap(minimapSize);
360
        minimapPixmap.fill(Qt::lightGray);
361
    }
362
    QPainter p_map(&minimapPixmap);
363
    m_miniMap->render(&p_map, QRect(QPoint(0,0), minimapSize));
364
 
365
    // Draw small view area:
366
    p_map.setPen(Qt::red);
367
    QRectF border = m_normalMap->getBorderCoord();
368
    QRect view = m_miniMap->coordToPixpos(border);
369
    //view.translate(minimapPosition);
370
    p_map.drawLine(view.topLeft(), view.topRight());
371
    p_map.drawLine(view.topRight(), view.bottomRight());
372
    p_map.drawLine(view.bottomRight(), view.bottomLeft());
373
    p_map.drawLine(view.bottomLeft(), view.topLeft());
374
 
375
    p_map.end();
376
}
377
 
378
 
379
void MapWidget::paintEvent(QPaintEvent *event) {
380
    QPainter p;
381
    p.begin(this);
382
 
383
    // Main Map:
384
    p.drawPixmap(QPoint(0,0), mainmapPixmap);
385
 
386
    // Painting minimap:
387
    p.setRenderHint(QPainter::Antialiasing);
388
    QPainterPath clipPath;
389
    clipPath.addEllipse(minimapCenter, minimapInnerRadius, minimapInnerRadius);
390
    p.setClipPath(clipPath);
391
    p.drawPixmap(minimapPosition, minimapPixmap);
392
    p.setClipping(false);
393
    p.drawPixmap(minimapPosition, minimapPixmapMask);
394
 
395
    //renderPosInfo(p);
396
 
397
    p.setPen(Qt::gray);
398
    p.drawPath(clipPath);
399
 
400
    if (invert) {
401
        p.setCompositionMode(QPainter::CompositionMode_Difference);
402
        p.fillRect(event->rect(), Qt::white);
403
    }
404
    p.end();
405
}
406
 
407
 
408
void MapWidget::mousePressEvent(QMouseEvent *event)
409
{
410
    setFocus();
411
    if (event->buttons() != Qt::LeftButton)
412
        return;
413
    pressed = true;
414
    pressPos = event->pos();
415
}
416
 
417
void MapWidget::mouseMoveEvent(QMouseEvent *event)
418
{
419
    if (!event->buttons())
420
        return;
421
 
422
    if (pressed) {
423
        QPoint delta = event->pos() - pressPos;
424
        pressPos = event->pos();
425
        m_normalMap->pan(delta);
426
        m_miniMap->setCenterCoord(m_normalMap->getCenterCoord());
427
 
428
        // Warning: 
429
        //      It will draw tiles that were already downloaded, others will be empty.
430
        //      Network request will on button release
431
        renderAll();
432
        update();
433
    }
434
}
435
 
436
void MapWidget::mouseReleaseEvent(QMouseEvent *) {
437
    pressed = false;
438
    emit signalRequestNetworkData();
439
}
440
 
441
void MapWidget::keyPressEvent(QKeyEvent *event)
442
{
443
    switch (event->key()) {
444
    case Qt::Key_Plus:
445
        if (m_normalMap->getZoom() < 19) {
446
            m_normalMap->setZoom(m_normalMap->getZoom()+1);
447
            m_normalMap->pan(QPoint());
448
            emit signalRequestNetworkData();
449
        }
450
        break;
451
    case Qt::Key_Minus:
452
        if (m_normalMap->getZoom() > 15) {
453
            m_normalMap->setZoom(m_normalMap->getZoom()-1);
454
            m_normalMap->pan(QPoint());
455
            emit signalRequestNetworkData();
456
        }
457
        break;
458
    default:;
459
    }
460
}
461
 
462
}  // namespace debugger

powered by: WebSVN 2.1.0

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