На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

Скорость отрисовки надписей

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: 1
RSS
Скорость отрисовки надписей, Скорость TurnRasterString
 
Добрый день.
Столкнулись с проблемой медленной отрисовки подписей на карте. На экране порядка 15 подписей, примерно по 10 знаков каждая.
Отключение слоя с надписями приводит к существенному росту скорости отрисовки.
Подписи отображаются без поворота (стоят галочки "Горизонтально"), с контурами, шрифт не курсив.
Размер шрифта = 2.0 (выставление размера 1.0 приводит к незначительному ускорению, похоже, просто за счет уменьшения площади надписей).

Профилировщик Google Performance Tools показывает, что более 80% времени уходит на выполнение функции TurnRasterString ГИС-Ядра:


Подскажите, как можно увеличить скорость отрисовки надписей?
Можно ли это сделать путем настройки карты или классификатора (например, за счет параметров шрифта)?

Версия ГИС-ядра 11.10.3 для Astra Linux.
Пробовали в нашем ПО выводить те же надписи поверх карты средствами библиотеки Pango: рендеринг надписей с помощью Pango не приводит к просадке скорости, т.е. железо позволяет быстро отрисовывать надписи.
Однако ПО поставлено  заказчику, поэтому хотелось бы решить вопрос именно модификацией карты.
Заранее спасибо за помощь!
 
Вы можете сами рисовать текст.
Код
void DrawText(DRAWFUNCPARM& dfp, const WCHAR *text,                                   // 11/07/16
              float height, int italic, int weight, int wide, const char *fontName)
{
  QString textString = QString::fromUtf16( text );

  // 12/11/14 Савелов
  QPainter   painter;

  QImage image( dfp.Begin, dfp.Width, dfp.Height, QImage::Format_RGB32 );
  //- Восстановил // 04/10/16 BEGIN -----------------------------------
  //- чтобы работало выделение подписей -------------------------------
  QWidget *DrawWidget = (QWidget*)(dfp.hWidget);
  if(DrawWidget)
  {
    if (DrawWidget->paintingActive()) return;
    painter.begin(DrawWidget);
  }
  else
  {
    if (dfp.Begin == 0) return;
    painter.begin(&image);
  }
  //- Восстановил // 04/10/16 END -----------------------------------

  painter.setRenderHint(QPainter::Antialiasing, false);

  if ( weight < 401 )
    weight = QFont::Light;
  else  if ( weight < 501 )
    weight = QFont::Normal;
  else  if ( weight < 701 )
    weight = QFont::DemiBold;
  else
    weight = QFont::Bold;

  QFont font( fontName, static_cast<int>(height), weight, italic );
  font.setPixelSize(static_cast<int>(height));    // Заново установить размер, т.к. выше он задан в поинтах

  if ( wide == UNIW_NARROW )
    font.setStretch(static_cast<int>(100.0 / 1.2));
  else if ( wide == UNIW_WIDE )
    font.setStretch(static_cast<int>(100.0 * 1.2));

#if QT_VERSION > 0x040800
  // Для RedHat отключим сглаживания шрифта, т.к. у Painter уже есть сглаживание        // 21/03/16 Letov V.I.
  // выставив PreferNoHinting
  // Для Астры необходимо PreferFullHinting
  //  font.setStyleStrategy( QFont::PreferFullHinting );
  font.setHintingPreference( QFont::PreferNoHinting );
#endif

  painter.setFont( font );

  // 24/11/14 Савелов
  painter.translate( dfp.Dx + dfp.DrawPointX * 1. ,
                     dfp.Dy + dfp.DrawPointY * 1. );
  painter.rotate( dfp.Angle * 180.0 / 3.14 );

  // 11/11/14 Савелов: блок отображения тени и контура
  //------------------------------------------------------
  if ( dfp.MarkColor != -1 )
  {
    QPen pen2( QColor( dfp.MarkColor ), dfp.MarkThick*2.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
    painter.setPen( pen2 );

    if ( dfp.MarkType == 0 )
    {
      // Тень
      painter.drawText( dfp.MarkThick * 2, dfp.MarkThick * 2, textString );   // 21/03/16 Letov V.I.
    }
    else
    {
      // Контур
      QPainterPath path;
      path.addText( 0, 0, font, textString );     // 21/03/16 Letov V.I.
      painter.drawPath( path );
    }
    painter.end();
    return;
  }
  //------------------------------------------------------
  // 11/11/14 Савелов: блок отображения текста
  if ( dfp.Color != -1 )
  {
    // 11/11/14 Савелов: сформировать цвет
    QColor qColor( dfp.Color );
    qColor.setAlpha( GetAlpha( dfp.Alpha ) );
    QPen  pen( qColor );

    painter.setPen( pen );
    painter.drawText( 0, 0, textString );            // 21/03/16 Letov V.I.
  }

  painter.end();
}

//регистрация коллбэка для отрисовки текста
mapDrawText(DrawText);





enum VTYPE               // ТИП ОТОБРАЖЕНИЯ КАРТЫ
{
   // ЭКРАННЫЙ ВЫВОД
   VT_SCREEN          = 1, // ЭКРАННЫЙ (ЧЕРЕЗ DIB)
   VT_SCREENCONTOUR   = 2, // ЭКРАННЫЙ КОНТУРНЫЙ

   // ПРИНТЕРНЫЙ ВЕКТОРНЫЙ ВЫВОД
   VT_PRINT           = 3, // ПРИНТЕРНЫЙ ВЕКТОРНЫЙ (ЧЕРЕЗ WIN API)
   VT_PRINTGLASS      = 4, // ПРИНТЕРНЫЙ БЕЗ ЗАЛИВКИ ПОЛИГОНОВ
   VT_PRINTCONTOUR    = 5, // ПРИНТЕРНЫЙ КОНТУРНЫЙ, БЕЗ УСЛОВНЫХ ЗНАКОВ

   // ПРИНТЕРНЫЙ РАСТРИЗОВАННЫЙ ВЫВОД
   VT_PRINTRST        = 6, // ПРИНТЕРНЫЙ РАСТРИЗОВАННЫЙ (ЧЕРЕЗ WIN API)
   VT_PRINTGLASSRST   = 7, // ПРИНТЕРНЫЙ БЕЗ ЗАЛИВКИ ПОЛИГОНОВ
   VT_PRINTCONTOURRST = 8, // ПРИНТЕРНЫЙ КОНТУРНЫЙ, БЕЗ УСЛОВНЫХ ЗНАКОВ

   // ПРИНТЕРНЫЙ РАСТРИЗОВАННЫЙ (СПЕЦИАЛЬНЫЙ) ВЫВОД       
   VT_PRINTRSTSQUARE  = 9, // ПРИНТЕРНЫЙ (ЗАЛИВКИ ПЛОЩАДНЫХ, ПОДПИСИ С ФОНОМ,
                           //             РАСТРЫ, МАТРИЦЫ)
   VT_PRINTRSTLINE    =10, // ПРИНТЕРНЫЙ (ЛИНИИ, ТОЧЕЧНЫЕ, ВЕКТОРНЫЕ,
                           //             ПОДПИСИ С ФОНОМ, ПОЛЬЗОВАТЕЛЬСКИЕ)
   VT_PRINTRSTTEXT    =11, // ПРИНТЕРНЫЙ (ПОДПИСИ, ШАБЛОНЫ)

   // ПРИНТЕРНЫЙ ВЕКТОРНЫЙ (СПЕЦИАЛЬНЫЙ) ВЫВОД. ИСПОЛЬЗУЕТСЯ ДЛЯ ЭКСПОРТА
   // ГРАФИКИ (POSTSCRIPT, WMF, EMF)                    
   VT_PRINTEX         =15, // ПРИНТЕРНЫЙ ВЕКТОРНЫЙ (ЧЕРЕЗ WIN API)
};

//после открытия карты, второй параметр я не помню какой нужно выставить чтобы всю отрисовку себе забрать, можно поиграться с этим
mapSetViewType(m_map, VT_PRINTRST)  

Это один из вариантов который нам предлагали. Только там ещё кучу других callback-ов надо зарегистрировать. Ну и отрисовку вы полностью себе получается заберёте.
 
Цитата
Владимир Егоров написал:
Вы можете сами рисовать текст.
Код
...
Это один из вариантов который нам предлагали. Только там ещё кучу других callback-ов надо зарегистрировать. Ну и отрисовку вы полностью себе получается заберёте.
Спасибо, интересно!
Возможно придется в будущем воспользоваться этим решением.

Но пока, повторюсь, в первую очередь интересно можно ли что-то сделать средствами карты/классификатора. Разработчики функции TurnRasterString я, надеюсь, подскажут, какой текст (шрифт/размер/etc) она сможет быстрее отрисовать.
Изменено: Sergio Garcia - 11.04.2018 11:40:24
 
Цитата
Sergio Garcia написал:
Подписи отображаются без поворота (стоят галочки "Горизонтально"), с контурами, шрифт не курсив.
Методом научного тыка подхода выяснили, что как раз контуры дают сильную просадку производительности. Без них скорость вменяемая.
Изменено: Sergio Garcia - 17.04.2018 10:37:09
 
Мы делали замеры кстати, на наших arm, правда они уже неактуальны, нам потом релизные библиотеки прислали, они пошустрее, но соотношения сохраняются.
График:
Справа от имени слоя количество объектов в этом слое (на всей карте).
Изменено: Владимир Егоров - 17.04.2018 11:14:21
 
Цитата
Sergio Garcia написал:
Добрый день.
Столкнулись с проблемой медленной отрисовки подписей на карте. На экране порядка 15 подписей, примерно по 10 знаков каждая.
Подскажите, как можно увеличить скорость отрисовки надписей?
Можно ли это сделать путем настройки карты или классификатора (например, за счет параметров шрифта)?
TurnRasterString - это внутренняя реализация шрифта типа Arial. Он один.
Если вывод экранный (VT_SCREEN), то работает эта ветка.
Для принтерного вывода (VT_PRINT и т.д.) вывод шрифтов идет через вызов функций Qt, которые могут быть оптимизированы за счет графических драйверов.
Текст функции для вывод через Qt приведен выше.
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2024

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности