From 375ecfb3695548ea471a3ef8159db3177baab3c4 Mon Sep 17 00:00:00 2001 From: Laura Sebesta Date: Sat, 18 Aug 2012 09:23:09 +0200 Subject: [PATCH] Streamlined paint function. --- .../opmapcontrol/src/mapwidget/uavitem.cpp | 177 ++++++++++-------- .../libs/opmapcontrol/src/mapwidget/uavitem.h | 8 + 2 files changed, 107 insertions(+), 78 deletions(-) diff --git a/ground/openpilotgcs/src/libs/opmapcontrol/src/mapwidget/uavitem.cpp b/ground/openpilotgcs/src/libs/opmapcontrol/src/mapwidget/uavitem.cpp index 3c0c13037..ac100e25d 100644 --- a/ground/openpilotgcs/src/libs/opmapcontrol/src/mapwidget/uavitem.cpp +++ b/ground/openpilotgcs/src/libs/opmapcontrol/src/mapwidget/uavitem.cpp @@ -50,6 +50,8 @@ namespace mapcontrol mapfollowtype=UAVMapFollowType::None; trailtype=UAVTrailType::ByDistance; timer.start(); + + generateArrowhead(); } UAVItem::~UAVItem() { @@ -64,7 +66,7 @@ namespace mapcontrol //Draw plane painter->drawPixmap(-pic.width()/2,-pic.height()/2,pic); - //Return if context menu switch for UAV info is off + //Return if UAV Info context menu is turned off if(!showUAVInfo){ showJustChanged=false; return; @@ -75,46 +77,19 @@ namespace mapcontrol //Turn on anti-aliasing so the fonts don't look terrible painter->setRenderHint(QPainter::Antialiasing, true); - qreal arrowSize = 10; - //Set pen attributes QColor myColor(Qt::red); myPen.setWidth(3); myPen.setColor(myColor); painter->setPen(myPen); - - //Create line from (0,0), to (1,1). Later, we'll scale and rotate it - QLineF line(0,0,1.0,1.0); - - //Set the starting point to (0,0) - line.setP1(QPointF(0,0)); - - //Set angle and length - line.setLength(60.0); - line.setAngle(90.0); - - //Form arrowhead - double angle = ::acos(line.dx() / line.length()); - if (line.dy() <= 0) - angle = (M_PI * 2) - angle; - - QPointF arrowP1 = line.pointAt(1) + QPointF(sin(angle + M_PI / 3) * arrowSize, - cos(angle + M_PI / 3) * arrowSize); - QPointF arrowP2 = line.pointAt(1) + QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize, - cos(angle + M_PI - M_PI / 3) * arrowSize); - - //Generate arrowhead - arrowHead.clear(); - arrowHead << line.pointAt(1) << arrowP1 << arrowP2; painter->drawPolygon(arrowHead); painter->setPen(myPen); - painter->drawLine(line); + painter->drawLine(arrowShaft); //*********** Create trend arc double radius; double spanAngle = yawRate_dps * 5; //Forecast 5 seconds into the future - //Find the scale factor between meters and pixels double pixels2meters = map->Projection()->GetGroundResolution(map->ZoomTotal(),coord.Lat()); float meters2pixels=1.0 / pixels2meters; @@ -164,56 +139,66 @@ namespace mapcontrol //***** Text info overlay. The font is a "glow" font, so that it's easier to use on the map + if (refreshPaint_flag==true){ + + //Define font + QFont borderfont( "Arial", 14, QFont::Normal, false ); + + //Top left corner of text + int textAnchorX = 20; + int textAnchorY = 20; + + //Create text lines + QString uavoInfoStrLine1, uavoInfoStrLine2; + QString uavoInfoStrLine3, uavoInfoStrLine4; + QString uavoInfoStrLine5; + + //For whatever reason, Qt does not let QPainterPath have text wrapping. So each line of + //text has to be added to a different line. + uavoInfoStrLine1.append(QString("CAS: %1 kph").arg(CAS_mps)); + uavoInfoStrLine2.append(QString("Groundspeed: %1 kph").arg(groundspeed_kph, 0, 'f',1)); + uavoInfoStrLine3.append(QString("Lat-Lon: %1, %2").arg(coord.Lat(), 0, 'f',7).arg(coord.Lng(), 0, 'f',7)); + uavoInfoStrLine4.append(QString("North-East: %1 m, %2 m").arg(NED[0], 0, 'f',1).arg(NED[1], 0, 'f',1)); + uavoInfoStrLine5.append(QString("Altitude: %1 m").arg(-NED[2], 0, 'f',1)); + + //Add the uavo info text to the path + //NOTE: We must use QPainterPath for the outlined text font. QPaint does not support this. + path = QPainterPath(); + + path.addText(textAnchorX, textAnchorY+16*0, borderfont, uavoInfoStrLine1); + path.addText(textAnchorX, textAnchorY+16*1, borderfont, uavoInfoStrLine2); + path.addText(textAnchorX, textAnchorY+16*2, borderfont, uavoInfoStrLine3); + path.addText(textAnchorX, textAnchorY+16*3, borderfont, uavoInfoStrLine4); + path.addText(textAnchorX, textAnchorY+16*4, borderfont, uavoInfoStrLine5); + + //Add text for time rings. + if(groundspeed_mps > 0){ + //Always add the left side... + path.addText(-(groundspeed_mps_filt*ringTime*1*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime,0,'f',0)); + path.addText(-(groundspeed_mps_filt*ringTime*2*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime*2,0,'f',0)); + path.addText(-(groundspeed_mps_filt*ringTime*4*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime*4,0,'f',0)); + //... and add the right side, only if it doesn't interfere with the uav info text + if(groundspeed_mps_filt*ringTime*4*meters2pixels > 200){ + if(groundspeed_mps_filt*ringTime*2*meters2pixels > 200){ + if(groundspeed_mps_filt*ringTime*1*meters2pixels > 200){ + path.addText(groundspeed_mps_filt*ringTime*1*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime,0,'f',0)); + } + path.addText(groundspeed_mps_filt*ringTime*2*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime*2,0,'f',0)); + } + path.addText(groundspeed_mps_filt*ringTime*4*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime*4,0,'f',0)); + } + } + + //Last thing to do: set bound rectangle as function of largest object + boundingRectSize=groundspeed_mps_filt*ringTime*4*meters2pixels+20; //Largest object is currently the biggest ring + a little bit of margin for the text + + refreshPaint_flag=false; + } + //Rotate the text back to vertical qreal rot=this->rotation(); painter->rotate(-1*rot); - //Define font - QFont borderfont( "Arial", 14, QFont::Normal, false ); - - //Top left corner of text - int textAnchorX = 20; - int textAnchorY = 20; - - //Create text lines - QString uavoInfoStrLine1, uavoInfoStrLine2; - QString uavoInfoStrLine3, uavoInfoStrLine4; - QString uavoInfoStrLine5; - - //For whatever reason, Qt does not let QPainterPath have text wrapping. So each line of - //text has to be added to a different line. - uavoInfoStrLine1.append(QString("CAS: %1 kph").arg(CAS_mps)); - uavoInfoStrLine2.append(QString("Groundspeed: %1 kph").arg(groundspeed_kph, 0, 'f',1)); - uavoInfoStrLine3.append(QString("Lat-Lon: %1, %2").arg(coord.Lat(), 0, 'f',7).arg(coord.Lng(), 0, 'f',7)); - uavoInfoStrLine4.append(QString("North-East: %1 m, %2 m").arg(NED[0], 0, 'f',1).arg(NED[1], 0, 'f',1)); - uavoInfoStrLine5.append(QString("Altitude: %1 m").arg(-NED[2], 0, 'f',1)); - - //Add the uavo info text to the path - //NOTE: We must use QPainterPath for the outlined text font. QPaint does not support this. - QPainterPath path; - path.addText(textAnchorX, textAnchorY+16*0, borderfont, uavoInfoStrLine1); - path.addText(textAnchorX, textAnchorY+16*1, borderfont, uavoInfoStrLine2); - path.addText(textAnchorX, textAnchorY+16*2, borderfont, uavoInfoStrLine3); - path.addText(textAnchorX, textAnchorY+16*3, borderfont, uavoInfoStrLine4); - path.addText(textAnchorX, textAnchorY+16*4, borderfont, uavoInfoStrLine5); - - //Add text for time rings. - if(groundspeed_mps > 0){ - //Always add the left side... - path.addText(-(groundspeed_mps_filt*ringTime*1*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime,0,'f',0)); - path.addText(-(groundspeed_mps_filt*ringTime*2*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime*2,0,'f',0)); - path.addText(-(groundspeed_mps_filt*ringTime*4*meters2pixels+10), 0, borderfont, QString("%1 s").arg(ringTime*4,0,'f',0)); - //... and add the right side, only if it doesn't interfere with the uav info text - if(groundspeed_mps_filt*ringTime*4*meters2pixels > 200){ - if(groundspeed_mps_filt*ringTime*2*meters2pixels > 200){ - if(groundspeed_mps_filt*ringTime*1*meters2pixels > 200){ - path.addText(groundspeed_mps_filt*ringTime*1*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime,0,'f',0)); - } - path.addText(groundspeed_mps_filt*ringTime*2*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime*2,0,'f',0)); - } - path.addText(groundspeed_mps_filt*ringTime*4*meters2pixels-8, 0, borderfont, QString("%1 s").arg(ringTime*4,0,'f',0)); - } - } //Now draw the text. First pass is the outline... myPen.setWidth(4); @@ -229,9 +214,6 @@ namespace mapcontrol painter->setPen(myPen); painter->drawPath(path); - - //Last thing to do: set bound rectangle as function of largest object - boundingRectSize=groundspeed_mps_filt*ringTime*4*meters2pixels+20; //Largest object is currently the biggest ring + a little bit of margin for the text } QRectF UAVItem::boundingRect()const @@ -254,6 +236,8 @@ namespace mapcontrol this->NED[0] = NED[0]; this->NED[1] = NED[1]; this->NED[2] = NED[2]; + + refreshPaint_flag=true; } void UAVItem::SetYawRate(double yawRate_dps){ @@ -266,10 +250,13 @@ namespace mapcontrol this->yawRate_dps=5e-1; } + refreshPaint_flag=true; } void UAVItem::SetCAS(double CAS_mps){ this->CAS_mps=CAS_mps; + + refreshPaint_flag=true; } void UAVItem::SetGroundspeed(double vNED[3], int m_maxUpdateRate_ms){ @@ -371,6 +358,8 @@ namespace mapcontrol } } + + refreshPaint_flag=true; } /** @@ -387,6 +376,8 @@ namespace mapcontrol if (this->rotation() != value) this->setRotation(value); } + + refreshPaint_flag=true; } @@ -413,7 +404,9 @@ namespace mapcontrol ww->setLine(map->FromLatLngToLocal(ww->coord1).X(),map->FromLatLngToLocal(ww->coord1).Y(),map->FromLatLngToLocal(ww->coord2).X(),map->FromLatLngToLocal(ww->coord2).Y()); } + refreshPaint_flag=true; } + void UAVItem::SetTrailType(const UAVTrailType::Types &value) { trailtype=value; @@ -455,4 +448,32 @@ namespace mapcontrol update(); } + void UAVItem::generateArrowhead(){ + qreal arrowSize = 10; + + //Create line from (0,0), to (1,1). Later, we'll scale and rotate it + arrowShaft=QLineF(0,0,1.0,1.0); + + //Set the starting point to (0,0) + arrowShaft.setP1(QPointF(0,0)); + + //Set angle and length + arrowShaft.setLength(60.0); + arrowShaft.setAngle(90.0); + + //Form arrowhead + double angle = ::acos(arrowShaft.dx() / arrowShaft.length()); + if (arrowShaft.dy() <= 0) + angle = (M_PI * 2) - angle; + + QPointF arrowP1 = arrowShaft.pointAt(1) + QPointF(sin(angle + M_PI / 3) * arrowSize, + cos(angle + M_PI / 3) * arrowSize); + QPointF arrowP2 = arrowShaft.pointAt(1) + QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize, + cos(angle + M_PI - M_PI / 3) * arrowSize); + + //Assemble arrowhead + arrowHead.clear(); + arrowHead << arrowShaft.pointAt(1) << arrowP1 << arrowP2; + + } } diff --git a/ground/openpilotgcs/src/libs/opmapcontrol/src/mapwidget/uavitem.h b/ground/openpilotgcs/src/libs/opmapcontrol/src/mapwidget/uavitem.h index 263a99930..eb7303015 100644 --- a/ground/openpilotgcs/src/libs/opmapcontrol/src/mapwidget/uavitem.h +++ b/ground/openpilotgcs/src/libs/opmapcontrol/src/mapwidget/uavitem.h @@ -221,8 +221,11 @@ namespace mapcontrol void SetShowUAVInfo(bool const& value); private: + void generateArrowhead(); + MapGraphicItem* map; QPolygonF arrowHead; + QLineF arrowShaft; int altitude; UAVMapFollowType::Types mapfollowtype; UAVTrailType::Types trailtype; @@ -252,6 +255,11 @@ namespace mapcontrol float boundingRectSize; bool showJustChanged; + bool refreshPaint_flag; + + QPainterPath path; + + public slots: signals: