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 4

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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