Аналитически я пришел к выводу, что используется EPSG:4087, так как я сопоставил примерные точки, ориентируясь на г. Таганрог. Координаты точки на MTW-карте были получены с помощью программы "Панорама", а EPSG:4087 было взято с этого сервиса https://epsg.io/4087. Результаты сравнения представлены на рисунке: https://ibb.co/qMx344L
Видно, что точки должны соответствовать, также делал для других карт (все совпало).
Вопросы: 1. Действительно ли используется EPSG: 4087 в данном MTW-файле? 2. Как определить, какая система координат используется? Рисунок с выводом информации об MTW-файле https://ibb.co/wp6fdBy. Для Открытия использовалась библиотека GDAL.
Матрица, которую Вы скачали, хранится в проекции Широта\Долгота на WGS-84. Это условно соответствует коду EPSG:4326. Это копия файла SRTM в этой же системе. Один файл соответствует квадратному градусу. Имя файла определяет этот градус - N37 / E038. Число элементов в строке и число строк разбивают градус на соответствующее число частей.
Разные цилиндрические проекции могут быть "похожи", но математика очень разная.
EPSG:4087 - WGS 84 / World Equidistant Cylindrical
Код
//--------------------------------------------------------------------
// Инициализация
//--------------------------------------------------------------------
void _fastcall TTranslate::InitCylindricalEqualSpaced()
{
// Вычисление постоянных по FirstMainParal
va = ParallelCurvatureRadius(FirstMainParallel) * BigAxis;
if (va == 0)
va = 1;
}
//--------------------------------------------------------------------
// Перевод прямоугольных координат в геодезические
// Входные данные:
// x,y - координаты точки в метрах
// Выходные данные:
// b,l - геодезические координаты точки в радианах
//--------------------------------------------------------------------
void _fastcall TTranslate::XY2BL_CylindricalEqualSpaced(double x, double y, double& b, double& l)
{
y -= FalseEasting;
x -= FalseNorthing;
l = y / va + AxisMeridian; // долготу получили
b = M_PI_4; // начальное значение 45
int sign = 0;
if (x < 0)
{
x = -x;
sign = 1;
}
double abc, abegin, aend;
abegin = 0; aend = M_PI_2; //начальный интервал 0--.--90
for (int i = 2; i < 18; i++)
{
// метод половинного деления
abc = x - ArcLength(b);
if (abc < 0)
{
aend = b;
b = (b + abegin) / 2.;
}
else
{
abegin = b;
b = (b + aend) / 2.;
}
if (fabs(abegin - aend) < TRANSLATEPRECISION)
break;
}
if (sign == 0)
b = (abegin + aend) / 2.0;
else
b = -(abegin + aend) / 2.0;
}
//--------------------------------------------------------------------
// Перевод геодезических координат в прямоугольные
// Входные данные:
// b,l - геодезические координаты точки в радианах
// Выходные данные:
// double x,y - прямоугольные координаты точки в метрах
//--------------------------------------------------------------------
void _fastcall TTranslate::BL2XY_CylindricalEqualSpaced(double b, double l, double& x, double& y)
{
if (b >= 0)
x = ArcLength(b); // прямоугольные
else
x = -ArcLength(-b); // прямоугольные
x += FalseNorthing;
y = va * (l - AxisMeridian) + FalseEasting;; // координаты в метрах
}
Широта/Долгота:
Код
//---------------------------------------------------------------------
// Вычисление геодезических координат точки B,L по координатам
// точки X,Y в цилиндрической проекции "Широта/Долгота" на шаре
// Входные данные:
// x,y - координаты точки в метрах
// Выходные данные:
// b,l - широта и долгота точки в радианах
//---------------------------------------------------------------------
void _fastcall TTranslate::XY2BL_LATLON(double x, double y, double& b, double& l)
{
b = (x - FalseNorthing) / BigAxis + MainPointParallel;
l = (y - FalseEasting) / BigAxis + AxisMeridian;
}
//---------------------------------------------------------------------
// Вычисление координат X,Y точки по геодезическим координатам
// точки B,L в цилиндрической проекции "Широта/Долгота" на шаре
// Входные данные:
// b,l - геодезические координаты точки в радианах
// Выходные данные:
// x,y - координаты точки в метрах
//---------------------------------------------------------------------
void _fastcall TTranslate::BL2XY_LATLON(double b, double l, double& x, double& y)
{
x = (b - MainPointParallel) * BigAxis + FalseNorthing;
y = (l - AxisMeridian) * BigAxis + FalseEasting;
}
Программно можно запросить параметры СК так:
Код
// Запросить данные о проекции матрицы
// hMap - идентификатор открытых данных
// number - номер матрицы в списке открытых матриц
// mapregister, datumparam, ellipsoidparam - адреса структур, содержащих данные о проекции
// Структуры MAPREGISTEREX, DATUMPARAM, ELLIPSOIDPARAM описаны в mapcreat.h
// ttype - тип локального преобразования координат (см. TRANSFORMTYPE в mapcreat.h) или 0
// tparm - параметры локального преобразования координат (см. mapcreat.h)
// При ошибке возвращает ноль
_MAPIMP long int _MAPAPI mapGetMtrProjectionDataPro(HMAP hMap, long int number, MAPREGISTEREX* mapregister,
DATUMPARAM *datumparam, ELLIPSOIDPARAM *ellipsoidparam, long int * ttype, LOCALTRANSFORM * tparm);
или посмотреть в диалоге Параметры проекции в ГИС Панорама
Как мы видим, в метаданных карты исходная точка отчета отмечена следующим образом:
Так ( GeoTransform 4.23014e+06, 92.7662, 0 GeoTransform 5.34343e+06, 0, -92.7662 ) Или так ( 4230140.650144 5343428.324319 )
Возможно, это особенности реализации GDAL, но именно эти координаты 4.23014e+06, 5.34343e+06 и наводят прямо на мысль о EPSG:4087. Широт и долгот тут не указано, может быть, какая-то несовместимость.
Сама же исходная задача простая - имея такую карту и библиотеку GDAL, ее читающую (а опенсорсных аналогов, способных прочитать эти карты, не знаем), переходить от географических координат к системе карты высот MTW. Грубо говоря, внятно ответить на вопрос, 4230140.650144, 5343428.324319 — это какие координаты в терминах широты и долготы?
И пока видится, что переход нужно делать от 4326 к 4087 и обратно. Поверхностные сверки дали пока положительный результат.
Выше приведены формулы для пересчета между геодезическими координатами и плоскими прямоугольными для проекции Цилиндрическая равнопромежуточная EPSG:4087 - WGS 84 / World Equidistant Cylindrical и для проекции Широта/Долгота, которая по сути соответствует EPSG:4326 (но это код геодезической системы, а не картографического представления). Обсуждать их близость не имеет смысла. Они разные.
Код EPSG для этой проекции подсказать не могу. Переход от условных метров к градусам выполняется через умножение на величину полуоси эллипсоида (для WGS-84 в данном случае - 6378137.0).
В GDAL для MTW эта проекция не описана (код проекции в Панорама - 33) и соответственно WKT (или его аналог) формируется не совсем точно.
Код
/************************************************************************/
/* "Panorama" projection codes. */
/************************************************************************/
constexpr long PAN_PROJ_NONE = -1L;
constexpr long PAN_PROJ_TM = 1L; // Gauss-Kruger (Transverse Mercator)
constexpr long PAN_PROJ_LCC = 2L; // Lambert Conformal Conic 2SP
constexpr long PAN_PROJ_STEREO = 5L; // Stereographic
constexpr long PAN_PROJ_AE = 6L; // Azimuthal Equidistant (Postel)
constexpr long PAN_PROJ_MERCAT = 8L; // Mercator
constexpr long PAN_PROJ_POLYC = 10L; // Polyconic
constexpr long PAN_PROJ_PS = 13L; // Polar Stereographic
constexpr long PAN_PROJ_GNOMON = 15L; // Gnomonic
constexpr long PAN_PROJ_UTM = 17L; // Universal Transverse Mercator (UTM)
constexpr long PAN_PROJ_WAG1 = 18L; // Wagner I (Kavraisky VI)
constexpr long PAN_PROJ_MOLL = 19L; // Mollweide
constexpr long PAN_PROJ_EC = 20L; // Equidistant Conic
constexpr long PAN_PROJ_LAEA = 24L; // Lambert Azimuthal Equal Area
constexpr long PAN_PROJ_EQC = 27L; // Equirectangular
constexpr long PAN_PROJ_CEA = 28L; // Cylindrical Equal Area (Lambert)
constexpr long PAN_PROJ_IMWP = 29L; // International Map of the World Polyconic
constexpr long PAN_PROJ_MILLER = 34L; // Miller