И ещё, судя по описанию, docHandle больше похоже на ui->MapView1 (QWidget???), чем на HMAP. [CODE]#ifdef WIN32API
HWND Handle; // Идентификатор главного окна приложения
#else
MSGHANDLER Handle; // Идентификатор обработчика команд главного окна приложения
#endif
HWND DocHandle; // Идентификатор окна карты (документа)
long int StayOnTop; // Признак выставления форме свойтсва StayOnTop // 14/05/05 [/CODE] Эти поля и сама структура видимо изначально вообще для WINDOWS делались. Тот же MSGHANDLER используется под Linux вместо окна, которому события посылаются (как CallBack функция) . Она у нас как правило static long onMsg(...){..}
Но я вероятно не прав, так как с TASKPARMEX не работал.
Но если натравить поиск на TASKPARMEX по компонентам для gisdesigner (QDMapVIew и прочие QD*) или примерам из пакета, то может быть там найдутся примеры как этой структурой пользоваться.
[CODE]typedef long int (* MSGHANDLER) (long int hwnd, long int code, long int p1, long int p2, long int typemsg); [/CODE] MapView1 - это метод с такой сигнатурой ?
У Вас же там куча предупреждений от компилятора должна была быть.
[QUOTE]Владимир Егоров написал: При этом вручную внести эти данные в Rsw файл я не могу, так как функция picexLoadRasterToRswUn создаёт файл в формате 1.04, который закрыт, я нашёл только описание формата версии 2.00 и 2.01[/QUOTE] Я нашёл упоминание этой версии в mappicex.h, с декабря 2018-го года получается искал =) [CODE]//======================================================================== // Привязка растра с масштабированием по двум точкам // Внимание: Возможна устанавка отличных друг от друга размеров пикселя по X и по Y // // ВАЖНО: // Если размеры пикселя по X и по Y отличаются друг от друга, то в растр // устанавливается версия 1.04 (0x0104). // Растры версии 1.04 открываются в ПО начинаяя с 11-ой версии. // // hMap - карта, содержащая векторные данные; // rswName - имя файла растра // pointMet1 - Координаты первой точки в метрах // pointMet1 - Координаты первой точки в метрах // pointMet2 - Координаты второй точки в метрах // pointMet2 - Координаты второй точки в метрах // message - флаг на выдачу сообщений (0\1) // При ошибке возвращает ноль //======================================================================== _PICIMP long int _PICAPI AttachRswWithScaling(HMAP hMap, const char* rswName, DOUBLEPOINT *pointMet1, DOUBLEPOINT *pointMetNew1, DOUBLEPOINT *pointMet2, DOUBLEPOINT *pointMetNew2, int message); [/CODE] То есть на сайте в документации к rsw/mtw не хватает пометки про эту особенность.
[QUOTE]Dmitry_ написал: Если в функциях привязки растра параметр hmap задать равным 0, то растр будет открыт в отдельном документе:[/QUOTE] Функция RswTransformingBySquareMethod не запускается (возвращает 0) если ей передать первым параметром 0, то есть открывать растр в отдельном документе нужно самому. И все другие функции из семейства функций привязок вроде тоже без hmap не запускаются.
Но это в версии 12.5.0 gisdesigner.
Может в следующих версиях уже по другому будет.
По поводу разницы алгоритмов. Насколько я понял, AttachRswWithScalingAndRotation - это линейное преобразование, сдвиг - масштаб - поворот, двух точек достаточно для вычисления параметров. RswTransformingBySquareMethod - это линейное преобразование, афинное (A0, A1, A2; B0, B1, B2) X = A0 + A1*Xi + A2*Yi; Y = B0 + B1*Xi + B2*Yi. Шесть параметров вычисляются методом наименьших квадратов, поэтому нужно минимум 4 точки (чтобы количество строк в матрице было больше чем количество столбцов = 3)
RswTransformingByBorderMethod - это нелинейное преобразование (видимо, "нелинейный резиновый лист", как описано здесь: [URL=http://help.gisserver.ru/ru/rswtrans/rtip.html.]http://help.gisserver.ru/ru/rswtrans/rtip.html[/URL]), не уверен.
И насколько я понял, для этого метода важно, чтобы опорные точки распологались на рамке листа ( 4 угла), а если опорных точек больше 4, то они должны распологаться равномерно.
Далее, для растров уже спроецированных на плоскость (то есть, находящихся в какой-то локальной прямоугольной системе координат) лучше применять линейные преобразования. Так же, линейные преобразования есть смысл применять для растров, немного сдвинутых относительно векторной карты (или более точной растровой). То есть, это случаи когда у вас уже привязанный растр при наложении на основную карту немного смещён/повернут. Или, когда у вас есть скриншот района из гугло/яндекс карт, и вы хотите его привязать.
Нелинейные преобразования (которое RswTransformingByBorderMethod) лучше применять для отсканированных бумажных листов топографической карты, когда привязка идёт по рамке и/или точкам пересечения километровой сетки. И в этом случае чем больше точек, тем лучше.
Поправьте меня пожалуйста, если я неправильно что-нибудь написал.
gisdesigner 12.5.0 (ГИС Конструктор для QtDesigner)
Продолжу тему с привязкой растра, но уже без файлов привязок.
То есть на входе - изображение, и оператор, который может отметить на изображении точки и сказать какие у этих точек координаты.
1) Подход в целом такой же как и в случае с файлами привязки, но мне интересно для каких целей используется параметр HMAP в функциях для привязки растрова из mappicex.h:
Скрытый текст
//======================================================================== // Привязка растра с масштабированием и поворотом по двум точкам // 15/09/05 // hmap - идентификатор карты, к которой добавляется растр // handle - идентификатор окна диалога для обработки сообщений о ходе процесса // rswname - путь к файлу растра, который трансформируется // pointmet1 - исходные координаты первой точки в метрах // pointmetnew1 - желаемые координаты первой точки в метрах // pointmet2 - исходные координаты второй точки в метрах // pointmet2 - желаемые координаты второй точки в метрах // message - флаг на выдачу сообщений (0\1) в процессе трансформирования // // Диалогу визуального сопровождения процесса обработки посылаются // сообщения: // - (WM_PROGRESSBAR) Извещение об изменении состояния процесса // WPARAM - текущее состояние процесса в процентах (0% - 100%) // Если функция-отклик возвращает WM_PROGRESSBAR, то процесс завершается. // При ошибке возвращает ноль //======================================================================== _PICIMP long int _PICAPI AttachRswWithScalingAndRotation(HMAP hmap, HMESSAGE handle, const char* rswname, // 21/09/05 DOUBLEPOINT *pointmet1, DOUBLEPOINT *pointmetnew1, DOUBLEPOINT *pointmet2, DOUBLEPOINT *pointmetnew2, int message);
_PICIMP long int _PICAPI AttachRswWithScalingAndRotationUn(HMAP hmap, HMESSAGE handle, const WCHAR * rswname, DOUBLEPOINT *pointmet1, DOUBLEPOINT *pointmetnew1, DOUBLEPOINT *pointmet2, DOUBLEPOINT *pointmetnew2, int message);
//======================================================================== // Привязка растра с масштабированием и поворотом по двум точкам // 10/03/06 // // hmap - карта, содержащая векторные данные; // handle - диалог визуального сопровождения процесса обработки. // rswnamein - имя исходного файла растра // rswNameOut - имя выходного файла растра (размер строки д.б. не менее MAX_PATH_LONG байт) // pointmet1 - Координаты первой точки в метрах // pointmet1 - Координаты первой точки в метрах // pointmet2 - Координаты второй точки в метрах // pointmet2 - Координаты второй точки в метрах // message - флаг на выдачу сообщений (0\1) // // Диалогу визуального сопровождения процесса обработки посылаются // сообщения: // - (WM_PROGRESSBAR) Извещение об изменении состояния процесса // WPARAM - текущее состояние процесса в процентах (0% - 100%) // Если функция-отклик возвращает WM_PROGRESSBAR, то процесс завершается. // При ошибке возвращает ноль //======================================================================== _PICIMP long int _PICAPI AttachRswWithScalingAndRotationEx(HMAP hmap, HMESSAGE handle, const char* rswnamein, char* rswnameout, DOUBLEPOINT *pointmet1, DOUBLEPOINT *pointmetnew1, DOUBLEPOINT *pointmet2, DOUBLEPOINT *pointmetnew2, int message);
// sizeNameIn - размер строки rswName в байтах // sizeNameOut - размер строки rswNameOut в байтах _PICIMP long int _PICAPI AttachRswWithScalingAndRotationExUn(HMAP hmap, HMESSAGE handle, const WCHAR* rswName, int sizeNameIn, WCHAR* rswNameOut, int sizeNameOut, DOUBLEPOINT *pointmet1, DOUBLEPOINT *pointmetnew1, DOUBLEPOINT *pointmet2, DOUBLEPOINT *pointmetnew2, int message);
//============================================================================== // Трансформирование растра // 08/02/07 // (вычисление коэффициентов пересчета координат методом наименьших квадратов) // // handle - диалог визуального сопровождения процесса обработки; // map - карта,содержащая векторные данные; // parm - параметры прикладной задачи; // namein - имя исходного растра (MAX_PATH_LONG) // nameout - имя выходного растра (размер выделенной памяти д.б. не менее MAX_PATH_LONG символов) // fact - исходные координаты опоры; // teor - желаемые координаты опоры; // count - количество опорных точек (не меньше 4-х). // // Диалогу визуального сопровождения процесса обработки посылаются сообщения: // - (WM_PROGRESSBAR) Извещение об изменении состояния процесса // WPARAM - текущее состояние процесса в процентах (0% - 100%) // Если функция-отклик возвращает WM_PROGRESSBAR, то процесс завершается. // При ошибке возвращает ноль, //============================================================================== _PICIMP long int _PICAPI RswTransformingBySquareMethod(HMAP map,HMESSAGE handle, TASKPARMEX * parm, const char * namein, char * nameout, long int count,DOUBLEPOINT * fact,DOUBLEPOINT * teor);
// sizeNameOut - размер выделенной памяти для nameout в байтах _PICIMP long int _PICAPI RswTransformingBySquareMethodUn(HMAP map,HMESSAGE handle, TASKPARMEX * parm, const WCHAR * namein, WCHAR * nameout, int sizeNameOut, long int count,DOUBLEPOINT * fact,DOUBLEPOINT * teor);
//============================================================================== // Трансформирование растра по рамке листа карты // 06/06/11 // // handle - диалог визуального сопровождения процесса обработки; // map - карта,содержащая векторные данные; // parm - параметры прикладной задачи; // namein - имя исходного растра; // nameout - имя выходного растра; // fact - исходные координаты опоры; // teor - желаемые координаты опоры; // count - количество опорных точек (не меньше 4-х). // // Диалогу визуального сопровождения процесса обработки посылаются сообщения: // - (WM_PROGRESSBAR) Извещение об изменении состояния процесса // WPARAM - текущее состояние процесса в процентах (0% - 100%) // Если функция-отклик возвращает WM_PROGRESSBAR, то процесс завершается. // При ошибке возвращает ноль, //============================================================================== _PICIMP long int _PICAPI RswTransformingByBorderMethod(HMAP map,HMESSAGE handle, TASKPARMEX * parm, const char * namein, const char * nameout, long int count,DOUBLEPOINT * fact,DOUBLEPOINT * teor);
_PICIMP long int _PICAPI RswTransformingByBorderMethodUn(HMAP map,HMESSAGE handle, TASKPARMEX * parm, const WCHAR * namein, const WCHAR * nameout, long int count,DOUBLEPOINT * fact,DOUBLEPOINT * teor);
//============================================================================== // Трансформирование растра по рамке листа карты // 21/06/11 // (нелинейное трансформирование) // handle - диалог визуального сопровождения процесса обработки; // map - карта,содержащая векторные данные; // parm - параметры прикладной задачи; // namein - имя исходного растра; // nameout - имя выходного растра; // fact - исходные координаты опоры; // teor - желаемые координаты опоры; // count - количество опорных точек (не меньше 4-х). // flagBorder- 0 - Установить рамку растра по теоретическим координатам (например - по рамке номенклатурного листа) // 1 - Установить рамку растра по пересчитанным габаритам исходного растра // Если исходный растр отображается по рамке, flagBorder игнорируется. // Рамка перессчитывается и устанавливается в выходной растр. // colorTransparent - указатель на неотображаемый цвет // (если colorTransparent != 0, то в качестве цвета фона используется цвет из colorTransparent. // Отображение цвета colorTransparent отключается) // // Диалогу визуального сопровождения процесса обработки посылаются сообщения: // - (WM_PROGRESSBAR) Извещение об изменении состояния процесса // WPARAM - текущее состояние процесса в процентах (0% - 100%) // Если функция-отклик возвращает WM_PROGRESSBAR, то процесс завершается. // При ошибке возвращает ноль, //============================================================================== _PICIMP long int _PICAPI RswTransformingByBorderMethodEx(HMAP map,HMESSAGE handle, TASKPARMEX * parm, const char * namein, const char * nameout, long int count,DOUBLEPOINT * fact,DOUBLEPOINT * teor, long int flagBorder, COLORREF * colorTransparent);
_PICIMP long int _PICAPI RswTransformingByBorderMethodExUn(HMAP map,HMESSAGE handle, TASKPARMEX * parm, const WCHAR * namein, const WCHAR * nameout, long int count,DOUBLEPOINT * fact,DOUBLEPOINT * teor, long int flagBorder, COLORREF * colorTransparent);
//============================================================================== // Трансформирование растра по рамке листа карты // 29/04/13 // (нелинейное трансформирование) // handle - диалог визуального сопровождения процесса обработки; // map - карта,содержащая векторные данные; // parm - параметры прикладной задачи; // namein - имя исходного растра; // nameout - имя выходного растра; // fact - исходные координаты опоры; // teor - желаемые координаты опоры; // count - количество опорных точек (не меньше 4-х). // colorTransparent - указатель на неотображаемый цвет // (если colorTransparent != 0, то в качестве цвета фона // используется цвет из colorTransparent. // Отображение цвета colorTransparent отключается) // flagCutting - флаг обрезки изображения выходного растра по рамке растра. // Значение флага принимается во внимание при установленной рамке в растр (см. flagBorder) // flagDuplicate - флаг создания уменьшенной копии изображения выходного растра (0/1) // flagBorderNew - 0 - Не устанавливать рамку выходного растра // 1 - Установить рамку выходного растра по теоретическим координатам // (например - по объекту <Рамка номенклатурного листа карты>) / // 2 - Установить рамку выходного растра по рамке исходного раста. // Если в исходном растре рамка не установлена, то будет установлена // рамка растра по пересчитанным габаритам исходного растра // 3 - Установить рамку выходного растра по пересчитанным габаритам исходного растра // // Диалогу визуального сопровождения процесса обработки посылаются сообщения: // - (WM_PROGRESSBAR) Извещение об изменении состояния процесса // WPARAM - текущее состояние процесса в процентах (0% - 100%) // Если функция-отклик возвращает WM_PROGRESSBAR, то процесс завершается. // При ошибке возвращает ноль, //============================================================================== _PICIMP long int _PICAPI RswTransformingWithBorderSetting(HMAP map,HMESSAGE handle, TASKPARMEX * parm, const char * namein, const char * nameout, long int count,DOUBLEPOINT * fact,DOUBLEPOINT * teor, COLORREF * colorTransparent, long int flagCutting, long int flagDuplicate, long int flagBorderNew);
_PICIMP long int _PICAPI RswTransformingWithBorderSettingUn(HMAP map,HMESSAGE handle, TASKPARMEX * parm, const WCHAR * namein, const WCHAR * nameout, long int count,DOUBLEPOINT * fact,DOUBLEPOINT * teor, COLORREF * colorTransparent, long int flagCutting, long int flagDuplicate, long int flagBorderNew);
Ну то есть что будет, если я сделаю растр из изображения с помощью функции picexLoadRasterToRswUn, потом открою его и выставлю параметры проекции, датум и эллипсоид (как СК-42, к примеру), закрою, потом открою векторную карту в системе координат уже другой (например, UTM на WGS84), и попытаюсь привязать растр с помощью функции привязки (любой), отдав первым параметром векторную карту, а в каждой паре точек в качестве фактической точки буду отдавать координаты с растра (в СК-42), а в качестве теоретической (желаемой) точки буду отдавать точку с векторной карты (в UTM).
Это так работает? Данные о проекции и системе координат из HMAP (открытой векторной карты) используются для того, чтобы обработать желаемые координаты точки? И тогда есть возможность исходные координаты задавать в системе растра, а желаемые в системе открытой векторной карты?
2) А ещё, я не очень понял чем отличаются друг от друга функции трансформации растров по рамке и МНК. Какие-то из этих функции работают дольше но точнее? Или разница только в параметрах обработки рамки?
Пометки "нелинейное трансформирование | расчёт коэффициентов по МНК | вообще никакой пометки" сбивают с толку.
[CODE] // Преобразование координат из геодезической системы координат карты к // в геодезические координаты в радианах (общеземной эллипсоид WGS84) // (поддерживается не для всех карт !) // При ошибке возвращает ноль
_MAPIMP long int _MAPAPI mapGeoToGeoWGS843D(HMAP hMap, double *Bx, double *Ly, double *H); [/CODE]Там вроде HMAP ожидается, а не HANDLE
Разбирался сейчас с функцией mapPlaneUTMToGeoWGS84ByZone в старой версии gisdesigner [B](11-ая версия)[/B]
На форуме информации не нашёл, поэтому оставлю здесь пост, может кому-нибудь пригодится (для большинства эти вещи очевидны, вероятно).
Итак, функция: [CODE] // Преобразование координат в метрах на местности из заданной зоны UTM // в геодезические координаты в системе WGS-84. // 03/07/06 // zone - номер исходной зоны системы UTM // x,y - преобразуемые координаты // на входе метры в одной зоне UTM, на выходе - радианы WGS-84. // При ошибке возвращает 0
_MAPIMP long int _MAPAPI mapPlaneUTMToGeoWGS84ByZone(long int zone, double * x, double * y);
[/CODE] С помощью этой функции я хотел вычислить координаты левого нижнего угла растрового файла , у которого в паспорте написано что он в системе UTM на WGS84.
[CODE] // Типы флага "Тип карты" typedef enum MAPTYPE { // UNDEFINED = -1, // Не установлено TOPOGRAPHIC = 1, // Топографическая (СК42), требует осевой меридиан CK_42 = 1, // Система координат 42 года, требует осевой меридиан ... UTMWGS84 = 11, // UTM на WGS84, требует осевой меридиан ... } MAPTYPE; [/CODE]Проекция, эллипсоид и система координат (поля в паспорте rsw) действительно соответствуют этому типу карты.
Координаты (по паспорту rsw) левого нижнего угла rsw:
[CODE]X: 6.69006e+06 Y: 609109 [/CODE]На выходе мы хотим получить WGS84 долготу/широту. Если использовать PHOTOMOD GeoCalculator, то результат будет:
[CODE]B:60.332346299 L:28.976193205 [/CODE]Тут главное не забыть, что в паспорте rsw ось X направлена вверх, ось Y направлена вправо (как в проекции Гаусса-Крюгера), а в универсальной поперечной проекции Меркатора ось Y вверх, а ось X вправо. Соответственно, X - это широта, а Y - это долгота (не смотря на то, что в проекции Меркатора Y это широта, а X долгота)
Зоны в Меркаторе нумеруются не так, как в Гауссе-Крюгере, они сдвинуты на 30 вправо относительно зон Гаусса-Крюгера:[CODE]int MapIndexer::calcTransverseMercatorZone(double axisMeridianInRadian) { int x = (calcSK42Zone(axisMeridianInRadian) + 30) % 60; return x?x:60; } [/CODE] В паспорте rsw осевой меридиан (AxisMeridian) указан как 27 градусов, это 5-ая зона в Гауссе-Крюгере и 35-ая зона в Меркаторе. Указываем данные (35-ая зона, E, N) в фотоплане и получаем координаты: [URL=https://drive.google.com/open?id=1w0sWn14g88qmiZbKYG9tnVUmpLgXqkrb]Скриншот[/URL]
А чтобы получить те же координаты с помощью mapPlaneUTMToGeoWGS84ByZone нам придётся отредактировать Y.
Сначала вычтем из него значение FalseEast из паспорта карты (смещение центра координат на восток) и получим расстояние от точки до осевого меридиана по оси Y
FalseEast в паспорте rsw указан как 500000 (метров), то есть Y получится 109109 вместо 609109.
Дальше к значению нужно прибавить номер зоны в меркаторе умноженный на 1000000 (миллион), то есть 35 * 10^6, получим 35109109.
И вот теперь функция mapPlaneUTMToGeoWGS84ByZone сможет вычислить для нас координаты. Пример:
Upd. А для точек в южном полушарии, вероятно, из X надо будет вычитать FalseNorth (поле в паспорте rsw) равное 10000000 (10 миллионов) метров. Чтобы, к примеру, из значения 3309940.0 получить -6690060.0 и уже вот это отрицательное значение отдавать в функцию mapPlaneUTMToGeoWGS84ByZone