void WAircraftGlyph::paint(WPainter* painter) { data_type& d = *data(); painter->setBrush(WBrush(Ws::NoBrush)); m_cd.aircraftMatrix = painter->worldTransform(); m_cd.labelMatrix_1 = m_cd.aircraftMatrix.inverted(); const WMatrix& mapToView = m_cd.aircraftMatrix; painter->setWorldTransform(WMatrix()); WColor symbolColor = d.m_SymbolColor; WPointF view_aircraft_pos_f = mapToView.map(d.m_pos); static const double R = 10.0; static const double RS = 15.0; //draw a bigger circle around, when aircraft is selected double x = view_aircraft_pos_f.x(); double y = view_aircraft_pos_f.y(); if (d.m_eSymbolType == SYMBOL_COMBINED/*AIRCRAFT_NOR*/) { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } //tmp painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); painter->drawLine(WLineF(x - R, y, x + R, y)); painter->drawLine(WLineF(x, y - R, x, y + R)); //DrawAircraft(painter, view_aircraft_pos); } else if (d.m_eSymbolType == SYMBOL_PRIMARY)//一次雷达 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } painter->drawLine(WLineF(x - R, y, x + R, y)); painter->drawLine(WLineF(x, y - R, x, y + R)); } else if (d.m_eSymbolType == SYMBOL_SECONDARY)//二次雷达 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); } else if (d.m_eSymbolType == SYMBOL_PLAN)//计划航迹 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } painter->drawRect(WRectF(x - R, y - R, R * 2, R * 2)); } else if (d.m_eSymbolType == SYMBOL_COAST)//进入盲区 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } WPen pen; pen.setWidth(4); pen.setColor(WColor(255, 255, 255)); painter->setPen(pen); painter->drawLine(WWorldLineF(x - R, y, x - R / 2, y)); painter->drawLine(WWorldLineF(x + R, y, x + R / 2, y)); painter->drawLine(WWorldLineF(x, y - R, x, y - R / 2)); painter->drawLine(WWorldLineF(x, y + R, x, y + R / 2)); pen.setWidth(1); pen.setColor(symbolColor); painter->setPen(pen); } else if (d.m_eSymbolType == SYMBOL_SPI)//处于SPI告警状态 { painter->setPen(WPen(symbolColor)); if (isSelected()) { painter->drawEllipse(WRectF(x - RS, y - RS, RS * 2, RS * 2)); } painter->drawLine(WLineF(x - R, y, x + R, y)); painter->drawLine(WLineF(x, y - R, x, y + R)); WPen pen; pen.setStyle(Ws::DashLine); pen.setColor(WColor(255, 255, 255)); painter->setPen(pen); painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); pen.setStyle(Ws::SolidLine); pen.setColor(symbolColor); painter->setPen(pen); } else if (d.m_eSymbolType == SYMBOL_VEHICLE)//车辆航迹(实心三角) { painter->setPen(WPen(symbolColor)); painter->setBrush(WBrush(symbolColor, Ws::SolidPattern)); WPointF Tmppoint; std::vector<WPointF> vPoints; Tmppoint.setXY(x, y - 5); vPoints.push_back(Tmppoint); Tmppoint.setXY(x - 5, y + 5); vPoints.push_back(Tmppoint); Tmppoint.setXY(x + 5, y + 5); vPoints.push_back(Tmppoint); painter->drawPolygon(WWorldPolygonF(vPoints)); painter->setBrush(WBrush(Ws::NoBrush)); if (isSelected()) { painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); } } else if (d.m_eSymbolType == SYMBOL_ADSB) // ADSB暂定符号(参考Indra手册)实心菱形 { painter->setPen(WPen(symbolColor)); painter->setBrush(WBrush(symbolColor, Ws::SolidPattern)); WPointF Tmppoint; std::vector<WPointF> vPoints; Tmppoint.setXY(x, y - 5); vPoints.push_back(Tmppoint); Tmppoint.setXY(x - 5, y); vPoints.push_back(Tmppoint); Tmppoint.setXY(x, y + 5); vPoints.push_back(Tmppoint); Tmppoint.setXY(x + 5, y); vPoints.push_back(Tmppoint); painter->drawPolygon(WWorldPolygonF(vPoints)); painter->setBrush(WBrush(Ws::NoBrush)); if (isSelected()) { painter->drawEllipse(WRectF(x - R, y - R, R * 2, R * 2)); } } else if (d.m_eSymbolType == SYMBOL_PIC_AIRCRAFT || d.m_eSymbolType == SYMBOL_PIC_HELICOPTER) { painter->setPen(WPen(symbolColor)); painter->setBrush(WBrush(symbolColor, Ws::SolidPattern)); painter->setBrush(WBrush(Ws::NoBrush)); painter->setRenderHint(Ws::SmoothPixmapTransform); WPixmap pixmap(d.m_eSymbolType == SYMBOL_PIC_AIRCRAFT ? ":/plane.png" : ":/helicopter.png"); WPixmap newPixmap = pixmap.xrotated(-90 + d.m_nHeading, Ws::SmoothTransformation); painter->drawPixmap(view_aircraft_pos_f-WPointF(newPixmap.width()/2, newPixmap.height()/2), newPixmap); } WLineF line(WPointF(), d.m_boundingRect.center()); if (line.length() > m_sLineMaxLength) { line.setLength(m_sLineMaxLength); WPointF offPoint = line.p2() - d.m_boundingRect.center(); d.m_boundingRect.translate(offPoint); d.m_showRect.translate(offPoint); } WPointF view_label_pos_f = d.m_boundingRect.bottomLeft() + view_aircraft_pos_f;// aircraft pos + label offset pos WPointF offset_f = d.m_showRect.bottomLeft() - d.m_boundingRect.bottomLeft(); WRectF view_label_rect(WRectF(view_label_pos_f, WSizeF(d.m_boundingRect.width(), d.m_boundingRect.height()))); //标牌避让 if (m_sLabelAvoidance) { const WRectF& r = view_label_rect; Mosaic::Instance().Allocate(reinterpret_cast<int>(this), r.left(), r.bottom(), r.right(), r.top()); } // label show rect指标牌边框显示区域,标牌有时候需要显示边框,边框与内容区域可能不一致,如C显示 WRectF label_show_rect(WRectF(view_label_rect.bottomLeft(), WSizeF(d.m_showRect.width(), d.m_showRect.height()))); label_show_rect.translate(offset_f); //show history // 尾迹点访问外部数据,本应该加锁,由于外部默认分配了很大数据存在,且点数据一致增加到默认最大值 // 内部通过下标访问不存在问题 // 如外部数据容器变小,就必须得加锁保护 if (m_sShowHistoryPoint && d.m_vHistory != NULL && d.m_vHistory->size() > 1) { size_t n = d.m_vHistory->size() - 1; size_t count = (m_sHstNum < n) ? m_sHstNum : n; size_t pos = n - 1; for (size_t i = 0; i < count; ++i, --pos) { static const double R = 0.8; double dx = 0.00; double dy = 0.00; mapToView.map((*d.m_vHistory)[pos]->x(), (*d.m_vHistory)[pos]->y(), &dx, &dy); painter->drawEllipse(WRectF(dx - R, dy - R, R * 2, R * 2)); //尾迹点 } } //show preline if (m_sShowPreLine) { painter->drawLine(WLineF(view_aircraft_pos_f, mapToView.map(d.m_PRLPos))); //预计线 } if (d.m_bShowLabel) { //show linkline (内部包含了外一点与一矩形中心点连线只绘制外一点到矩形边框的算法) DrawLabelLine(painter, view_aircraft_pos_f, label_show_rect); WPainterProxy proxy(painter); painter->setRenderHint(Ws::Antialiasing, false); // 绘制矩形的时候去掉反锯齿,效果更好 painter->setRenderHint(Ws::TextAntialiasing, false); if (d.m_bShowBounding) { painter->setPen(d.m_penBounding); // 标牌边框颜色与航迹符号与文本是分开的 painter->drawRect(label_show_rect); } //show label painter->setFont(m_sLabelFont); m_cache_locker.lock(); // 对访问d.m_blocks进行加锁,网络线程在FormatLable的时候会重新组织m_blocks数据,数据需要同步操作 BOOST_FOREACH(const WBlockData& block, m_blocks) { painter->setPen(block.m_penText); WRectF r = block.m_boundingRect.translated(view_label_pos_f); painter->drawText(r, Ws::AlignCenter, block.m_text); }