Карта мира с произвольным центральным меридианом в MapInfo: различия между версиями

Материал из GIS-Lab
Перейти к навигации Перейти к поиску
Строка 76: Строка 76:
|Ссылка = left
|Ссылка = left
|Выравнивание_заголовка = left
|Выравнивание_заголовка = left
|Заголовок = triangulate.c
|Заголовок = shiftxy.c
|Фон_заголовка = #ccccff
|Фон_заголовка = #ccccff
|Содержание =  
|Содержание =  

Версия от 07:42, 24 апреля 2014

Эта страница опубликована в основном списке статей сайта
по адресу http://gis-lab.info/qa/mapinfo-worldmap-custom-meridian.html


Статья представляет собой пошаговое руководство для пользователей MapInfo по подготовке карты мира для отображения в проекциях с меридианом, отличающимся от среднего меридиана имеющихся слоёв.

Введение

Опишем проблему парой картинок. Предположим, нужно отобразить стандартную карту мира в проекции Робинсона с центральным меридианом 150° з. д.

Так рисует карту MapInfo
Такую карту хотелось бы видеть

Очевидно, MapInfo, как многие другие ГИС, при отображении карты в какой-либо проекции не оборачивает отображаемые слои вокруг меридиана-антипода, который отстоит на 180° от центрального. Это позволяет создавать карты мира, разрезанные по произвольной линии, например, линии смены дат. Однако для пользователя свобода, как обычно, идёт рука об руку с дополнительными хлопотами. Если имеющаяся в наличии карта должна быть отображена в форме милой глазу симметричной фигуры в проекции, центральный меридиан которой отличается от среднего меридиана исходной карты, то картографу для этого придётся приложить некоторые усилия.

Данные

В качестве тестового материала используем карту мира GSHHG, которая распространяется под лицензией LGPL. Эта карта развивается как географическая основа открытого проекта GMT. GMT умеет оборачивать данные вокруг меридиана-антипода, поэтому слои карты в «родном» формате не содержат разрезанных объектов. Однако при экспорте слоёв в формат ESRI shapefiles полигоны под меридианом 180° разрезаются на восточную и западную часть, что даёт карту в стандартном диапазоне долгот ±180°. Для демонстрации возьмём из GSHHG несколько слоёв грубого (crude) разрешения.

Постановка задачи

Наша задача - отобразить карту в паре проекций с центральным меридианом 150° з. д. Для достижения этой цели создадим новые слои в диапазоне долгот от 330° з. д. до 30° в. д. Кроме того, дополним карту слоями сетки параллелей и меридианов grid15 и «океана» ocean.

Построение карты с помощью программы PacWorld

Утилита PacWorld от IAA Pty Ltd решает задачу преобразования карты из стандартного диапазона долгот в диапазон 0°–360°. Поскольку она доступна в кодах MapBasic, можно модифицировать её для работы с произвольным центральным меридианом.

Алгоритм работы начинается с создания полигона, одной из сторон которого является начальный меридиан. Объекты слоя разрезается этим полигоном. Затем объекты западного полушария модифицируются: каждый узел перемещается на 360° к востоку.

Недостатки PacWorld, помимо упомянутой жёсткой привязки к меридиану 180° в. д.:

  • разрезы материков на краю карты отображаются в проекциях несглаженными прямыми отрезками; — легко исправить, запрограммировав вставку промежуточных узлов в сторону полигона, образованную начальным меридианом;
  • некорректно трансформируется Антарктида; — можно обойти эту проблему через конвертирование полигона в полилинию и обратно с некоторым редактированием;
  • зависание при переносе объектов с большим количеством узлов; с картой GSHHG это происходит уже для слоя континентов со средним (intermediate) разрешением; похоже, дело в принципиальной ограниченности ресурсов, выделяемых программам MapBasic; — фатальный недостаток.

Главная проблема с зависанием связана не с процедурой разрезания. Зависание происходит в процессе перемещения узлов. Можно модифицировать PacWorld так, чтобы он только разрезал объекты, а перемещение осуществить другими средствами. Однако с методической точки зрения полезно поработать руками.

Построение карты вручную

Конструирование координатной сетки и «океана»

Построим слой параллелей и меридианов grid15 программой GridMaker, входящей в набор стандартных утилит MapInfo. Используем четыре линии по контуру для создания слоя «океана» ocean.

Диалог GridMaker: параметры введены
Слой grid15 создан
Выделим крайние линии
Скопируем в косметический слой
Объединим и превратим в полигон
Сохраним косметику в слой ocean

Разрезание слоя

Разрежем слой континентов и островов GSHHS_c_L1 на две половины полигоном слоя ocean. Часть, попадающую на полигон (и, следовательно, на будущую карту), сохраним как новый слой с прежним именем GSHHS_c_L1 в другую папку. Часть, не попадающую на полигон, экспортируем в файл формата MIF/MID под именем GSHHS_c_L1_1.MIF.

Откроем ocean и исходный слой островов GSHHS_c_L1
Выделим все объекты слоя островов
Перейдём в режим выбора изменяющих объектов
Укажем ocean в качестве изменяющего объекта
После команды [Erase Outside] сохраним объекты в новый слой GSHHS_c_L1; восстановим таблицу
Повторим действия с выделениями; после команды [Erase] экспортируем объекты в файл MIF

Перемещение половины слоя на 360°

Чтобы объекты из файла GSHHS_c_L1_1.MIF оказались на своих местах на будущей карте, их необходимо перенести на 360° к западу. К сожалению, перенести объекты ровно на заданное число градусов по долготе или широте в MapInfo практически невозможно. Мы слукавили, говоря о построении карты вручную от начала и до конца.

Приведём листинг программы, которая смещает объекты файла MIF/MID на заданные приращения координат ∆X и ∆Y:


Сохраним код в файл shiftxy.c. Исполняемый модуль можно создать, например, компилятором gcc:

$ gcc -o shiftxy shiftxy.c

Для MS Windows можно загрузить уже скомпилированную программу.

Утилита shiftxy запускается в командной строке с четырьмя аргументами: имя входного файла MIF, имя выходного файла MIF, сдвиг ∆X, сдвиг ∆Y. Переместим объекты GSHHS_c_L1_1.MIF на 360 координатных единиц слоя к западу и запишем в GSHHS_c_L1_2.MIF:

shiftxy GSHHS_c_L1_1.MIF GSHHS_c_L1_2.MIF -360 0

Создадим файл GSHHS_c_L1_2.MID из GSHHS_c_L1_2.MID копированием или переименованием:

copy GSHHS_c_L1_1.MID GSHHS_c_L1_2.MID

Теперь понятно, зачем мы экспортировали в MIF вместо сохранения в нормальный слой.

Воссоединение слоя

Импортируем новый MIF с передвинутыми объектами и сольём его с новым слоем GSHHS_c_L1:

Откроем новый слой GSHHS_c_L1
Импортируем GSHHS_c_L1_2.MIF в GSHHS_c_L1_2
Добавим записи и объекты GSHHS_c_L1_2 к GSHHS_c_L1
Слой GSHHS_c_L1 со средним меридианом 150° з. д. готов

Отображение карты в проекциях

Повторим описанные действия с несколькими слоями GSHHG, содержащими водоёмы, реки и сухопутные границы, чтобы получить в результате готовую карту.

Карта из преобразованных слоёв

Добавим в файл MAPINFOW.PRJ описание проекций Мольвейде и Робинсона с центральным меридианом 150° з. д.:

"Mollweide (Equal-Area) 150W WGS84", 13, 104, 7, -150
"Robinson 150W WGS84", 12, 104, 7, -150

Отобразим полученные слои в заданных проекциях:

Карта в проекции Робинсона
Карта в проекции Мольвейде

Заключение

Предложенная последовательность действий позволяет получить набор слоёв со средним меридианом, совпадающим с центральным меридианом проекции. Можно усложнить задачу, заменив меридиан сворачивания более сложной линией.

Если подобные задачи возникают часто и связаны с данными больших объёмов, имеет смысл автоматизировать процесс, скажем, написав программу на языке C++ с MapInfo API.

Ссылки