Marble

GeoPainter.h
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2008-2009 Torsten Rahn <[email protected]>
4 //
5 
6 #ifndef MARBLE_GEOPAINTER_H
7 #define MARBLE_GEOPAINTER_H
8 
9 
10 #include "marble_export.h"
11 
12 // Marble
13 #include "MarbleGlobal.h"
14 #include "ClipPainter.h"
15 
16 #include <QSizeF>
17 
18 class QImage;
19 class QPaintDevice;
20 class QRegion;
21 class QString;
22 
23 namespace Marble
24 {
25 
26 class ViewportParams;
27 class GeoPainterPrivate;
28 class GeoDataCoordinates;
29 class GeoDataLineString;
30 class GeoDataLinearRing;
31 class GeoDataPoint;
32 class GeoDataPolygon;
33 
34 
35 /*!
36  \class GeoPainter
37  \brief A painter that allows to draw geometric primitives on the map.
38 
39  This class allows application developers to draw simple geometric shapes
40  and objects onto the map.
41 
42  The API is modeled after the QPainter API.
43 
44  The GeoPainter provides a wide range of methods that are using geographic
45  ("geodesic") coordinates to position the item.
46  For example a point or the nodes of a polygon can fully be described in
47  geographic coordinates.
48 
49  In all these cases the position of the object is specified in geographic
50  coordinates.
51 
52  There are however some cases where there are two viable cases:
53  \li the shape of the object could still use screen coordinates (like a label
54  or an icon).
55  \li Alternatively the shape of the object can get projected according
56  to the current projection (e.g. a texture projected onto the spherical
57  surface)
58 
59  If screen coordinates are used then e.g. width and height are assumed to be
60  expressed in pixels, otherwise degrees are used.
61 
62  Painter transformations (e.g. translate) always happen in screen
63  coordinates.
64 
65  Like in QPainter drawing objects onto a widget should always considered to
66  be a volatile operation. This means that e.g. placemarks don't get added to
67  the globe permanently.
68  So the drawing needs to be done on every repaint to prevent that drawings
69  will disappear during the next paint event.
70 
71  So if you want to add placemarks to your map widget permanently (i.e. you
72  don't want to take care of repainting) then you need to use other solutions
73  such as the KML import of the Marble framework or Marble's GeoGraphicsItems.
74 
75  \note By default the GeoPainter automatically filters geographical content
76  in order to provide fast painting:
77  \li Geographically positioned objects which are outside the viewport are not
78  drawn at all.
79  Parts of objects which are specified through geographic coordinates
80  (like polygons, ellipses etc.) get cut off if they are not placed within the
81  viewport.
82  \li Objects which have a shape that is specified through geographic
83  coordinates get filtered according to the viewport resolution:
84  If the object is much smaller than a pixel then it won't get drawn at all.
85 */
86 
87 
88 class MARBLE_EXPORT GeoPainter : public ClipPainter
89 {
90  public:
91  enum Frame {
92  NoOptions = 0x0,
93  RoundFrame = 0x1
94  };
95 
96  Q_DECLARE_FLAGS(Frames, Frame)
97 
98 /*!
99  \brief Creates a new geo painter.
100 
101  To create a geo painter it's necessary to provide \a paintDevice
102  as a canvas and the viewportParams to specify the map projection
103  inside the viewport.
104 */
105  GeoPainter( QPaintDevice * paintDevice,
106  const ViewportParams *viewportParams,
107  MapQuality mapQuality = NormalQuality );
108 
109 
110 /*!
111  \brief Destroys the geo painter.
112 */
113  ~GeoPainter();
114 
115 
116 /*!
117  \brief Returns the map quality.
118  \return The map quality that got assigned to the painter.
119 */
120  MapQuality mapQuality() const;
121 
122 
123 /*!
124  \brief Draws a text annotation that points to a geodesic position.
125 
126  The annotation consists of a bubble with the specified \a text inside.
127  By choosing an appropriate pen for the painter it's possible to change
128  the color and line style of the bubble outline and the text. The brush
129  chosen for the painter is used to paint the background of the bubble
130 
131  The optional parameters which describe the layout of the bubble are
132  similar to those used by QPainter::drawRoundedRect().
133  Unlike in QPainter the rounded corners are not specified in percentage
134  but in pixels to provide for optimal aesthetics.
135  By choosing a positive or negative bubbleOffset it's possible to
136  place the annotation on top, bottom, left or right of the annotated
137  position.
138 
139  \param position The geodesic position
140  \param text The text contained by the bubble
141  \param bubbleSize The size of the bubble that holds the annotation text.
142  A height of 0 can be used to have the height calculated
143  automatically to fit the needed text height.
144  \param bubbleOffsetX The x-axis offset between the annotated position and
145  the "root" of the speech bubble's "arrow".
146  \param bubbleOffsetY The y-axis offset between the annotated position and
147  the "root" of the speech bubble's "arrow".
148  \param xRnd Specifies the geometry of the rounded corners in pixels along
149  the x-axis.
150  \param yRnd Specifies the geometry of the rounded corners in pixels along
151  the y-axis.
152 
153  \see GeoDataCoordinates
154 */
155  void drawAnnotation( const GeoDataCoordinates & position,
156  const QString & text,
157  QSizeF bubbleSize = QSizeF( 130, 100 ),
158  qreal bubbleOffsetX = -10, qreal bubbleOffsetY = -30,
159  qreal xRnd = 5, qreal yRnd = 5 );
160 
161 
162 /*!
163  \brief Draws a single point at a given geographic position.
164  The point is drawn using the painter's pen color.
165 
166  \see GeoDataCoordinates
167 */
168  void drawPoint ( const GeoDataCoordinates & position );
169 
170 
171 /*!
172  \brief Creates a region for a given geographic position.
173 
174  A QRegion object is created that represents the area covered by
175  GeoPainter::drawPoint( GeoDataCoordinates ). It can be used e.g. for
176  input event handling of objects that have been painted using
177  GeoPainter::drawPoint( GeoDataCoordinates ).
178 
179  The width allows to set the "stroke width" for the region. For input
180  event handling it's always advisable to use a width that is slightly
181  bigger than the width of the painter's pen.
182 
183  \see GeoDataCoordinates
184 */
185  QRegion regionFromPoint ( const GeoDataCoordinates & position,
186  qreal strokeWidth = 3) const;
187 
188 
189 /*!
190  \brief Draws a single point at a given geographic position.
191  The point is drawn using the painter's pen color.
192 
193  \see GeoDataPoint
194 */
195  void drawPoint ( const GeoDataPoint & point );
196 
197 
198 /*!
199  \brief Create a region for a given geographic position.
200 
201  A QRegion object is created that represents the area covered by
202  GeoPainter::drawPoint( GeoDataPoint ). It can be used e.g. for
203  input event handling of objects that have been painted using
204  GeoPainter::drawPoint( GeoDataPoint ).
205 
206  The width allows to set the "stroke width" for the region. For input
207  event handling it's always advisable to use a width that is slightly
208  bigger than the width of the painter's pen.
209 */
210  QRegion regionFromPoint ( const GeoDataPoint & point,
211  qreal strokeWidth = 3) const;
212 
213 
214 /*!
215  \brief Draws the given text at a given geographic position.
216  The \a text is drawn starting at the given \a position using the painter's
217  font property. The text rendering is performed in screen coordinates and is
218  not subject to the current projection.
219  An offset given in screenPixels can be provided via xOffset and yOffset
220  in order to tweak the text position.
221  By optionally adding a width, height and text options the text flow can be
222  further influenced.
223 */
224  void drawText ( const GeoDataCoordinates & position, const QString & text,
225  qreal xOffset = 0.0, qreal yOffset = 0.0,
226  qreal width = 0.0, qreal height = 0.0,
227  const QTextOption & option = QTextOption() );
228 
229 
230 /*!
231  \brief Draws an ellipse at the given position.
232  The ellipse is placed with its center located at the given \a centerPosition.
233 
234  For the outline it uses the painter's pen and for the background the
235  painter's brush.
236 
237  If \a isGeoProjected is true then the outline of the ellipse is drawn
238  in geographic coordinates. In this case the \a width and the \a height
239  are interpreted to be degrees.
240  If \a isGeoProjected is false then the outline of the ellipse is drawn
241  in screen coordinates. In this case the \a width and the \a height
242  are interpreted to be pixels.
243 
244  \see GeoDataCoordinates
245 */
246  void drawEllipse ( const GeoDataCoordinates & centerPosition,
247  qreal width, qreal height, bool isGeoProjected = false );
248 
249 
250 /*!
251  \brief Creates a region for an ellipse at a given position
252 
253  A QRegion object is created that represents the area covered by
254  GeoPainter::drawEllipse(). As such it can be used e.g. for input event
255  handling for objects that have been painted using GeoPainter::drawEllipse().
256 
257  The \a strokeWidth allows to extrude the QRegion by half the amount of
258  "stroke width" pixels. For input event handling it's always advisable to use
259  a width that is slightly bigger than the width of the painter's pen.
260 
261  \see GeoDataCoordinates
262 */
263  QRegion regionFromEllipse ( const GeoDataCoordinates & centerPosition,
264  qreal width, qreal height, bool isGeoProjected = false,
265  qreal strokeWidth = 3 ) const;
266 
267 
268 /*!
269  \brief Draws an image at the given position.
270  The image is placed with its center located at the given \a centerPosition.
271 
272  The image rendering is performed in screen coordinates and is
273  not subject to the current projection.
274 
275  \see GeoDataCoordinates
276 */
277  void drawImage ( const GeoDataCoordinates & centerPosition,
278  const QImage & image /* , bool isGeoProjected = false */ );
279 
280 
281 /*!
282  \brief Draws a pixmap at the given position.
283  The pixmap is placed with its center located at the given \a centerPosition.
284 
285  The image rendering is performed in screen coordinates and is
286  not subject to the current projection.
287 
288  \see GeoDataCoordinates
289 */
290  void drawPixmap ( const GeoDataCoordinates & centerPosition,
291  const QPixmap & pixmap /*, bool isGeoProjected = false */ );
292 
293 /*!
294  \brief Creates a region for a rectangle for a pixmap at a given position.
295 
296  A QRegion object is created that represents the area covered by
297  GeoPainter::drawPixmap(). This can be used e.g. for input event handling
298  for objects that have been painted using GeoPainter::drawPixmap().
299 
300  The \a margin allows to extrude the QRegion by "margin" pixels on every side.
301 
302  \see GeoDataCoordinates
303 */
304  QRegion regionFromPixmapRect(const GeoDataCoordinates &centerCoordinates,
305  int width, int height,
306  int margin = 0) const;
307 
308 /*!
309  \brief Helper method for safe and quick linestring conversion.
310 
311  In general drawPolyline() should be used instead. However
312  in situations where the same linestring is supposed to be
313  drawn multiple times it's a good idea to cache the
314  screen polygons using this method.
315 
316  \see GeoDataLineString
317 */
318  void polygonsFromLineString( const GeoDataLineString &lineString,
319  QVector<QPolygonF*> &polygons) const;
320 
321 
322 /*!
323  \brief Draws a given line string (a "polyline") with a label.
324 
325  The \a lineString is drawn using the current pen. It's possible to
326  provide a \a labelText for the \a lineString. The text is rendered using
327  the painter's font property.
328  The position of the \a labelText can be specified using the
329  \a labelPositionFlags.
330 
331  \see GeoDataLineString
332 */
333  void drawPolyline ( const GeoDataLineString & lineString,
334  const QString& labelText,
335  LabelPositionFlags labelPositionFlags = LineCenter,
336  const QColor& labelcolor = Qt::black);
337 
338 /*!
339  \brief Draws Labels for a given set of screen polygons.
340 
341  In common cases the drawPolyline overload can be used instead.
342  However in certain more complex cases this particular method
343  might be helpful for further optimization.
344 */
345 
346  void drawLabelsForPolygons( const QVector<QPolygonF*> &polygons,
347  const QString& labelText,
348  LabelPositionFlags labelPositionFlags,
349  const QColor& labelColor );
350 
351 /*!
352  \brief Draws a given line string (a "polyline").
353 
354  The \a lineString is drawn using the current pen.
355 
356  \see GeoDataLineString
357 */
358  void drawPolyline(const GeoDataLineString & lineString);
359 
360 /*!
361  \brief Creates a region for a given line string (a "polyline").
362 
363  A QRegion object is created that represents the area covered by
364  GeoPainter::drawPolyline( GeoDataLineString ). As such it can be used
365  e.g. for input event handling for objects that have been painted using
366  GeoPainter::drawPolyline( GeoDataLineString ).
367 
368  The \a strokeWidth allows to extrude the QRegion by half the amount of
369  "stroke width" pixels. For input event handling it's always advisable to use
370  a width that is slightly bigger than the width of the painter's pen.
371 
372  \see GeoDataLineString
373 */
374  QRegion regionFromPolyline ( const GeoDataLineString & lineString,
375  qreal strokeWidth = 3 ) const;
376 
377 
378 /*!
379  \brief Draws a given linear ring (a "polygon without holes").
380 
381  The outline of the \a linearRing is drawn using the current pen. The
382  background is painted using the current brush of the painter.
383  Like in QPainter::drawPolygon() the \a fillRule specifies the
384  fill algorithm that is used to fill the polygon.
385 
386  \see GeoDataLinearRing
387 */
388  void drawPolygon ( const GeoDataLinearRing & linearRing,
389  Qt::FillRule fillRule = Qt::OddEvenFill );
390 
391 
392 /*!
393  \brief Creates a region for a given linear ring (a "polygon without holes").
394 
395  A QRegion object is created that represents the area covered by
396  GeoPainter::drawPolygon( GeoDataLinearRing ). As such it can be used
397  e.g. for input event handling for objects that have been painted using
398  GeoPainter::drawPolygon( GeoDataLinearRing ).
399 
400  Like in drawPolygon() the \a fillRule specifies the fill algorithm that is
401  used to fill the polygon.
402 
403  The \a strokeWidth allows to extrude the QRegion by half the amount of
404  "stroke width" pixels. For input event handling it's always advisable to use
405  a width that is slightly bigger than the width of the painter's pen.
406 
407  For the polygon case a "cosmetic" strokeWidth of zero should provide the
408  best performance.
409 
410  \see GeoDataLinearRing
411 */
412  QRegion regionFromPolygon ( const GeoDataLinearRing & linearRing,
413  Qt::FillRule fillRule, qreal strokeWidth = 3 ) const;
414 
415 
416 /*!
417  \brief Draws a given polygon (which may contain holes).
418 
419  The outline of the \a polygon is drawn using the current pen. The
420  background is painted using the current brush of the painter.
421  Like in QPainter::drawPolygon() the \a fillRule specifies the
422  fill algorithm that is used to fill the polygon.
423 
424  \see GeoDataPolygon
425 */
426  void drawPolygon ( const GeoDataPolygon & polygon,
427  Qt::FillRule fillRule = Qt::OddEvenFill );
428 
429 
430  QVector<QPolygonF*> createFillPolygons( const QVector<QPolygonF*> & outerPolygons,
431  const QVector<QPolygonF*> & innerPolygons ) const;
432 
433 /*!
434  \brief Draws a rectangle at the given position.
435  The rectangle is placed with its center located at the given
436  \a centerPosition.
437 
438  For the outline it uses the painter's pen and for the background the
439  painter's brush.
440 
441  If \a isGeoProjected is true then the outline of the rectangle is drawn
442  in geographic coordinates. In this case the \a width and the \a height
443  are interpreted to be degrees.
444  If \a isGeoProjected is false then the outline of the rectangle is drawn
445  in screen coordinates. In this case the \a width and the \a height
446  are interpreted to be pixels.
447 
448  \see GeoDataCoordinates
449 */
450  void drawRect ( const GeoDataCoordinates & centerPosition,
451  qreal width, qreal height,
452  bool isGeoProjected = false );
453 
454 
455 /*!
456  \brief Creates a region for a rectangle at a given position.
457 
458  A QRegion object is created that represents the area covered by
459  GeoPainter::drawRect(). This can be used e.g. for input event handling
460  for objects that have been painted using GeoPainter::drawRect().
461 
462  The isGeoProjected parameter is used the same way as for
463  GeoPainter::drawRect().
464 
465  The \a strokeWidth allows to extrude the QRegion by half the amount of
466  "stroke width" pixels. For input event handling it's always advisable to use
467  a width that is slightly bigger than the width of the painter's pen. This is
468  especially true for small objects.
469 
470  \see GeoDataCoordinates
471 */
472  QRegion regionFromRect ( const GeoDataCoordinates & centerPosition,
473  qreal width, qreal height,
474  bool isGeoProjected = false,
475  qreal strokeWidth = 3 ) const;
476 
477 
478 /*!
479  \brief Draws a rectangle with rounded corners at the given position.
480  The rectangle is placed with its center located at the given
481  \a centerPosition.
482 
483  For the outline it uses the painter's pen and for the background the
484  painter's brush.
485  Unlike in QPainter::drawRoundedRect() the rounded corners are not specified
486  in percentage but in pixels to provide for optimal aesthetics.
487 
488  \param centerPosition Position of rectangle center
489  \param width Width of the rectangle in pixels
490  \param height Height of the rectangle in pixels
491  \param xRnd Specifies the geometry of the rounded corners in pixels along
492  the x-axis.
493  \param yRnd Specifies the geometry of the rounded corners in pixels along
494  the y-axis.
495 
496  \see GeoDataCoordinates
497 */
498  void drawRoundedRect(const GeoDataCoordinates &centerPosition,
499  qreal width, qreal height,
500  qreal xRnd = 25.0, qreal yRnd = 25.0);
501 
502 
503  void drawTextFragment(const QPoint &position, const QString &text,
504  const qreal fontSize, const QColor &color = Qt::black,
505  const Frames &flags = Frames());
506 
507 
508  // Reenabling QPainter+ClipPainter methods.
509  using QPainter::drawText;
510  using QPainter::drawEllipse;
511  using QPainter::drawImage;
512  using QPainter::drawPixmap;
513  using QPainter::drawPoint;
514  using ClipPainter::drawPolyline;
515  using ClipPainter::drawPolygon;
516  using QPainter::drawRect;
518 
519  private:
520  Q_DISABLE_COPY( GeoPainter )
521  GeoPainterPrivate * const d;
522 };
523 
524 }
525 
526 #endif
A 3d point representation.
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
void drawEllipse(const QRectF &rectangle)
A polygon that can have "holes".
void drawRect(const QRectF &rectangle)
A Geometry object representing a 3d point.
Definition: GeoDataPoint.h:42
void drawText(const QPointF &position, const QString &text)
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags)
FillRule
A LineString that allows to store a contiguous set of line segments.
A public class that controls what is visible in the viewport of a Marble map.
void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
MapQuality
This enum is used to choose the map quality shown in the view.
Definition: MarbleGlobal.h:74
Binds a QML item to a specific geodetic location in screen coordinates.
A painter that allows to draw geometric primitives on the map.
Definition: GeoPainter.h:88
void drawPoint(const QPointF &position)
@ NormalQuality
Normal quality.
Definition: MarbleGlobal.h:77
A LinearRing that allows to store a closed, contiguous set of line segments.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Sep 22 2023 03:53:11 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.