This forum has been archived. All content is frozen. Please use KDE Discuss instead.

customPaint or subclass LayerInterface?

Tags: None
(comma "," separated)
rainbowgoblin
Registered Member
Posts
21
Karma
0
I'm interested in drawing on a MarbleWidget, and the Marble tutorials present two ways to do this: subclass MarbleWidget and override the customPaint function, or subclass LayerInterface and write a render function. I like LayerInterface, but I'd like the objects I draw to stay the same size as users zoom in and out of the map. This seems to work well enough using the customPaint approach, but I'd like to paint in the "HOVERS_ABOVE_SURFACE" layer.

1) Is it possible to use LayerInterface, but to somehow specify that objects shouldn't respond to geometry changes?
2) Is there a better way to do this? What I'd really like is to have something like a GeoDataPlacemark, but that gets drawn very differently (I need pie charts). I considered subclassing GeoDataPlacemark, but it looks like the drawing is done by a GeoGraphicsItem subclass in GeometryLayer, and subclassing GeoGraphicsItem would be fine, but GeometryLayer wouldn't know what kind of GeoGraphicsItem to return, and subclassing GeometryLayer looks like a nightmare that would basically involve rewriting the whole class to be nearly identical, except that it could return my custom GeoGraphicsItem subclass, and then subclassing a whole lot of other classes to use my custom GeometryLayer subclass.

Thanks for any thoughts.
User avatar
Earthwings
KDE Developer
Posts
172
Karma
1
OS
Here's a solution using a custom rendering class derived from LayerInterface. To keep it simple I implemented only basic culling and no collision detection. Pies are kept at the same size by using (mostly) the original QPainter methods for drawing and doing the geo coordinates => screen coordinates conversion via ViewportParams. It looks like that:
Image

Source (compiles against current master, older versions will need some slight changes. Data is public domain from CIA World Factbook):
Code: Select all
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013      Dennis Nienhüser <earthwings@gentoo.org>
//

#include <marble/MarbleWidget.h>
#include <marble/GeoPainter.h>
#include <marble/LayerInterface.h>
#include <marble/ViewportParams.h>

#include <QtCore/qmath.h>
#include <QtGui/QApplication>

using namespace Marble;

struct Pie
{
    GeoDataCoordinates coordinates;
    QString name;
    QVector<double> values;
};

class MyPaintLayer : public QObject, public LayerInterface
{
public:
    MyPaintLayer();
    QStringList renderPosition() const;
    bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos = "NONE", GeoSceneLayer * layer = 0 );
    qreal zValue() const;

private:
    void createPie( const GeoDataCoordinates &coordinates, const QString &name, const QVector<double> &values );
    QColor color( int index ) const;
    void renderPie(GeoPainter *painter, ViewportParams *viewport, const Pie &pie);
    void renderLegend( GeoPainter *painter, ViewportParams *viewport );
    void renderLegendItem( GeoPainter *painter, int index, const QColor &color, const QString &text );
 
    QVector<Pie> m_pies;
};

MyPaintLayer::MyPaintLayer()
{
    bool dummy;
    createPie( GeoDataCoordinates::fromString( "41 00 N, 20 00 E", dummy ), "Albania", QVector<double>() << 9.9 << 0.0 << 0.0 << 90.1 );
    createPie( GeoDataCoordinates::fromString( "28 00 N, 3 00 E", dummy ), "Algeria", QVector<double>() << 97.3 << 0.0 << 0.0 << 2.7 );
    createPie( GeoDataCoordinates::fromString( "14 20 S, 170 00 W", dummy ), "American Samoa", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "12 30 S, 18 30 E", dummy ), "Angola", QVector<double>() << 56.9 << 0.0 << 0.0 << 43.1 );
    createPie( GeoDataCoordinates::fromString( "17 03 N, 61 48 W", dummy ), "Antigua and Barbuda", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "34 00 S, 64 00 W", dummy ), "Argentina", QVector<double>() << 65.4 << 3.2 << 0.1 << 28.3 );
    createPie( GeoDataCoordinates::fromString( "40 00 N, 45 00 E", dummy ), "Armenia", QVector<double>() << 53.3 << 11.8 << 0.1 << 34.7 );
    createPie( GeoDataCoordinates::fromString( "12 30 N, 69 58 W", dummy ), "Aruba", QVector<double>() << 88.7 << 0.0 << 11.3 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "27 00 S, 133 00 E", dummy ), "Australia", QVector<double>() << 79.0 << 0.0 << 4.7 << 13.7 );
    createPie( GeoDataCoordinates::fromString( "47 20 N, 13 20 E", dummy ), "Austria", QVector<double>() << 27.5 << 0.0 << 12.8 << 59.6 );
    createPie( GeoDataCoordinates::fromString( "40 30 N, 47 30 E", dummy ), "Azerbaijan", QVector<double>() << 82.3 << 0.0 << 0.0 << 17.7 );
    createPie( GeoDataCoordinates::fromString( "24 15 N, 76 00 W", dummy ), "Bahamas, The", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "26 00 N, 50 33 E", dummy ), "Bahrain", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "24 00 N, 90 00 E", dummy ), "Bangladesh", QVector<double>() << 95.8 << 0.0 << 0.3 << 4.0 );
    createPie( GeoDataCoordinates::fromString( "13 10 N, 59 32 W", dummy ), "Barbados", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "53 00 N, 28 00 E", dummy ), "Belarus", QVector<double>() << 99.7 << 0.0 << 0.1 << 0.2 );
    createPie( GeoDataCoordinates::fromString( "50 50 N, 4 00 E", dummy ), "Belgium", QVector<double>() << 46.4 << 33.7 << 11.7 << 0.6 );
    createPie( GeoDataCoordinates::fromString( "17 15 N, 88 45 W", dummy ), "Belize", QVector<double>() << 33.3 << 0.0 << 29.5 << 37.2 );
    createPie( GeoDataCoordinates::fromString( "9 30 N, 2 15 E", dummy ), "Benin", QVector<double>() << 98.3 << 0.0 << 0.0 << 1.7 );
    createPie( GeoDataCoordinates::fromString( "32 20 N, 64 45 W", dummy ), "Bermuda", QVector<double>() << 98.2 << 0.0 << 1.8 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "27 30 N, 90 30 E", dummy ), "Bhutan", QVector<double>() << 1.1 << 0.0 << 0.0 << 98.9 );
    createPie( GeoDataCoordinates::fromString( "17 00 S, 65 00 W", dummy ), "Bolivia", QVector<double>() << 58.9 << 0.0 << 1.7 << 39.3 );
    createPie( GeoDataCoordinates::fromString( "44 00 N, 18 00 E", dummy ), "Bosnia and Herzegovina", QVector<double>() << 44.5 << 0.0 << 0.0 << 55.5 );
    createPie( GeoDataCoordinates::fromString( "22 00 S, 24 00 E", dummy ), "Botswana", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "10 00 S, 55 00 W", dummy ), "Brazil", QVector<double>() << 17.1 << 1.9 << 6.3 << 74.7 );
    createPie( GeoDataCoordinates::fromString( "18 30 N, 64 30 W", dummy ), "British Virgin Islands", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "4 30 N, 114 40 E", dummy ), "Brunei", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "43 00 N, 25 00 E", dummy ), "Bulgaria", QVector<double>() << 46.4 << 20.3 << 1.9 << 22.2 );
    createPie( GeoDataCoordinates::fromString( "13 00 N, 2 00 W", dummy ), "Burkina Faso", QVector<double>() << 87.3 << 0.0 << 0.0 << 12.7 );
    createPie( GeoDataCoordinates::fromString( "22 00 N, 98 00 E", dummy ), "Burma", QVector<double>() << 67.7 << 0.0 << 0.0 << 32.3 );
    createPie( GeoDataCoordinates::fromString( "3 30 S, 30 00 E", dummy ), "Burundi", QVector<double>() << 1.9 << 0.0 << 0.0 << 98.1 );
    createPie( GeoDataCoordinates::fromString( "13 00 N, 105 00 E", dummy ), "Cambodia", QVector<double>() << 95.2 << 0.0 << 1.5 << 3.3 );
    createPie( GeoDataCoordinates::fromString( "6 00 N, 12 00 E", dummy ), "Cameroon", QVector<double>() << 27.8 << 0.0 << 0.0 << 72.2 );
    createPie( GeoDataCoordinates::fromString( "60 00 N, 95 00 W", dummy ), "Canada", QVector<double>() << 28.8 << 10.1 << 3.9 << 57.0 );
    createPie( GeoDataCoordinates::fromString( "16 00 N, 24 00 W", dummy ), "Cape Verde", QVector<double>() << 96.9 << 0.0 << 3.1 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "19 30 N, 80 30 W", dummy ), "Cayman Islands", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "7 00 N, 21 00 E", dummy ), "Central African Republic", QVector<double>() << 45.7 << 0.0 << 0.0 << 54.3 );
    createPie( GeoDataCoordinates::fromString( "15 00 N, 19 00 E", dummy ), "Chad", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "30 00 S, 71 00 W", dummy ), "Chile", QVector<double>() << 64.4 << 0.0 << 0.7 << 34.8 );
    createPie( GeoDataCoordinates::fromString( "35 00 N, 105 00 E", dummy ), "China", QVector<double>() << 69.5 << 1.1 << 7.6 << 21.8 );
    createPie( GeoDataCoordinates::fromString( "4 00 N, 72 00 W", dummy ), "Colombia", QVector<double>() << 32.9 << 0.0 << 0.4 << 66.6 );
    createPie( GeoDataCoordinates::fromString( "12 10 S, 44 15 E", dummy ), "Comoros", QVector<double>() << 83.3 << 0.0 << 0.0 << 16.7 );
    createPie( GeoDataCoordinates::fromString( "0 00 N, 25 00 E", dummy ), "Congo, Democratic Republic of the", QVector<double>() << 1.3 << 0.0 << 0.0 << 98.7 );
    createPie( GeoDataCoordinates::fromString( "1 00 S, 15 00 E", dummy ), "Congo, Republic of the", QVector<double>() << 51.2 << 0.0 << 0.0 << 48.8 );
    createPie( GeoDataCoordinates::fromString( "21 14 S, 159 46 W", dummy ), "Cook Islands", QVector<double>() << 98.9 << 0.0 << 1.1 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "10 00 N, 84 00 W", dummy ), "Costa Rica", QVector<double>() << 24.8 << 0.0 << 13.7 << 61.5 );
    createPie( GeoDataCoordinates::fromString( "8 00 N, 5 00 W", dummy ), "Cote d'Ivoire", QVector<double>() << 50.6 << 0.0 << 0.0 << 49.4 );
    createPie( GeoDataCoordinates::fromString( "45 10 N, 15 30 E", dummy ), "Croatia", QVector<double>() << 47.2 << 0.0 << 0.8 << 44.7 );
    createPie( GeoDataCoordinates::fromString( "21 30 N, 80 00 W", dummy ), "Cuba", QVector<double>() << 99.3 << 0.0 << 0.1 << 0.6 );
    createPie( GeoDataCoordinates::fromString( "35 00 N, 33 00 E", dummy ), "Cyprus", QVector<double>() << 99.7 << 0.0 << 0.3 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "49 45 N, 15 30 E", dummy ), "Czech Republic", QVector<double>() << 60.0 << 20.9 << 7.1 << 5.7 );
    createPie( GeoDataCoordinates::fromString( "56 00 N, 10 00 E", dummy ), "Denmark", QVector<double>() << 65.8 << 0.0 << 34.2 << 0.1 );
    createPie( GeoDataCoordinates::fromString( "11 30 N, 43 00 E", dummy ), "Djibouti", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "15 25 N, 61 20 W", dummy ), "Dominica", QVector<double>() << 72.1 << 0.0 << 0.3 << 16.6 );
    createPie( GeoDataCoordinates::fromString( "19 00 N, 70 40 W", dummy ), "Dominican Republic", QVector<double>() << 83.0 << 0.0 << 0.3 << 16.6 );
    createPie( GeoDataCoordinates::fromString( "2 00 S, 77 30 W", dummy ), "Ecuador", QVector<double>() << 56.2 << 0.0 << 2.1 << 41.7 );
    createPie( GeoDataCoordinates::fromString( "27 00 N, 30 00 E", dummy ), "Egypt", QVector<double>() << 86.9 << 0.0 << 1.7 << 11.4 );
    createPie( GeoDataCoordinates::fromString( "13 50 N, 88 55 W", dummy ), "El Salvador", QVector<double>() << 53.0 << 0.0 << 15.6 << 31.4 );
    createPie( GeoDataCoordinates::fromString( "2 00 N, 10 00 E", dummy ), "Equatorial Guinea", QVector<double>() << 96.8 << 0.0 << 0.0 << 3.2 );
    createPie( GeoDataCoordinates::fromString( "15 00 N, 39 00 E", dummy ), "Eritrea", QVector<double>() << 99.3 << 0.0 << 0.7 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "59 00 N, 26 00 E", dummy ), "Estonia", QVector<double>() << 94.6 << 0.0 << 5.1 << 0.3 );
    createPie( GeoDataCoordinates::fromString( "8 00 N, 38 00 E", dummy ), "Ethiopia", QVector<double>() << 17.2 << 0.0 << 0.6 << 82.1 );
    createPie( GeoDataCoordinates::fromString( "51 45 S, 59 00 W", dummy ), "Falkland Islands (Islas Malvinas)", QVector<double>() << 90.0 << 0.0 << 10.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "62 00 N, 7 00 W", dummy ), "Faroe Islands", QVector<double>() << 64.9 << 0.0 << 4.1 << 31.0 );
    createPie( GeoDataCoordinates::fromString( "18 00 S, 175 00 E", dummy ), "Fiji", QVector<double>() << 54.8 << 0.0 << 6.4 << 38.8 );
    createPie( GeoDataCoordinates::fromString( "64 00 N, 26 00 E", dummy ), "Finland", QVector<double>() << 52.5 << 16.4 << 12.0 << 19.1 );
    createPie( GeoDataCoordinates::fromString( "46 00 N, 2 00 E", dummy ), "France", QVector<double>() << 20.5 << 53.0 << 5.3 << 17.6 );
    createPie( GeoDataCoordinates::fromString( "15 00 S, 140 00 W", dummy ), "French Polynesia", QVector<double>() << 66.4 << 0.0 << 0.0 << 33.6 );
    createPie( GeoDataCoordinates::fromString( "1 00 S, 11 45 E", dummy ), "Gabon", QVector<double>() << 59.0 << 0.0 << 0.0 << 41.0 );
    createPie( GeoDataCoordinates::fromString( "13 28 N, 16 34 W", dummy ), "Gambia, The", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "42 00 N, 43 30 E", dummy ), "Georgia", QVector<double>() << 37.2 << 0.0 << 0.0 << 62.8 );
    createPie( GeoDataCoordinates::fromString( "51 00 N, 9 00 E", dummy ), "Germany", QVector<double>() << 55.0 << 23.0 << 13.0 << 3.0 );
    createPie( GeoDataCoordinates::fromString( "8 00 N, 2 00 W", dummy ), "Ghana", QVector<double>() << 40.6 << 0.0 << 0.0 << 59.4 );
    createPie( GeoDataCoordinates::fromString( "36 08 N, 5 21 W", dummy ), "Gibraltar", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "39 00 N, 22 00 E", dummy ), "Greece", QVector<double>() << 70.5 << 0.0 << 8.5 << 17.0 );
    createPie( GeoDataCoordinates::fromString( "72 00 N, 40 00 W", dummy ), "Greenland", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "12 07 N, 61 40 W", dummy ), "Grenada", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "13 28 N, 144 47 E", dummy ), "Guam", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "15 30 N, 90 15 W", dummy ), "Guatemala", QVector<double>() << 58.2 << 0.0 << 12.7 << 29.1 );
    createPie( GeoDataCoordinates::fromString( "11 00 N, 10 00 W", dummy ), "Guinea", QVector<double>() << 61.1 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "12 00 N, 15 00 W", dummy ), "Guinea-Bissau", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "5 00 N, 59 00 W", dummy ), "Guyana", QVector<double>() << 99.7 << 0.0 << 0.0 << 0.3 );
    createPie( GeoDataCoordinates::fromString( "19 00 N, 72 25 W", dummy ), "Haiti", QVector<double>() << 79.0 << 0.0 << 0.0 << 21.0 );
    createPie( GeoDataCoordinates::fromString( "15 00 N, 86 30 W", dummy ), "Honduras", QVector<double>() << 63.9 << 0.0 << 5.4 << 30.8 );
    createPie( GeoDataCoordinates::fromString( "22 15 N, 114 10 E", dummy ), "Hong Kong", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "47 00 N, 20 00 E", dummy ), "Hungary", QVector<double>() << 72.0 << 20.0 << 7.0 << 1.0 );
    createPie( GeoDataCoordinates::fromString( "65 00 N, 18 00 W", dummy ), "Iceland", QVector<double>() << 4.7 << 0.0 << 22.4 << 72.9 );
    createPie( GeoDataCoordinates::fromString( "20 00 N, 77 00 E", dummy ), "India", QVector<double>() << 69.9 << 2.2 << 7.0 << 20.9 );
    createPie( GeoDataCoordinates::fromString( "5 00 S, 120 00 E", dummy ), "Indonesia", QVector<double>() << 87.0 << 0.0 << 3.1 << 9.9 );
    createPie( GeoDataCoordinates::fromString( "32 00 N, 53 00 E", dummy ), "Iran", QVector<double>() << 86.1 << 0.0 << 0.1 << 13.7 );
    createPie( GeoDataCoordinates::fromString( "33 00 N, 44 00 E", dummy ), "Iraq", QVector<double>() << 69.0 << 0.0 << 0.0 << 31.0 );
    createPie( GeoDataCoordinates::fromString( "53 00 N, 8 00 W", dummy ), "Ireland", QVector<double>() << 75.3 << 0.0 << 17.5 << 3.2 );
    createPie( GeoDataCoordinates::fromString( "31 30 N, 34 45 E", dummy ), "Israel", QVector<double>() << 99.7 << 0.0 << 0.3 << 0.1 );
    createPie( GeoDataCoordinates::fromString( "42 50 N, 12 50 E", dummy ), "Italy", QVector<double>() << 65.0 << 0.0 << 15.8 << 18.0 );
    createPie( GeoDataCoordinates::fromString( "18 15 N, 77 30 W", dummy ), "Jamaica", QVector<double>() << 93.5 << 0.0 << 4.7 << 1.8 );
    createPie( GeoDataCoordinates::fromString( "36 00 N, 138 00 E", dummy ), "Japan", QVector<double>() << 63.9 << 17.2 << 2.3 << 7.7 );
    createPie( GeoDataCoordinates::fromString( "31 00 N, 36 00 E", dummy ), "Jordan", QVector<double>() << 99.3 << 0.0 << 0.2 << 0.5 );
    createPie( GeoDataCoordinates::fromString( "48 00 N, 68 00 E", dummy ), "Kazakhstan", QVector<double>() << 88.2 << 0.0 << 0.0 << 11.8 );
    createPie( GeoDataCoordinates::fromString( "1 00 N, 38 00 E", dummy ), "Kenya", QVector<double>() << 43.3 << 0.0 << 12.9 << 43.8 );
    createPie( GeoDataCoordinates::fromString( "1 25 N, 173 00 E", dummy ), "Kiribati", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "40 00 N, 127 00 E", dummy ), "Korea, North", QVector<double>() << 47.4 << 0.0 << 0.0 << 52.6 );
    createPie( GeoDataCoordinates::fromString( "37 00 N, 127 30 E", dummy ), "Korea, South", QVector<double>() << 69.9 << 22.0 << 1.3 << 2.0 );
    createPie( GeoDataCoordinates::fromString( "29 30 N, 45 45 E", dummy ), "Kuwait", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "41 00 N, 75 00 E", dummy ), "Kyrgyzstan", QVector<double>() << 20.1 << 0.0 << 0.0 << 79.9 );
    createPie( GeoDataCoordinates::fromString( "18 00 N, 105 00 E", dummy ), "Laos", QVector<double>() << 2.7 << 0.0 << 0.0 << 97.3 );
    createPie( GeoDataCoordinates::fromString( "57 00 N, 25 00 E", dummy ), "Latvia", QVector<double>() << 27.3 << 0.0 << 1.8 << 71.0 );
    createPie( GeoDataCoordinates::fromString( "33 50 N, 35 50 E", dummy ), "Lebanon", QVector<double>() << 87.9 << 0.0 << 0.0 << 12.1 );
    createPie( GeoDataCoordinates::fromString( "29 30 S, 28 30 E", dummy ), "Lesotho", QVector<double>() << 0.0 << 0.0 << 0.0 << 100.0 );
    createPie( GeoDataCoordinates::fromString( "6 30 N, 9 30 W", dummy ), "Liberia", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "25 00 N, 17 00 E", dummy ), "Libya", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "56 00 N, 24 00 E", dummy ), "Lithuania", QVector<double>() << 53.8 << 25.2 << 2.4 << 2.4 );
    createPie( GeoDataCoordinates::fromString( "49 45 N, 6 10 E", dummy ), "Luxembourg", QVector<double>() << 28.4 << 0.0 << 5.0 << 2.0 );
    createPie( GeoDataCoordinates::fromString( "22 10 N, 113 33 E", dummy ), "Macau", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "41 50 N, 22 00 E", dummy ), "Macedonia", QVector<double>() << 65.7 << 0.0 << 0.0 << 34.3 );
    createPie( GeoDataCoordinates::fromString( "20 00 S, 47 00 E", dummy ), "Madagascar", QVector<double>() << 69.5 << 0.0 << 0.0 << 30.5 );
    createPie( GeoDataCoordinates::fromString( "13 30 S, 34 00 E", dummy ), "Malawi", QVector<double>() << 5.7 << 0.0 << 0.0 << 94.3 );
    createPie( GeoDataCoordinates::fromString( "2 30 N, 112 30 E", dummy ), "Malaysia", QVector<double>() << 91.7 << 0.0 << 0.0 << 8.3 );
    createPie( GeoDataCoordinates::fromString( "3 15 N, 73 00 E", dummy ), "Maldives", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "17 00 N, 4 00 W", dummy ), "Mali", QVector<double>() << 48.4 << 0.0 << 0.0 << 51.6 );
    createPie( GeoDataCoordinates::fromString( "35 50 N, 14 35 E", dummy ), "Malta", QVector<double>() << 99.7 << 0.0 << 0.3 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "20 00 N, 12 00 W", dummy ), "Mauritania", QVector<double>() << 61.7 << 0.0 << 0.0 << 38.3 );
    createPie( GeoDataCoordinates::fromString( "20 17 S, 57 33 E", dummy ), "Mauritius", QVector<double>() << 75.2 << 0.0 << 18.1 << 6.7 );
    createPie( GeoDataCoordinates::fromString( "23 00 N, 102 00 W", dummy ), "Mexico", QVector<double>() << 75.0 << 2.3 << 3.3 << 19.4 );
    createPie( GeoDataCoordinates::fromString( "47 00 N, 29 00 E", dummy ), "Moldova", QVector<double>() << 88.4 << 0.0 << 0.0 << 11.6 );
    createPie( GeoDataCoordinates::fromString( "46 00 N, 105 00 E", dummy ), "Mongolia", QVector<double>() << 99.9 << 0.0 << 0.1 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "42 30 N, 19 18 E", dummy ), "Montenegro", QVector<double>() << 24.2 << 0.0 << 0.0 << 75.8 );
    createPie( GeoDataCoordinates::fromString( "16 45 N, 62 12 W", dummy ), "Montserrat", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "32 00 N, 5 00 W", dummy ), "Morocco", QVector<double>() << 67.6 << 0.0 << 4.1 << 20.8 );
    createPie( GeoDataCoordinates::fromString( "18 15 S, 35 00 E", dummy ), "Mozambique", QVector<double>() << 0.1 << 0.0 << 0.0 << 99.9 );
    createPie( GeoDataCoordinates::fromString( "22 00 S, 17 00 E", dummy ), "Namibia", QVector<double>() << 33.3 << 0.0 << 0.0 << 66.7 );
    createPie( GeoDataCoordinates::fromString( "0 32 S, 166 55 E", dummy ), "Nauru", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "28 00 N, 84 00 E", dummy ), "Nepal", QVector<double>() << 7.9 << 0.0 << 0.0 << 92.1 );
    createPie( GeoDataCoordinates::fromString( "52 30 N, 5 45 E", dummy ), "Netherlands", QVector<double>() << 84.1 << 2.0 << 13.7 << 0.1 );
    createPie( GeoDataCoordinates::fromString( "21 30 S, 165 30 E", dummy ), "New Caledonia", QVector<double>() << 79.1 << 0.0 << 2.4 << 18.5 );
    createPie( GeoDataCoordinates::fromString( "41 00 S, 174 00 E", dummy ), "New Zealand", QVector<double>() << 30.0 << 0.0 << 13.3 << 56.7 );
    createPie( GeoDataCoordinates::fromString( "13 00 N, 85 00 W", dummy ), "Nicaragua", QVector<double>() << 66.0 << 0.0 << 24.5 << 9.5 );
    createPie( GeoDataCoordinates::fromString( "16 00 N, 8 00 E", dummy ), "Niger", QVector<double>() << 67.1 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "10 00 N, 8 00 E", dummy ), "Nigeria", QVector<double>() << 67.1 << 0.0 << 0.0 << 32.9 );
    createPie( GeoDataCoordinates::fromString( "19 02 S, 169 52 W", dummy ), "Niue", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "62 00 N, 10 00 E", dummy ), "Norway", QVector<double>() << 2.6 << 0.0 << 2.0 << 91.1 );
    createPie( GeoDataCoordinates::fromString( "21 00 N, 57 00 E", dummy ), "Oman", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "30 00 N, 70 00 E", dummy ), "Pakistan", QVector<double>() << 65.2 << 2.3 << 0.0 << 32.5 );
    createPie( GeoDataCoordinates::fromString( "9 00 N, 80 00 W", dummy ), "Panama", QVector<double>() << 51.6 << 0.0 << 0.0 << 48.4 );
    createPie( GeoDataCoordinates::fromString( "6 00 S, 147 00 E", dummy ), "Papua New Guinea", QVector<double>() << 61.1 << 0.0 << 8.0 << 30.9 );
    createPie( GeoDataCoordinates::fromString( "23 00 S, 58 00 W", dummy ), "Paraguay", QVector<double>() << 0.1 << 0.0 << 0.0 << 99.9 );
    createPie( GeoDataCoordinates::fromString( "10 00 S, 76 00 W", dummy ), "Peru", QVector<double>() << 59.0 << 0.0 << 0.0 << 41.0 );
    createPie( GeoDataCoordinates::fromString( "13 00 N, 122 00 E", dummy ), "Philippines", QVector<double>() << 66.1 << 0.0 << 12.8 << 21.1 );
    createPie( GeoDataCoordinates::fromString( "52 00 N, 20 00 E", dummy ), "Poland", QVector<double>() << 91.2 << 0.0 << 2.7 << 6.1 );
    createPie( GeoDataCoordinates::fromString( "39 30 N, 8 00 W", dummy ), "Portugal", QVector<double>() << 48.3 << 0.0 << 22.5 << 23.3 );
    createPie( GeoDataCoordinates::fromString( "18 15 N, 66 30 W", dummy ), "Puerto Rico", QVector<double>() << 97.2 << 0.0 << 0.0 << 2.8 );
    createPie( GeoDataCoordinates::fromString( "25 30 N, 51 15 E", dummy ), "Qatar", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "46 00 N, 25 00 E", dummy ), "Romania", QVector<double>() << 61.7 << 9.4 << 1.9 << 27.0 );
    createPie( GeoDataCoordinates::fromString( "60 00 N, 100 00 E", dummy ), "Russia", QVector<double>() << 67.7 << 17.2 << 0.0 << 15.1 );
    createPie( GeoDataCoordinates::fromString( "2 00 S, 30 00 E", dummy ), "Rwanda", QVector<double>() << 53.3 << 0.0 << 0.4 << 46.2 );
    createPie( GeoDataCoordinates::fromString( "17 20 N, 62 45 W", dummy ), "Saint Kitts and Nevis", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "13 53 N, 60 58 W", dummy ), "Saint Lucia", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "46 50 N, 56 20 W", dummy ), "Saint Pierre and Miquelon", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "13 15 N, 61 12 W", dummy ), "Saint Vincent and the Grenadines", QVector<double>() << 81.6 << 0.0 << 0.0 << 18.4 );
    createPie( GeoDataCoordinates::fromString( "13 35 S, 172 20 W", dummy ), "Samoa", QVector<double>() << 70.6 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "1 00 N, 7 00 E", dummy ), "Sao Tome and Principe", QVector<double>() << 57.1 << 0.0 << 0.0 << 42.9 );
    createPie( GeoDataCoordinates::fromString( "25 00 N, 45 00 E", dummy ), "Saudi Arabia", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "14 00 N, 14 00 W", dummy ), "Senegal", QVector<double>() << 99.7 << 0.0 << 0.3 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "44 00 N, 21 00 E", dummy ), "Serbia", QVector<double>() << 66.1 << 0.0 << 0.0 << 26.6 );
    createPie( GeoDataCoordinates::fromString( "4 35 S, 55 40 E", dummy ), "Seychelles", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "8 30 N, 11 30 W", dummy ), "Sierra Leone", QVector<double>() << 92.3 << 0.0 << 0.0 << 7.7 );
    createPie( GeoDataCoordinates::fromString( "1 22 N, 103 48 E", dummy ), "Singapore", QVector<double>() << 99.8 << 0.0 << 0.2 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "48 40 N, 19 30 E", dummy ), "Slovakia", QVector<double>() << 37.1 << 25.4 << 2.7 << 22.0 );
    createPie( GeoDataCoordinates::fromString( "46 07 N, 14 49 E", dummy ), "Slovenia", QVector<double>() << 42.2 << 21.5 << 1.8 << 34.5 );
    createPie( GeoDataCoordinates::fromString( "8 00 S, 159 00 E", dummy ), "Solomon Islands", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "10 00 N, 49 00 E", dummy ), "Somalia", QVector<double>() << 93.8 << 0.0 << 0.0 << 6.3 );
    createPie( GeoDataCoordinates::fromString( "29 00 S, 24 00 E", dummy ), "South Africa", QVector<double>() << 90.8 << 4.1 << 0.5 << 1.5 );
    createPie( GeoDataCoordinates::fromString( "40 00 N, 4 00 W", dummy ), "Spain", QVector<double>() << 48.7 << 7.6 << 24.4 << 13.7 );
    createPie( GeoDataCoordinates::fromString( "7 00 N, 81 00 E", dummy ), "Sri Lanka", QVector<double>() << 53.8 << 0.0 << 1.6 << 44.6 );
    createPie( GeoDataCoordinates::fromString( "15 00 N, 30 00 E", dummy ), "Sudan", QVector<double>() << 30.7 << 0.0 << 3.0 << 66.3 );
    createPie( GeoDataCoordinates::fromString( "4 00 N, 56 00 W", dummy ), "Suriname", QVector<double>() << 51.4 << 0.0 << 0.0 << 48.6 );
    createPie( GeoDataCoordinates::fromString( "26 30 S, 31 30 E", dummy ), "Swaziland", QVector<double>() << 67.7 << 0.0 << 0.0 << 32.3 );
    createPie( GeoDataCoordinates::fromString( "62 00 N, 15 00 E", dummy ), "Sweden", QVector<double>() << 12.5 << 25.0 << 15.2 << 46.9 );
    createPie( GeoDataCoordinates::fromString( "47 00 N, 8 00 E", dummy ), "Switzerland", QVector<double>() << 2.5 << 16.6 << 2.5 << 69.2 );
    createPie( GeoDataCoordinates::fromString( "35 00 N, 38 00 E", dummy ), "Syria", QVector<double>() << 84.8 << 0.0 << 0.0 << 15.2 );
    createPie( GeoDataCoordinates::fromString( "23 30 N, 121 00 E", dummy ), "Taiwan", QVector<double>() << 77.2 << 10.6 << 6.9 << 5.3 );
    createPie( GeoDataCoordinates::fromString( "39 00 N, 71 00 E", dummy ), "Tajikistan", QVector<double>() << 9.0 << 0.0 << 0.0 << 91.0 );
    createPie( GeoDataCoordinates::fromString( "6 00 S, 35 00 E", dummy ), "Tanzania", QVector<double>() << 39.5 << 0.0 << 0.0 << 60.5 );
    createPie( GeoDataCoordinates::fromString( "15 00 N, 100 00 E", dummy ), "Thailand", QVector<double>() << 89.0 << 0.0 << 0.2 << 10.9 );
    createPie( GeoDataCoordinates::fromString( "8 00 N, 1 10 E", dummy ), "Togo", QVector<double>() << 21.2 << 0.0 << 0.0 << 78.8 );
    createPie( GeoDataCoordinates::fromString( "20 00 S, 175 00 W", dummy ), "Tonga", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "11 00 N, 61 00 W", dummy ), "Trinidad and Tobago", QVector<double>() << 99.7 << 0.0 << 0.3 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "34 00 N, 9 00 E", dummy ), "Tunisia", QVector<double>() << 96.9 << 0.0 << 1.4 << 1.7 );
    createPie( GeoDataCoordinates::fromString( "39 00 N, 35 00 E", dummy ), "Turkey", QVector<double>() << 65.3 << 0.0 << 2.2 << 32.5 );
    createPie( GeoDataCoordinates::fromString( "40 00 N, 60 00 E", dummy ), "Turkmenistan", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "21 45 N, 71 35 W", dummy ), "Turks and Caicos Islands", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "1 00 N, 32 00 E", dummy ), "Uganda", QVector<double>() << 37.8 << 0.0 << 2.6 << 59.5 );
    createPie( GeoDataCoordinates::fromString( "49 00 N, 32 00 E", dummy ), "Ukraine", QVector<double>() << 64.4 << 25.4 << 0.1 << 10.0 );
    createPie( GeoDataCoordinates::fromString( "24 00 N, 54 00 E", dummy ), "United Arab Emirates", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "54 00 N, 2 00 W", dummy ), "United Kingdom", QVector<double>() << 75.4 << 12.3 << 7.3 << 1.9 );
    createPie( GeoDataCoordinates::fromString( "38 00 N, 97 00 W", dummy ), "United States", QVector<double>() << 75.5 << 9.9 << 4.8 << 7.7 );
    createPie( GeoDataCoordinates::fromString( "33 00 S, 56 00 W", dummy ), "Uruguay", QVector<double>() << 38.5 << 0.0 << 0.4 << 61.1 );
    createPie( GeoDataCoordinates::fromString( "41 00 N, 64 00 E", dummy ), "Uzbekistan", QVector<double>() << 85.2 << 0.0 << 0.0 << 14.8 );
    createPie( GeoDataCoordinates::fromString( "16 00 S, 167 00 E", dummy ), "Vanuatu", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "8 00 N, 66 00 W", dummy ), "Venezuela", QVector<double>() << 35.7 << 0.0 << 0.0 << 64.3 );
    createPie( GeoDataCoordinates::fromString( "16 10 N, 107 50 E", dummy ), "Vietnam", QVector<double>() << 55.0 << 0.0 << 0.1 << 45.0 );
    createPie( GeoDataCoordinates::fromString( "18 20 N, 64 50 W", dummy ), "Virgin Islands", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "32 00 N, 35 15 E", dummy ), "West Bank", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "24 30 N, 13 00 W", dummy ), "Western Sahara", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "15 00 N, 48 00 E", dummy ), "Yemen", QVector<double>() << 100.0 << 0.0 << 0.0 << 0.0 );
    createPie( GeoDataCoordinates::fromString( "15 00 S, 30 00 E", dummy ), "Zambia", QVector<double>() << 0.4 << 0.0 << 0.0 << 99.6 );
    createPie( GeoDataCoordinates::fromString( "20 00 S, 30 00 E", dummy ), "Zimbabwe", QVector<double>() << 66.1 << 0.0 << 0.0 << 33.9 );
}

QStringList MyPaintLayer::renderPosition() const
{
    return QStringList() << "HOVERS_ABOVE_SURFACE";
}

bool MyPaintLayer::render( GeoPainter *painter, ViewportParams *viewport, const QString&, GeoSceneLayer *)
{
    foreach( const Pie &pie, m_pies ) {
        renderPie( painter, viewport, pie );
    }

    renderLegend( painter, viewport );
}

qreal MyPaintLayer::zValue() const
{
    return 5.0;
}

void MyPaintLayer::createPie(const GeoDataCoordinates &coordinates, const QString &name, const QVector<double> &values)
{
    Pie pie;
    pie.coordinates = coordinates;
    pie.name = name;
    pie.values = values;
    m_pies << pie;
}

QColor MyPaintLayer::color(int index) const
{
    switch (index % 4) {
    case 0: return Oxygen::woodBrown4;
    case 1: return Oxygen::sunYellow4;
    case 2: return Oxygen::forestGreen4;
    case 3: return Oxygen::skyBlue4;
    }
}

void MyPaintLayer::renderPie( GeoPainter *painter, ViewportParams *viewport, const Pie &pie )
{
    bool globeHidesPoint;
    qreal x, y;
    bool const visible = viewport->screenCoordinates( pie.coordinates, x, y, globeHidesPoint );
    if ( visible && !globeHidesPoint ) {
      painter->save();
      painter->setPen( QPen( Oxygen::aluminumGray2 ) );
      QRectF pieRect;
      pieRect.setSize( QSizeF( 75, 75 ) );
      pieRect.moveCenter( QPointF( x, y ) );
      double sum = 0.0;
      foreach( double value, pie.values ) {
        Q_ASSERT( value >= 0.0 );
        sum += value;
      }
      double offset = 0.0;
      int colorIndex = 0;
      foreach( double value, pie.values ) {
        int startAngle = 360 * 16 * offset / sum;
        int span = 360 * 16 * value / sum;
        painter->setBrush( QBrush( color( colorIndex++ ) ) );
        painter->drawPie( pieRect, startAngle, span );
        offset += value;
      }
      painter->setPen( QColor( Qt::black ) );
      painter->drawText( x - painter->fontMetrics().width( pie.name ) / 2, y, pie.name );
      painter->restore();
    }
}

void MyPaintLayer::renderLegend( GeoPainter *painter, ViewportParams *viewport )
{
    painter->save();
    painter->setPen( QPen( QColor( Qt::black ) ) );
    int const width = 200;
    int const height = 120;
    int const marginBottom = 50;
    int const marginLeft = 10;
    int const marginTop = 10;
    painter->setBrush( QBrush( QColor( 192, 192, 192, 192 ) ) );
    painter->drawRect( marginLeft, viewport->height() - height - marginBottom, width, height );

    painter->translate( 2 * marginLeft, viewport->height() - height - marginBottom + marginTop + 10 );
    painter->drawText( 0, 0, "Electricity plants by country" );
    painter->translate( 0, 10 );
    renderLegendItem( painter, 0, color( 0 ), "fossil fuels" );
    painter->translate( 0, 20 );
    renderLegendItem( painter, 0, color( 1 ), "radioactive decay" );
    painter->translate( 0, 20 );
    renderLegendItem( painter, 0, color( 2 ), "renewable sources" );
    painter->translate( 0, 20 );
    renderLegendItem( painter, 0, color( 3 ), "water-driven turbines" );
    painter->restore();
}

void MyPaintLayer::renderLegendItem( GeoPainter *painter, int index, const QColor &color, const QString &text )
{
    painter->setPen( QPen( Oxygen::aluminumGray2 ) );
    painter->setBrush( QBrush( color ) );
    painter->drawRect( 0, 0, 10, 10 );
    painter->setPen( QPen( Qt::black ) );
    painter->drawText( 20, 10, text );
}

int main(int argc, char** argv)
{
    QApplication app( argc,argv );
    MarbleWidget *mapWidget = new MarbleWidget;

    MyPaintLayer layer;
    mapWidget->addLayer( &layer );

    mapWidget->setMapThemeId( "earth/plain/plain.dgml" );
    mapWidget->setProjection( Mercator );
    mapWidget->show();

    return app.exec();
}


Another possible approach would be to implement a new online service for it (see e.g. src/plugins/render/earthquake/).

Being able to provide a custom placemark render delegate would indeed be nice, but so far nobody worked on that. Maybe you can file a feature request for it?
rainbowgoblin
Registered Member
Posts
21
Karma
0
Thanks! I actually came up with a similar solution on my own, and forgot to check back in.

A feature request is a great idea, though. I'll do that.


Bookmarks



Who is online

Registered users: bancha, Bing [Bot], Evergrowing, Google [Bot], lockheed, mesutakcan, Sogou [Bot]