У меня лицензионная версия ГИС Конструктора для Qt Designer x64 версия, GetMapAccessVersion выдает 0x133ED5B.
При запуске программы, код которой приведен ниже, с вот этой картой osm-map-union Первый вызов `mapPaintToXImage` отрабатывает за 108 секунд, и сама программа при этом потребляет 6.8 ГБ резидентой памяти (RES), сама карта на диске занимат 7.4 ГБ.
Карта отсортирована, mapGetSiteInfoEx в DeviceCapability возвращает -1. Исходя из документации
Код
// Запретить/Разрешить построение дерева объектов для отображения всех карт // 26/02/18
// Построение дерева замедляет (от долей секунды до нескольких секунд) открытие
// неотсортированных карт с большим числом объектов (от нескольких сот тысяч и более),
// но ускоряет (в 1,5 - 3 раза) отображение больших карт в крупных масштабах
// (отбор объектов для фрагмента)
// Дерево объектов обычно применяется для серверных приложений или индикаторов,
// длительно работающих с постоянным набором карт и интенсивным отображением
// flag - признак применения дерева объектов (если не ноль)
// Возвращает ранее установленное значение
_MAPIMP long int _MAPAPI mapSetFrameTree(long int flag);
`mapPaintToXImage` не должен замедляться, да и с памятью непонятно, это утечки памяти при построении r-tree или при использовании `mapSetFrameTree` нужно памяти столько же, сколько сама карта занимает на диске?
Код
#include <cassert>
#include <cmath>
#include <cstdint>
#include <QApplication>
#include <QElapsedTimer>
#include <QImage>
#include <QScreen>
#include <QtDebug>
#include <mapapi.h>
#include <qdmcmp.h>
using Pixel = uint32_t;
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QDMapView forProtection;
auto screen = app.primaryScreen();
const int max_width = 5000;
const int max_height = 4000;
const int pic_width = 3840;
const int pic_height = 2160;
mapMessageEnable(1);
mapSetFrameTree(1);
mapSetMaxScreenImageSize(max_width, max_height);
const auto width_mm = static_cast<qreal>(screen->size().width()) /
screen->physicalDotsPerInchX() * 25.4;
const auto height_mm = static_cast<qreal>(screen->size().height()) /
screen->physicalDotsPerInchY() * 25.4;
mapSetScreenSizePro(std::hypot(width_mm, height_mm));
mapSetScreenPrecisionEx(screen->physicalDotsPerInchX() / 25.4 * 1000.,
screen->physicalDotsPerInchY() / 25.4 * 1000.);
qInfo("map access version %lX", GetMapAccessVersion());
long errcode = 0;
HMAP hmap = mapOpenAnyData(QString::fromUtf8(argv[1]).utf16(), GENERIC_READ,
&errcode);
assert(hmap != 0);
assert(mapIsGeoSupported(hmap) != 0);
long int img_center_x = 0, img_center_y = 0;
mapSetViewScale(hmap, &img_center_x, &img_center_y, 25000 /*200000*/);
QImage img(QSize(pic_width, pic_height), 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());
bool save_res = img.save("/tmp/res.png");
assert(save_res);
return app.exec();
}
Добрый день. Скорость первого построения зависит от объема открытых данных. Все последующие будут быстрее. Для деревьев необходимо размещение всех векторных данных в памяти. Если вы пытаетесь отрисовать всю карту, то ускорений, как и замедлений не будет (за исключением первого раза).
Владимир Железняков написал: Добрый день. Скорость первого построения зависит от объема открытых данных. Все последующие будут быстрее. Для деревьев необходимо размещение всех векторных данных в памяти. Если вы пытаетесь отрисовать всю карту, то ускорений, как и замедлений не будет (за исключением первого раза).
А нельзя как-то сохранить это "дерево" в файл для всей карты, а потом сделать mmap этого файла в память? 6.8 ГБ ОЗУ свободных на машине, на которой я планирую запускать программу у меня нет, а вот в ПЗУ это влезет и оно достаточно быстрое (SSD).