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

[MAPAPI] Получение данных о проекции растра

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: Пред. 1 2 3 След.
RSS
[MAPAPI] Получение данных о проекции растра, [MAPAPI] Получение данных о проекции растра
 
Здравствуйте.

Так как всё таки добиться того чтобы в файле Rsw появились данные о системе координат ?

Функция picexLoadRasterToRswUn не заполняет в заголовке Rsw данные о системе координат (несмотря на их наличие в файле привязке Tab).
При этом вручную внести эти данные в Rsw файл я не могу, так как функция picexLoadRasterToRswUn создаёт файл в формате 1.04, который закрыт, я нашёл только описание формата версии 2.00 и 2.01

Функции picexLoadBmpToRstAndCompress и picexLoadBmpToRstAndCompressUn создают растры из Bmp, но так как информации о системах координат в Bmp нет (а лежащие рядом Tab игнорируются), то и в rsw файлах нет данных о системе координат. Функция mapSetRstProjectionDataPro не отрабатывает на этих растрах - я не знаю как правильно вызывать эту функцию, ведь она принимает первым параметром HMAP. Мои попытки не увенчались успехом.


Пока мне удалось получить привязанный rsw только из Tiff + Tab файлов (picexLoadRasterToRswUn), остальные пары (BMP/Jpeg/PNG + Tab) не привязались (то есть в паспорте нет данных о СК).
 
Да, импорт через эту функцию не прочитал TAB и не привязывает поэтому. Поправим. А Tiff привязался, потому что он GeoTIFF :)
 
Спасибо, будем ждать следующую версию.

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

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

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

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

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


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

 
Функции из семейства RswProjectionReforming* изменяют проекцию растра и преобразуют его содержимое к необходимой проекции. Но они не могут преобразовать его, если проекции у исходного растра нет. Нельзя преобразовать из ничего в WGS-84, например.

Чтобы задать начальную проекцию растру, необходимо его открыть и вызвать mapSetRstProjectionData, mapSetRstEllipsoidParam, mapSetRstDatumParam, указав соответствующие данные. Получить их Вы можете при помощи функций работы с СК или заполнить самостоятельно, если Вы понимаете что и как заполнять.
Не вижу проблемы с использованием HMAP - в своей функции открываете, назначаете и закрываете растр.

Функции RswProjectionReforming и RswProjectionReformingUn устарели, потому что в них только MAPREGISTER передается.
Чтение TAB-файла будет исправлено в следующей версии.
 
Цитата
Не вижу проблемы с использованием HMAP - в своей функции открываете, назначаете и закрываете растр.
Разобрался. Так работает:
Код
    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);
Я раньше вторым параметром отдавал 0, надо было 1, несмотря на то что сам растр открыт как главная карта.
Info, datum и ellipsoid я взял из Tab файла:


Код
    long rc = picexCheckMapInfoProjectionEx(COORDSYS_MAPINFO,
                                                      buf, 512, info,
                                                      &ellipsoid,
                                                      &datum,
                                                      &epsg,
                                                      &retCode);
 
Я вроде наконец-то понял всю суть импорта картинок с файлами привязок, поправьте меня если я не прав. А то мне больше спрашивать не у кого.

На входе  - изображение (любое для файлов привязки TAB, так как они поддерживаются в mappicex.h; и BMP для всех других файлов привязки - для упрощения, так как других простых функций кроме picexLoadBmpToRstAndCompress (без HMAP) я не нашёл/не осилил как пользоваться).
и файл привязки. Сложные форматы с данными о привязке внутри (GeoTIFF - это то что я знаю, PNG + GDAL - это я в комментариях в mappicex.h подсмотрел, с gdal не работал вообще не разбираюсь) не рассматриваем.
На выходе хотим привязанный файл rsw, с данными о проекции, который потом можно добавить на векторную карту.
Если файл привязки TAB - скармливаем его picexLoadRasterToRswUn и идём дальше по своим делам.
Если файл привязки не TAB (и изображения BMP, в BMP в случае чего и сконвертировать можно):
  1. парсим файл сами, получаем информацию о СК
  2. Если СК - плоские прямоугольные (проекция, Гаусса-Крюгера, например), то есть данные о точках в метрах в какой-то  проекции, то  пункт 3, иначе пункт 6
  3. Забираем координаты в метрах углов изображения. Если изображение без поворота (в примере для Гаусса-Крюгера у двух нижних точек X (широта, вертикальная ось в проекции) одинаков ) то пункт 4, иначе (растр с поворотом) пункт 5
  4. Так как изображение без поворота, и в плоских прямоугольных координатах, то можно просто положить его в rsw, а затем установить данные о проекции. Вычисляем координаты юго-западного угла в метрах, вычисляем meterInPixelX(в гауссе крюгере это высота пикселя в метрах, то есть просто делим разность северозападного угла и юго-западного угла по широте (X) в метрах на высоту изображения), вычисляем meterInPixelY(в гауссе крюгере это ширина пикселя в метрах, разница по долготе в метрах делится на ширину изображения) и вызывается picexLoadBmpToRstAndCompress, после чего надо установить данные о СК - проекции в rsw, вызвав mapSetRstProjectionDataPro с правильно заполненными MAPREGISTEREX, DATUM и ELLIPSOIDPARAM.
  5. Выходной растр будет с поворотом, а исходное изображение прямоугольное. Вычислим координаты юго-западного угла изображения в метрах, и загрузим изображение в rsw с помощью picexLoadBmpToRstAndCompress, отдав в качестве meterInPixelX и meterInPixelY единицу (1.0). Выставляем параметры СК в rsw с помощью mapSetRstProjectionDataPro. Теперь у нас есть растр, у которого юго-западный угол правильный, а три других неправильные, но мы знаем их координаты. В гауссе крюгере, к примеру, координатами левого верхнего угла изображения будут координаты северозападного угла rsw. Так как мы задали размер пикселя метр на метр, то можем вычислить координаты северзападного угла просто прибавив по широте высоту изображения, а северо восточного - прибавив по широте высоту изображения, а по долготе ширину изображения. Используя функцию AttachRswWithScalingAndRotationEx мы можем повернуть растр. В качестве двух исходных точек нужно отдать текущие координаты двух углов rsw (например, юго-западного и северовосточного), а в качестве двух желаемых точек нужно подставить координаты в метрах соответствующих углов изображения (левого нижнего правого верхнего в этом примере) из файла привязки. После этого ещё нужно рамку выставить, по которой будет отображаться растр, но я пока не умею это делать не добавляя rsw в район работ, так как для установки рамки требуется HOBJ, который не создать без векторной карты. Можно попробовать вручную заполнить соответствующую секцию в rsw файле, но в спецификации RSW 2.0 не описан формат хранения координат метрики замкнутого объекта, вероятно там массив DOUBLEPOINT, я не проверял. Без рамки у вас будет rsw в виде серого прямоугольника, в который вписан повернутый растр. Возможно рамка выставляется функцией AttachRswWithScalingAndRotationEx, я ещё не пробовал.
  6. Нужно сконвертировать СК из геодезической в какую-то проекцию, и работать в ней. Для примера - в проекцию Гаусса Крюгера на СК-42. После получения координат точек привязки в плоской проекции идём в пункт 3.
 
Из того, что знаю я: алгоритм верный. Есть небольшое уточнение: некоторые файлы привязок указывают не координаты угла растра, а в центр углового пикселя растра. Тут надо каждый формат изучать отдельно. А по поводу пункта 6 я не уверен, возможно используется сразу та СК, в которой надо получить растр без преобразований.
 
Цитата
Есть небольшое уточнение: некоторые файлы привязок указывают не координаты угла растра, а в центр углового пикселя растра.
Спасибо =)

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

А в rsw можно записать данные в геодезической ск (широта/долгота в градусах)?
Я изучал спецификацию rsw 2.0, и судя по заголовкам в файле rsw и приложению 1 спецификации (ссылка), описывающему способ доступа к элементу по координатам в метрах - там всегда должна быть проекция - плоские прямоугольные координаты в метрах.

Я только поэтому сделал пункт 6.
 
gisdesigner 12.5.0 (ГИС Конструктор для QtDesigner)


Продолжу тему с привязкой растра, но уже без файлов привязок.

То есть на входе - изображение, и оператор, который может отметить на изображении точки и сказать какие у этих точек координаты.

1)
Подход в целом такой же как и в случае с файлами привязки, но мне интересно для каких целей используется параметр HMAP в функциях для привязки растрова из mappicex.h:
Скрытый текст

Ну то есть что будет, если я сделаю растр из изображения с помощью функции picexLoadRasterToRswUn, потом открою его и выставлю параметры проекции, датум и эллипсоид (как СК-42, к примеру),
закрою, потом открою векторную карту в системе координат уже другой (например, UTM на WGS84), и попытаюсь привязать растр с помощью функции привязки (любой), отдав первым параметром векторную карту, а в каждой паре точек в качестве фактической точки буду отдавать координаты с растра (в СК-42), а в качестве теоретической (желаемой) точки буду отдавать точку с векторной карты (в UTM).



Это так работает?
Данные о проекции и системе координат из HMAP (открытой векторной карты) используются для того, чтобы обработать желаемые координаты точки?
И тогда есть возможность исходные координаты задавать в системе растра, а желаемые в системе открытой векторной карты?


2)
А ещё, я не очень понял чем отличаются друг от друга функции трансформации растров по рамке и МНК.
Какие-то из этих функции работают дольше но точнее?
Или разница только в параметрах обработки рамки?

Пометки "нелинейное трансформирование | расчёт коэффициентов по МНК | вообще никакой пометки" сбивают с толку.

Что правильнее/корректнее использовать?
 
Цитата
мне интересно для каких целей используется параметр HMAP в функциях для привязки растрова из mappicex.h:
hmap  -  дескриптор карты, к которой добавлен растр
Если в функциях привязки растра параметр hmap задать равным 0, то растр будет открыт в отдельном документе:
Код
 if (hMap == 0)
    {
     hMap = mapOpenDataUn(rswName);
     flagCreate = 1;
    }

Цитата
Ну то есть что будет, если я сделаю растр из изображения с помощью функции picexLoadRasterToRswUn, потом открою его и выставлю параметры проекции, датум и эллипсоид (как СК-42, к примеру),
закрою, потом открою векторную карту в системе координат уже другой (например, UTM на WGS84), и попытаюсь привязать растр с помощью функции привязки (любой), отдав первым параметром векторную карту, а в каждой паре точек в качестве фактической точки буду отдавать координаты с растра (в СК-42), а в качестве теоретической (желаемой) точки буду отдавать точку с векторной карты (в UTM).
Предлагаю простой и надежный алгоритм привязки растра:
1. Импортируем растр без привязки.
2. Добавляем созданный растр в документ карты.
3. Привязываем растр по точкам с карты.
4. Устанавливаем проекцию и СК карты в растр.

После этого растр можно добавлять в любой документ с отличными параметрами проекции и СК.
При добавлении в документ с отличными параметрами проекции и СК такой растр будет трансформироваться налету.
Цитата
И тогда есть возможность исходные координаты задавать в системе растра, а желаемые в системе открытой векторной карты?
Исходные и желаемые координаты д.б. в системе координат документа HMAP.
Цитата
А ещё, я не очень понял чем отличаются друг от друга функции трансформации растров по рамке и МНК.
Какие-то из этих функции работают дольше но точнее?
Или разница только в параметрах обработки рамки?

В функциях RswTransformingBySquareMethod, RswTransformingBySquareMethodUn применяется метод наименьших квадратов.
Алгоритм метода наименьших квадратов: http://gis-lab.info/qa/polynom.html

В функциях RswTransformingByBorderMethod, RswTransformingByBorderMethodUn применяется механизм нелинейного трансформирования.
Используются функции (mapCreateNonlineTransform), объявленные в файле MATHAPI.H:

Код
// Создание класса нелинейного трансформирования координат
// count     - количество точек для расчета параметров трансформирования
//   В зависимости от типа трансформирования:
//   NT_LINEARSHEET, NT_NONLINEARSHEET - минимальное количество точек = 3
//   NT_POLYNOM                        - минимальное количество точек = количеству коэффициентов
//   NT_POLYNOMRANK2                   - минимальное количество точек = 6
//   NT_POLYNOMRANK3                   - минимальное количество точек = 10
//   NT_POLYNOMRANK4                   - минимальное количество точек = 15
//   NT_POLYNOMRANK5                   - минимальное количество точек = 21
// pointsin  - координаты точек в исходной системе координат
// pointsout - координаты точек в выходной системе координат
// interestframe - область интереса, т.е. прямоугольник, ограничивающий область
//   применения функции mapNonlineTransformIn2Out.
//   Если = 0, то экстраполяция искажений вне области расположения опорных точек
//   не выполняется, в этом случае virtualpointcount должно быть равно 0
// virtualpointcount - количество виртуальных точек, добавляемых по границе
//   области интереса. Минимальное количество = 4. Если interestframe = 0, то
//   virtualpointcount должно быть равно 0.
// transftype - тип нелинейного трансформирования см. NONLINEARTRANSFTYPE
// Возвращает идентификатор класса нелинейного трансформирования координат
// Для каждого полученного и больше не используемого идентификатора
// необходим вызов функции mapFreeNonlineTransform()
// При ошибке возвращает ноль

  HNONLINETRANSF HNonLineTransf = (*lpfn_mapCreateNonlineTransform)(count, fact, teor,
                                                        0, //DFRAME *interestframe
                                                        0, //long int virtualpointcount
                                                        NT_POLYNOM4 //NONLINEARTRANSFTYPE transftype
                                                        );

Класс нелинейного трансформирования координат реализован по труду Hiroshi Akima: A method of bivariate interpolation and smooth surface fitting for values given at irregularly distributed points (Hiroshi Akima)

Цитата
Что правильнее/корректнее использовать?
Рекомендации по выбору типа трансформирования:
http://help.gisserver.ru/ru/rswtrans/index.html

Страницы: Пред. 1 2 3 След.
Читают тему (гостей: 1)



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

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