LINUX.ORG.RU

Реализация ГИС.

 , ,


0

2

Возможно ли с помощью QGraphicsView реализовать класс, действующий подобно главному окну 2gis, яндекс.карт и google maps?
Есть движок, который по сырым данным строит картинку (в памяти,rgb32). При использовании QGraphicsView возникла проблема скорости прорисовки при прокрутке и приближении/отдалении при хардкорном подходе удаления всех items сцены и создание и добавление новой.
Возможно ли избавиться от тормозов при использовании qgraphicsview, или нужно копать в сторону opengl или других классов?

★★★★

при хардкорном подходе удаления всех items сцены и создание и добавление новой.

нахрена? почему просто не менять тайлы на существующих (видимых) итемах?

Stil ★★★★★
()
Ответ на: комментарий от Unnamed_Hero

Ммм, ты о чём? Я гисами раньше не интересовался вроде как. Но спасибо, посмотрю.

aptyp ★★★★
() автор топика
Ответ на: комментарий от Unnamed_Hero

то растр. Когда начинался какой-нибудь вектор - даже явовские gvsig и udig его отрисовывали не в пример быстрее. Просто тупое изменение масштаба было страшным - без шуток, иногда покурить успевал.

ЗЫ «какой-нибудь» - это не один трек с навигатора или подобное. Конкретно я с графами дорог имелся и с вектором из OSM.

arkhnchul ★★
()
Последнее исправление: arkhnchul (всего исправлений: 1)

При использовании QGraphicsView возникла проблема скорости прорисовки при прокрутке и приближении/отдалении при хардкорном подходе удаления всех items сцены и создание и добавление новой.

В Qt есть стандартный пример «40000 микросхем». Он векторный, можно зумить как угодно и ничего не тормозит.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Немного не то, тут один и тотже рисунок, не меняющийся. Я же при скроллинге заново перерисовываю картинку, причём в сторонней dllке. Судя по всему, надо будет использовать тайлы, генерировать только 9 самых близких, ненужные со временем удалять.

aptyp ★★★★
() автор топика
Ответ на: комментарий от aptyp

тут один и тотже рисунок, не меняющийся

Во первых, все чипы в демке индивидуальны: у каждого есть свои координаты, которые можно независимо от остальных менять, и свой цвет (при полном уменьшении масштаба чипы складываются в картинку). А во-вторых, в вашей реализации тайлы всё время меняются?

Может стоит попробовать такой вариант: определить свой класс тайла — наследник QGraphicsItem, разместить эти тайлы по сцене в нужных координатах. Когда тайл попадёт в область видимости в QGraphicsView (Qt строит BSP-дерево, поэтому данная операция производится очень эффективно) будет автоматически вызван метод paint, в котором можно запросить внешнюю dll-ку (и да, на винфак же) для получения конкретного участка карты. Можно оптимизировать связь с внешней библиотекой, реализовав кэш.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Какой винфак, Qt же) Спасибо за советы.
А как в таком случае выгрузка уже неотображаемых тайлов производится?

aptyp ★★★★
() автор топика
Последнее исправление: aptyp (всего исправлений: 1)
Ответ на: комментарий от aptyp

Происходит примерно так: на сцену добавляем множество объектов QGraphicsItem. Каждый из них знает свои размеры и положение в «мире». Когда такой объект появляется в видимой области, вызывается его метод paint, в котором тайл может рисовать себя. Например, он может загрузить картинку из файла в QImage, а затем отрисовать. При выходе из метода QImage удаляется (со стека) и чистит за собой память. Таким образом, в памяти остаются только объекты тайлов с координатами и BSP-дерево.

Если же узким местом становится загрузка картинок, то, как я уже говорил, можно организовать кэш, в котором хранится некоторое количество картинок.

Я экспериментировал с картой 400*400 (это 80000 объектов). Основное время занимает построение BSP, и то я тупо добавлял объекты по очереди, хотя эффективнее было бы сделать объекты-кластеры, например 10*10 тайлов. Тогда, вероятно, дерево строилось бы быстрее.

static_lab ★★★★★
()
Ответ на: комментарий от aptyp

Разница вроде есть: там, насколько я понял, картинка подгружается в память при первом использовании и уже не удаляется, пока не будет удалён объект тайла.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Вроде бы нет

 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                   QWidget *widget){
            if(NULL == item){
                // load item:
                QImage a(...);
                item = new QGraphicsPixmapItem(... );
            }
            item->paint(painter, option, widget);
        }

Таким образом разве картинка не исчёзнет?

aptyp ★★★★
() автор топика
Ответ на: комментарий от aptyp

При создании QGraphicsPixmapItem в него скопируются пиксели. Поэтому даже когда удалится QImage a, копия битмапа в памяти останется.

Я делал так:

class MapItem : public QGraphicsItem { ... };


QRectF MapItem::boundingRect() const
{
    return QRectF(0.0, 0.0, 256.0, 256.0); // возвращаем ограничивающий прямоугольник
}

void MapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    QImage image(...); // грузим картинку, память освободится автоматически

    // Другой вариант - поручать загрузку и контроль памяти кэшу:
    // QImage& image = imageCache->image( ... );

    painter->drawImage(0, 0, image); // рисуем
}
static_lab ★★★★★
()
Ответ на: комментарий от aptyp

угу, это из-за btrees. у меня та же проблема из-за CAD-подобной репозиционирующейся привязки в сцене, если много статичных итемов (>30k), тормозит.

Obey-Kun ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.