PDA

View Full Version : Converting coordinates system QGraphicScene to Latitude,Lognitude



db
16th May 2008, 14:04
I have been reviewing the forum posts on converting coordinate systems but I am still confused.

I am trying to convert the coordinate system of a QGraphicScene (physical) into geographic (latitude, longitude). This is so I can move my airplane object by latitude, longitude.

Currently I have code that creates the graphic item and will move it within the physical points but I’m not sure how/where to set the Window coordinates to get it to move on latitude, longitude. If you notice in my code I tried on the painter object and that didn’t work.

Can anyone help?


//-----------------------------------------------------------------------------------

class CMapView : public QGraphicsView
{
Q_OBJECT

public:
CMapView(QWidget * parent = 0);
};

CMapView::CMapView(QWidget * parent)
: QGraphicsView(parent)
{
setDragMode( ScrollHandDrag );
}


//-----------------------------------------------------------------------------------

CFlightPath : public QMainWindow
{
Q_OBJECT

public:
CFlightPath();

private slots:

protected:
void placeAircraft();

QGraphicsScene * scene;
CMapView * view;
};

CFlightPath::CFlightPath()
{
scene = new QGraphicsScene(0,0,400,400);

placeAircraft();

view = new CMapView();
view->setScene(scene);

setCentralWidget(view);

setWindowTitle("Flight Path");

mainClose = false;
}

void CFlightPath::placeAircraft()
{
CAircraft * airplane = new CAircraft();
ownship->setPos( 200, 300 );

scene->addItem( airplane );
}

//-----------------------------------------------------------------------------------

class CAircraft : public QObject, public QGraphicsItem
{
Q_OBJECT

public:
CAircraft();

QRectF boundingRect() const;
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget);

private slots:
void moveAircraft();

private:
QPainterPath shape;

QTimer * updateTimer;

float xPos, yPos, deg, prevDeg;
int count;
};


CAircraft::CAircraft()
{
double localX = -24.0;
double localY = -14.0;

QPolygonF aircraft;

aircraft << QPointF( (localX+24.0), (localY+0.0) )
<< QPointF( (localX+25.0), (localY+1.0) )
<< QPointF( (localX+26.0), (localY+2.0) )
<< QPointF( (localX+27.0), (localY+3.0) )
<< QPointF( (localX+27.0), (localY+9.0) )
<< QPointF( (localX+32.0), (localY+9.0) )
<< QPointF( (localX+32.0), (localY+8.0) )
<< QPointF( (localX+35.0), (localY+8.0) )
<< QPointF( (localX+35.0), (localY+9.0) )
<< QPointF( (localX+38.0), (localY+9.0) )
<< QPointF( (localX+38.0), (localY+8.0) )
<< QPointF( (localX+41.0), (localY+8.0) )
<< QPointF( (localX+41.0), (localY+9.0) )
<< QPointF( (localX+47.0), (localY+9.0) )
<< QPointF( (localX+48.0), (localY+10.0) )
<< QPointF( (localX+47.0), (localY+11.0) )
<< QPointF( (localX+36.0), (localY+13.0) )
<< QPointF( (localX+27.0), (localY+16.0) )
<< QPointF( (localX+26.0), (localY+31.0) )
<< QPointF( (localX+30.0), (localY+31.0) )
<< QPointF( (localX+31.0), (localY+32.0) )
<< QPointF( (localX+25.0), (localY+34.0) )
<< QPointF( (localX+23.0), (localY+34.0) )
<< QPointF( (localX+17.0), (localY+32.0) )
<< QPointF( (localX+18.0), (localY+31.0) )
<< QPointF( (localX+22.0), (localY+31.0) )
<< QPointF( (localX+21.0), (localY+16.0) )
<< QPointF( (localX+12.0), (localY+13.0) )
<< QPointF( (localX+1.0), (localY+11.0) )
<< QPointF( (localX+0.0), (localY+10.0) )
<< QPointF( (localX+1.0), (localY+9.0) )
<< QPointF( (localX+7.0), (localY+9.0) )
<< QPointF( (localX+7.0), (localY+8.0) )
<< QPointF( (localX+10.0), (localY+8.0) )
<< QPointF( (localX+10.0), (localY+9.0) )
<< QPointF( (localX+13.0), (localY+9.0) )
<< QPointF( (localX+13.0), (localY+8.0) )
<< QPointF( (localX+16.0), (localY+8.0) )
<< QPointF( (localX+16.0), (localY+9.0) )
<< QPointF( (localX+21.0), (localY+9.0) )
<< QPointF( (localX+21.0), (localY+3.0) )
<< QPointF( (localX+22.0), (localY+2.0) )
<< QPointF( (localX+23.0), (localY+1.0) );

shape.addPolygon( aircraft );

setFlag(ItemIgnoresTransformations, true);

updateTimer = new QTimer();
updateTimer->setInterval( 50 );
connect( updateTimer, SIGNAL(timeout()), this, SLOT(moveAircraft()));
updateTimer->start();

xPos = 200.0;
yPos = 300.0;
deg = 270.0;
prevDeg = 0.0;
count = 0;
};

QRectF CAircraft::boundingRect() const
{
return QRectF(-24,-14,48,34);
}

void CAircraft::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * /*widget*/)
{
painter->setWindow(-100,-100, 200, 200);

painter->fillPath( shape, Qt::darkGray );
}

void CAircraft::moveAircraft()
{
float x, y;

if ( count < 50 )
xPos -= 1.0;
else if (count < 100 )
yPos += 1.0;
else if (count < 150 )
xPos += 1.0;
else if (count < 200 )
yPos -= 1.0;
else if (count < 250 )
{
yPos += 1.0;
xPos -= 1.0;
}
else if (count < 300 )
{
yPos -= 1.0;
xPos += 1.0;
}

count++;

x = xPos;
y = yPos;

setPos(x, y);
}

wysota
16th May 2008, 16:55
Why not simply make the scene extend from (-180,-90) to (180,90)? Or (-180*60,-90*60) to (180*60,90*60) to include minutes.

db
16th May 2008, 19:56
But will then that make the actuall widget 180 by 360 pixels? Or if I size the widget to be say 400 by 600 will the proposed scene coordinates be used on top of them?

wysota
16th May 2008, 20:36
But will then that make the actuall widget 180 by 360 pixels?
No. The view size is independent of the scene size.


Or if I size the widget to be say 400 by 600 will the proposed scene coordinates be used on top of them?

Consider scene coordinates as world coordinates and widget's coordinates as view (physical) coordinates. So if you have a scene that is 400 units wide shown in a widget that is 200 pixels wide, each two units of the scene will correspond to 1 pixel of the widget (unless you apply some scaling, of course).

db
4th June 2008, 18:41
Sorry got busy on another item... thanks fpr the response.... so back to this one.

What I think understand is that I make the scene mapping 90,-180,180,360 but after I create the view I set its size to 400,400 (or some size).

Then when is set the position for a graphics item added to the scene I use the actual lat and lon values (not pixels).

If this is true when I select a point with the mouse will the x,y be pixels or lat/lon?

wysota
4th June 2008, 20:29
Everything will be calculated in scene coordinates, so lat/long.

db
4th June 2008, 21:22
Thanks... let me continue with this new thought... may have to provide you some more code

db
7th June 2008, 21:48
I tried you suggestion and it doesn’t seem to work. I must be missing something in the discussion. I have included my code for the project. Can you help? I attached a zip file.

Should be able to build it and run (windows). Puts up a map gui and a flight plan gui. Either select a predefined set of points or enter your own., the click on “flying”. The version as is works the way I would expect it to work but it is using pixel per degree conversions instead of scene coordinates. If you change the PIXELFACTOR to 0 then the code will attempt to do the conversion in latitude,longitude.

Under lat, lon approach I want the reseet the scene parameters with each new set of waypoints and all processing to be based on the lat, lon boundaries.

Problems I am having are:

1) It won’t reestablish the scene boundaries every time a new set of waypoints is supplied. (works in the pixel conversion approach).

2) It won’t o zoom in on the scene with things staying center oriented; everything moves up and out of view, no longer accessable.

3) Would like the scene mouse double click to return the mouse position in the scene lat, lon.

4) Would like the scroll drag to work. When I do the mouse double click the scene drag stops working.

5) Finally when I do this version under Linux, when you zoom in white lines begin to appear. As the object moves across the screen white spacing is left behind. Like some background isn’t updating

Thanks for help

twells5
3rd June 2016, 13:54
Hi All,

Sorry to revive an old thread but I am trying to do the same thing and am a little confused... If I set up my scene as suggested by Master Wysota (90, -180, 180, 360) so I get a conversion to lat/lon coords, but I only want to view
a very small area, for example a 250nm radius around a given lat/lon point, how do I then have the view "zoom in" to display only that area and maintain the lat/lon coord conversion for that area? I am trying to make a radar/sonar type of
display using lat/lon points...

Thank you in advance,
tim

ChrisW67
3rd June 2016, 21:33
Calculate the rectangle containing your radar circle (world coordinates), about 6 degrees wide/high, and call QGraphicsView::fitInView()
Alternatively, you can call QGraphicsView::centerOn() with the centre point of your radar and then scale to suit.

twells5
9th June 2016, 17:02
Hi Chris,

Thank you for your reply. I will try your suggetion...

tim