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

преобразование проекций средствами ГИС Конструктор под ОС Astra-Linux v.1.3

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: 1 2 3 4 5 ... 7 След.
RSS
преобразование проекций средствами ГИС Конструктор под ОС Astra-Linux v.1.3, получение косой азимутальной равнопромежуточной проекции путём трансформации других проекций
 
Стоит задача иметь возможность получать косую азимутальную равнопромежуточную проекцию фрагмента Земного шара с расположением полюса проекции в любой произвольной точке на его поверхности, используя в качестве исходных данных карту мира. Для этой цели применяется присутствующая в Конструкторе функция mapSetDocProjection (...). При попытке использовать в качестве исходных данных для её работы всю карту мира целиком результирующие проекции получаются некорректно. Ранее было высказано предположение, что причина этого в большой протяжённости исходной карты. Т.е., если карту мира разбивать на фрагменты и выполнять преобразования координат уже для них, то проекция сформируется правильно. Подтверждения этой идеи я так и не получил, ввиду чего прошу ответить на следующие вопросы:

1.
Если в приложениях Оператор-2011 или Карта-2011 создавать новую карту с азимутальной проекцией и, используя буфер обмена, копировать на неё все объекты из открытой в другом окне карты мира с цилиндрической проекцией, то новая карта формируется корректно вне зависимости от протяжённости копируемых районов (вплоть до поверхности всего Земного шара). Аналогичная задача функцией mapSetDocProjection () из состава Конструктора решается не корректно. Отсюда вопрос: формулы пересчёта координат  в этих двух случаях используются одни и те же? Если "да" то почему результат их работы разный?

2.
Помятуя о том, что для работы функции mapSetDocProjection () требуются карты малой протяжённости, и, желая проверить работу функции при построении азимутальной проекции в районе полюса, мною была подготовлена карта, на которой присутствует лишь два района, сопрягающиеся друг с другом в районе полюса (упомянутые районы выделены розовым цветом):



Результат получения азимутальной проекции указанной карты первым способом (путём создания новой карты в азимутальной проекции и копирования туда объектов исходной карты) представлен на следующем рисунке и выглядит достаточно корректно :



Напротив, результат преобразования координат вторым способом (функцией mapSetDocProjection () ) некорректен и зависит от долготы полюса проекции. Для долготы +20  изображение выглядит так:



Для долготы   -160  результат следующий:



В обоих последних случаях широта полюса проекции равна +90.
Как видно из изображений, функция  mapSetDocProjection () вообще не формирует проекцию для района, находящегося по другую сторону от полюса. Как выходить из этой ситуации?

3.
Если открыта векторная карта и соответствующая ей матрица высот, то возможно ли программно выполнить вместе с трансформацией карты ещё и трансформацию матрицы? Для этого тоже следует использовать функцию mapSetDocProjection () или в ГИС Конструкторе для этого предусмотрен иной механизм?
Изменено: Алексей Агулов - 14.10.2014 12:06:39
 
Мы дополнили Руководство программиста разделом 4.2.24 Копирование объектов на другую карту с изменением системы координат -

http://gistoolkit.ru/download/doc/mapapi.pdf

Алгоритм переноса объектов более сложный, чем процесс отображения с другими параметрами системы координат (mapSetDocProjection).
В зависимости от полюса проекции объект может быть симметрично перекинут относительно полюса для лучшей читаемости карты.
В процессе отображения это сделать сложнее.
То есть лучше готовить изображения полюсов на отдельных картах и переходить на них динамически.
При использовании методов буферизации экрана (изображение строится в памяти и по готовности отображается)
оператор не заметит перехода.

4.2.24 Копирование объектов на другую карту с изменением системы координат

Копирование объектов на другую карту может применяться для следующих задач:
- трансформирование векторной карты в новую систему координат и проекцию;
- представление участка местности в заданной проекции, имеющей ограничение на размер территории, который может быть отображен без искажений;
- деление исходной единой карты на листы;
- объединение многолистовой карты в единую карту;
- подготовка различных отчетов, требующих специальный состав объектов, собранных из разных источников.

Для копирования объектов необходимо открыть исходную карту и открыть или создать выходную карту в заданной проекции и системе координат.
Копироваться могут все объекты или объекты, выделенные по некоторому набору критериев.
Для чтения всех объектов применяется функция mapReadObjectByNumber.

Для чтения объектов, выделенных на карте, применяется функция mapTotalSeekObject. Для чтения объектов по заданным условиям применяется функция mapSeekSiteSelectObject.
В условия отбора объектов может входить область выбора объектов в виде прямоугольника или произвольный полигон.
Для переноса считанного объекта на другую карту применяется функция mapChangeObjectMap.

Код
  // Перенести объект на другую карту (пересчитать координаты и 
  // заменить ссылку в объекте на карту)
  // При переносе объекта выполняется перекодировка объекта
  // для нового классификатора, если код не найден -
  // он устанавливается в ноль, прежнее значение
  // сохраняется в семантике (код 32800).
  // (для замены вызывается mapRegisterObject())
  // Метрика преобразуется в соответствии с типом карты
  // hSite - идентификатор открытой пользовательской карты
  // hObj  - идентификатор объекта пользовательской карты
  // hMap  - идентификатор открытой основной карты
  // Объект на исходной карте при этом не удаляется,
  // для записи объекта в новой карте необходимо вызвать mapCommitObject
  // При ошибке возвращает ноль

_MAPIMP long int _MAPAPI mapSetObjectMap(HOBJ info, HSITE hSite);
_MAPIMP long int _MAPAPI mapChangeObjectMap(HOBJ hObj, HMAP hMap, HSITE hSite);

Для копирования объектов необходимо открыть исходную карту и открыть или создать выходную карту в заданной проекции и системе координат.
Копирование объектов для трансформирования всей карты может иметь следующий вид:

Код
int listcount = mapGetSiteListCount(hMap, hSite);
for (int list = 1; list < listcount; list++)
{
   int objectcount = mapGetSiteObjectCountInList(Map, hSite, list);
   for (int object = 1; object < objectcount; object++)
   {
       // Чтение объекта
       if (mapReadObjectByNumber(hMap, hSite, hObj, list, number) == hObj)
          {
             // Перенос объекта на другую карту (hMap может не меняться)
             if (mapChangeObjectMap(hObj, hMapNew, hSiteNew) != 0)
                {
                   // Запись на новую карту (для нарезки по листам - mapCommitWithPlace)   
                   mapCommitObject(hObj);
                 }
           }
   }
}


Копирование объектов по заданным условиям может иметь следующий вид:

Код
// Параметры объекта будут переустановлены автоматически при чтении объекта
HOBJ hObj = mapCreateSiteObject(hMap, hSite, IDDOUBLE2, 0);
HOBJ hTemp = mapCreateSiteObject(hMap, hSite, IDDOUBLE2, 0);

int flag = WO_FIRST;
while (mapSeekSiteSelectObject(hMap, hSite, hObj, hSelect, flag) != 0)
{
    flag = WO_NEXT;

    // Сделать копию объекта, чтобы не нарушить 
    // последовательность поиска объектов в mapSeekSiteSelectObject
    mapReadCopyObject(hTemp, hObj); 

    // Перенос объекта на другую карту (hMap может не меняться)
    if (mapChangeObjectMap(hTemp, hMapNew, hSiteNew) != 0)
      {
          // Запись на новую карту (для нарезки по листам - mapCommitWithPlace)   
          mapCommitObject(hTemp);
      }
} 

mapFreeObject(hTemp);
mapFreeObject(hObj);
 
Спасибо за развёрнутый ответ по вопросу работы алгоритма переноса объектов.
Т.е., если я правильно понял, вариант отображения проекций с другими параметрами системы координат (с использованием процедуры mapSetDocProjection) неприемлем для случаев, когда в пределы карты попадают географические полюса.
Остаётся только реализация программным способом алгоритма переноса объектов. Но, насколько я заметил, в имеющихся у меня версиях приложений Карта-2011 и Оператор-2011 нет возможности создавать новую карту в косой азимутальной равнопромежуточной проекции(допускается только создание азимутальных полярных проекций). По-видимому, данная возможность отсутствует и в ГИС Конструкторе. Или я ошибаюсь?
Если, всё же, существует возможность программно создавать выходную карту в косой азимутальной равнопромежуточной проекции (с тем, чтобы впоследствии выполнить перенос на неё объектов исходной карты), сообщите как это можно правильно сделать.
 
Карту Вы уже создавали в своих приложениях.
Коды типа проекции описаны в mapcreat.h.

Вы применяете проекцию:

LAMBERTOBLIQUEAZIMUTHAL     = 30, // Азимутальная (косая, нормальная, поперечная) равновеликая проекция Ламберта (зависит от положения полюса)

Она может быть косой, нормальной, поперечной, полярной.

Общие сведения о программном создании карты приведены в Руководстве программиста, 4.2.2 Создание новой карты и плана.

В ГИС Карта 2011 и ГИС Оператор есть выбор проекции Азимутальная равновеликая Ламберта - Lambert azimuthal equal-area projection,
(то, что у Вас называлось равнопромежуточной, код AZIMUTHALOBLIQUE - устаревший).
 
Спасибо.
Теперь открытым остается только вопрос относительно матрицы высот:
"Если открыта векторная карта и соответствующая ей матрица высот, то возможно ли программно выполнить вместе с трансформацией карты ещё и трансформацию матрицы?
Для этого тоже следует использовать функцию mapSetDocProjection () или в ГИС Конструкторе для этого предусмотрен иной механизм?"

Возможно, если идти по пути переноса объектов на новую карту, то удобнее будет не трансформировать старую матрицу, а просчитать её заново для новой карты?
Какую процедуру использовать для этого?

И какой из методов (трансформации или просчёта заново) наиболее предпочтителен для решения задачи получения матрицы высот для новой проекции?
 
Если матрица нужна для расчетов, то лучше построить заново.
Но можно и трансформировать средствами ГИС Карта 2011.
 
Какую процедуру из состава ГИС Конструктора следует использовать для построения матрицы высот?
Где можно посмотреть пример её использования?
 
Посмотрите mtrapi.h, функция mapBuildMtw.

Общие сведения о ее применении есть в Руководстве программиста, 6.3.3 Обработка матриц высот.

Средства построения матриц есть в ГИС Карта 2011.
 
Спасибо.
Поясните ещё, пожалуйста, вопрос относительно указания типа проекции для получения косой азимутальной равнопромежуточной проекции.

Вы пишите; "В ГИС Карта 2011 и ГИС Оператор есть выбор проекции Азимутальная равновеликая Ламберта - Lambert azimuthal equal-area projection,
(то, что у Вас называлось равнопромежуточной, код AZIMUTHALOBLIQUE - устаревший)."

В mapcreat.h содержится код:
 
AZIMUTHALOBLIQUE            = 7,  // Азимутальная равнопромежуточная косая
(то же, что и 30) // 25/01/11

LAMBERTOBLIQUEAZIMUTHAL     = 30, // Азимутальная (косая, нормальная, поперечная) равновеликая
проекция Ламберта (зависит от положения полюса)

Но, насколько мне известно, равнопромежуточная и равновеликая азимутальные проекции не совсем одно и тоже. Для равновеликой масштаб расстояний по мере удаления от полюса проекции уменьшается. Нам же требуется иметь истинные расстояния по направлению от полюса, что обеспечивается только в равнопромежуточной проекции.

Как так вышло, что в Конструкторе эти разные проекции имеют, по сути, одинаковые обозначения?
И как указать Конструктору, чтобы в данном конкретном случае при создании новой карты он построил именно равнопромежуточную проекцию?
 
В комментарии к типу проекции для номера 7 была ошибка.
Строится именно равновеликая проекция.
Для отображения карты в мелком масштабе нет особой разницы в таких нюансах.


В перечне проекций есть такая позиция:

POSTEL = 6,  // Азимутальная (нормальная) равнопромежуточная проекция Постеля

Но ее адаптировали только для северного полушария.
Страницы: 1 2 3 4 5 ... 7 След.
Читают тему (гостей: 1)



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

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