Карта отсортирована, по запросу могу выложить куда-нибудь.
Вызов mapPaintToXImage занимает ~15 секунд (для тестирования скорости работы она запускается в цикле с одними и теми же параметрами), вызов mapSetFrameTree только замедляет первый вызов mapPaintToXImage (вместо 15 секунд - 40 секунд), но никак не ускоряет последующие вызовы.
CPU ~4.2Ghz, DDR4 3GHz, файлы карты находятся на tmpfs, то есть в оперативной памяти.
perf показывает что 75% процентов времени тратиться в SQUAREVISUAL::SquareVisual(unsigned int), а если точнее:
Можно ли как-то ускорить "рендеринг" карты, а то время работы >5 секунд, это слишком много?
Код используемый для тестирования скорости работы:
Код
#include <QApplication>
#include <QElapsedTimer>
#include <QImage>
#include <cassert>
#include <cmath>
#include <cstdint>
#include <mapapi.h>
#include <qdmcmp.h>
using Pixel = uint32_t;
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QDMapView forProtection;
mapMessageEnable(1);
// mapSetFrameTree(1);
mapSetMaxScreenImageSize(5000, 4000);
mapSetScreenSizePro(std::sqrt(std::pow(527., 2) + std::pow(296., 2)));
mapSetScreenPrecisionEx(3840 / 527. * 1000., 2160. / 296. * 1000.);
qInfo("map access version %lX", GetMapAccessVersion());
long errcode = 0;
HMAP hmap = mapOpenAnyData(QString::fromUtf8(argv[1]).utf16(), GENERIC_READ,
&errcode);
assert(hmap != 0);
long int img_center_x = 0, img_center_y = 0;
mapSetViewScale(hmap, &img_center_x, &img_center_y, 25000);
QImage img(QSize(4608, 3072), QImage::Format_RGB32);
double x = (55. + 44. / 60.) / 180. * 3.14;
double y = (37. + 38. / 60.) / 180. * 3.14;
double h = 0;
mapGeoWGS84ToGeo3D(hmap, &x, &y, &h);
mapGeoToPlane(hmap, &x, &y);
mapPlaneToPicture(hmap, &x, &y);
int left = static_cast<int>(std::round(x));
int top = static_cast<int>(std::round(y));
XIMAGEDESC image_desc{reinterpret_cast<char *>(img.bits()),
img.width(),
img.height(),
sizeof(Pixel) * 8,
sizeof(Pixel),
img.width() * sizeof(Pixel)};
RECT all_rect{left, top, left + img.width(), top + img.height()};
QElapsedTimer timer;
timer.start();
auto ret = mapPaintToXImage(hmap, &image_desc, 0, 0, &all_rect);
assert(ret != 0);
qInfo("mapPaintToXImage takes %lld ms", timer.elapsed());
for (size_t i = 0; i < 5; ++i) {
timer.restart();
mapPaintToXImage(hmap, &image_desc, 0, 0, &all_rect);
qInfo("rerun of mapPaintToXImage takes %lld ms", timer.elapsed());
}
bool save_res = img.save("/tmp/res.png");
assert(save_res);
}
У Вас изображение 4600 на 3070. У Вас экран такой большой ?
Пардон, перечитал пост. 15 секунд на один вызов и правда долго. Пробовали делить исходно изображение на несколько часте (на 4, к примеру) ? Мы так ускоряли отрисовку при изменении масштаба, то что в окне видно делили на две одинаковые части и рендерили в первую очередь, а то что за окном делили на 4 части и рендерили во вторую очередь (пользователь просто не может делать scroll/zoom пока вся отрисовка не закончится, но результат первой очереди видел сразу, чтоб поотзывчивей выглядело).
Владимир Егоров написал: У Вас изображение 4600 на 3700. У Вас экран такой большой ? 15/5 = 3 секунды, для такой огромной картинки - приемлемый результат, кстати. Мы на своих устройствах рендеринг такого изображения ждали бы секунд 10-30 наверное.
Экран `3840x2160`, взято с небольшим запасом, чтобы позволить пользователю чуть-чуть двигать картинку.
4к монитор получается, понятно. Вроде была возможность в нескольких потоках отрисовку делать, но я не пользовался. Там другие функции применяются - mapCreatePaintControl, mapPaintByFrameToXImagePro, может поможет.
Да, я понял, экран 3840x2160, изображение у `mapPaintToXImage` запрашивается больше, чтобы закэшировать результат и позволить пользователю "скролить" карту без обращений к mapPaintToXImage на каждый сдвиг карты на несколько десятков пикселей.
Евгений Душистов написал: Да, я понял, экран 3840x2160, изображение у `mapPaintToXImage` запрашивается больше,чтобы закэшировать и резельтат и позволить пользователю "скролить" карту без обращенийк mapPaintToXImage на каждый сдвиг карты на несколько десятков пикселей.
Мы так же делаем, только у нас разрешение раза в 4 меньше =). И мы делаем изображение в два раза больше чем ViewPort, пока пользователь таскает изображение просто ViewPort перемещаем в пределах всего изображения, а когда отпускает мышку (отрывает палец от дисплея) "шифтим/сдвигаем" изображение и запускаем дорендеривание двух оставшихся кусков.
А мне кажется, что быстро) Ничего что на карте больше миллиона объектов?) Такую карту можно на гис веб сервис положить, сгенерировать картинки по ней и открывать по WMTS\WMS.
Немного поэкспериментировал с картой МО указанной в теме.
При помощи Панорама Мини сконвертировал ее в sitx. Преобразовалась как-то странно местами. Некоторые знаки в классификаторе не нашлись похоже. Открыл sitx, посмотрел как рисуется. Скорость нормальная вполне: 2300х1280 у меня рисуется за 290мс.
Немного поэкспериментировал с картой МО указанной в теме.
Скорость нормальная вполне: 2300х1280 у меня рисуется за 290мс.
Во-первых их нужно объеденить в одну .map (МО и Москву), не пробовал раздельно, во-вторых масштаб и область важны. В других масштабах у меня тоже за ~0.3 секунды все обсчитывается.