14.03.2017 Изучаем и экспериментируем с MapServer

Всупление

Данная статья является логическим продолжением цикла статей, посвященных настройке MapServer: Установка и начальная настройка MapServer и Подключаем MapServer к MS SQL. Поэтому подразумевается, что читатель уже знает, что такое MapServer, как его установить и как настроить для простой отрисовки слоя из shape-файла и из БД MS SQL. Если вы не знакомы с данным материалом, то можете прочесть вышеуказанные статьи. А сейчас - в путь!

Выделяем классы в векторном слое с помощью логических условий

На данном моменте повествования я предполагаю, что в вашем экземпляре MS SQL Server уже существует БД MySpatialDb, которая содержит таблицу tm_world_borders_simpl с пространственными данными границ стран мира. О том, как создать подобную таблицу рассказано в предыдущей статье. Эта таблица хранит полигоны стран как тип geometry.

Теперь, когда все геоданные у нас подготовлены, давайте выделим каким-либо цветом те страны Африки, которые имеют площадь более 100 000 каких-то единиц ) Информация о площади хранится у нас в поле area. Далее, необходимо обозначить штриховкой те страны Африки, которые имеют население более 20 000 000 человек. Эту информацию содержит поле pop2005. А информация о принадлежности страны к материку содержится в поле region. Разобравшись с атрибутивной информацией мы можем приступать к настройке нашего map-файла. На этот раз назовем его afr.map и также сохраним его в той же директории, где хранятся у нас и предыдущие map-файлы, т.е. это ms4w\Apache\htdocs\mydemo. Содержимое afr.map представлено ниже:

MAP
    NAME "sample"
    EXTENT 10 -37 18 40 # Geographic
    SIZE 800 400
    IMAGECOLOR 220 221 239
    SYMBOLSET "./symbols/symbols.txt"
  
    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 "PopArea"
        EXPRESSION ([pop2005] > 20000000 AND [area] > 100000 AND [region] = 2) 
        STYLE
          COLOR 120 120 255
          OUTLINECOLOR 100 100 100
        END				
        STYLE
          SYMBOL "hatchsymbol"
          COLOR 0 0 0
          SIZE 4
          ANGLE 45
        END # STYLE
      END	

      CLASS
        NAME "Pop"
        EXPRESSION ([pop2005] > 20000000 AND [region] = 2) 
        STYLE
          OUTLINECOLOR 100 100 100
        END			
        STYLE
          SYMBOL "hatchsymbol"
          COLOR 0 0 0
          SIZE 4
          ANGLE 45
        END # STYLE
      END		  
	  
      CLASS
        NAME "Area"
        EXPRESSION ([area] > 100000 AND [region] = 2) 
        STYLE
          COLOR  120 120 255
          OUTLINECOLOR 100 100 100		
        END		
      END	  
	  
      CLASS
        NAME "The World"
        STYLE
          COLOR 240 240 240
          OUTLINECOLOR 100 100 100
        END		
      END	 	  
	  
      PROCESSING 'CLOSE_CONNECTION=DEFER'
    END # layer  	
  
END # MAP

За основу был взят наш файл mssql.map из прошлой статьи. Рассмотрим изменения, которые здесь произошли. Во первых, мы изменили наш экстент таким образом, чтобы выходное изображение содержало в основном Африканский континент. А во-вторых, появился ряд новых параметров о которых подробнее будет рассказано чуть позже. Пока обратим внимание на только на параметр SYMBOLSET, который содержит путь к некоторому файлу symbols.txt. Забегая вперед, скажу, что параметр SYMBOLSET задает путь к файлу, который содержит определения набора символов, и которые будут использоваться различными объектами map-файла. Сейчас создадим файл symbols.txt в директории ms4w\Apache\htdocs\mydemo\symbols и поместим в него вот такое содержимое:

SYMBOLSET

	SYMBOL
	  NAME 'circle'
	  TYPE ELLIPSE
	  POINTS 1 1 END
	  FILLED TRUE
	END 

	SYMBOL
	  NAME 'hatchsymbol'
	  TYPE hatch
	END

END

Файл набора символов начинается с объекта SYMBOLSET и содержит обычные определения символов, о которых упоминалось в прошлой статье Подключаем MapServer к MS SQL. Поэтому определение символа с именем circle вам уже знакомо. По факту, мы перенесли определение символа из MAP-объекта в отдельный файл. Получилось что-то вроде директивы include в C/С++. Второй символ с именем hatchsymbol имеет тип "штриховка" и используется нами в файле afr.map.

Теперь рассмотрим новые параметры, которые встретились в файле afr.map:

  • SYMBOLSET - путь к файлу с набором символов. Путь может быть абсолютный или относительный, который определяется относительно map-файла.
  • EXPRESSION - Выражение, которое определяет класс. Допускается использовать 4 типа выражений: строковые сравнения, регулярные выражения, логические выражения и строковые функции. Если никакое выражение не задано, то считается, что все объекты принадлежат этому классу.
    • Строковые выражения являются регистрозависимыми и вычисляются быстрей всего. Нет необходимости использовать какие-либо специальные разделители, хотя строки должны заключаться в кавычки, если они содержат спецсимволы. (Хорошей практикой считается заключать в кавычки любые строки). Атрибут, который используется для сравнения определяется параметром CLASSITEM в объекте LAYER.
    • Регулярные выражения заключаются в символы слеша (/regex/). Атрибут, который используется для сравнения определяется параметром CLASSITEM в объекте LAYER.
    • Логические условия позволяют составлять достаточно сложные условия, которые включают в себя один или более атрибутов. Логические выражения разделяются круглыми скобками ("expression"). Названия атрибутов заключаются в квадратные скобки "[ATTRIBUTE]". Названия атрибутов чувствительны к регистру символов и должны соответствовать названиям в shape-файле. Поддерживаются следующие операторы: =, >, <, <=, >=, =, or, and, lt, gt, ge, le, eq, ne, in, ~, ~*. Обработка логических условий происходит медленнее.
    • Существует одна строковая функция: length(). Она подсчитывает длину строки. Пример: EXPRESSION (length('[NAME_E]') < 8)

В нашем случае определяется 3 логических условия. Причем условия должны располагаться от частных к общим случаям. Т.е. первым должно быть самое строгое условие, а последним - самое общее. У нас самым строгим является условие отбора стран с населением более 20 000 000 и территорией более 100 000 и регионом равным 2, что соответствует Африке. А самым общим - вообще отсутствие параметра EXPRESSION, т.е. любой полигон в слое. В самом первом классе определяется два стиля. Первый стиль соответствует сплошной заливке, а второй задает штриховку черным цветом под 45 градусов, как указано в параметре ANGLE. Параметр SIZE определяет расстояние между линиями штриховки. Чем больше значение - тем больше расстояние. Очевидно, что, если условия не "конфликтуют" между собой, то порядок определения классов не имеет значения. Подобную технику составления логических выражений можно, конечно же, применить и к пространственным данным, хранящимся в shape-файлах.

Теперь в браузере в адресной строке сформируем url http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/afr.map&layer=world_poly&mode=map и перейдем по нему. В результате мы получим такое изображение:

Результат примера использования логических выражений в определении классов
Результат примера использования логических выражений в определении классов

Выделяем классы в векторном слое с помощью сравнения и задаем подписи

В этом разделе мы рассмотрим применение параметра CLASSITEM для выделения классов с помощью строк сравнения и параметра LABEL для нанесения подписей на карту. Создадим новый файл lbl.map в уже знакомой директории ms4w\Apache\htdocs\mydemo. Содержимое этого файла выглядит следующим образом:

MAP
    NAME "sample"
    EXTENT -180 -90 180 90 # Geographic
    SIZE 800 400
    IMAGECOLOR 220 221 239
    SHAPEPATH "./shp"
    FONTSET "./fonts/fonts.txt"
    SYMBOLSET "./symbols/symbols.txt"
  
    LAYER
      NAME "world_poly"
      TYPE POLYGON
      STATUS ON
      CLASSITEM    "iso3" 
      LABELITEM    "Name"
                              
      ####
      DATA 'TM_WORLD_BORDERS_SIMPL-0.3.shp'
      ####
      PROJECTION
        "init=epsg:4326"
      END	 

      CLASS
        NAME "Russia"
        EXPRESSION 'RUS'
        STYLE
          COLOR 153 204 255
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR  150 150 150
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 14
          ANGLE 0
          PARTIALS FALSE
        END
      END	 

      CLASS
        NAME "Brazil"
        EXPRESSION 'BRA'
        STYLE
          COLOR 255 204 255
          OUTLINECOLOR 100 100 100
        END	
        LABEL
          COLOR  51 51 0
          OUTLINECOLOR 255 255 255
          FONT "arial"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END			
      END	

      CLASS
        NAME "USA"
        EXPRESSION 'USA'
        STYLE
          COLOR 255 204 0
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR "#333300"
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END					
      END	   
	  
      CLASS
        NAME "The World"
        STYLE
          COLOR 240 240 240
          OUTLINECOLOR 100 100 100
        END		
      END	 	  
	  
    END # layer

END # MAP

В данном слое вместо подключения к MS SQL Server я использовал геоданные из файла TM_WORLD_BORDERS_SIMPL-0.3.shp в основном для того, чтобы продемонстрировать назначение параметра SHAPEPATH. Описание новых параметров MAP-объекта:

  • SHAPEPATH - Путь к директории, содержащей shape-файлы или тайлы. Могут быть и другие поддиректории ниже SHAPEPATH. Поэтому в параметре DATA объекта LAYER теперь нужно просто указать имя файла: TM_WORLD_BORDERS_SIMPL-0.3.shp
  • FONTSET - Путь к файлу с набором шрифтов, которые будут использованы из map-файла. Путь может быть относительным (относительно map-файла) или абсолютным.

В нашем случае указан путь к файлу ./fonts/fonts.txt. Создадим директорию ms4w\Apache\htdocs\mydemo\fonts и там создадим файл fonts.txt со следующим содержимым:

sans		micross.ttf
arial		arial.ttf

Также в директорию ms4w\Apache\htdocs\mydemo\fonts я скопировал 2 файла шрифтов (из системной директории Fonts): arial.ttf и micross.ttf. Очевидно, что файл устанавливает соответствие между файлом шрифта и названием, которое будет использовано далее в map-файле.

Приведу описание новых параметров, которые появились в объекте LAYER:

  • CLASSITEM - Название поля атрибутивных данных, которое будут использоваться для поиска классов.
  • LABELITEM - Название поля атрибутивных данных, которое будут использоваться для создания аннотаций (подписей).

В нашем случае в качестве CLASSITEM использовано поле iso3, которое содержит коды стран, состоящие из трех символов, а в качестве LABELITEM - поле Name, содержащее полное название страны. В параметрах EXPRESSION объектов CLASS я выделил три страны по их коду: - Россия, Америка и Бразилия. В самом конце определен класс, который не использует выражение сравнения и отображает все страны цветом RGB(240,240,240). Как уже упоминалось ранее, самый общий случай должен располагаться в конце всех определений классов.

Теперь рассмотрим механизм создания аннотаций (подписей). Параметр LABELITEM определяет поле, значения которого будут использованы для нанесения подписей. Я использую поле Name - название страны. Для тонкой настройки подписи в объекте CLASS добавлен новый объект LABEL, который в нашем случае содержит такие параметры:

  • COLOR - цвет метки, можно указывать как rgb компоненты, так и строку, содержащую шестнадцатеричное представление цвета. Возможно также указывать прозрачность, добавив 4 компонент, например: COLOR "#FF00FFCC". В квадратных скобках можно также указать название поля из атрибутов, которое содержит информацию о цвете. Например: COLOR [MYCOLOR].
  • OUTLINECOLOR - цвет контура. Значения задаются также, как и у параметра COLOR.
  • FONT - Алиас шрифта (определенный в файле параметра FONTSET), который будет использоваться для подписи. Можно указать поле атрибутивной информации, которое содержит алиас шрифта.
  • TYPE - Тип шрифта - bitmap или truetype. Обычно bitmap-шрифты отрисовываются быстрее, однако, truetype-шрифты масштабируемы и существует достаточно их много типов. Убедитесь, что вы указали параметр FONT, если выбрали тип TrueType.
  • SIZE - Размер шрифта. Используйте числовое значение, чтобы указать размер шрифта в пикселах, если используется шрифт типа TrueType. Если же используются bitmap-шрифты (растровые), то можно указать одно из следующих значений в качестве параметра: tiny|small|medium|large|giant. Если значение параметра хранится в атрибутивных данных, то можно указать название этого поля, при этом его необходимо заключать в квадратные скобки, например: SIZE [MYSIZE].
  • ANGLE - double, угол поворота подписи против часовой стрелки. Возможно значение AUTO, которое позволяет MapServer вычислить значение самостоятельно. Возможно установить только для слоев типа LINE. Также возможно значение AUTO2, за исключением того, что не предпринимаются попытки вывести текст в читабельной ориентации (т.е. текст может быть выведен перевернутым). Полезно, когда положение текста указывает направление линии.
  • PARTIALS - Может ли текст убегать за край карты. По умолчанию - true.

Перейдем в браузере по следующему url: http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/lbl.map&layer=world_poly&mode=map. MapServer согласно нашим настройкам отрисовал такое изображение:

Результат примера создания подписей и классов в MapServer
Результат примера создания подписей и классов в MapServer

Отображение растровых данных

Используемое мной в примере растровое изображение можно загрузить здесь. Создадим директорию ms4w\Apache\htdocs\mydemo\rasters и распакуем туда содержимое архива таким образом, чтобы файл NE2_LR_LC.tif был доступен по пути ms4w\Apache\htdocs\mydemo\rasters\NE2_LR_LC.tif. Теперь в конец файла lbl.map добавим еще один слой - растровый. Обновленное содержимое этого файла должно иметь вид:

MAP
    NAME "sample"
    EXTENT -180 -90 180 90 # Geographic
    SIZE 800 400
    IMAGECOLOR 220 221 239
    SHAPEPATH "./shp"
    FONTSET "./fonts/fonts.txt"
    SYMBOLSET "./symbols/symbols.txt"
  
    LAYER
      NAME "world_poly"
      TYPE POLYGON
      STATUS ON
      CLASSITEM    "iso3" 
      LABELITEM    "Name"
                              
      ####
      DATA 'TM_WORLD_BORDERS_SIMPL-0.3.shp'
      ####
      PROJECTION
        "init=epsg:4326"
      END	 

      CLASS
        NAME "Russia"
        EXPRESSION 'RUS'
        STYLE
          COLOR 153 204 255
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR  150 150 150
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 14
          ANGLE 0
          PARTIALS FALSE
        END
      END	 

      CLASS
        NAME "Brazil"
        EXPRESSION 'BRA'
        STYLE
          COLOR 255 204 255
          OUTLINECOLOR 100 100 100
        END	
        LABEL
          COLOR  51 51 0
          OUTLINECOLOR 255 255 255
          FONT "arial"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END			
      END	

      CLASS
        NAME "USA"
        EXPRESSION 'USA'
        STYLE
          COLOR 255 204 0
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR "#333300"
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END					
      END	   
	  
      CLASS
        NAME "The World"
        STYLE
          COLOR 240 240 240
          OUTLINECOLOR 100 100 100
        END		
      END	 	  
	  
    END # layer

    LAYER
      NAME "raster"
      TYPE RASTER
      STATUS ON	  
      COMPOSITE
        OPACITY 50
      END
      DATA "../rasters/NE2_LR_LC.tif"
      #PROCESSING "BANDS=1"
      OFFSITE 255 255 255
    END # layer

END # MAP

Параметр TYPE имеет значение RASTER, т.к. мы определяем растровый слой. Параметр DATA задает путь к растру. Путь указывается относительно директории, заданной в параметре SHAPEPATH. Рассмотрим новые параметры:

  • COMPOSITE - новый объект, содержащий параметр OPACITY, значение которого определяет прозрачность слоя. 100 - непрозрачный, 0 - полностью прозрачный.
  • PROCESSING - Передает обрабатывающую директиву, применяемую к слою. Поддерживаемые обрабатывающие директивы зависят от типа слоя и драйвера, который обрабатывает их. Директива BANDS позволяет указать определенный канал или каналы, которые необходимо выделить из растрового файла. Если выбран только один канал, то он интерпретируется как оттенки серого. Если три - как цвета RGB, если 4 - как цвета RGB и альфа-канал (прозрачность).
  • OFFSITE - Устанавливает цветовой индекс, который будет считаться прозрачным для растровых слоев. Значение RGB или шестнадцатиричная строка. Например: OFFSITE "#FFFFFF".

Перейдем в браузере по url: http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/lbl.map&layer=world_poly&layer=raster&mode=map. Обратите внимание в строку запроса добавился новый слой с именем raster. Это имя было указано в параметре NAME нашего растрового слоя.

Отображение растрового слоя в MapServer
Отображение растрового слоя в MapServer

Поэкспериментируем с директивой BANDS. Укажем параметр PROCESSING следующим образом: PROCESSING "BANDS=1", т.е. просто раскомментируем в нашем файле эту строку. В результате получим растровое изображение, состоящее из оттенков серого.

Отображение растрового слоя в виде оттенков серого в MapServer
Отображение растрового слоя в виде оттенков серого в MapServer

Работа с проекциями в MapServer

Существуют тысячи географических систем координат. Чтобы совмещать наборы пространственных данных с различными географическими системами координат в пределах одной карты эти наборы геоданных должны быть преобразованы (спроецированы) в выбранную для карты систему координат. Ранее была опубликована статья по введению в системы координат в картографии.

Чтобы задать проекцию необходимо определить один объект PROJECTION для выходного изображения (в объекте MAP) и один объект PROJECTION для каждого слоя (в объектах LAYER). MapServer использует библиотеку PROJ.4 для перепроецирования. Поэтому объекты PROJECTION состоят из серии ключевых слов библиотеки PROJ.4, которые непосредственно определяются внутри объекта или ссылаются на EPSG-файл. EPSG-файл - это справочный файл, содержащий параметры проекции и являющийся частью библиотеки PROJ.4.

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

Определение встроенных параметров проекции:

PROJECTION
  "proj=utm"
  "ellps=GRS80"
  "datum=NAD83"
  "zone=15"
  "units=m"
  "north"
  "no_defs"
END

Использование EPSG проекции:

PROJECTION
   "init=epsg:26915"
END

Эта запись ссылается на справочный файл EPSG, который содержит код "26915" со всеми параметрами проекции. Строка "epsg" в этом примере может быть чувствительна к регистру, т.к. ссылается на имя файла. Если файловая система является чувствительной к регистру, то эта срока должна быть указана в нижнем регистре, в противном случае MapServer (в действительности библиотека PROJ.4) сообщит о невозможности найти этот файл.

Следующие два примера как возможно определить неспроецированную широту/долоту.

Определение встроенных параметров:

PROJECTION
  "proj=latlong"
  "ellps=WGS84"
  "datum=WGS84"
END

Использование EPSG нотации:

PROJECTION
   "init=epsg:4326"
END

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

PROJECTION
   AUTO
END
  • В случае OGR-подключения проекция информация о проекции будет получена из OGR-слоя.
  • В случае shape-файла проекция будет получена из связанного prj-файла.
  • В случае растровых слоев, ссылающихся на единственный растровый файл (с помощью ключевого слова DATA) проекция будет получена из источника данных GDAL. Если растровый слой ссылается на тайловый индекс (слоя OGR или shape-файла) проекция будет получена согласно вышеуказанным правилам.

Для других типов слоев синтаксис является недействительным.

Параметр CONFIG объекта MAP может быть использован для указания местоположения EPSG файлов:

MAP
  CONFIG "PROJ_LIB" "/usr/share/proj/"
  PROJECTION
    "init=epsg:3857"
  END # PROJECTION
  ...

Необходимо, чтобы строка CONFIG "ROJ_LIB" предшествовала блоку PROJECTION. Важные замечания:

  • Если все данные в map-файле имеют одну и ту же проекцию, то можно не указывать объекты PROJECTION. MapServer будет предполагать, что все данные имеют одну и ту же проекцию.
  • Думайте об объекте PROJECTION уровня MAP как о выходной проекции. Значения параметров EXTENT и UNITS уровня объекта MAP должны быть указаны в единицах результирующей проекции. Но если у вас есть слои в других проекциях (отличных от выходной проекции уровня MAP-объекта), то тогда вам необходимо определить объект PROJECTION для этих слоев, чтобы сообщить MapServer об их проекции.
  • Если вы определите проекцию уровня объекта MAP, и только одну проекцию в объекте LAYER, MapServer будет считать, что все остальные слои имеют такую же проекцию, как объект MAP.
  • Всегда ссылайтесь на EPSG файл в нижнем регистре, потому что имя файла указано в нижнем регистре, а в системах Linux/Unix этот параметр является чувствительным к регистру.

Добавим в наш map-файл lbl.map еще один слой из shape-файла condivl020.shp, пространственные данные которого имеют систему координат NAD83 (EPSG:4269). Поскольку система координат в слое отличается от результирующей (объект PROJECTION уровня объекта MAP), то для данного слоя обязательно объявить блок PROJECTION. В результате добавления нового слоя файл lbl.map будет иметь вид:

MAP
    NAME "sample"
    #EXTENT -180 -90 180 90 # Geographic
    EXTENT -125 25 -65 50 # Geographic
    SIZE 800 400
    IMAGECOLOR 220 221 239
    SHAPEPATH "./shp"
    FONTSET "./fonts/fonts.txt"
    SYMBOLSET "./symbols/symbols.txt"
  
    LAYER
      NAME "world_poly"
      TYPE POLYGON
      STATUS ON
      CLASSITEM    "iso3" 
      LABELITEM    "Name"
                              
      ####
      DATA 'TM_WORLD_BORDERS_SIMPL-0.3.shp'
      ####
      PROJECTION
        "init=epsg:4326"
      END	 

      CLASS
        NAME "Russia"
        EXPRESSION 'RUS'
        STYLE
          COLOR 153 204 255
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR  150 150 150
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 14
          ANGLE 0
          PARTIALS FALSE
        END
      END	 

      CLASS
        NAME "Brazil"
        EXPRESSION 'BRA'
        STYLE
          COLOR 255 204 255
          OUTLINECOLOR 100 100 100
        END	
        LABEL
          COLOR  51 51 0
          OUTLINECOLOR 255 255 255
          FONT "arial"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END			
      END	

      CLASS
        NAME "USA"
        EXPRESSION 'USA'
        STYLE
          COLOR 255 204 0
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR "#333300"
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END					
      END	   
	  
      CLASS
        NAME "The World"
        STYLE
          COLOR 240 240 240
          OUTLINECOLOR 100 100 100
        END		
      END	 	  
	  
    END # layer

    LAYER
      NAME "condivl"
      TYPE LINE
      STATUS ON
      DATA condivl020.shp
      PROJECTION
        "init=epsg:4269"
      END	
      CLASS
        STYLE
          COLOR 102 102 102
          WIDTH 4.0
        END # STYLE
        STYLE
          COLOR 255 255 255
          WIDTH 2.0
          LINECAP BUTT
          PATTERN 8 12 END
        END 
      END 
    END # layer	

    LAYER
      NAME "raster"
      TYPE RASTER
      STATUS ON	  
      COMPOSITE
        OPACITY 50
      END
      DATA "../rasters/NE2_LR_LC.tif"
      #PROCESSING "BANDS=1"
      OFFSITE 255 255 255
    END # layer

END # MAP

Чтобы лучше рассмотреть результат изменим параметр EXTENT на следующее значение: EXTENT -125 25 -65 50. В выходное изображение попадет участок в районе США. Также в новом объекте LAYER в объекте CLASS во втором объекте STYLE содержатся два новых параметра:

  • LINECAP - Задает стиль окончания линии. Возможные значения: butt, round, square. По умолчанию - round. Пример значений параметра LINECAP представлен на рисунке ниже.
  • PATTERN - используется для определения шаблона для линий (линейных объектов, контуров полигонов, линий штриховки и т.д.). Числа (типа double) определяют длину штриха и пробела пунктирного шаблона в SIZEUNITS слоя.
Пример типов параметра LINECAP
Пример типов параметра LINECAP

Чтобы просмотреть результат перейдем в браузере по url: http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/lbl.map&layer=world_poly&layer=raster&layer=condivl&mode=map. Обратите внимание, что в строке запроса появился новый параметр layer=condiv, который соответствует имени нового слоя. Результат показан на рисунке ниже:

Результат отрисовки линейного слоя геоданных в системе координат NAD83
Результат отрисовки линейного слоя геоданных в системе координат NAD83

Встроенное (инлайновое) определение слоя

С помощью объекта FEATURE возможно указать координаты объектов слоя прямо в map-файле. Рассмотрим параметры этого объекта:

  • POINTS - набор пар координат xy, оканчивающиеся ключевым словом END. Например: POINTS 1 1 50 50 1 50 1 1 END. Слои полигонов и полилиний должны начинаться и заканчиваться той же самой точкой (т.е. замыкать объект).
  • ITEMS - список атрибутов, разделенных точкой с запятой. Пример: ITEMS "value1;value2;value3". Рекомендуется указывать одинаковое количество значений для каждого объекта того же самого слоя.
  • TEXT - строка, которая будет использоваться для подписи объекта.
  • WKT - описание геометрии в формате WKT (OpenGIS Well Known Text geometry). Этот параметр поддерживается только, если MapServer собран с поддержкой OGR или GEOS. Пример: WKT "POLYGON((500 500, 3500 500, 3500 2500, 500 2500, 500 500))" или WKT "POINT(2000 2500)".

Встроенные (инлайновые) объекты должны быть определены в отдельных слоях map-файла. Если определен параметр CONNECTIONTYPE в том же слое, то MapServer будет всегда использовать встроенные объекты для отрисовки слоя и игнорировать другие параметры CONNECTIONTYPE.

В качестве примера инлайнового слоя зададим объект бермудского треугольника прямо в map-файле. Для этого добавим в него новый слой.

LAYER
  NAME "bermuda"
  STATUS ON
  TYPE LINE
  FEATURE
    POINTS
	-80.000848868711898 26.331945645288432
	-66.378164696877519 18.50924697701587 
	-64.875079482210083 32.398753642874262
	-79.947506278258246 26.437751244172741
    END # Points
  END # Feature
  CLASS
    STYLE
      COLOR 255 51 0
      WIDTH 4
    END 
  END 
END # layer

Обновленный файл lbl.map будет иметь вид:

MAP
    NAME "sample"
    EXTENT -180 -90 180 90 # Geographic
    #EXTENT -125 25 -65 50 # Geographic
    SIZE 800 400
    IMAGECOLOR 220 221 239
    SHAPEPATH "./shp"
    FONTSET "./fonts/fonts.txt"
    SYMBOLSET "./symbols/symbols.txt"
  
    LAYER
      NAME "world_poly"
      TYPE POLYGON
      STATUS ON
      CLASSITEM    "iso3" 
      LABELITEM    "Name"
                              
      ####
      DATA 'TM_WORLD_BORDERS_SIMPL-0.3.shp'
      ####
      PROJECTION
        "init=epsg:4326"
      END	 

      CLASS
        NAME "Russia"
        EXPRESSION 'RUS'
        STYLE
          COLOR 153 204 255
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR  150 150 150
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 14
          ANGLE 0
          PARTIALS FALSE
        END
      END	 

      CLASS
        NAME "Brazil"
        EXPRESSION 'BRA'
        STYLE
          COLOR 255 204 255
          OUTLINECOLOR 100 100 100
        END	
        LABEL
          COLOR  51 51 0
          OUTLINECOLOR 255 255 255
          FONT "arial"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END			
      END	

      CLASS
        NAME "USA"
        EXPRESSION 'USA'
        STYLE
          COLOR 255 204 0
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR "#333300"
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END					
      END	   
	  
      CLASS
        NAME "The World"
        STYLE
          COLOR 240 240 240
          OUTLINECOLOR 100 100 100
        END		
      END	 	  
	  
    END # layer

    LAYER
      NAME "condivl"
      TYPE LINE
      STATUS ON
      DATA condivl020.shp
      PROJECTION
        "init=epsg:4269"
      END	
      CLASS
        STYLE
          COLOR 102 102 102
          WIDTH 4.0
        END # STYLE
        STYLE
          COLOR 255 255 255
          WIDTH 2.0
          LINECAP BUTT
          PATTERN 8 12 END
        END 
      END 
    END # layer	

    LAYER
      NAME "bermuda"
      STATUS ON
      TYPE LINE
      FEATURE
        POINTS
          -80.000848868711898 26.331945645288432
          -66.378164696877519 18.50924697701587 
          -64.875079482210083 32.398753642874262
          -79.947506278258246 26.437751244172741
        END # Points
      END # Feature
      CLASS
        STYLE
          COLOR 255 51 0
          WIDTH 4
        END 
      END 
    END # layer

    LAYER
      NAME "raster"
      TYPE RASTER
      STATUS ON	  
      COMPOSITE
        OPACITY 50
      END
      DATA "../rasters/NE2_LR_LC.tif"
      #PROCESSING "BANDS=1"
      OFFSITE 255 255 255
    END # layer

END # MAP

Обратите внимание, что я вернул параметр EXTENT к старым значениям: EXTENT -180 -90 180 90. Откроем в браузере новый url http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/lbl.map&layer=world_poly&layer=raster&layer=condivl&layer=bermuda&mode=map, в который добавлен новый слой: layer=bermuda.

Определение инлайнового слоя в map-файле
Определение инлайнового слоя в map-файле

Фильтрация объектов в слое

Вернемся к нашим трем странам (Россия, США и Бразилия), которые мы выделили с помощью параметра CLASSITEM и параметров EXPRESSION. Теперь давайте с помощью слоя ne_10m_populated_places, который был загружен в БД MS SQL в предыдущей статье, отобразим популярные места только этих трех стран. Для этого добавим новый слой и воспользуемся параметром FILTER.

LAYER
      NAME "pop_places"
      TYPE POINT
      STATUS ON
      ####
      CONNECTIONTYPE OGR
      CONNECTION "MSSQL:server=.\SQLEXPRESS;trusted_connection=yes;database=MySpatialDb;tables=ne_10m_populated_places(ogr_geometry)"
      ####
      FILTER ("[iso_a2]"='RU' OR "[iso_a2]"='US' OR "[iso_a2]"='BR')	  
      PROJECTION
        "init=epsg:4326"
      END
      CLASS
        NAME "Pop Places"
        STYLE
          COLOR 10 100 50
          SYMBOL 'circle'
          SIZE 2		
        END
      END
      PROCESSING 'CLOSE_CONNECTION=DEFER'
	END # layer
  • FILTER - позволяет определять выражение фильтрации объектов, которые должны быть включены в слой.

В примере выше с помощью параметра FILTER я привел условие выборки только тех объектов, которые принадлежат какой-либо из наших стран. Полный пример файла lbl.map будет выглядеть так:

MAP
    NAME "sample"
    EXTENT -180 -90 180 90 # Geographic
    #EXTENT -125 25 -65 50 # Geographic
    SIZE 800 400
    IMAGECOLOR 220 221 239
    SHAPEPATH "./shp"
    FONTSET "./fonts/fonts.txt"
    SYMBOLSET "./symbols/symbols.txt"
  
    LAYER
      NAME "world_poly"
      TYPE POLYGON
      STATUS ON
      CLASSITEM    "iso3" 
      LABELITEM    "Name"
                              
      ####
      DATA 'TM_WORLD_BORDERS_SIMPL-0.3.shp'
      ####
      PROJECTION
        "init=epsg:4326"
      END	 

      CLASS
        NAME "Russia"
        EXPRESSION 'RUS'
        STYLE
          COLOR 153 204 255
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR  150 150 150
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 14
          ANGLE 0
          PARTIALS FALSE
        END
      END	 

      CLASS
        NAME "Brazil"
        EXPRESSION 'BRA'
        STYLE
          COLOR 255 204 255
          OUTLINECOLOR 100 100 100
        END	
        LABEL
          COLOR  51 51 0
          OUTLINECOLOR 255 255 255
          FONT "arial"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END			
      END	

      CLASS
        NAME "USA"
        EXPRESSION 'USA'
        STYLE
          COLOR 255 204 0
          OUTLINECOLOR 100 100 100
        END		
        LABEL
          COLOR "#333300"
          OUTLINECOLOR 255 255 255
          FONT "sans"
          TYPE truetype
          SIZE 10
          ANGLE 0
          PARTIALS FALSE
        END					
      END	   
	  
      CLASS
        NAME "The World"
        STYLE
          COLOR 240 240 240
          OUTLINECOLOR 100 100 100
        END		
      END	 	  
	  
    END # layer

    LAYER
      NAME "condivl"
      TYPE LINE
      STATUS ON
      DATA condivl020.shp
      PROJECTION
        "init=epsg:4269"
      END	
      CLASS
        STYLE
          COLOR 102 102 102
          WIDTH 4.0
        END # STYLE
        STYLE
          COLOR 255 255 255
          WIDTH 2.0
          LINECAP BUTT
          PATTERN 8 12 END
        END # STYLE
      END # CLASS
    END # layer	

    LAYER
      NAME "bermuda"
      STATUS ON
      TYPE LINE
      FEATURE
        POINTS
          -80.000848868711898 26.331945645288432
          -66.378164696877519 18.50924697701587 
          -64.875079482210083 32.398753642874262
          -79.947506278258246 26.437751244172741
        END # Points
      END # Feature
      CLASS
        STYLE
          COLOR 255 51 0
          WIDTH 4
        END
      END
    END # layer

    LAYER
      NAME "pop_places"
      TYPE POINT
      STATUS ON
      ####
      CONNECTIONTYPE OGR
      CONNECTION "MSSQL:server=.\SQLEXPRESS;trusted_connection=yes;database=MySpatialDb;tables=ne_10m_populated_places(ogr_geometry)"
      ####
      FILTER ("[iso_a2]"='RU' OR "[iso_a2]"='US' OR "[iso_a2]"='BR')	  
      PROJECTION
        "init=epsg:4326"
      END
      CLASS
        NAME "Pop Places"
        STYLE
          COLOR 10 100 50
          SYMBOL 'circle'
          SIZE 2		
        END
      END
      PROCESSING 'CLOSE_CONNECTION=DEFER'
	END # layer

    LAYER
      NAME "raster"
      TYPE RASTER
      STATUS ON	  
      COMPOSITE
        OPACITY 50
      END
      DATA "../rasters/NE2_LR_LC.tif"
      #PROCESSING "BANDS=1"
      OFFSITE 255 255 255
    END # layer

END # MAP

А сам url HTTP-запроса выглядит так: http://localhost:8888/cgi-bin/mapserv.exe?map=../htdocs/mydemo/lbl.map&layer=world_poly&layer=raster&layer=condivl&layer=bermuda&layer=pop_places&mode=map. В строку запроса добавился новый слой: layer=pop_places. А выходное изображение имеет вид:

Результат применения фильтрации объектов слоя
Результат применения фильтрации объектов слоя

Файлы для загрузки:


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