File indexing completed on 2024-04-14 14:11:46

0001 /*
0002     SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "mapcanvas.h"
0008 #include <cstdlib>
0009 
0010 #include <QPainter>
0011 #include <QPixmap>
0012 #include <QMouseEvent>
0013 #include <QPaintEvent>
0014 #include <QStandardPaths>
0015 #include "kspaths.h"
0016 
0017 #include "dialogs/locationdialog.h"
0018 #include "kstars.h"
0019 #include "kstarsdata.h"
0020 
0021 MapCanvas::MapCanvas(QWidget *parent) : QFrame(parent), ld(nullptr)
0022 {
0023     setAutoFillBackground(false);
0024 
0025     QString bgFile = KSPaths::locate(QStandardPaths::AppLocalDataLocation, "geomap.jpg");
0026     bgImage        = new QPixmap(bgFile);
0027     xsize= width();
0028     ysize = height();
0029     ximage = bgImage->width();
0030     yimage = bgImage->height();
0031     ratio = ximage / yimage;
0032     xscale = xsize / 360;
0033     yscale = ysize / (360 / ratio);
0034     origin.setX(width() / 2);
0035     origin.setY(height() / 2);
0036 }
0037 
0038 MapCanvas::~MapCanvas()
0039 {
0040     delete bgImage;
0041 }
0042 
0043 void MapCanvas::setGeometry(int x, int y, int w, int h)
0044 {
0045     QWidget::setGeometry(x, y, w, h);
0046     origin.setX(w / 2);
0047     origin.setY(h / 2);
0048 }
0049 
0050 void MapCanvas::setGeometry(const QRect &r)
0051 {
0052     QWidget::setGeometry(r);
0053     origin.setX(r.width() / 2);
0054     origin.setY(r.height() / 2);
0055 }
0056 
0057 void MapCanvas::mousePressEvent(QMouseEvent *e)
0058 {
0059     //Determine Lat/Long corresponding to event press
0060     int lng = ((e->x() - origin.x()) / xscale);
0061     int lat = ((origin.y() - e->y()) / yscale);
0062 
0063     if (ld)
0064         ld->findCitiesNear(lng, lat);
0065 }
0066 
0067 void MapCanvas::paintEvent(QPaintEvent *)
0068 {
0069     QPainter p;
0070 
0071     xsize= width();
0072     ysize = height();
0073     ximage = bgImage->width();
0074     yimage = bgImage->height();
0075     ratio = ximage / yimage;
0076     xscale = xsize / 360;
0077     yscale = ysize / (360 / ratio);
0078     origin.setX(width() / 2);
0079     origin.setY(height() / 2);
0080 
0081     //prepare the canvas
0082     p.begin(this);
0083     p.drawPixmap(0, 0, bgImage->scaled(size()));
0084     p.setPen(QPen(QColor("SlateGrey")));
0085 
0086     //Draw cities
0087     QPoint o;
0088 
0089     foreach (GeoLocation *g, KStarsData::Instance()->getGeoList())
0090     {
0091         convertAndScale(o, *g);
0092 
0093         if (o.x() >= 0 && o.x() <= width() && o.y() >= 0 && o.y() <= height())
0094         {
0095             p.drawPoint(o.x(), o.y());
0096         }
0097     }
0098 
0099     // FIXME: there must be better way to this. Without bothering LocationDialog
0100     if (ld)
0101     {
0102         //redraw the cities that appear in the filtered list, with a white pen
0103         //If the list has not been filtered, skip the redraw.
0104         if (ld->filteredList().size())
0105         {
0106             p.setPen(Qt::white);
0107             foreach (GeoLocation *g, ld->filteredList())
0108             {
0109                 convertAndScale(o, *g);
0110 
0111                 if (o.x() >= 0 && o.x() <= width() && o.y() >= 0 && o.y() <= height())
0112                 {
0113                     p.drawPoint(o.x(), o.y());
0114                 }
0115             }
0116         }
0117 
0118         GeoLocation *g = ld->selectedCity();
0119         if (g)
0120         {
0121             convertAndScale(o, *g);
0122 
0123             p.setPen(Qt::red);
0124             p.setBrush(Qt::red);
0125             p.drawEllipse(o.x() - 3, o.y() - 3, 6, 6);
0126             p.drawLine(o.x() - 16, o.y(), o.x() - 8, o.y());
0127             p.drawLine(o.x() + 8, o.y(), o.x() + 16, o.y());
0128             p.drawLine(o.x(), o.y() - 16, o.x(), o.y() - 8);
0129             p.drawLine(o.x(), o.y() + 8, o.x(), o.y() + 16);
0130             p.setPen(Qt::white);
0131             p.setBrush(Qt::white);
0132         }
0133     }
0134     p.end();
0135 }
0136 
0137 void MapCanvas::convertAndScale(QPoint &o, GeoLocation &g)
0138 {
0139     int xpos = g.lng()->Degrees();
0140     int ypos = g.lat()->Degrees();
0141     o.setX((xpos * xscale) + origin.x());
0142     o.setY(height() - ((ypos * yscale) + origin.y()));
0143 }