Marble

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

KDE's Doxygen guidelines are available online.