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

EPSG, конвертация в СК42 из WGS84

Поиск  Пользователи  Правила  Войти
Форум » Общие вопросы » Системы координат
Страницы: 1
RSS
EPSG, конвертация в СК42 из WGS84
 
Здравствуйте.

Раньше использовали собственные библиотеки для работы с координатами,
теперь хотим всё работу с координатами проводить только через MAPAPI.

Разбираю пример с конвертированием координат по EPSG коду.

Функция из примера конвертирующая в СК-42:
Код
int convertToSK42( double B, double L )
{
   int zoneNumber = mapGetZoneByMeridian( L );
   int epsg = base_epsg_sk42 + zoneNumber;
   return convertByEPSG( B, L, epsg );
}


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

   mapGeoWGS84ToUserGeo( userSystemHandle, &B, &L );

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

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

   mapDeleteUserSystemParameters( userSystemHandle );
   return 1;
}

Точка на общеземном эллипсоиде WGS-84:   B: 60.0,   L: 29.9999

Результат работы программы:
Код
Исходная точка в общеземном эллипсоиде WGS-84: B = +60°00'0,00000" , L = 
+29°59'59,64000"
B = 1,047197551 , L = 0,523597030
Выполнен пересчет в СК с кодом EPSG = 28405  : B = +60°00'0,11449" , L = 
+30°00'7,78658"
B = 1,047198106 , L = 0,523636526
Выполнен пересчет в прямоугольные координаты : X = 6657993,983756073 , Y 
= 5667484,989601249

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

Это корректно? Или правильнее сначала перевести в геодезические СК-42, а
уже потом вычислять зону по долготе?



И ещё вопрос.

В функцию convertByEPSG отдаётся код EPSG с учётом зоны, я правильно
понимаю что при вызове функции mapGeoWGS84ToUserGeo на зону не смотрят и
координаты просто переводятся в геодезические на указанном эллипсоиде. А
учитывается зона только при переводе в плоские прямоугольные ?


А ещё можете написать код epsg для ПЗ-90? (если он существует).
Коды для других требуемых систем координат (ПЗ90.02, ПЗ90.11) я нашёл в примере.

Спасибо.
 
А если у Вас две точки в разных зонах и Вы их будете так пересчитывать и наносить на одну карту с координатами в разных системах?
Можно придумать много "некорректных" примеров.

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

Реальная задача не должна "рыскать" по системам координат. Они должны быть однозначно заданы.

ПЗ-90 "не жилец". В разных ГОСТ даны разные параметры перехода. Это уже мусор.
 
Здравствуйте.

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

Код
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;
}  


Вывод:

Код
Выполнен пересчет в СК с кодом 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

Online-конвертор

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

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



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

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