Создание WMS сервера на базе GRASS GIS и Pyramid

Материал из GIS-Lab
Перейти к навигации Перейти к поиску

В данной статье описывается простейший пример создания WMS сервера на базе геоинформационной системы GRASS. Доступ к данным организован при помощи фреймворка Pyramid.

Данная статья является расширенным переводом с английского языка статьи GRASS GIS Web Map Service with Pyramid.

Общие сведения

Статья расчитана на читателя, который на базовом уровне знаком с геоинформационной системой GRASS и языком программирования Python. В частности, читатель должен представлять, как происходит вызов команд GRASS на языке Python и быть знакомым с основами использования фреймворка Pyramid.

В статье испольуется GRASS версии 6.4 (тем не менее, изменения в приведенном коде для GRASS 7 должны быть минимальными).

Архитектура системы

В основе WMS сервера будет лежать модуль d.mon, отвечающий за отрисовку геоданных. При этом будет использоваться графический драйвер Cairo, который позволяет генерировать изображения в форматах PNG, BMP, PPM, PS, PDF и SVG.

Для реализации сервера потребуется создать функции, служащие для:

  1. Настройки путей к GRASS.
  2. Получения и анализа параметров запроса WMS.
  3. Отрисовки слоев по запросу клиента и сохранения результата в графический файл.
  4. Возвращения результата обработки запроса клиенту.

Собственно к GRASS относятся первый и третий пункты, остальные --- обычные действия, которые реализуются при помощи Pyramid и с GRASS никак не связаны. Поэтому для простоты изложения и реализации объединим первый и третий пункты в виде одной функции.

Реализация

Настройка путей GRASS и обработка запроса клиента

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

На вход функция принимает список слоев (layers), которые требуется отрисовать, охват интересующего пользователя региона (bbox) и ширину/высоту (width/height) изображения. На выходе функция возвращает имя файла, в котором будет сохранено запрошенное изображение.

def _grass_wms(layers=[], bbox=[], width=256, height=256):
   # Прописываем пути к GRASS. Исправить под свои нужды.
   gisdbase = "/home/username/GRASSDATA"
   location = "Moscow"
   mapset = "PERMANENT"
   gisbase = os.environ["GISBASE"] = "/usr/lib64/grass-6.4.3"
   
   # Добавляем путь модулям GRASS в системные пути
   sys.path.append("%s/etc/python" % gisbase)

   # Импортируем библиотеки GRASS
   from grass.script import core as grass
   from grass.script import setup as gsetup

   # Инициализируем GRASS
   gsetup.init(gisbase, gisdbase,
               location, mapset)

   # Получаем список известных растровых и векторных слоев
   vector_layers = grass.list_strings("vect")
   raster_layers = grass.list_strings("rast")

   grass.run_command("g.region", w=bbox[0], s=bbox[1], e=bbox[2], n=bbox[3])

   # Создание временного файла
   tempfile = grass.tempfile()
   filename = "%s.png" % tempfile

   grass.run_command("d.mon",
                     start="cairo",
                     width=width,
                     height=height,
                     output=filename)
   for layer in layers:
       if layer in raster_layers:
           grass.run_command("d.rast", map=layer, quiet=1)
       elif layer in vector_layers:
           grass.run_command("d.vect", map=layer, quiet=1, fcolor="0:0:255", color=None)

   grass.run_command("d.mon", stop="cairo")

   return filename

Как видим, большая часть кода связана с первоначальной настройкой GRASS. Основной код по отрисовке запрошенных слоев использует команды GRASS занимает пять строк:

 for layer in layers:
 ...

При этом все векторные слои будут отрисованы синим цветом, (команда grass.run_command("d.vect", map=layer, quiet=1, fcolor="0:0:255", color=None)). Внешний вид слоя может быть изменен настройкой параметров команды d.vect, например, можно назначить стиль отображения объекта в зависимости от его атрибутов или геометрических характеристик.

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

Анализ запроса пользователя

Анализ запроса пользователя производится в следующей функции:

@view_config(route_name="wms")
def wms_view(request):

   layers = request.params.get("LAYERS", "").split(",")
   bbox = request.params.get("BBOX", "").split(",")
   width = request.params.get("WIDTH")
   height = request.params.get("HEIGHT")

   try:
       filename = _grass_wms(layers=layers,
                             bbox=bbox,
                             width=width,
                             height=height)
       f = open(filename, "r+")
       return Response(body=f.read(), content_type="image/png")
   except:
       pass

Данная функция принимает запрос (request), в котором могжет определяться

* список слоев в запрашиваемом изображении (параметр LAYERS);
* охват области запрашиваемого изображения (параметр BBOX);
* высота и ширина запрашиваемого изображения (параметры HEIGHT и WIDTH).

Полученные параметры анализируются и передаются в определенную выше функцию _grass_wms. Результат работы функции --- имя файла изображения --- считывается с диска и возвращается в качестве ответа на запрос.

Ограничения данной реализации