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

Draw a Polygon on an Overlay

Tags: None
(comma "," separated)
mwesterfield
Registered Member
Posts
7
Karma
0

Draw a Polygon on an Overlay

Tue Jan 15, 2013 7:52 pm
Hi all,

I'm using Marble to incorporate a more sophisticated looking map into an existing piece of software. I have been using the LayerInterface class to draw markers, such as simple rectangles and circles. My class is derived from the example in the "Documentation" section of the website. The GeoPainter::drawRect() and GeoPainter::drawEllipse() overloaded functions have an instance where I can declare the center point using GeoDataCoordinates and then describe the width and height. I would like to implement this for different shaped polygons (say, for a diamond) because I haven't found any existing functions in GeoPainter for this.

Yes, I do realize there are the drawConvexPolygon() and drawPolygon() functions, but they don't have an instance for me to set it as a fixed size at a specified location on the map. If anyone knows of a way to do what I'm asking for please let me know.

Thanks,
Matt
User avatar
Earthwings
KDE Developer
Posts
172
Karma
1
OS
The simplest way is to do the GeoDataCoordinates/ScreenCoordinates transformation yourself and use GeoPainter like a plain QPainter. Similar to this example drawing a big star:
Image

Code: Select all
#include <marble/MarbleWidget.h>
#include <marble/GeoPainter.h>
#include <marble/LayerInterface.h>
#include <marble/ViewportParams.h>

#include <QtGui/QApplication>
#include <QtGui/QPolygonF>

using namespace Marble;

class MyPaintLayer : public QObject, public LayerInterface
{
public:
    // Implemented from LayerInterface
    virtual QStringList renderPosition() const;

    // Implemented from LayerInterface
    virtual bool render( GeoPainter *painter, ViewportParams *viewport,
       const QString& renderPos = "NONE", GeoSceneLayer * layer = 0 );
};

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

bool MyPaintLayer::render( GeoPainter *painter, ViewportParams *viewport,
    const QString& renderPos, GeoSceneLayer * layer )
{
    GeoDataCoordinates home(8.4, 48.0, 0.0, GeoDataCoordinates::Degree);
    QPointF center;
    if ( viewport->screenCoordinates( home, center ) ) {
      QPolygonF star;
      qreal const c = 15;
      qreal const d = 35;
      bool inner = true;
      for ( qreal i=0; i<2*M_PI; i+=M_PI/8.0, inner=!inner ) {
        qreal const f = inner ? c : d;
        star << QPointF( f * cos(i), f * sin(i) );
      }
      star.translate( center );

      painter->setRenderHint( QPainter::Antialiasing, true );
      painter->setBrush( QBrush( Qt::yellow ) );
      painter->setPen( QPen( QBrush( Qt::lightGray ), 2.0, Qt::SolidLine, Qt::RoundCap ) );
      painter->drawPolygon( star );
    }

    return true;
}

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

    // Create and register our paint layer
    MyPaintLayer* layer = new MyPaintLayer;
    mapWidget->addLayer(layer);

    // Finish widget creation.
    mapWidget->setMapThemeId("earth/bluemarble/bluemarble.dgml");
    mapWidget->show();

    return app.exec();
}
mwesterfield
Registered Member
Posts
7
Karma
0

Re: Draw a Polygon on an Overlay

Wed Jan 16, 2013 1:51 pm
Thank you so much Earthwings. I was unaware of that screenCoordinates() call. I was wondering if you could answer me this though. I'm trying to draw an open polygon, but the drawPolygon() function keeps connecting the last QPointF with the first. Here is my code:

Code: Select all
   float xCent = m_center.x();
   float yCent = m_center.y();
   float size_2 = m_targetSize / 2;
   float size_4 = m_targetSize / 4;

   QPolygonF pol;
   
   pol.append( QPointF( xCent-size_2, yCent ) );
   pol.append( QPointF( xCent-size_2, yCent-size_4 ) );
   pol.append( QPointF( xCent-size_4, yCent-size_4 ) );
   pol.append( QPointF( xCent-size_4, yCent-size_2 ) );
   pol.append( QPointF( xCent+size_4, yCent-size_2 ) );
   pol.append( QPointF( xCent+size_4, yCent-size_4 ) );
   pol.append( QPointF( xCent+size_2, yCent-size_4 ) );
   pol.append( QPointF( xCent+size_2, yCent ) );

   painter->drawPolygon( pol );


The QPointF m_center is what I fed into the screenCoordinates() call and int m_targetSize is the height and width of the marker I am trying to draw. This should be the bottom half of a "plus sign", without the line going horizontally across the center. Should I possibly simply try drawing lines instead of using a polygon, because the GeoDataLinearRing doesn't work either?
User avatar
Earthwings
KDE Developer
Posts
172
Karma
1
OS

Re: Draw a Polygon on an Overlay

Wed Jan 16, 2013 7:59 pm
QPainter has drawPolygon and drawPolyline - the latter is the one that does not connect the last point to the first. If you switch to it, you should get the behavior you're looking for.
User avatar
tackat
KDE Developer
Posts
131
Karma
0
OS

Re: Draw a Polygon on an Overlay

Fri Jan 18, 2013 11:39 am
Note that the preferred way for adding contents to the map is this approach

http://techbase.kde.org/Projects/Marble ... aPlacemark

This is much more highlevel than using GeoPainter and has lots of advantages.
mwesterfield
Registered Member
Posts
7
Karma
0

Re: Draw a Polygon on an Overlay

Fri Jan 18, 2013 2:32 pm
tackat wrote:Note that the preferred way for adding contents to the map is this approach

http://techbase.kde.org/Projects/Marble ... aPlacemark

This is much more highlevel than using GeoPainter and has lots of advantages.


Yes, I initially tried that route, but the symbols I'm trying to overlay are of specific shapes. The GeoDataPlacemark class only provides certain symbols.
User avatar
tackat
KDE Developer
Posts
131
Karma
0
OS

Re: Draw a Polygon on an Overlay

Fri Jan 18, 2013 3:08 pm
Well you can assign any icon bitmap to the placemark - if that is the issue. Just have a look at the tutorial how it's done with the "Arc of Triumph" photo. You basically create an IconStyle and adjust it to your needs.

If on the other hand you really want some crisp drawn polygons in screencoordinates then the approach Dennis showed is the right one.
mwesterfield
Registered Member
Posts
7
Karma
0

Re: Draw a Polygon on an Overlay

Fri Jan 18, 2013 3:29 pm
Right. I also need to provide the user with the availability to change the linewidth and symbol size in pixels. This seemed like the better approach for that, rather than loading different bitmaps for different symbol sizes/linewidths. Thank you though!
User avatar
tackat
KDE Developer
Posts
131
Karma
0
OS

Re: Draw a Polygon on an Overlay

Fri Jan 18, 2013 8:56 pm
Ok, just wanted to make sure you get the best possible solution :-)


Bookmarks



Who is online

Registered users: Bing [Bot], claydoh, Google [Bot], rblackwell