23.03.2017 Настройка WMS-сервиса на платформе MapServer

Что такое WMS?

Согласно определению в википедии, WMS (Web Map Service, служба веб-картографии) - стандартный протокол для обслуживания через Интернет географически привязанных изображений, генерируемых картографическим сервером на основе данных из БД ГИС. WMS позволяет использовать данные из нескольких различных серверов и предоставляет возможность создания сети картографических серверов, из которых клиенты могут составлять свои кастомизированные (настроенные под свои потребности) карты. Следующая документация базируется на реализации WMS спецификации версии 1.1.1. Для реализации службы WMS необходим MapServer версии 3.5 и выше. На данный момент MapServer поддерживает следующие версии WMS: 1.0.0, 1.0.7, 1.1.0 (также известную как 1.0.8), 1.1.1 и 1.3.0. Если сказать проще, то в ответ на определенный http-запрос клиенту возвращается изображение карты с геопривязкой.

Данная статья предполагает, что читатель уже знаком с некоторыми аспектами настройки MapServer:

  • Настройка MapServer с помощью map-файлов.
  • Знакомство со спецификацией WMS также будет полезно. Хотя с основами WMS читатель ознакомится по ходу статьи.

О настройке MapServer есть ряд статей в разделе MapServer - практика.

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

  • GetCapabilities - возвращает XML документ с метаданными содержимого WMS.
  • GetMap - возвращает изображение карты согласно запросу пользователя.

Поддержка следующих типов запросов является необязательной:

  • GetFeatureInfo - возвращает информацию об объекте (объектах) по запрошенному местоположению (клик мыши). MapServer поддерживает три типа ответов для данного запроса:
    • text/plain ответ с атрибутивной информацией.
    • text/html ответ с применением шаблонов запросов, определяемых в параметре TEMPLATE объекта CLASS (имя файла должно иметь расширение .html). MIME-тип, возвращаемый шаблонами классов, установлен в text/html и может быть изменен используя метаданные "wms_feature_info_mime_type".
    • application/vnd.ogc.gm, GML.1 или GML для GML объектов.
  • DescribeLayer - возвращает XML описание для одного или более слоев.
  • GetLegendGraphic - возвращает изображение легенды для запрошенного слоя, с подписями.

Что касается MapServer, то это CGI программа "mapserv", которая знает, как обрабатывать WMS запросы. Таким образом, настройка WMS сервера с помощью MapServer включает в себя установку CGI программы "mapserv" и настройку map-файла с необходимыми метаданными. Об этом пойдет речь в оставшейся части статьи.

Проверка поддержки WMS

WMS запросы обрабатываются CGI программой "mapserv". Не все версии этой программы поддерживают WMS (поддержка включена по умолчанию, если вы компилируете вместе с библиотекой PROJ). Таким образом, первым шагом будет проверка, поддерживается ли WMS. Одним из способов проверки - использование параметра командной строки "-v" и поиск в выводе строки "SUPPORTS=WMS_SERVER".

D:\ms4w\Apache\cgi-bin>mapserv.exe -v 
MapServer version 7.0.1 (MS4W 3.1.4) OUTPUT=PNG OUTPUT=JPEG OUTPUT=KML SUPPORTS=PROJ SUPPORTS=AGG SUPPORTS=FREETYPE SUPPORTS=CAIRO SUPPORTS=ICONV SUPPORTS=FRIBIDI SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER SUPPORTS=SOS_SERVER SUPPORTS=FASTCGI SUPPORTS=THREADS SUPPORTS=GEOS INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE

Настройка map-файла для поддержки WMS

Каждый экземпляр WMS сервера содержит свой собственный map-файл. Это обычный map-файл, в котором присутствуют некоторые обязательные параметры и метаданные. Большая часть метаданных необходима для настройки правильных выходных данных для запроса GetCapabilities.

Вот список параметров и метаданных, которые необязательно указывать при настройке MapServer, но требуются (или крайне рекомендуется) для настройки WMS:

В объекте MAP:

  • NAME
  • PROJECTION
  • METADATA (в объекте WEB)
    • wms_title
    • wms_onlineresource
    • wms_srs (если объект PROJECTION не определен с использованием "init = epsg: ...")
    • wms_enable_request

Для каждого слоя:

  • NAME
  • PROJECTION
  • METADATA
    • wms_title
    • wms_srs (опционально, если слой наследует значение SRS объекта MAP)
  • STATUS
    • Слои со статусом DEFAULT всегда будут отправлены клиенту.
    • Слои со статусом ON или OFF могут быть запрошены клиентом.
  • TEMPLATE (требуются для запросов GetFeatureInfo - см. Templating)

Давайте рассмотрим эти параметры подробнее.

  • NAME объекта MAP и wms_title

    Для настройки WMS-сервиса необходимо указать параметр NAME и wms_title для каждого слоя. Параметр NAME и метаданные wms_title объекта MAP будут использоваться для задания имени и заголовка корневого слоя в XML-ответе запроса GetCapabilities. Корневой слой в WMS-контексте соответствует всему map-файлу.

  • NAME объекта LAYER и метаданные wms_title

    Каждому отдельному слою необходимо задать собственное уникальное имя и заголовок. Названия слоев также используются в запросах GetMap и GetFeatureInfo для ссылки на слои, которые должны быть включены в отрисовку карты и в запрос. Названия слоев должны начинаться с буквы при настройке WMS сервера (названия слоев не должны начинаться с цифры или содержать пробелы).

  • Объект PROJECTION уровня объекта MAP и метаданные wms_srs

    WMS сервера должны предоставлять информацию о проекции, в которой они могут отдавать геоданные используя EPSG коды проекций. Последние версии библиотеки PROJ4 содержат таблицу EPSG кодов и позволяют пользователям определять проекции следующим образом:

    PROJECTION
       "init=epsg:4269"
    END

    Обратите внимание, что "epsg" необходимо указывать в нижнем регистре в случае использования в директиве "init" библиотеки PROJ4.

    Если блок PROJECTION объекта MAP указан в формате "init=epsg:xxxx", то тогда MapServer будет использовать эту информацию для создания тега <BoundingBox> для верхнего слоя в документе, описывающем возможности WMS. BoundingBox - обязательный элемент для описания возможностей WMS версии 1.3.0 (для WMS версии 1.1.0 он опционален, но считается хорошим тоном позволить MapServer включить его, когда это возможно).

    Вышеперечисленного достаточно для того, чтобы MapServer распознал EPSG-код и включил его в тег SRS в документ, описывающий возможности (в этом случае метаданные wms_srs можно не указывать). Однако, часто нет возможности определить EPSG код, который соответствует проекции ваших пространственных данных. В этом случае метаданные "wms_srs" используются для перечисления одного или более EPSG кодов, в которых геоданные могут быть предоставлены и объект PROJECTION содержит действительное PROJ4 определение проекции данных.

    Вот пример WMS сервера, который предоставляет данные в равноугольной конической проекции Ламберта (42304). WMS может предоставлять данные в проекциях EPSG:4269 и EPSG:4326 (широта/долгота), но объект PROJECTION указывает на настоящую проекцию пространственных данных:

    NAME "DEMO"
    ...
    
    WEB
      ...
      METADATA
        "wms_title"           "WMS Demo Server"
        "wms_onlineresource"  "http://my.host.com/cgi-bin/mapserv?map=wms.map&"
        "wms_srs"             "EPSG:4269 EPSG:4326"
      END
    END
    
    PROJECTION
      "init=epsg:42304"
    END
    ...
    END

    В дополнение к проекциям типа EPSG:xxxx, WMS сервер может объявлять проекции пространства имен AUTO:xxxx. Проекции AUTO с 42001 по 42005 нативно поддерживаются MapServer. Однако, проекции AUTO полезны только в сочетании с умными WMS-клиентами, поскольку клиенты должны определить параметры проекции в WMS-запросах к серверу. Для более подробной информации см. Приложение E спецификации WMS 1.1.1 и раздел 6.5.5.2 этого же документа. См. также FAQ по проекциям AUTO в конце этого документа.

  • Объект PROJECTION уровня объекта LAYER и метаданные wms_srs

    По умолчанию слои наследуют SRS от их родительского слоя (PROJECTION уровня объекта MAP в случае c MapServer). Поэтому необязательно (но все еще крайне рекомендуется) указывать объект PROJECTION и wms_srs для каждого слоя. Если объект PROJECTION уровня слоя не указан, то предполагается использование проекции карты.

    Объект PROJECTION уровня объекта LAYER и метаданные wms_srs определяются точно также, как и объект PROJECTION и wms_srs объекта MAP.

    Для векторных слоев, если объект PROJECTION указан в формате "init=epsg:xxxx", то MapServer будет использовать эту информацию для создания тега <BoundingBox> для этого слоя в документе, описывающим возможности WMS. BoundingBox - обязательный элемент для WMS 1.3.0 (для WMS 1.1.0 он опционален, но считается хорошим тоном позволить MapServer включить его, когда это возможно).

  • Метаданные "wms_onlineresource"

    Метаданные "wms_onlineresource" указываются в объекте WEB уровня объекта MAP и определяют URL, который должен использоваться для доступа к вашему серверу. Это необходимо для запросов GetCapabilities. Если wms_onlineresource не указан, то MapServer попытается создать значение по умолчанию, используя имя скрипта и хоста, но на это вам не следует слишком полагаться. Крайне рекомендуется указывать значение метаданных .

    См. раздел 6.2.2 спецификации WMS 1.1.1 для полного описания ресурса URL. Главное, что нужно указать - это полный HTTP URL, включая префикс протокола (http://), имя хоста, имя скрипта, возможно параметр "map=", и заканчивая URL символом "?" или "&". Ниже пример правильного URL:

    http://my.host.com/cgi-bin/mapserv?map=mywms.map&

    Создав скрипт-обертку на сервере, возможно скрыть параметр "map=" из URL, и тогда ваш URL может выглядеть примерно таким образом:

    http://my.host.com/cgi-bin/mywms?
  • Метаданные "wms_enable_request"

    Определяет, какие запросы разрешены. Если не указано, то не разрешены никакие запросы!

  • Настройка запросов GetFeatureInfo

    Вы должны задать параметр TEMPLATE для слоя, чтобы возможно было выполнить запрос методом GetFeatureInfo. Для запросов типа "text/html" необходимо также для слоя задать параметры HEADER и FOOTER.

    Для MapServer 4.6 необходимо задать метаданные gml_* для атрибутов слоя.

Практический пример настройки WMS.

Используя пример из предыдущей статьи Подключаем MapServer к MS SQL, настроим наш WMS сервер. За основу я возьму map-файл следующего содержания:

MAP
    NAME "sample"
    EXTENT -180 -90 180 90 # Geographic
    SIZE 800 400
    IMAGECOLOR 220 221 239
  
    LAYER
      NAME "world_poly"
      TYPE POLYGON
      STATUS ON
      ####
      CONNECTIONTYPE OGR
      CONNECTION "MSSQL:server=.\SQLEXPRESS;trusted_connection=yes;database=MySpatialDb;tables=tm_world_borders_simpl(ogr_geometry)"
      ####
      PROJECTION
        "init=epsg:4326"
      END
      CLASS
        NAME "The World"
        STYLE
          COLOR 240 240 240
          OUTLINECOLOR 100 100 100
        END
      END
      PROCESSING 'CLOSE_CONNECTION=DEFER'
    END # layer  
  
END # MAP

Чтобы добавить поддержку WMS изменим данный map-файл, как показано ниже и сохраним его под именем wms.map в директории, где хранятся все наши map-файлы: ms4w\Apache\htdocs\mydemo.

MAP

    NAME "WMS"
    IMAGETYPE PNG
    EXTENT -180 -90 180 90 # Geographic
    SIZE 800 400
    IMAGECOLOR 220 221 239  
  
    WEB
      METADATA
        wms_title                  "WMS Demo"
        wms_abstract               "Demo WMS Server"
        wms_onlineresource         "http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/wms.map&"
        wms_srs                    "EPSG:4326"
        wms_getfeatureinfo         "http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/wms.map&"
        wms_featureinfoformat      "text/plain"
        wms_enable_request 			"*"
      END
    END 

    PROJECTION
      "init=epsg:4326"
    END 

    LAYER
      NAME "world_poly"
      TYPE POLYGON
      STATUS ON
      ####
      CONNECTIONTYPE OGR
      CONNECTION "MSSQL:server=.\SQLEXPRESS;trusted_connection=yes;database=MySpatialDb;tables=tm_world_borders_simpl(ogr_geometry)"
      ####
      PROJECTION
        "init=epsg:4326"
      END
      CLASS
        NAME "The World"
        STYLE
          COLOR 240 240 240
          OUTLINECOLOR 100 100 100
        END
      END
      PROCESSING 'CLOSE_CONNECTION=DEFER'
	
      METADATA
        wms_title "World Map"
        wms_abstract "World Map Countries"
        wms_srs "EPSG:4326"
        wms_include_items "all"
        wms_enable_request "*"
        #wms_extent "-180 -90 180 90"
      END	
	
  END # layer 
  
END

Среди метаданных объектов MAP и LAYER добавился ряд новых:

  • wms_abstract - опциональный, содержит строку описания WMS сервиса.
  • wms_include_items - опциональный, разделенный запятыми список значений для включения или ключевое слово "all".
  • wms_extent - опциональный, используется для тега BoundingBox слоя в случаях, где невозможно (или неэффективно) для MapServer исследовать источник данных на предмет его экстентов. Значение этих метаданных указывается в виде "minx miny maxx maxy", разделяется пробелами. Значения указываются в единицах проекции слоя. Если параметр wms_extent указан, то он имеет более высокий приоритет и MapServer не будет пытаться прочитать экстенты источника данных. Для растров MapServer может использовать этот параметр для регистрации изображения. Если файл с расширением .wld не найден, MapServer просматривает метаданные wms_extent и использует экстенты и размеры изображения для георегистрации.

Теперь проверим на WMS сервер, перейдя браузером по адресу: http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/wms.map&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities. Этот запрос должен вернуть документ с MIME-типом application/vnd.ogc.wms_xml, поэтому ваш браузер, вероятно, предложит вам сохранить файл. Сохраните его и откройте в любом текстовом редакторе (например, Notepad), и вы увидите документ XML, полученный от WMS сервера.

Если все в порядке, вы должны получить полный XML с возможностями WMS. Поищите в нем слово "WARNING". MapServer вставляет XML комментарии, начинающиеся с "<!–WARNING: ", если он находит пропущенные параметры map-файла или значения метаданных. Если вы обнаружите любое предупреждение, то вам необходимо его устранить, прежде чем WMS-клиенты начнут выполнять запросы. В противном случае, скорей всего, что-то пойдет не так.

Чтобы увидеть пример предупреждения, закомментируйте в нашем map-файле строку # wms_title "World Map". Тогда вы получите следующее предупреждение:

<!-- WARNING: Mandatory metadata '..._title' was missing in this context. -->

На следующем шаге получим изображение карты. Выполним такой запрос такой в браузере:

http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/wms.map&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=world_poly&STYLES=&SRS=EPSG:4326&BBOX=-180,-90,180,90&WIDTH=800&HEIGHT=400&FORMAT=image/png

В параметрах мы указали:

  • тип службы - SERVICE=WMS
  • версию - VERSION=1.1.1
  • запрос - REQUEST=GetMap
  • слой для отрисовки - LAYERS=world_poly
  • нужную проекцию - SRS=EPSG:4326
  • экстент для отрисовки - BBOX=-180,-90,180,90
  • ширину и высоту изображения - WIDTH=800&HEIGHT=400
  • формат изображения - FORMAT=image/png

В результате мы получили уже знакомое нам изображение (если вы знакомы с предыдущими статьями по теме ГИС и MapServer в частности):

Изображение, полученное от службы WMS MapServer
Изображение, полученное от службы WMS MapServer

Тестирование нашей WMS-службы в настольной ГИС

В качестве настольной ГИС я буду использовать свободное ПО Quantum GIS (QGIS). На момент написания статьи последней версией была 2.18.4, которую я и скачал под ОС Windows. Вы можете загрузить эту программу с официального сайта qgis.org.

После установки и запуска нажмите Cntrl+Shift+W (или в главном меню: "Слой - Добавить слой - Добавить слой WMS/WMTS"). После того как появится окно для добавления службы WMS/WMTS, нажмите кнопку "Создать" и в новом модальном окне укажите произвольное название, описывающую службу, а в поле "Адрес" скопируйте значение из параметра wms_onlineresource, т.е. укажите наш URL: http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/wms.map&

Добавление службы WMS в QGIS
Добавление службы WMS в QGIS

Жмем "OK", выбираем слой, затем нажимаем кнопку "Подключиться". Выбираем слой, как показано на изображении ниже и жмем "Добавить" и закрываем окно.

Подключение к службе WMS в QGIS
Подключение к службе WMS в QGIS

Если все прошло успешно, то уже можно работать с этим слоем в программе. Выглядеть это должно как на рисунке ниже:

Работа со службой WMS в QGIS
Работа со службой WMS в QGIS

Предыдущие статьи по теме разработки веб-ГИС и настройки MapServer: