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

Владимир Егоров (Все сообщения пользователя)

Поиск  Пользователи  Правила  Войти
Форум » Пользователи » Владимир Егоров
Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 21 След.
mapPaintToXImage слишком медленно работает при крупных масштабах
 
У Вас изображение 4600 на 3070. У Вас экран такой большой ?

Пардон, перечитал пост. 15 секунд на один вызов и правда долго. Пробовали делить исходно изображение на несколько часте (на 4, к примеру) ? Мы так ускоряли отрисовку при изменении масштаба, то что в окне видно делили на две одинаковые части и рендерили в первую очередь, а то что за окном делили на 4 части и рендерили во вторую очередь (пользователь просто не может делать scroll/zoom пока вся отрисовка не закончится, но результат первой очереди видел сразу, чтоб поотзывчивей выглядело).
Изменено: Владимир Егоров - 30.01.2019 19:00:37
mapSetScreenImageSize, корректное использование
 
У нас вот такие настройки экрана при инициализации:

[CODE]void SetupScreenSettings(){
   QSize screenSizePix = QGuiApplication::primaryScreen()->geometry().size();
   long scWidth = static_cast<long>(screenSizePix.width());
   long scHeight =static_cast<long>(screenSizePix.height());
   panorama::mapSetScreenImageSize(scWidth, scHeight);
   QString env = QProcessEnvironment::systemEnvironment().value(envScreenWidthInMM, "");
   bool ok = false;
   if (env.isEmpty()){
       return;
   }
   double scWidthMM = static_cast<double>(env.toInt(&ok));
   if (!ok || (env.toInt() == 0)){
       return;
   }
   env = QProcessEnvironment::systemEnvironment().value(envScreenHeightInMM, "");
   ok = false;
   if (env.isEmpty()){
       return;
   }
   double scHeightMM = static_cast<double>(env.toInt(&ok));
   if (!ok || (env.toInt() == 0)){
       return;
   }
   double scHorPrecision = static_cast<double>(scWidth * 1000) / (scWidthMM);
   double scVerPrecision = static_cast<double>(scHeight * 1000) / (scHeightMM);
   panorama::mapSetScreenPrecisionEx(scHorPrecision, scVerPrecision);
}
[/CODE]
[RSCAPI] mapGetRscSegment всегда возвращает ноль, mapGetRscSegment всегда возвращает ноль
 
Лучше б комментарии поправили =(
Преобразования пространственных прямоугольных координат, WGS84->ПЗ90.11, коэффициенты преобразования прямоугольных координат.
 
[QUOTE]B: 59° 59' 59.925906000''; //(расчёты через MAPAPI)
B: 60° 0' 0.000412000'';      //(рукописная реализация)[/QUOTE]
Вот же =)
EPSG, конвертация в СК42 из WGS84
 
Здравствуйте.

Разбираемся с проекцией UTM на WGS84.
В примере EPSGConverts нашли ошибку.

[CODE]const long int base_epsg_utm_wgs84 = 32600;

int convertByEPSG( double B, double L, long epsg )
{
 HANDLE userSystemHandle = mapCreateUserSystemParametersByEpsg( epsg );
 if ( userSystemHandle == 0 )
 {
   printf( "Невозможно создать пользовательскую систему координат с кодом EPSG = %d\n",
           static_cast<int>(epsg) );
   return 0;
 }

 mapGeoWGS84ToUserGeo( userSystemHandle, &B, &L );

 printf( "Выполнен пересчет в СК с кодом EPSG = %d  : ",
         static_cast<int>(epsg) );
 printDegree( B, L );
 printRadian( B, L );

 if ( mapGetUserSystemType(userSystemHandle) == 1 )
 {
   mapUserGeoToUserPlane( userSystemHandle, &B, &L );
   printf( "Выполнен пересчет в прямоугольные координаты : " );
   printMeters( B, L );
 }
 else
 {
   printf( "Выбранная система координат не поддерживает пересчет в метры на плоскости. EPSG = %d\n",
           static_cast<int>(epsg) );
 }

 mapDeleteUserSystemParameters( userSystemHandle );
 return 1;
}

int convertToUTMWGS84( double B, double L )
{
 long zoneNumber = mapGetZoneByMeridian( L );
 long epsg = base_epsg_utm_wgs84 + zoneNumber;
 return convertByEPSG( B, L, epsg );
}

int main()
{
   mapMessageEnable(1);
   gis::coord::GisCoord::init();
   double B = gis::coord::common::degree2radian(-27.37400);
   double L = gis::coord::common::degree2radian(133.67001);
   convertToUTMWGS84(B, L);
   long zone = 53;
   HANDLE utmOnWGS84 = mapCreateUserSystemParametersByEpsg(base_epsg_utm_wgs84 + zone);
   if (utmOnWGS84 == 0){
       qDebug() << "unable to create user system parameters by epsg" << base_epsg_utm_wgs84 + zone;
   }
   long rc = mapGeoWGS84ToUserPlane(utmOnWGS84,&B, &L);
   if (rc != 0){
       std::printf("Bx: %.9lf Ly: %.9lf",B<0?B+10000000:B,L);
   }else{
       qDebug() << "unable to convert geo WGS84 to plane utm";
   }
   mapDeleteUserSystemParameters(utmOnWGS84);
   return 0;
}  
[/CODE]

Вывод:

[CODE]Выполнен пересчет в СК с кодом EPSG = 32623 : B = -27°-22'-26,40000" , L = +133°40'12,03600"
B = -0,477766429 , L = 2,332981786
Выполнен пересчет в прямоугольные координаты : X = -150565104,187907010 , Y = 36875373,199651480
Bx: 6971437,752046177 Ly: 368477,270090956
[/CODE]
[URL=https://drive.google.com/open?id=1XTu0Y7MVJ88seZWQhzWxnuRj1lQW73Ic]Online-конвертор[/URL]

1) mapGetZoneByMeridian возвращает зону проекции Гаусса-Крюгера по долготе системы СК-42. Для UTM зоны считаются по другому.
2) Оси X и Y в UTM направлены по другому (в отличии от Гаусса-Крюгера) - X вправо (долгота), Y - вверх (широта)
3) Функции, переводящие в UserPlane для проекции Гаусса-Крюгера на эллипсоиде Красовского (базовый EPSG код 28400) автоматически добавляют к долготе смещение, для проекции UTM на wgs84 (базовый код 32600) такого не происходит (там по широте для южного полушария надо добавлять 10 000 000 (10 миллионов метров) , по долготе смешение добавляется всегда - 500000 - такое же как в Гауссе-Крюгере). Ну то есть по долготе смещение прибавляется, по широте - нет

То есть, чтобы правильно получить проекцию UTM на WGS84 надо:
[LIST=1]
[*] сначала перевести исходные координаты в геодезические WGS84
[*]вычислить по долготе WGS84 зону UTM (вручную, mapGetZoneByMeridian для этих целей не подходит)
[*]Создать пользовательскую систему координат по EPSG коду 32600 + номер зоны
[*]Вызвать [B]mapGetWGS84ToUserPlane[/B]
[*]Результат (X,Y) обменять местами, так как оси в UTM направлены по другому.
[*]Если Y (широта) меньше 0 - прибать к Y 10 000 000
[/LIST]
P.S. Хотя на самом деле всё это не важно, потому-что пример EPSGConverts был предоставлен только для ознакомления с функциями по работе с координатами, со своей задачей он справился. А перевод в UTM на WGS84 может кому-нибудь пригодится. версия gisdesigner - 12.3.1
Изменено: Владимир Егоров - 25.12.2018 14:12:06
[MAPAPI] Получение данных о проекции растра, [MAPAPI] Получение данных о проекции растра
 
[QUOTE]Есть небольшое уточнение: некоторые файлы привязок указывают не координаты угла растра, а в центр углового пикселя растра.[/QUOTE]
Спасибо =)

[QUOTE]А по поводу пункта 6 я не уверен, возможно используется сразу та СК, в которой надо получить растр без преобразований.[/QUOTE]

А в rsw можно записать данные в геодезической ск (широта/долгота в градусах)?
Я изучал спецификацию rsw 2.0, и судя по заголовкам в файле rsw и приложению 1 спецификации ([URL=http://gistoolkit.ru/download/doc/sxf4mtwrsw.pdf]ссылка[/URL]), описывающему способ доступа к элементу по координатам в метрах - там всегда должна быть проекция - плоские прямоугольные координаты в метрах.

Я только поэтому сделал пункт 6.
[MAPAPI] Получение данных о проекции растра, [MAPAPI] Получение данных о проекции растра
 
Я вроде наконец-то понял всю суть импорта картинок с файлами привязок, поправьте меня если я не прав. А то мне больше спрашивать не у кого.

На входе  - изображение (любое для файлов привязки TAB, так как они поддерживаются в [B]mappicex.h; [/B]и BMP для всех других файлов привязки - для упрощения, так как других простых функций кроме [B]picexLoadBmpToRstAndCompress[/B] (без HMAP) я не нашёл/не осилил как пользоваться).
и файл привязки. Сложные форматы с данными о привязке внутри (GeoTIFF - это то что я знаю, PNG + GDAL - это я в комментариях в mappicex.h подсмотрел, с gdal не работал вообще не разбираюсь) не рассматриваем.
На выходе хотим привязанный файл rsw, с данными о проекции, который потом можно добавить на векторную карту.
Если файл привязки TAB - скармливаем его [B]picexLoadRasterToRswUn [/B]и идём дальше по своим делам.
Если файл привязки не TAB (и изображения BMP, в BMP в случае чего и сконвертировать можно):
[LIST=1]
[*]парсим файл сами, получаем информацию о СК
[*]Если СК - плоские прямоугольные (проекция, Гаусса-Крюгера, например), то есть данные о точках в метрах в какой-то проекции, то пункт 3, иначе пункт 6
[*]Забираем координаты в метрах углов изображения. Если изображение без поворота (в примере для Гаусса-Крюгера у двух нижних точек X (широта, вертикальная ось в проекции) одинаков ) то пункт 4, иначе (растр с поворотом) пункт 5
[*]Так как изображение без поворота, и в плоских прямоугольных координатах, то можно просто положить его в rsw, а затем установить данные о проекции. Вычисляем координаты юго-западного угла в метрах, вычисляем meterInPixelX(в гауссе крюгере это высота пикселя в метрах, то есть просто делим разность северозападного угла и юго-западного угла по широте (X) в метрах на высоту изображения), вычисляем meterInPixelY(в гауссе крюгере это ширина пикселя в метрах, разница по долготе в метрах делится на ширину изображения) и вызывается [B]picexLoadBmpToRstAndCompress[/B], после чего надо установить данные о СК - проекции в rsw, вызвав [B]mapSetRstProjectionDataPro[/B] с правильно заполненными MAPREGISTEREX, DATUM и ELLIPSOIDPARAM.
[*]Выходной растр будет с поворотом, а исходное изображение прямоугольное. Вычислим координаты юго-западного угла изображения в метрах, и загрузим изображение в rsw с помощью [B]picexLoadBmpToRstAndCompress[/B], отдав в качестве meterInPixelX и meterInPixelY единицу (1.0). Выставляем параметры СК в rsw с помощью [B]mapSetRstProjectionDataPro. [/B]Теперь у нас есть растр, у которого юго-западный угол правильный, а три других неправильные, но мы знаем их координаты. В гауссе крюгере, к примеру, координатами левого верхнего угла изображения будут координаты северозападного угла rsw. Так как мы задали размер пикселя метр на метр, то можем вычислить координаты северзападного угла просто прибавив по широте высоту изображения, а северо восточного - прибавив по широте высоту изображения, а по долготе ширину изображения. Используя функцию [B]AttachRswWithScalingAndRotationEx[/B] мы можем повернуть растр. В качестве двух исходных точек нужно отдать текущие координаты двух углов rsw (например, юго-западного и северовосточного), а в качестве двух желаемых точек нужно подставить координаты в метрах соответствующих углов изображения (левого нижнего правого верхнего в этом примере) из файла привязки. После этого ещё нужно рамку выставить, по которой будет отображаться растр, но я пока не умею это делать не добавляя rsw в район работ, так как для установки рамки требуется HOBJ, который не создать без векторной карты. Можно попробовать вручную заполнить соответствующую секцию в rsw файле, но в спецификации RSW 2.0 не описан формат хранения координат метрики замкнутого объекта, вероятно там массив DOUBLEPOINT, я не проверял. Без рамки у вас будет rsw в виде серого прямоугольника, в который вписан повернутый растр. Возможно рамка выставляется функцией AttachRswWithScalingAndRotationEx, я ещё не пробовал.
[*]Нужно сконвертировать СК из геодезической в какую-то проекцию, и работать в ней. Для примера - в проекцию Гаусса Крюгера на СК-42. После получения координат точек привязки в плоской проекции идём в пункт 3.
[/LIST]
[MAPAPI] Получение данных о проекции растра, [MAPAPI] Получение данных о проекции растра
 
[QUOTE]Не вижу проблемы с использованием HMAP - в своей функции открываете, назначаете и закрываете растр.[/QUOTE]
Разобрался. Так работает:
[CODE] rc = picexLoadBmpToRstAndCompress(onMsg, SRC_PATH_DEF, dstPathKoi8r.constData(), &meterInX, &meterInY, &location, 0);
   HMAP rst = mapOpenData(dstPathKoi8r.constData());
   rc = mapSetRstProjectionDataPro(rst, 1, info, &datum, &ellipsoid,0, nullptr);
[/CODE]Я раньше вторым параметром отдавал 0, надо было 1, несмотря на то что сам растр открыт как главная карта.
Info, datum и ellipsoid я взял из Tab файла:


[CODE] long rc = picexCheckMapInfoProjectionEx(COORDSYS_MAPINFO,
                                                     buf, 512, info,
                                                     &ellipsoid,
                                                     &datum,
                                                     &epsg,
                                                     &retCode);
[/CODE]
Библиотеки для разработки прикладных задач к ГИС Оператор 11
 
[URL=https://drive.google.com/open?id=1mk0LgaBwTlXsrMHIFOG8uwlN4dnuF_Ow]Картинка[/URL]
[MAPAPI] Получение данных о проекции растра, [MAPAPI] Получение данных о проекции растра
 
Спасибо, будем ждать следующую версию.

У меня были подозрения про GeoTIFF, но проверять уже не стал.

Функция чтения файла TAB тоже не работает, а парсинг строки из TAB файла с описанием СК работает.

Но самое главное - [B]mapSetRstProjectionDataPro [/B], мне надо научиться ей пользоваться или похожей функцией, которая не использует HMAP а работает по имени файла rsw (наподобие [B]RswProjectionReformingPro[/B]). Это нужно чтобы привязывать растры по файлу привязку не TAB а MAP или DAT (Ozi Explorer и SASPlanet), наши клиенты в основном этими файлами привязки пользуются, и если в прошлых версиях нашего софта мы игнорировали заголовки Rsw, то теперь они нам очень нужны корректные. Насколько я понял эти функции то ли не умеют конкретную версию Rsw обработать (1.0 или 2.0), то ли не умеют выставить СК когда rsw не привязан (ну то есть MAPREGISTEREX/DATUM/ELLIPSOIDPARAM пустые)

А ещё, вспомнил тут.

В библиотеке libqdmappicex.so нет двух функций - RswProjectionReforming и RswProjectionReformingUn. Если они устарели то их наверное надо убрать из mappicex.h


[CODE]vegorov@vegorov-amd64:/usr/lib/gisdesigner$ nm -D libqdmappicex.so | grep RswProjectionReforming
0000000000096a0f T RswProjectionReformingEvent
0000000000096f54 T RswProjectionReformingEx
0000000000096f23 T RswProjectionReformingExUn
0000000000096ef0 T RswProjectionReformingPro

[/CODE]
Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 21 След.



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

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