1 /********************************************************************************************** 2 Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de> 3 Copyright (C) 2017 Norbert Truchsess <norbert.truchsess@t-online.de> 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 **********************************************************************************************/ 19 20 #ifndef CCANVAS_H 21 #define CCANVAS_H 22 23 #include "gis/IGisItem.h" 24 25 #include <QMap> 26 #include <QPainter> 27 #include <QPointer> 28 #include <QWidget> 29 30 class IDrawContext; 31 class CMapDraw; 32 class CGrid; 33 class CDemDraw; 34 class CPoiDraw; 35 class QGestureEvent; 36 class CGisDraw; 37 class CRtDraw; 38 class CGisItemWpt; 39 class CGisItemTrk; 40 class CGisItemRte; 41 class CGisItemOvlArea; 42 class CColorLegend; 43 class CMouseAdapter; 44 class QSettings; 45 class QPointF; 46 class IMouse; 47 class QTimer; 48 class QMovie; 49 class QLabel; 50 class QTextBrowser; 51 class IPlot; 52 struct SGisLine; 53 struct poi_t; 54 class CTableTrkInfo; 55 56 class CCanvas : public QWidget 57 { 58 Q_OBJECT 59 public: 60 CCanvas(QWidget* parent, const QString& name); 61 virtual ~CCanvas(); 62 63 static void setOverrideCursor(const QCursor& cursor, const QString& src); 64 static void restoreOverrideCursor(const QString& src); 65 static void changeOverrideCursor(const QCursor& cursor, const QString& src); 66 67 68 void saveConfig(QSettings& cfg); 69 void loadConfig(QSettings& cfg); 70 71 void setupGrid(); 72 void convertGridPos2Str(const QPointF& pos, QString& str, bool simple); 73 void convertRad2Px(QPointF& pos) const; 74 void convertPx2Rad(QPointF& pos) const; 75 76 void setupBackgroundColor(); 77 78 void setup(); 79 QString getProjection(); 80 void setProjection(const QString& proj); 81 82 enum scales_type_e 83 { 84 eScalesDefault 85 , eScalesSquare 86 }; 87 88 void setScales(const scales_type_e type); 89 scales_type_e getScalesType(); 90 91 qreal getElevationAt(const QPointF& pos) const; 92 void getElevationAt(const QPolygonF& pos, QPolygonF& ele) const; 93 void getElevationAt(SGisLine& line) const; 94 95 qreal getSlopeAt(const QPointF& pos) const; 96 void getSlopeAt(const QPolygonF& pos, QPolygonF& slope) const; 97 98 void moveTo(const QPointF& newFocus); 99 void moveMap(const QPointF& delta); 100 void zoomTo(const QRectF& rect); 101 void zoom(int index); 102 void displayInfo(const QPoint& px); 103 ///The POIs can be clustered together, so the icon is not necessarily displayed where the POI is. 104 /// Thus the location where to draw the highlight is separately given 105 void findPoiCloseBy(const QPoint& px, QSet<poi_t>& poiItems, QList<QPointF>& posPoiHighlight) const; 106 ///The POIs can be clustered together, so the icon is not necessarily displayed where the POI is. 107 /// Thus the location where to draw the highlight is separately given 108 void findPoisIn(const QRectF& degRect, QSet<poi_t>& poiItems, QList<QPointF>& posPoiHighlight) const; 109 110 enum redraw_e 111 { 112 eRedrawNone = 0 113 , eRedrawMap = 0x01 114 , eRedrawDem = 0x02 115 , eRedrawGis = 0x04 116 , eRedrawMouse = 0x08 117 , eRedrawRt = 0x10 118 , eRedrawPoi = 0x20 119 , eRedrawAll = 0xFFFFFFFF 120 }; 121 122 static void triggerCompleteUpdate(CCanvas::redraw_e flags); 123 124 void abortMouse(); 125 void resetMouse(); 126 void mouseTrackingLost(); 127 void setMouseMoveWpt(CGisItemWpt& wpt); 128 void setMouseRadiusWpt(CGisItemWpt& wpt); 129 void setMouseEditTrk(CGisItemTrk& trk); 130 void setMouseRangeTrk(CGisItemTrk& trk); 131 void setMouseEditTrk(const QPointF& pt); 132 void setMouseEditRte(const QPointF& pt); 133 void setMouseEditRte(CGisItemRte& rte); 134 void setMouseEditArea(CGisItemOvlArea& area); 135 void setMouseEditArea(const QPointF& pt); 136 void setMouseWptBubble(const IGisItem::key_t& key); 137 void setMouseRuler(); 138 void setMousePrint(); 139 void setMouseSelect(); 140 141 void showProfileAsWindow(); 142 void showProfile(bool yes); 143 144 void buildHelpText(); 145 146 /** 147 @brief Add a message by key to be reported on the canvas 148 149 Messages from various sources will be collected in a list and displayed in the top left corner 150 of the widget. 151 152 @note The object reporting has to take care to remove the message by reporting an empty string. 153 154 @param key the key to identify the reporting object 155 @param msg the message to report 156 */ 157 void reportStatus(const QString& key, const QString& msg); 158 159 /** 160 @brief Find a matching street polyline 161 162 The polyline must be close enough in terms of pixel to point 1 and 2. "Close enough" is defined by 163 the threshold. The returned polyline uses lon/lat as coordinates. 164 165 @param pt1 first point in [rad] 166 @param pt2 second point in [rad] 167 @param threshold the "close enough" threshold in [pixel] 168 @param polyline the resulting polyline, if any, in [rad] 169 @return Return true if a line has been found. 170 */ 171 bool findPolylineCloseBy(const QPointF& pt1, const QPointF& pt2, qint32 threshold, QPolygonF& polyline); 172 173 void print(QPainter& p, const QRectF& area, const QPointF& focus, bool printScale = true); 174 175 /** 176 @brief Set a single map file to be shown on the canvas 177 178 @param filename the map's file path, can be a resource, too 179 */ 180 void setMap(const QString& filename); 181 182 void followPosition(const QPointF& pos); 183 184 /// Allows showing the track overlays if they are set in CMainWindow allowShowTrackOverlays(bool show)185 void allowShowTrackOverlays(bool show) 186 { 187 showTrackOverlays = show; 188 } 189 190 /// save the size of the track profile if it is in window mode 191 void saveSizeTrackProfile(); 192 193 static qreal gisLayerOpacity; 194 195 void linkMapViewEnabled(); 196 197 signals: 198 void sigMousePosition(const QPointF& pos, qreal ele, qreal slope); 199 void sigMoveAndZoom(int index, const QPointF& focus); 200 void sigZoom(); 201 void sigMove(); 202 void sigResize(const QSize& size); 203 204 public slots: 205 void slotTriggerCompleteUpdate(CCanvas::redraw_e flags); 206 void slotUpdateTrackInfo(bool updateVisuals); 207 void slotCheckTrackOnFocus(); 208 209 protected: 210 bool event(QEvent*) override; 211 bool gestureEvent(QGestureEvent* e); 212 void resizeEvent(QResizeEvent* e) override; 213 void paintEvent(QPaintEvent* e) override; 214 void mousePressEvent(QMouseEvent* e) override; 215 void mouseMoveEvent(QMouseEvent* e) override; 216 void mouseReleaseEvent(QMouseEvent* e) override; 217 void mouseDoubleClickEvent(QMouseEvent* e) override; 218 void wheelEvent(QWheelEvent* e) override; 219 void enterEvent(QEvent* e) override; 220 void leaveEvent(QEvent* e) override; 221 void keyPressEvent(QKeyEvent* e) override; 222 223 224 private slots: 225 void slotToolTip(); 226 227 private: 228 void drawStatusMessages(QPainter& p); 229 void drawTrackStatistic(QPainter& p); 230 void drawScale(QPainter& p, QRectF drawRect); drawScale(QPainter & p)231 void drawScale(QPainter& p)//Default use, drawRect is introduced for correct printing 232 { 233 drawScale(p, rect()); 234 } 235 void setZoom(bool in, redraw_e& needsRedraw); 236 void setSizeTrackProfile(); 237 /** 238 @brief Resize all registered drwa context objects 239 240 @param s the new size 241 242 @return Return false if one of the draw conext could not be resized 243 because it's thread is running and blocking access to the data 244 */ 245 bool setDrawContextSize(const QSize& s); 246 247 bool isShowMinMaxSummary() const; 248 bool isShowTrackSummary() const; 249 bool isShowTrackInfoTable() const; 250 bool isShowTrackInfoPoints() const; 251 bool isShowTrackProfile() const; 252 bool isShowTrackHighlight() const; 253 254 bool showTrackOverlays = true; 255 256 QColor backColor = 0x00FFFFBF; //< the background color used in case of missing map tiles 257 redraw_e needsRedraw = eRedrawAll; //< set true to initiate a complete redraw of the screen content 258 CMapDraw* map; //< the map object attached to this canvas 259 CDemDraw* dem; //< the elevation data layer attached to this canvas 260 CPoiDraw* poi; //< the poi database attached to this canvas 261 CGisDraw* gis; //< the GIS data layer attached to this canvas 262 CRtDraw* rt; //< the real time data layer attached to this canvas 263 CGrid* grid; //< the grid attached to this canvas 264 265 QList<IDrawContext*> allDrawContext; 266 267 /// the current point of focus (usually the canvas center) 268 QPointF posFocus {0.209439510239, 0.855211333477}; 269 270 /// the mouse handler 271 CMouseAdapter* mouse; 272 273 /// tool tip timer for vector map tool tips 274 QTimer* timerToolTip; 275 /// the position of the tool tip 276 QPoint posToolTip; 277 278 /// load indicator for maps 279 QMovie* loadIndicator1; 280 QLabel* mapLoadIndicator; 281 282 /// load indicator for DEM 283 QMovie* loadIndicator2; 284 QLabel* demLoadIndicator; 285 286 /// load indicator for POI 287 QMovie* loadIndicator3; 288 QLabel* poiLoadIndicator; 289 290 QPointer<CColorLegend> colorLegend; 291 292 /// current accumulated angleDelta, used/required for zooming on trackpads 293 int zoomAngleDelta = 0; 294 295 /// timer to poll for track gaining/loosing focus 296 QTimer* timerTrackOnFocus; 297 /// the key of the currently focused track 298 IGisItem::key_t keyTrackOnFocus; 299 /// the track profile plot 300 QPointer<IPlot> plotTrackProfile; 301 /// a label with a track 302 QLabel* labelTrackStatistic; 303 304 QLabel* labelTrackInfo; 305 306 QTextBrowser* textStatusMessages; 307 QMap<QString, QString> statusMessages; 308 309 QMutex mousePressMutex; 310 bool mouseLost = false; 311 312 QTextBrowser* labelHelp = nullptr; 313 }; 314 315 class CCanvasCursorLock 316 { 317 public: CCanvasCursorLock(const QCursor & cursor,const QString & src)318 CCanvasCursorLock(const QCursor& cursor, const QString& src) 319 : src(src) 320 { 321 CCanvas::setOverrideCursor(cursor, src); 322 } 323 ~CCanvasCursorLock()324 ~CCanvasCursorLock() 325 { 326 CCanvas::restoreOverrideCursor(src); 327 } 328 329 private: 330 const QString src; 331 }; 332 333 334 Q_DECLARE_METATYPE(CCanvas*) 335 336 #endif //CCANVAS_H 337 338