<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.gis-lab.info/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vasnake</id>
	<title>GIS-Lab - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.gis-lab.info/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vasnake"/>
	<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/w/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Vasnake"/>
	<updated>2026-04-03T20:32:10Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.39.6</generator>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE_HTTP-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=12886</id>
		<title>Создание простейшего HTTP-сервиса для публикации векторных данных</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE_HTTP-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=12886"/>
		<updated>2013-06-13T13:06:25Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: /* Веб-фреймворк */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
При разработке Веб-ГИС зачастую возникает необходимость в передаче векторных данных с сервера на клиентскую сторону. При этом, как правило, векторные&lt;br /&gt;
данные имеют большой объем или находятся в различных хранилищах и поэтому требуется некоторое промежуточное звено, которое бы могло получать от клиентского приложения запрос данных, удовлетворяющих определенному критерию (например, попадающие в некий охват), подключаться к хранилищу данных, извлекать нужный набор и возвращать его клиенту.&lt;br /&gt;
&lt;br /&gt;
Для решения данной задачи существует специальный протокол [http://www.opengeospatial.org/standards/wfs OGC Web Feature Service], о котором мы рассказывали в одной из предыдущих [http://gis-lab.info/qa/wfs-begin.html статей]. С одной стороны, опубликовав свои данные по WFS, мы получаем очень богатые возможности:&lt;br /&gt;
&lt;br /&gt;
* отображение данных в настольных ГИС;&lt;br /&gt;
* гибкий язык описания фильтров;&lt;br /&gt;
* возможность редактирования данных.&lt;br /&gt;
&lt;br /&gt;
Если бы перед нами стояла задача просто опубликовать некоторый набор данных по WFS, то никаких проблем - берем [http://mapserver.org/trunk/tinyows/ TinyOWS],&lt;br /&gt;
[http://mapserver.org/ MapServer] или [http://geoserver.org/ GeoServer], настраиваем подключение к хранилищу - всё. Но это не наш случай, нам нужно добавить&lt;br /&gt;
WFS-функционал непосредственно в наше приложение. Как поступить в этом случае? Вариантов на самом деле не много: либо найти необходимую библиотеку на том языке&lt;br /&gt;
программирования, на котором ведется разработка, либо каким-то образом &amp;quot;прикрутить&amp;quot; имеющийся WFS-сервер к нашему приложению. Не беремся утверждать за другие языки&lt;br /&gt;
программирования, но, например, в случае Python не существует нативных библиотек, реализующих функционал WFS-сервиса, только лишь баиндинги к&lt;br /&gt;
[http://mapserver.org/mapscript/introduction.html mapscript], а это по сути сводится к установке библиотек MapServer (который написан на C/C++). Завязывание&lt;br /&gt;
же своего приложения на внешний по отношению к нему WFS-сервер - задача непростая и тянущая за собой ряд очень серьезных проблем:&lt;br /&gt;
&lt;br /&gt;
* необходимость подготовки дистрибутива WFS-сервера под целевую платформу;&lt;br /&gt;
* язык программирования, используемый при разработке основного приложения и WFS-сервера зачастую не совпадают, следовательно в случае возникновение проблем с последним, необходимо привлечение дополнительных ресурсов;&lt;br /&gt;
* сама задача по интеграции приложение с WFS-сервером далеко не тривиальная.&lt;br /&gt;
&lt;br /&gt;
Поэтому, если вы все-таки хотите использовать возможности WFS в своем приложении, то наиболее правильным видится подход в разработке соответствующего ПО на том&lt;br /&gt;
же языке программирования, что используется в вашем приложении. В этом случае вы имеете полный контроль над своей системой.&lt;br /&gt;
&lt;br /&gt;
Как показывает практика, для разработки небольших картографических Веб-приложений функционал, предлагаемый спецификацией WFS, крайне избыточен. Зачастую оказывается ненужным ни отображение данных в настольных ГИС, ни гибкий язык описания фильтров, поэтому в большинстве случаев достаточно написания собственного простейшего HTTP-сервиса, возвращающего данные в каком-нибудь стандартном формате (например,[http://gis-lab.info/docs/geojson_ru.html GeoJSON]). Именно решению данной&lt;br /&gt;
задачи и будет посвящена оставшаяся часть статьи. В качестве примера использования подобного сервиса может служить проект [http://demo.nextgis.ru/openpolice/ Найди участкового], откройте консоль вашего браузера и посмотрите какие запросы уходят на сервер при сдвиге карты.&lt;br /&gt;
&lt;br /&gt;
В качестве языка программирования будем использовать Python, операционная система - Debian GNU/Linux 7.0.&lt;br /&gt;
&lt;br /&gt;
== Выбор API ==&lt;br /&gt;
&lt;br /&gt;
Если вам требуется разработать полнофункциональный HTTP-сервис, то, чтобы не изобретать велосипед, можно взять готовое описание какого-нибудь&lt;br /&gt;
API (в зависимости от задач) и реализовать его. Например,&lt;br /&gt;
[http://trac.mapfish.org/trac/mapfish/wiki/MapFishProtocol MapFish Protocol] или [http://resources.arcgis.com/en/help/rest/apiref/index.html?featureserver.html ArcGIS Server REST API] (открытая реализация HTTP-сервиса, реализующая данный API уже [http://gis-lab.info/qa/mapfeatureserver.html существует]).&lt;br /&gt;
&lt;br /&gt;
В нашем случае мы разработаем HTTP-сервис, поддерживающий 3 GET-параметра:&lt;br /&gt;
&lt;br /&gt;
* bbox={xmin,ymin,xmax,ymax} - запрашиваемый bbox (по умолчанию считается, что координаты указаны в системе координат EPSG:4326);&lt;br /&gt;
* epsg={num} - система координат в которой должны быть возвращены данные, также используется как система координат для bbox;&lt;br /&gt;
* attrs={field1}[,{field2},...] - имена запрашиваемых атрибутивных полей.&lt;br /&gt;
&lt;br /&gt;
== Хранилище и формат выходных данных ==&lt;br /&gt;
&lt;br /&gt;
В качестве данных возьмем БД PostGIS, созданную в рамках&lt;br /&gt;
[http://gis-lab.info/qa/geodetdom-coord.html проекта по созданию слоя детских учреждений]. Выходной формат - GeoJSON.&lt;br /&gt;
&lt;br /&gt;
При разработке Веб-ГИС стандартная практика заключается в передаче данных клиенту в формате GeoJSON, при этом объект GeoJSON - это объект типа&lt;br /&gt;
&amp;quot;FeatureCollection&amp;quot; - коллекция элементарных объектов. Объект типа &amp;quot;FeatureCollection&amp;quot; содержит одно свойство &amp;quot;features&amp;quot;, значение данного свойства – массив,&lt;br /&gt;
каждый элемент которого представляет собой [http://gis-lab.info/docs/geojson_ru.html#2.2 элементарный объект].&lt;br /&gt;
&lt;br /&gt;
В PostgreSQL, начиная с версии 9.2, появились специальные функции для работы с JSON-данными, в частности [http://www.postgresql.org/docs/devel/static/functions-json.html row_to_json], позволяющие, используя SQL-запрос к базе данных PostGIS, получить &amp;quot;FeatureCollection&amp;quot;. О том как это сделать подробно описано в статье&lt;br /&gt;
[http://www.postgresonline.com/journal/archives/267-Creating-GeoJSON-Feature-Collections-with-JSON-and-PostGIS-functions.html Creating GeoJSON Feature Collections with JSON and PostGIS functions], мы же, ввиду того что используемое нами хранилище развернуто на PostgreSQL 9.1, будем формировать &amp;quot;FeatureCollection&amp;quot; самостоятельно в коде&lt;br /&gt;
нашего сервиса.&lt;br /&gt;
&lt;br /&gt;
== Веб-фреймворк ==&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы облегчить себе жизнь и не писать служебный код, в качестве инструмента для работы с HTTP-запросами&lt;br /&gt;
выберем какой-нибудь Веб-фреймворк. Остановимся на [http://bottlepy.org/docs/dev/ Bottle]. Данный фреймворк уже использовался нами в статье&lt;br /&gt;
[http://gis-lab.info/qa/dynamic-tms.html Основы работы динамических TMS-сервисов].&lt;br /&gt;
&lt;br /&gt;
== Установка программного обеспечения ==&lt;br /&gt;
&lt;br /&gt;
=== Установка Bottle ===&lt;br /&gt;
&lt;br /&gt;
Установим Bottle в [http://guide.python-distribute.org/virtualenv.html виртуальное окружение]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo aptitude install python-virtualenv&lt;br /&gt;
cd ~&lt;br /&gt;
virtualenv --no-site-packages geoservice&lt;br /&gt;
source geoservice/bin/activate&lt;br /&gt;
pip install bottle&lt;br /&gt;
pip install waitress&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Установка psycopg2 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pip install psycopg2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае возникновения ошибок при установке требуется установка необходимых библиотек на уровне операционной системы,&lt;br /&gt;
[http://stackoverflow.com/a/5450183/813758 подробнее].&lt;br /&gt;
&lt;br /&gt;
=== Установка библиотеки для парсинга конфигурационного файла ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pip install pyyaml&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создание сервиса ==&lt;br /&gt;
&lt;br /&gt;
Переходим в директорию нашего виртуального окружения geoservice:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cd geoservice&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и создаём в ней файл geoservice.py, в котором и будет располагаться код будущего HTTP-сервиса, также здесь поместим файл, содержащий описание подключения&lt;br /&gt;
к нашей базе данных config.yaml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
touch geoservice.py&lt;br /&gt;
touch config.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Открываем файл config.yaml и помещаем в него следующее содержимое:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
db:&lt;br /&gt;
  host: gis-lab.info&lt;br /&gt;
  port: 5432&lt;br /&gt;
  name: gedetdom&lt;br /&gt;
  table: data&lt;br /&gt;
  user: guest&lt;br /&gt;
  password: guest&lt;br /&gt;
  geometry_column: geometry&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Затем открываем файл geoservice.py и пишем в него:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# -*- encoding: utf-8 -*-&lt;br /&gt;
import json&lt;br /&gt;
import psycopg2&lt;br /&gt;
from bottle import route, response, request, run&lt;br /&gt;
from yaml import load&lt;br /&gt;
&lt;br /&gt;
# Остальной код будет располагаться тут&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    run(host='0.0.0.0', port=8087, server='waitress')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключение к базе данных ===&lt;br /&gt;
&lt;br /&gt;
Извлекаем информацию о подключении из конфигурационного файла:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
db_config_file = open('config.yaml', 'rb')&lt;br /&gt;
db_config = load(db_config_file).get('db')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И подключаемся к базе данных:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
conn_string = 'host=%(host)s dbname=%(name)s user=%(user)s password=%(password)s'&lt;br /&gt;
conn_string %= db_config&lt;br /&gt;
conn = psycopg2.connect(conn_string)&lt;br /&gt;
cursor = conn.cursor()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Извлечение данных из базы ===&lt;br /&gt;
&lt;br /&gt;
Опишем функцию, которая будет извлекать значения GET-параметров из URL, осуществлять запрос к базе данных и передавать данные обратно клиенту:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
@route('/features')&lt;br /&gt;
def geoservice(bbox='-180,-90,180,90', epsg='4326'):&lt;br /&gt;
&lt;br /&gt;
    # Параметры запроса&lt;br /&gt;
    bbox = (request.GET.get('bbox') or bbox).split(',')&lt;br /&gt;
    epsg = request.GET.get('epsg') or epsg&lt;br /&gt;
    attrs = request.GET.get('attrs',[])&lt;br /&gt;
    coordinates = dict(xmin=bbox[0],ymin=bbox[1],xmax=bbox[2],ymax=bbox[3])&lt;br /&gt;
    geometry_column = db_config.get('geometry_column')&lt;br /&gt;
    table = db_config.get('table')&lt;br /&gt;
&lt;br /&gt;
    # Строка запроса&lt;br /&gt;
    query = &amp;quot;&amp;quot;&amp;quot;select st_asgeojson(st_transform({gc}, {epsg})) as g, *&lt;br /&gt;
          from {table}&lt;br /&gt;
          where st_transform({gc}, {epsg}) &amp;amp;&amp;amp; st_makeenvelope({xmin},{ymin},{xmax},{ymax},{epsg});&lt;br /&gt;
          &amp;quot;&amp;quot;&amp;quot;.format(gc=geometry_column, epsg=epsg, table=table, **coordinates)&lt;br /&gt;
&lt;br /&gt;
    # Выполнение запроса&lt;br /&gt;
    cursor.execute(query)&lt;br /&gt;
    records = cursor.fetchall()&lt;br /&gt;
&lt;br /&gt;
    # Формируем GeoJSON вручную&lt;br /&gt;
    collection = {'type': 'FeatureCollection', 'features': []}&lt;br /&gt;
    for rec in records:&lt;br /&gt;
        feature = dict()&lt;br /&gt;
        feature['type'] = 'Feature'&lt;br /&gt;
        feature['properties'] = dict()&lt;br /&gt;
&lt;br /&gt;
        # Функция, возвращающая список вида [(0, attr1), (1, attr2), ..., (n, attrn)],&lt;br /&gt;
        # то есть осуществляется сопоставление имен и индексов полей&lt;br /&gt;
        columns = lambda a: zip(range(len(a)), a)&lt;br /&gt;
&lt;br /&gt;
        # Итерация по полям&lt;br /&gt;
        for colnum, col in columns(cursor.description):&lt;br /&gt;
            if col.name == 'g':&lt;br /&gt;
                feature['geometry'] = json.loads(rec[colnum])&lt;br /&gt;
                continue&lt;br /&gt;
            if col.name in attrs:&lt;br /&gt;
                feature['properties'][col.name] = rec[colnum]&lt;br /&gt;
        collection['features'].append(feature)&lt;br /&gt;
&lt;br /&gt;
    response.content_type = 'application/json'&lt;br /&gt;
    return json.dumps(collection)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Запуск сервиса ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ python geoservice.py&lt;br /&gt;
Bottle v0.11.6 server starting up (using WaitressServer())...&lt;br /&gt;
Listening on http://0.0.0.0:8087/&lt;br /&gt;
Hit Ctrl-C to quit.&lt;br /&gt;
&lt;br /&gt;
serving on http://0.0.0.0:8087&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Результаты ==&lt;br /&gt;
&lt;br /&gt;
Пришло время проверить, что же получилось. Откроем браузер и протестируем следующие URL.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://localhost:8087/features?bbox=4180824.1850282,7488851.5571727,4187192.3449474,7490776.8148227&amp;amp;epsg=3857&amp;amp;attrs=post,name&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;FeatureCollection&amp;quot;,&lt;br /&gt;
    &amp;quot;features&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    4184578.0278406707,&lt;br /&gt;
                    7489606.364854654&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;117303, Москва, ул. Каховка, 2&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Школа-интернат № 24 дя детей-сирот&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    4186044.5508123846,&lt;br /&gt;
                    7488978.3756106505&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;117452, Москва, Симферопольский б-р, 20&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Школа-интернат № 95 общеобразовательная&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как можно увидеть получены данные, удовлетворяющие заданному охвату в системе координат EPSG:3857.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://localhost:8087/features?bbox=82,53,83,54&amp;amp;attrs=post,name&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;FeatureCollection&amp;quot;,&lt;br /&gt;
    &amp;quot;features&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.995135,&lt;br /&gt;
                    53.320683&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659000, Алтайский край, с.Павловск, ул. Шумилова, 1&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Павловский детский дом&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.984438,&lt;br /&gt;
                    53.311395&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659000, Алтайский край, с.Павловск, ул. Коминтерна, 2&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Павловская школа-интернат спец.корр.&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.470054,&lt;br /&gt;
                    53.443182&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659053, Алтайский край, Шелаболихинский р-н, с.Кучук, ул. Новая, 15&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Кучукский детский дом&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.316406,&lt;br /&gt;
                    53.784103&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;633623, Новосибирская обл., п. Сузун, ул. Толстого, 11&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Социальный приют для детей и подростков \&amp;quot;Лесовичек\&amp;quot;&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.316406,&lt;br /&gt;
                    53.784103&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;633610, Новосибирская обл., п. Сузун, ул. Партизанская, 19&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Сузунская школа-интернат для детей-сирот 8ого вида&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для представления JSON-данных в удобочитаемом варианте можно воспользоватся сервисом [http://jsonlint.com/ JSONLint], что мы собственно и сделали.&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
&lt;br /&gt;
Таким образом, мы создали простейший HTTP-сервис, который на входе принимает определенный набор параметров и возвращает результат в формате GeoJSON. И хотя это всего-лишь учебный вариант, в котором не предусмотрена никакая обработка ошибок, но он наглядно показывает как может быть устроен простейший сервис подобного типа. Данные, предоставляемые этим сервисом, легко могут быть визуализированы с помощью картографического JavaScript-клиента, например, OpenLayers.&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE_HTTP-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=12885</id>
		<title>Создание простейшего HTTP-сервиса для публикации векторных данных</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE_HTTP-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=12885"/>
		<updated>2013-06-13T13:05:42Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: /* Хранилище и формат выходных данных */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
При разработке Веб-ГИС зачастую возникает необходимость в передаче векторных данных с сервера на клиентскую сторону. При этом, как правило, векторные&lt;br /&gt;
данные имеют большой объем или находятся в различных хранилищах и поэтому требуется некоторое промежуточное звено, которое бы могло получать от клиентского приложения запрос данных, удовлетворяющих определенному критерию (например, попадающие в некий охват), подключаться к хранилищу данных, извлекать нужный набор и возвращать его клиенту.&lt;br /&gt;
&lt;br /&gt;
Для решения данной задачи существует специальный протокол [http://www.opengeospatial.org/standards/wfs OGC Web Feature Service], о котором мы рассказывали в одной из предыдущих [http://gis-lab.info/qa/wfs-begin.html статей]. С одной стороны, опубликовав свои данные по WFS, мы получаем очень богатые возможности:&lt;br /&gt;
&lt;br /&gt;
* отображение данных в настольных ГИС;&lt;br /&gt;
* гибкий язык описания фильтров;&lt;br /&gt;
* возможность редактирования данных.&lt;br /&gt;
&lt;br /&gt;
Если бы перед нами стояла задача просто опубликовать некоторый набор данных по WFS, то никаких проблем - берем [http://mapserver.org/trunk/tinyows/ TinyOWS],&lt;br /&gt;
[http://mapserver.org/ MapServer] или [http://geoserver.org/ GeoServer], настраиваем подключение к хранилищу - всё. Но это не наш случай, нам нужно добавить&lt;br /&gt;
WFS-функционал непосредственно в наше приложение. Как поступить в этом случае? Вариантов на самом деле не много: либо найти необходимую библиотеку на том языке&lt;br /&gt;
программирования, на котором ведется разработка, либо каким-то образом &amp;quot;прикрутить&amp;quot; имеющийся WFS-сервер к нашему приложению. Не беремся утверждать за другие языки&lt;br /&gt;
программирования, но, например, в случае Python не существует нативных библиотек, реализующих функционал WFS-сервиса, только лишь баиндинги к&lt;br /&gt;
[http://mapserver.org/mapscript/introduction.html mapscript], а это по сути сводится к установке библиотек MapServer (который написан на C/C++). Завязывание&lt;br /&gt;
же своего приложения на внешний по отношению к нему WFS-сервер - задача непростая и тянущая за собой ряд очень серьезных проблем:&lt;br /&gt;
&lt;br /&gt;
* необходимость подготовки дистрибутива WFS-сервера под целевую платформу;&lt;br /&gt;
* язык программирования, используемый при разработке основного приложения и WFS-сервера зачастую не совпадают, следовательно в случае возникновение проблем с последним, необходимо привлечение дополнительных ресурсов;&lt;br /&gt;
* сама задача по интеграции приложение с WFS-сервером далеко не тривиальная.&lt;br /&gt;
&lt;br /&gt;
Поэтому, если вы все-таки хотите использовать возможности WFS в своем приложении, то наиболее правильным видится подход в разработке соответствующего ПО на том&lt;br /&gt;
же языке программирования, что используется в вашем приложении. В этом случае вы имеете полный контроль над своей системой.&lt;br /&gt;
&lt;br /&gt;
Как показывает практика, для разработки небольших картографических Веб-приложений функционал, предлагаемый спецификацией WFS, крайне избыточен. Зачастую оказывается ненужным ни отображение данных в настольных ГИС, ни гибкий язык описания фильтров, поэтому в большинстве случаев достаточно написания собственного простейшего HTTP-сервиса, возвращающего данные в каком-нибудь стандартном формате (например,[http://gis-lab.info/docs/geojson_ru.html GeoJSON]). Именно решению данной&lt;br /&gt;
задачи и будет посвящена оставшаяся часть статьи. В качестве примера использования подобного сервиса может служить проект [http://demo.nextgis.ru/openpolice/ Найди участкового], откройте консоль вашего браузера и посмотрите какие запросы уходят на сервер при сдвиге карты.&lt;br /&gt;
&lt;br /&gt;
В качестве языка программирования будем использовать Python, операционная система - Debian GNU/Linux 7.0.&lt;br /&gt;
&lt;br /&gt;
== Выбор API ==&lt;br /&gt;
&lt;br /&gt;
Если вам требуется разработать полнофункциональный HTTP-сервис, то, чтобы не изобретать велосипед, можно взять готовое описание какого-нибудь&lt;br /&gt;
API (в зависимости от задач) и реализовать его. Например,&lt;br /&gt;
[http://trac.mapfish.org/trac/mapfish/wiki/MapFishProtocol MapFish Protocol] или [http://resources.arcgis.com/en/help/rest/apiref/index.html?featureserver.html ArcGIS Server REST API] (открытая реализация HTTP-сервиса, реализующая данный API уже [http://gis-lab.info/qa/mapfeatureserver.html существует]).&lt;br /&gt;
&lt;br /&gt;
В нашем случае мы разработаем HTTP-сервис, поддерживающий 3 GET-параметра:&lt;br /&gt;
&lt;br /&gt;
* bbox={xmin,ymin,xmax,ymax} - запрашиваемый bbox (по умолчанию считается, что координаты указаны в системе координат EPSG:4326);&lt;br /&gt;
* epsg={num} - система координат в которой должны быть возвращены данные, также используется как система координат для bbox;&lt;br /&gt;
* attrs={field1}[,{field2},...] - имена запрашиваемых атрибутивных полей.&lt;br /&gt;
&lt;br /&gt;
== Хранилище и формат выходных данных ==&lt;br /&gt;
&lt;br /&gt;
В качестве данных возьмем БД PostGIS, созданную в рамках&lt;br /&gt;
[http://gis-lab.info/qa/geodetdom-coord.html проекта по созданию слоя детских учреждений]. Выходной формат - GeoJSON.&lt;br /&gt;
&lt;br /&gt;
При разработке Веб-ГИС стандартная практика заключается в передаче данных клиенту в формате GeoJSON, при этом объект GeoJSON - это объект типа&lt;br /&gt;
&amp;quot;FeatureCollection&amp;quot; - коллекция элементарных объектов. Объект типа &amp;quot;FeatureCollection&amp;quot; содержит одно свойство &amp;quot;features&amp;quot;, значение данного свойства – массив,&lt;br /&gt;
каждый элемент которого представляет собой [http://gis-lab.info/docs/geojson_ru.html#2.2 элементарный объект].&lt;br /&gt;
&lt;br /&gt;
В PostgreSQL, начиная с версии 9.2, появились специальные функции для работы с JSON-данными, в частности [http://www.postgresql.org/docs/devel/static/functions-json.html row_to_json], позволяющие, используя SQL-запрос к базе данных PostGIS, получить &amp;quot;FeatureCollection&amp;quot;. О том как это сделать подробно описано в статье&lt;br /&gt;
[http://www.postgresonline.com/journal/archives/267-Creating-GeoJSON-Feature-Collections-with-JSON-and-PostGIS-functions.html Creating GeoJSON Feature Collections with JSON and PostGIS functions], мы же, ввиду того что используемое нами хранилище развернуто на PostgreSQL 9.1, будем формировать &amp;quot;FeatureCollection&amp;quot; самостоятельно в коде&lt;br /&gt;
нашего сервиса.&lt;br /&gt;
&lt;br /&gt;
== Веб-фреймворк ==&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы облегчить себе жизнь и не писать служебный код в качестве инструмента для работы с HTTP-запросами&lt;br /&gt;
выберем какой-нибудь Веб-фреймворк. Остановимся на [http://bottlepy.org/docs/dev/ Bottle]. Данный фреймворк уже использовался нами в статье&lt;br /&gt;
[http://gis-lab.info/qa/dynamic-tms.html Основы работы динамических TMS-сервисов].&lt;br /&gt;
&lt;br /&gt;
== Установка программного обеспечения ==&lt;br /&gt;
&lt;br /&gt;
=== Установка Bottle ===&lt;br /&gt;
&lt;br /&gt;
Установим Bottle в [http://guide.python-distribute.org/virtualenv.html виртуальное окружение]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo aptitude install python-virtualenv&lt;br /&gt;
cd ~&lt;br /&gt;
virtualenv --no-site-packages geoservice&lt;br /&gt;
source geoservice/bin/activate&lt;br /&gt;
pip install bottle&lt;br /&gt;
pip install waitress&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Установка psycopg2 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pip install psycopg2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае возникновения ошибок при установке требуется установка необходимых библиотек на уровне операционной системы,&lt;br /&gt;
[http://stackoverflow.com/a/5450183/813758 подробнее].&lt;br /&gt;
&lt;br /&gt;
=== Установка библиотеки для парсинга конфигурационного файла ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pip install pyyaml&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создание сервиса ==&lt;br /&gt;
&lt;br /&gt;
Переходим в директорию нашего виртуального окружения geoservice:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cd geoservice&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и создаём в ней файл geoservice.py, в котором и будет располагаться код будущего HTTP-сервиса, также здесь поместим файл, содержащий описание подключения&lt;br /&gt;
к нашей базе данных config.yaml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
touch geoservice.py&lt;br /&gt;
touch config.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Открываем файл config.yaml и помещаем в него следующее содержимое:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
db:&lt;br /&gt;
  host: gis-lab.info&lt;br /&gt;
  port: 5432&lt;br /&gt;
  name: gedetdom&lt;br /&gt;
  table: data&lt;br /&gt;
  user: guest&lt;br /&gt;
  password: guest&lt;br /&gt;
  geometry_column: geometry&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Затем открываем файл geoservice.py и пишем в него:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# -*- encoding: utf-8 -*-&lt;br /&gt;
import json&lt;br /&gt;
import psycopg2&lt;br /&gt;
from bottle import route, response, request, run&lt;br /&gt;
from yaml import load&lt;br /&gt;
&lt;br /&gt;
# Остальной код будет располагаться тут&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    run(host='0.0.0.0', port=8087, server='waitress')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключение к базе данных ===&lt;br /&gt;
&lt;br /&gt;
Извлекаем информацию о подключении из конфигурационного файла:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
db_config_file = open('config.yaml', 'rb')&lt;br /&gt;
db_config = load(db_config_file).get('db')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И подключаемся к базе данных:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
conn_string = 'host=%(host)s dbname=%(name)s user=%(user)s password=%(password)s'&lt;br /&gt;
conn_string %= db_config&lt;br /&gt;
conn = psycopg2.connect(conn_string)&lt;br /&gt;
cursor = conn.cursor()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Извлечение данных из базы ===&lt;br /&gt;
&lt;br /&gt;
Опишем функцию, которая будет извлекать значения GET-параметров из URL, осуществлять запрос к базе данных и передавать данные обратно клиенту:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
@route('/features')&lt;br /&gt;
def geoservice(bbox='-180,-90,180,90', epsg='4326'):&lt;br /&gt;
&lt;br /&gt;
    # Параметры запроса&lt;br /&gt;
    bbox = (request.GET.get('bbox') or bbox).split(',')&lt;br /&gt;
    epsg = request.GET.get('epsg') or epsg&lt;br /&gt;
    attrs = request.GET.get('attrs',[])&lt;br /&gt;
    coordinates = dict(xmin=bbox[0],ymin=bbox[1],xmax=bbox[2],ymax=bbox[3])&lt;br /&gt;
    geometry_column = db_config.get('geometry_column')&lt;br /&gt;
    table = db_config.get('table')&lt;br /&gt;
&lt;br /&gt;
    # Строка запроса&lt;br /&gt;
    query = &amp;quot;&amp;quot;&amp;quot;select st_asgeojson(st_transform({gc}, {epsg})) as g, *&lt;br /&gt;
          from {table}&lt;br /&gt;
          where st_transform({gc}, {epsg}) &amp;amp;&amp;amp; st_makeenvelope({xmin},{ymin},{xmax},{ymax},{epsg});&lt;br /&gt;
          &amp;quot;&amp;quot;&amp;quot;.format(gc=geometry_column, epsg=epsg, table=table, **coordinates)&lt;br /&gt;
&lt;br /&gt;
    # Выполнение запроса&lt;br /&gt;
    cursor.execute(query)&lt;br /&gt;
    records = cursor.fetchall()&lt;br /&gt;
&lt;br /&gt;
    # Формируем GeoJSON вручную&lt;br /&gt;
    collection = {'type': 'FeatureCollection', 'features': []}&lt;br /&gt;
    for rec in records:&lt;br /&gt;
        feature = dict()&lt;br /&gt;
        feature['type'] = 'Feature'&lt;br /&gt;
        feature['properties'] = dict()&lt;br /&gt;
&lt;br /&gt;
        # Функция, возвращающая список вида [(0, attr1), (1, attr2), ..., (n, attrn)],&lt;br /&gt;
        # то есть осуществляется сопоставление имен и индексов полей&lt;br /&gt;
        columns = lambda a: zip(range(len(a)), a)&lt;br /&gt;
&lt;br /&gt;
        # Итерация по полям&lt;br /&gt;
        for colnum, col in columns(cursor.description):&lt;br /&gt;
            if col.name == 'g':&lt;br /&gt;
                feature['geometry'] = json.loads(rec[colnum])&lt;br /&gt;
                continue&lt;br /&gt;
            if col.name in attrs:&lt;br /&gt;
                feature['properties'][col.name] = rec[colnum]&lt;br /&gt;
        collection['features'].append(feature)&lt;br /&gt;
&lt;br /&gt;
    response.content_type = 'application/json'&lt;br /&gt;
    return json.dumps(collection)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Запуск сервиса ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ python geoservice.py&lt;br /&gt;
Bottle v0.11.6 server starting up (using WaitressServer())...&lt;br /&gt;
Listening on http://0.0.0.0:8087/&lt;br /&gt;
Hit Ctrl-C to quit.&lt;br /&gt;
&lt;br /&gt;
serving on http://0.0.0.0:8087&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Результаты ==&lt;br /&gt;
&lt;br /&gt;
Пришло время проверить, что же получилось. Откроем браузер и протестируем следующие URL.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://localhost:8087/features?bbox=4180824.1850282,7488851.5571727,4187192.3449474,7490776.8148227&amp;amp;epsg=3857&amp;amp;attrs=post,name&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;FeatureCollection&amp;quot;,&lt;br /&gt;
    &amp;quot;features&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    4184578.0278406707,&lt;br /&gt;
                    7489606.364854654&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;117303, Москва, ул. Каховка, 2&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Школа-интернат № 24 дя детей-сирот&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    4186044.5508123846,&lt;br /&gt;
                    7488978.3756106505&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;117452, Москва, Симферопольский б-р, 20&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Школа-интернат № 95 общеобразовательная&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как можно увидеть получены данные, удовлетворяющие заданному охвату в системе координат EPSG:3857.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://localhost:8087/features?bbox=82,53,83,54&amp;amp;attrs=post,name&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;FeatureCollection&amp;quot;,&lt;br /&gt;
    &amp;quot;features&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.995135,&lt;br /&gt;
                    53.320683&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659000, Алтайский край, с.Павловск, ул. Шумилова, 1&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Павловский детский дом&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.984438,&lt;br /&gt;
                    53.311395&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659000, Алтайский край, с.Павловск, ул. Коминтерна, 2&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Павловская школа-интернат спец.корр.&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.470054,&lt;br /&gt;
                    53.443182&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659053, Алтайский край, Шелаболихинский р-н, с.Кучук, ул. Новая, 15&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Кучукский детский дом&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.316406,&lt;br /&gt;
                    53.784103&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;633623, Новосибирская обл., п. Сузун, ул. Толстого, 11&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Социальный приют для детей и подростков \&amp;quot;Лесовичек\&amp;quot;&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.316406,&lt;br /&gt;
                    53.784103&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;633610, Новосибирская обл., п. Сузун, ул. Партизанская, 19&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Сузунская школа-интернат для детей-сирот 8ого вида&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для представления JSON-данных в удобочитаемом варианте можно воспользоватся сервисом [http://jsonlint.com/ JSONLint], что мы собственно и сделали.&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
&lt;br /&gt;
Таким образом, мы создали простейший HTTP-сервис, который на входе принимает определенный набор параметров и возвращает результат в формате GeoJSON. И хотя это всего-лишь учебный вариант, в котором не предусмотрена никакая обработка ошибок, но он наглядно показывает как может быть устроен простейший сервис подобного типа. Данные, предоставляемые этим сервисом, легко могут быть визуализированы с помощью картографического JavaScript-клиента, например, OpenLayers.&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE_HTTP-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=12884</id>
		<title>Создание простейшего HTTP-сервиса для публикации векторных данных</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE_HTTP-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=12884"/>
		<updated>2013-06-13T13:03:49Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: /* Выбор API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
При разработке Веб-ГИС зачастую возникает необходимость в передаче векторных данных с сервера на клиентскую сторону. При этом, как правило, векторные&lt;br /&gt;
данные имеют большой объем или находятся в различных хранилищах и поэтому требуется некоторое промежуточное звено, которое бы могло получать от клиентского приложения запрос данных, удовлетворяющих определенному критерию (например, попадающие в некий охват), подключаться к хранилищу данных, извлекать нужный набор и возвращать его клиенту.&lt;br /&gt;
&lt;br /&gt;
Для решения данной задачи существует специальный протокол [http://www.opengeospatial.org/standards/wfs OGC Web Feature Service], о котором мы рассказывали в одной из предыдущих [http://gis-lab.info/qa/wfs-begin.html статей]. С одной стороны, опубликовав свои данные по WFS, мы получаем очень богатые возможности:&lt;br /&gt;
&lt;br /&gt;
* отображение данных в настольных ГИС;&lt;br /&gt;
* гибкий язык описания фильтров;&lt;br /&gt;
* возможность редактирования данных.&lt;br /&gt;
&lt;br /&gt;
Если бы перед нами стояла задача просто опубликовать некоторый набор данных по WFS, то никаких проблем - берем [http://mapserver.org/trunk/tinyows/ TinyOWS],&lt;br /&gt;
[http://mapserver.org/ MapServer] или [http://geoserver.org/ GeoServer], настраиваем подключение к хранилищу - всё. Но это не наш случай, нам нужно добавить&lt;br /&gt;
WFS-функционал непосредственно в наше приложение. Как поступить в этом случае? Вариантов на самом деле не много: либо найти необходимую библиотеку на том языке&lt;br /&gt;
программирования, на котором ведется разработка, либо каким-то образом &amp;quot;прикрутить&amp;quot; имеющийся WFS-сервер к нашему приложению. Не беремся утверждать за другие языки&lt;br /&gt;
программирования, но, например, в случае Python не существует нативных библиотек, реализующих функционал WFS-сервиса, только лишь баиндинги к&lt;br /&gt;
[http://mapserver.org/mapscript/introduction.html mapscript], а это по сути сводится к установке библиотек MapServer (который написан на C/C++). Завязывание&lt;br /&gt;
же своего приложения на внешний по отношению к нему WFS-сервер - задача непростая и тянущая за собой ряд очень серьезных проблем:&lt;br /&gt;
&lt;br /&gt;
* необходимость подготовки дистрибутива WFS-сервера под целевую платформу;&lt;br /&gt;
* язык программирования, используемый при разработке основного приложения и WFS-сервера зачастую не совпадают, следовательно в случае возникновение проблем с последним, необходимо привлечение дополнительных ресурсов;&lt;br /&gt;
* сама задача по интеграции приложение с WFS-сервером далеко не тривиальная.&lt;br /&gt;
&lt;br /&gt;
Поэтому, если вы все-таки хотите использовать возможности WFS в своем приложении, то наиболее правильным видится подход в разработке соответствующего ПО на том&lt;br /&gt;
же языке программирования, что используется в вашем приложении. В этом случае вы имеете полный контроль над своей системой.&lt;br /&gt;
&lt;br /&gt;
Как показывает практика, для разработки небольших картографических Веб-приложений функционал, предлагаемый спецификацией WFS, крайне избыточен. Зачастую оказывается ненужным ни отображение данных в настольных ГИС, ни гибкий язык описания фильтров, поэтому в большинстве случаев достаточно написания собственного простейшего HTTP-сервиса, возвращающего данные в каком-нибудь стандартном формате (например,[http://gis-lab.info/docs/geojson_ru.html GeoJSON]). Именно решению данной&lt;br /&gt;
задачи и будет посвящена оставшаяся часть статьи. В качестве примера использования подобного сервиса может служить проект [http://demo.nextgis.ru/openpolice/ Найди участкового], откройте консоль вашего браузера и посмотрите какие запросы уходят на сервер при сдвиге карты.&lt;br /&gt;
&lt;br /&gt;
В качестве языка программирования будем использовать Python, операционная система - Debian GNU/Linux 7.0.&lt;br /&gt;
&lt;br /&gt;
== Выбор API ==&lt;br /&gt;
&lt;br /&gt;
Если вам требуется разработать полнофункциональный HTTP-сервис, то, чтобы не изобретать велосипед, можно взять готовое описание какого-нибудь&lt;br /&gt;
API (в зависимости от задач) и реализовать его. Например,&lt;br /&gt;
[http://trac.mapfish.org/trac/mapfish/wiki/MapFishProtocol MapFish Protocol] или [http://resources.arcgis.com/en/help/rest/apiref/index.html?featureserver.html ArcGIS Server REST API] (открытая реализация HTTP-сервиса, реализующая данный API уже [http://gis-lab.info/qa/mapfeatureserver.html существует]).&lt;br /&gt;
&lt;br /&gt;
В нашем случае мы разработаем HTTP-сервис, поддерживающий 3 GET-параметра:&lt;br /&gt;
&lt;br /&gt;
* bbox={xmin,ymin,xmax,ymax} - запрашиваемый bbox (по умолчанию считается, что координаты указаны в системе координат EPSG:4326);&lt;br /&gt;
* epsg={num} - система координат в которой должны быть возвращены данные, также используется как система координат для bbox;&lt;br /&gt;
* attrs={field1}[,{field2},...] - имена запрашиваемых атрибутивных полей.&lt;br /&gt;
&lt;br /&gt;
== Хранилище и формат выходных данных ==&lt;br /&gt;
&lt;br /&gt;
В качестве данных возьмем БД PostGIS, созданную в рамках&lt;br /&gt;
[http://gis-lab.info/qa/geodetdom-coord.html проекта по созданию слоя детских учреждений]. Выходной формат - GeoJSON.&lt;br /&gt;
&lt;br /&gt;
При разработке Веб-ГИС стандартная практика заключается в передаче данных клиенту в формате GeoJSON, при этом объект GeoJSON - это объект типа&lt;br /&gt;
&amp;quot;FeatureCollection&amp;quot; - коллекция элементарных объектов. Объект типа &amp;quot;FeatureCollection&amp;quot; содержит одно свойство &amp;quot;features&amp;quot;, значение данного свойства – массив,&lt;br /&gt;
каждый элемент которого представляет собой [http://gis-lab.info/docs/geojson_ru.html#2.2 элементарный объект].&lt;br /&gt;
&lt;br /&gt;
В PostgreSQL, начиная с версии 9.2, появились специальные функции для работы с JSON-данными, в частности [http://www.postgresql.org/docs/devel/static/functions-json.html row_to_json], позволяющие, используя SQL-запрос к базе данных PostGIS, получить &amp;quot;FeatureCollection&amp;quot;. О том как это сделать подробно описано в статье&lt;br /&gt;
[http://www.postgresonline.com/journal/archives/267-Creating-GeoJSON-Feature-Collections-with-JSON-and-PostGIS-functions.html Creating GeoJSON Feature Collections with JSON and PostGIS functions], мы же ввиду того что используемое нами хранилище развернуто на PostgreSQL 9.1 будем формировать &amp;quot;FeatureCollection&amp;quot; самостоятельно в коде&lt;br /&gt;
нашего сервиса.&lt;br /&gt;
&lt;br /&gt;
== Веб-фреймворк ==&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы облегчить себе жизнь и не писать служебный код в качестве инструмента для работы с HTTP-запросами&lt;br /&gt;
выберем какой-нибудь Веб-фреймворк. Остановимся на [http://bottlepy.org/docs/dev/ Bottle]. Данный фреймворк уже использовался нами в статье&lt;br /&gt;
[http://gis-lab.info/qa/dynamic-tms.html Основы работы динамических TMS-сервисов].&lt;br /&gt;
&lt;br /&gt;
== Установка программного обеспечения ==&lt;br /&gt;
&lt;br /&gt;
=== Установка Bottle ===&lt;br /&gt;
&lt;br /&gt;
Установим Bottle в [http://guide.python-distribute.org/virtualenv.html виртуальное окружение]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo aptitude install python-virtualenv&lt;br /&gt;
cd ~&lt;br /&gt;
virtualenv --no-site-packages geoservice&lt;br /&gt;
source geoservice/bin/activate&lt;br /&gt;
pip install bottle&lt;br /&gt;
pip install waitress&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Установка psycopg2 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pip install psycopg2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае возникновения ошибок при установке требуется установка необходимых библиотек на уровне операционной системы,&lt;br /&gt;
[http://stackoverflow.com/a/5450183/813758 подробнее].&lt;br /&gt;
&lt;br /&gt;
=== Установка библиотеки для парсинга конфигурационного файла ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pip install pyyaml&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создание сервиса ==&lt;br /&gt;
&lt;br /&gt;
Переходим в директорию нашего виртуального окружения geoservice:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cd geoservice&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и создаём в ней файл geoservice.py, в котором и будет располагаться код будущего HTTP-сервиса, также здесь поместим файл, содержащий описание подключения&lt;br /&gt;
к нашей базе данных config.yaml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
touch geoservice.py&lt;br /&gt;
touch config.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Открываем файл config.yaml и помещаем в него следующее содержимое:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
db:&lt;br /&gt;
  host: gis-lab.info&lt;br /&gt;
  port: 5432&lt;br /&gt;
  name: gedetdom&lt;br /&gt;
  table: data&lt;br /&gt;
  user: guest&lt;br /&gt;
  password: guest&lt;br /&gt;
  geometry_column: geometry&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Затем открываем файл geoservice.py и пишем в него:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# -*- encoding: utf-8 -*-&lt;br /&gt;
import json&lt;br /&gt;
import psycopg2&lt;br /&gt;
from bottle import route, response, request, run&lt;br /&gt;
from yaml import load&lt;br /&gt;
&lt;br /&gt;
# Остальной код будет располагаться тут&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    run(host='0.0.0.0', port=8087, server='waitress')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключение к базе данных ===&lt;br /&gt;
&lt;br /&gt;
Извлекаем информацию о подключении из конфигурационного файла:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
db_config_file = open('config.yaml', 'rb')&lt;br /&gt;
db_config = load(db_config_file).get('db')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И подключаемся к базе данных:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
conn_string = 'host=%(host)s dbname=%(name)s user=%(user)s password=%(password)s'&lt;br /&gt;
conn_string %= db_config&lt;br /&gt;
conn = psycopg2.connect(conn_string)&lt;br /&gt;
cursor = conn.cursor()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Извлечение данных из базы ===&lt;br /&gt;
&lt;br /&gt;
Опишем функцию, которая будет извлекать значения GET-параметров из URL, осуществлять запрос к базе данных и передавать данные обратно клиенту:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
@route('/features')&lt;br /&gt;
def geoservice(bbox='-180,-90,180,90', epsg='4326'):&lt;br /&gt;
&lt;br /&gt;
    # Параметры запроса&lt;br /&gt;
    bbox = (request.GET.get('bbox') or bbox).split(',')&lt;br /&gt;
    epsg = request.GET.get('epsg') or epsg&lt;br /&gt;
    attrs = request.GET.get('attrs',[])&lt;br /&gt;
    coordinates = dict(xmin=bbox[0],ymin=bbox[1],xmax=bbox[2],ymax=bbox[3])&lt;br /&gt;
    geometry_column = db_config.get('geometry_column')&lt;br /&gt;
    table = db_config.get('table')&lt;br /&gt;
&lt;br /&gt;
    # Строка запроса&lt;br /&gt;
    query = &amp;quot;&amp;quot;&amp;quot;select st_asgeojson(st_transform({gc}, {epsg})) as g, *&lt;br /&gt;
          from {table}&lt;br /&gt;
          where st_transform({gc}, {epsg}) &amp;amp;&amp;amp; st_makeenvelope({xmin},{ymin},{xmax},{ymax},{epsg});&lt;br /&gt;
          &amp;quot;&amp;quot;&amp;quot;.format(gc=geometry_column, epsg=epsg, table=table, **coordinates)&lt;br /&gt;
&lt;br /&gt;
    # Выполнение запроса&lt;br /&gt;
    cursor.execute(query)&lt;br /&gt;
    records = cursor.fetchall()&lt;br /&gt;
&lt;br /&gt;
    # Формируем GeoJSON вручную&lt;br /&gt;
    collection = {'type': 'FeatureCollection', 'features': []}&lt;br /&gt;
    for rec in records:&lt;br /&gt;
        feature = dict()&lt;br /&gt;
        feature['type'] = 'Feature'&lt;br /&gt;
        feature['properties'] = dict()&lt;br /&gt;
&lt;br /&gt;
        # Функция, возвращающая список вида [(0, attr1), (1, attr2), ..., (n, attrn)],&lt;br /&gt;
        # то есть осуществляется сопоставление имен и индексов полей&lt;br /&gt;
        columns = lambda a: zip(range(len(a)), a)&lt;br /&gt;
&lt;br /&gt;
        # Итерация по полям&lt;br /&gt;
        for colnum, col in columns(cursor.description):&lt;br /&gt;
            if col.name == 'g':&lt;br /&gt;
                feature['geometry'] = json.loads(rec[colnum])&lt;br /&gt;
                continue&lt;br /&gt;
            if col.name in attrs:&lt;br /&gt;
                feature['properties'][col.name] = rec[colnum]&lt;br /&gt;
        collection['features'].append(feature)&lt;br /&gt;
&lt;br /&gt;
    response.content_type = 'application/json'&lt;br /&gt;
    return json.dumps(collection)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Запуск сервиса ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ python geoservice.py&lt;br /&gt;
Bottle v0.11.6 server starting up (using WaitressServer())...&lt;br /&gt;
Listening on http://0.0.0.0:8087/&lt;br /&gt;
Hit Ctrl-C to quit.&lt;br /&gt;
&lt;br /&gt;
serving on http://0.0.0.0:8087&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Результаты ==&lt;br /&gt;
&lt;br /&gt;
Пришло время проверить, что же получилось. Откроем браузер и протестируем следующие URL.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://localhost:8087/features?bbox=4180824.1850282,7488851.5571727,4187192.3449474,7490776.8148227&amp;amp;epsg=3857&amp;amp;attrs=post,name&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;FeatureCollection&amp;quot;,&lt;br /&gt;
    &amp;quot;features&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    4184578.0278406707,&lt;br /&gt;
                    7489606.364854654&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;117303, Москва, ул. Каховка, 2&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Школа-интернат № 24 дя детей-сирот&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    4186044.5508123846,&lt;br /&gt;
                    7488978.3756106505&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;117452, Москва, Симферопольский б-р, 20&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Школа-интернат № 95 общеобразовательная&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как можно увидеть получены данные, удовлетворяющие заданному охвату в системе координат EPSG:3857.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://localhost:8087/features?bbox=82,53,83,54&amp;amp;attrs=post,name&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;FeatureCollection&amp;quot;,&lt;br /&gt;
    &amp;quot;features&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.995135,&lt;br /&gt;
                    53.320683&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659000, Алтайский край, с.Павловск, ул. Шумилова, 1&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Павловский детский дом&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.984438,&lt;br /&gt;
                    53.311395&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659000, Алтайский край, с.Павловск, ул. Коминтерна, 2&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Павловская школа-интернат спец.корр.&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.470054,&lt;br /&gt;
                    53.443182&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659053, Алтайский край, Шелаболихинский р-н, с.Кучук, ул. Новая, 15&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Кучукский детский дом&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.316406,&lt;br /&gt;
                    53.784103&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;633623, Новосибирская обл., п. Сузун, ул. Толстого, 11&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Социальный приют для детей и подростков \&amp;quot;Лесовичек\&amp;quot;&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.316406,&lt;br /&gt;
                    53.784103&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;633610, Новосибирская обл., п. Сузун, ул. Партизанская, 19&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Сузунская школа-интернат для детей-сирот 8ого вида&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для представления JSON-данных в удобочитаемом варианте можно воспользоватся сервисом [http://jsonlint.com/ JSONLint], что мы собственно и сделали.&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
&lt;br /&gt;
Таким образом, мы создали простейший HTTP-сервис, который на входе принимает определенный набор параметров и возвращает результат в формате GeoJSON. И хотя это всего-лишь учебный вариант, в котором не предусмотрена никакая обработка ошибок, но он наглядно показывает как может быть устроен простейший сервис подобного типа. Данные, предоставляемые этим сервисом, легко могут быть визуализированы с помощью картографического JavaScript-клиента, например, OpenLayers.&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE_HTTP-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=12883</id>
		<title>Создание простейшего HTTP-сервиса для публикации векторных данных</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%81%D1%82%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE_HTTP-%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BD%D1%8B%D1%85_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=12883"/>
		<updated>2013-06-13T13:03:19Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: /* Выбор API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
При разработке Веб-ГИС зачастую возникает необходимость в передаче векторных данных с сервера на клиентскую сторону. При этом, как правило, векторные&lt;br /&gt;
данные имеют большой объем или находятся в различных хранилищах и поэтому требуется некоторое промежуточное звено, которое бы могло получать от клиентского приложения запрос данных, удовлетворяющих определенному критерию (например, попадающие в некий охват), подключаться к хранилищу данных, извлекать нужный набор и возвращать его клиенту.&lt;br /&gt;
&lt;br /&gt;
Для решения данной задачи существует специальный протокол [http://www.opengeospatial.org/standards/wfs OGC Web Feature Service], о котором мы рассказывали в одной из предыдущих [http://gis-lab.info/qa/wfs-begin.html статей]. С одной стороны, опубликовав свои данные по WFS, мы получаем очень богатые возможности:&lt;br /&gt;
&lt;br /&gt;
* отображение данных в настольных ГИС;&lt;br /&gt;
* гибкий язык описания фильтров;&lt;br /&gt;
* возможность редактирования данных.&lt;br /&gt;
&lt;br /&gt;
Если бы перед нами стояла задача просто опубликовать некоторый набор данных по WFS, то никаких проблем - берем [http://mapserver.org/trunk/tinyows/ TinyOWS],&lt;br /&gt;
[http://mapserver.org/ MapServer] или [http://geoserver.org/ GeoServer], настраиваем подключение к хранилищу - всё. Но это не наш случай, нам нужно добавить&lt;br /&gt;
WFS-функционал непосредственно в наше приложение. Как поступить в этом случае? Вариантов на самом деле не много: либо найти необходимую библиотеку на том языке&lt;br /&gt;
программирования, на котором ведется разработка, либо каким-то образом &amp;quot;прикрутить&amp;quot; имеющийся WFS-сервер к нашему приложению. Не беремся утверждать за другие языки&lt;br /&gt;
программирования, но, например, в случае Python не существует нативных библиотек, реализующих функционал WFS-сервиса, только лишь баиндинги к&lt;br /&gt;
[http://mapserver.org/mapscript/introduction.html mapscript], а это по сути сводится к установке библиотек MapServer (который написан на C/C++). Завязывание&lt;br /&gt;
же своего приложения на внешний по отношению к нему WFS-сервер - задача непростая и тянущая за собой ряд очень серьезных проблем:&lt;br /&gt;
&lt;br /&gt;
* необходимость подготовки дистрибутива WFS-сервера под целевую платформу;&lt;br /&gt;
* язык программирования, используемый при разработке основного приложения и WFS-сервера зачастую не совпадают, следовательно в случае возникновение проблем с последним, необходимо привлечение дополнительных ресурсов;&lt;br /&gt;
* сама задача по интеграции приложение с WFS-сервером далеко не тривиальная.&lt;br /&gt;
&lt;br /&gt;
Поэтому, если вы все-таки хотите использовать возможности WFS в своем приложении, то наиболее правильным видится подход в разработке соответствующего ПО на том&lt;br /&gt;
же языке программирования, что используется в вашем приложении. В этом случае вы имеете полный контроль над своей системой.&lt;br /&gt;
&lt;br /&gt;
Как показывает практика, для разработки небольших картографических Веб-приложений функционал, предлагаемый спецификацией WFS, крайне избыточен. Зачастую оказывается ненужным ни отображение данных в настольных ГИС, ни гибкий язык описания фильтров, поэтому в большинстве случаев достаточно написания собственного простейшего HTTP-сервиса, возвращающего данные в каком-нибудь стандартном формате (например,[http://gis-lab.info/docs/geojson_ru.html GeoJSON]). Именно решению данной&lt;br /&gt;
задачи и будет посвящена оставшаяся часть статьи. В качестве примера использования подобного сервиса может служить проект [http://demo.nextgis.ru/openpolice/ Найди участкового], откройте консоль вашего браузера и посмотрите какие запросы уходят на сервер при сдвиге карты.&lt;br /&gt;
&lt;br /&gt;
В качестве языка программирования будем использовать Python, операционная система - Debian GNU/Linux 7.0.&lt;br /&gt;
&lt;br /&gt;
== Выбор API ==&lt;br /&gt;
&lt;br /&gt;
Если вам требуется разработать полнофункциональный HTTP-сервис, то, чтобы не изобретать велосипед, можно взять готовое описание какого-нибудь&lt;br /&gt;
API (в зависимости от задач) и реализовать его, например,&lt;br /&gt;
[http://trac.mapfish.org/trac/mapfish/wiki/MapFishProtocol MapFish Protocol] или [http://resources.arcgis.com/en/help/rest/apiref/index.html?featureserver.html ArcGIS Server REST API] (открытая реализация HTTP-сервиса, реализующая данный API уже [http://gis-lab.info/qa/mapfeatureserver.html существует]).&lt;br /&gt;
&lt;br /&gt;
В нашем случае мы разработаем HTTP-сервис, поддерживающий 3 GET-параметра:&lt;br /&gt;
&lt;br /&gt;
* bbox={xmin,ymin,xmax,ymax} - запрашиваемый bbox (по умолчанию считается, что координаты указаны в системе координат EPSG:4326);&lt;br /&gt;
* epsg={num} - система координат в которой должны быть возвращены данные, также используется как система координат для bbox;&lt;br /&gt;
* attrs={field1}[,{field2},...] - имена запрашиваемых атрибутивных полей.&lt;br /&gt;
&lt;br /&gt;
== Хранилище и формат выходных данных ==&lt;br /&gt;
&lt;br /&gt;
В качестве данных возьмем БД PostGIS, созданную в рамках&lt;br /&gt;
[http://gis-lab.info/qa/geodetdom-coord.html проекта по созданию слоя детских учреждений]. Выходной формат - GeoJSON.&lt;br /&gt;
&lt;br /&gt;
При разработке Веб-ГИС стандартная практика заключается в передаче данных клиенту в формате GeoJSON, при этом объект GeoJSON - это объект типа&lt;br /&gt;
&amp;quot;FeatureCollection&amp;quot; - коллекция элементарных объектов. Объект типа &amp;quot;FeatureCollection&amp;quot; содержит одно свойство &amp;quot;features&amp;quot;, значение данного свойства – массив,&lt;br /&gt;
каждый элемент которого представляет собой [http://gis-lab.info/docs/geojson_ru.html#2.2 элементарный объект].&lt;br /&gt;
&lt;br /&gt;
В PostgreSQL, начиная с версии 9.2, появились специальные функции для работы с JSON-данными, в частности [http://www.postgresql.org/docs/devel/static/functions-json.html row_to_json], позволяющие, используя SQL-запрос к базе данных PostGIS, получить &amp;quot;FeatureCollection&amp;quot;. О том как это сделать подробно описано в статье&lt;br /&gt;
[http://www.postgresonline.com/journal/archives/267-Creating-GeoJSON-Feature-Collections-with-JSON-and-PostGIS-functions.html Creating GeoJSON Feature Collections with JSON and PostGIS functions], мы же ввиду того что используемое нами хранилище развернуто на PostgreSQL 9.1 будем формировать &amp;quot;FeatureCollection&amp;quot; самостоятельно в коде&lt;br /&gt;
нашего сервиса.&lt;br /&gt;
&lt;br /&gt;
== Веб-фреймворк ==&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы облегчить себе жизнь и не писать служебный код в качестве инструмента для работы с HTTP-запросами&lt;br /&gt;
выберем какой-нибудь Веб-фреймворк. Остановимся на [http://bottlepy.org/docs/dev/ Bottle]. Данный фреймворк уже использовался нами в статье&lt;br /&gt;
[http://gis-lab.info/qa/dynamic-tms.html Основы работы динамических TMS-сервисов].&lt;br /&gt;
&lt;br /&gt;
== Установка программного обеспечения ==&lt;br /&gt;
&lt;br /&gt;
=== Установка Bottle ===&lt;br /&gt;
&lt;br /&gt;
Установим Bottle в [http://guide.python-distribute.org/virtualenv.html виртуальное окружение]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo aptitude install python-virtualenv&lt;br /&gt;
cd ~&lt;br /&gt;
virtualenv --no-site-packages geoservice&lt;br /&gt;
source geoservice/bin/activate&lt;br /&gt;
pip install bottle&lt;br /&gt;
pip install waitress&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Установка psycopg2 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pip install psycopg2&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае возникновения ошибок при установке требуется установка необходимых библиотек на уровне операционной системы,&lt;br /&gt;
[http://stackoverflow.com/a/5450183/813758 подробнее].&lt;br /&gt;
&lt;br /&gt;
=== Установка библиотеки для парсинга конфигурационного файла ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pip install pyyaml&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Создание сервиса ==&lt;br /&gt;
&lt;br /&gt;
Переходим в директорию нашего виртуального окружения geoservice:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cd geoservice&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и создаём в ней файл geoservice.py, в котором и будет располагаться код будущего HTTP-сервиса, также здесь поместим файл, содержащий описание подключения&lt;br /&gt;
к нашей базе данных config.yaml:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
touch geoservice.py&lt;br /&gt;
touch config.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Открываем файл config.yaml и помещаем в него следующее содержимое:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
db:&lt;br /&gt;
  host: gis-lab.info&lt;br /&gt;
  port: 5432&lt;br /&gt;
  name: gedetdom&lt;br /&gt;
  table: data&lt;br /&gt;
  user: guest&lt;br /&gt;
  password: guest&lt;br /&gt;
  geometry_column: geometry&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Затем открываем файл geoservice.py и пишем в него:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# -*- encoding: utf-8 -*-&lt;br /&gt;
import json&lt;br /&gt;
import psycopg2&lt;br /&gt;
from bottle import route, response, request, run&lt;br /&gt;
from yaml import load&lt;br /&gt;
&lt;br /&gt;
# Остальной код будет располагаться тут&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    run(host='0.0.0.0', port=8087, server='waitress')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подключение к базе данных ===&lt;br /&gt;
&lt;br /&gt;
Извлекаем информацию о подключении из конфигурационного файла:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
db_config_file = open('config.yaml', 'rb')&lt;br /&gt;
db_config = load(db_config_file).get('db')&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
И подключаемся к базе данных:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
conn_string = 'host=%(host)s dbname=%(name)s user=%(user)s password=%(password)s'&lt;br /&gt;
conn_string %= db_config&lt;br /&gt;
conn = psycopg2.connect(conn_string)&lt;br /&gt;
cursor = conn.cursor()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Извлечение данных из базы ===&lt;br /&gt;
&lt;br /&gt;
Опишем функцию, которая будет извлекать значения GET-параметров из URL, осуществлять запрос к базе данных и передавать данные обратно клиенту:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
@route('/features')&lt;br /&gt;
def geoservice(bbox='-180,-90,180,90', epsg='4326'):&lt;br /&gt;
&lt;br /&gt;
    # Параметры запроса&lt;br /&gt;
    bbox = (request.GET.get('bbox') or bbox).split(',')&lt;br /&gt;
    epsg = request.GET.get('epsg') or epsg&lt;br /&gt;
    attrs = request.GET.get('attrs',[])&lt;br /&gt;
    coordinates = dict(xmin=bbox[0],ymin=bbox[1],xmax=bbox[2],ymax=bbox[3])&lt;br /&gt;
    geometry_column = db_config.get('geometry_column')&lt;br /&gt;
    table = db_config.get('table')&lt;br /&gt;
&lt;br /&gt;
    # Строка запроса&lt;br /&gt;
    query = &amp;quot;&amp;quot;&amp;quot;select st_asgeojson(st_transform({gc}, {epsg})) as g, *&lt;br /&gt;
          from {table}&lt;br /&gt;
          where st_transform({gc}, {epsg}) &amp;amp;&amp;amp; st_makeenvelope({xmin},{ymin},{xmax},{ymax},{epsg});&lt;br /&gt;
          &amp;quot;&amp;quot;&amp;quot;.format(gc=geometry_column, epsg=epsg, table=table, **coordinates)&lt;br /&gt;
&lt;br /&gt;
    # Выполнение запроса&lt;br /&gt;
    cursor.execute(query)&lt;br /&gt;
    records = cursor.fetchall()&lt;br /&gt;
&lt;br /&gt;
    # Формируем GeoJSON вручную&lt;br /&gt;
    collection = {'type': 'FeatureCollection', 'features': []}&lt;br /&gt;
    for rec in records:&lt;br /&gt;
        feature = dict()&lt;br /&gt;
        feature['type'] = 'Feature'&lt;br /&gt;
        feature['properties'] = dict()&lt;br /&gt;
&lt;br /&gt;
        # Функция, возвращающая список вида [(0, attr1), (1, attr2), ..., (n, attrn)],&lt;br /&gt;
        # то есть осуществляется сопоставление имен и индексов полей&lt;br /&gt;
        columns = lambda a: zip(range(len(a)), a)&lt;br /&gt;
&lt;br /&gt;
        # Итерация по полям&lt;br /&gt;
        for colnum, col in columns(cursor.description):&lt;br /&gt;
            if col.name == 'g':&lt;br /&gt;
                feature['geometry'] = json.loads(rec[colnum])&lt;br /&gt;
                continue&lt;br /&gt;
            if col.name in attrs:&lt;br /&gt;
                feature['properties'][col.name] = rec[colnum]&lt;br /&gt;
        collection['features'].append(feature)&lt;br /&gt;
&lt;br /&gt;
    response.content_type = 'application/json'&lt;br /&gt;
    return json.dumps(collection)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Запуск сервиса ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ python geoservice.py&lt;br /&gt;
Bottle v0.11.6 server starting up (using WaitressServer())...&lt;br /&gt;
Listening on http://0.0.0.0:8087/&lt;br /&gt;
Hit Ctrl-C to quit.&lt;br /&gt;
&lt;br /&gt;
serving on http://0.0.0.0:8087&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Результаты ==&lt;br /&gt;
&lt;br /&gt;
Пришло время проверить, что же получилось. Откроем браузер и протестируем следующие URL.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://localhost:8087/features?bbox=4180824.1850282,7488851.5571727,4187192.3449474,7490776.8148227&amp;amp;epsg=3857&amp;amp;attrs=post,name&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;FeatureCollection&amp;quot;,&lt;br /&gt;
    &amp;quot;features&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    4184578.0278406707,&lt;br /&gt;
                    7489606.364854654&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;117303, Москва, ул. Каховка, 2&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Школа-интернат № 24 дя детей-сирот&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    4186044.5508123846,&lt;br /&gt;
                    7488978.3756106505&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;117452, Москва, Симферопольский б-р, 20&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Школа-интернат № 95 общеобразовательная&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как можно увидеть получены данные, удовлетворяющие заданному охвату в системе координат EPSG:3857.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://localhost:8087/features?bbox=82,53,83,54&amp;amp;attrs=post,name&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;FeatureCollection&amp;quot;,&lt;br /&gt;
    &amp;quot;features&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.995135,&lt;br /&gt;
                    53.320683&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659000, Алтайский край, с.Павловск, ул. Шумилова, 1&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Павловский детский дом&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.984438,&lt;br /&gt;
                    53.311395&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659000, Алтайский край, с.Павловск, ул. Коминтерна, 2&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Павловская школа-интернат спец.корр.&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.470054,&lt;br /&gt;
                    53.443182&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;659053, Алтайский край, Шелаболихинский р-н, с.Кучук, ул. Новая, 15&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Кучукский детский дом&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.316406,&lt;br /&gt;
                    53.784103&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;633623, Новосибирская обл., п. Сузун, ул. Толстого, 11&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Социальный приют для детей и подростков \&amp;quot;Лесовичек\&amp;quot;&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
                &amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;br /&gt;
                &amp;quot;coordinates&amp;quot;: [&lt;br /&gt;
                    82.316406,&lt;br /&gt;
                    53.784103&lt;br /&gt;
                ]&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;Feature&amp;quot;,&lt;br /&gt;
            &amp;quot;properties&amp;quot;: {&lt;br /&gt;
                &amp;quot;post&amp;quot;: &amp;quot;633610, Новосибирская обл., п. Сузун, ул. Партизанская, 19&amp;quot;,&lt;br /&gt;
                &amp;quot;name&amp;quot;: &amp;quot;Сузунская школа-интернат для детей-сирот 8ого вида&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для представления JSON-данных в удобочитаемом варианте можно воспользоватся сервисом [http://jsonlint.com/ JSONLint], что мы собственно и сделали.&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
&lt;br /&gt;
Таким образом, мы создали простейший HTTP-сервис, который на входе принимает определенный набор параметров и возвращает результат в формате GeoJSON. И хотя это всего-лишь учебный вариант, в котором не предусмотрена никакая обработка ошибок, но он наглядно показывает как может быть устроен простейший сервис подобного типа. Данные, предоставляемые этим сервисом, легко могут быть визуализированы с помощью картографического JavaScript-клиента, например, OpenLayers.&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12701</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12701"/>
		<updated>2013-05-31T11:54:26Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) и реализующий&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для слоев типа&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer].&lt;br /&gt;
MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими&lt;br /&gt;
[http://resources.arcgis.com/content/web/web-apis ArcGIS API],&lt;br /&gt;
равно как и получить дополнительные возможности, отсутствующие в ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет,&lt;br /&gt;
поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
Как open source продукт, MFS может принести дополнительную пользу разработчикам знающим Python.&lt;br /&gt;
&lt;br /&gt;
== Введение в тему ==&lt;br /&gt;
&lt;br /&gt;
Чтобы было понятнее, что такое MFS, нужно иметь представление о стеке технологий, поверх которых он работает.&lt;br /&gt;
&lt;br /&gt;
Как известно, есть такой подкласс ГИС решений как клиент-серверные ГИС. В случае, когда клиент использует для работы с картами&lt;br /&gt;
веб-браузер или мобильный терминал вроде смартфона или планшета, применяется название «веб-ГИС». Вероятно потому, что&lt;br /&gt;
для общения клиент-сервер используются веб технологии. Основные отличающие черты таких решений&lt;br /&gt;
заключаются в применении некоего картографического сервера и использовании HTTP/HTTPS для передачи данных между клиентом и сервером.&lt;br /&gt;
Самый распространенный вариант - это отрисовка клиентом растровых картинок, присылаемых с сервера по запросу. Из этих растровых картинок (тайлов),&lt;br /&gt;
как из мозаики, складывается изображение карты.&lt;br /&gt;
&lt;br /&gt;
На текущий момент известно не так много веб-ГИС решений, которые позволяют не только получать растровые тайлы, но и дают клиенту возможность&lt;br /&gt;
полноценно работать со слоями данных, используя геометрию объектов (features) в слоях карты,&lt;br /&gt;
передавая между клиентом и сервером координаты точек, составляющих фигуры, их атрибуты и сопутствующие метаданные.&lt;br /&gt;
Естественно, передача таких данных, назовем их условно «геометрия», осуществляется согласно определенным протоколам.&lt;br /&gt;
Тут я говорю о форматах передачи данных поверх HTTP/HTTPS. В мире свободного ПО самое большое распространение получили протоколы&lt;br /&gt;
[http://en.wikipedia.org/wiki/Web_Map_Service WMS/WFS] а если точнее, согласно теме данной статьи,&lt;br /&gt;
[http://en.wikipedia.org/wiki/Web_Feature_Service  WFS (Web Feature Service)].&lt;br /&gt;
&lt;br /&gt;
У компании Esri есть свое решение. Продукт под названием&lt;br /&gt;
[http://www.esri.com/software/arcgis/arcgisserver/features ArcGIS for Server] содержит подсистему, которая публикует веб карты,&lt;br /&gt;
слои данных из которых сделаны эти карты, и много чего еще, в данном случае не существенного. В процессе публикации карты или слоя,&lt;br /&gt;
на сервере АркГИС создаются так называемые [http://resources.arcgis.com/content/enterprisegis/10.0/services_webservices «веб сервисы»].&lt;br /&gt;
Нас, согласно теме, интересуют опубликованные слои, из которых собираются карты. В терминологии АркГИС такие слои называются&lt;br /&gt;
[http://gis.stackexchange.com/questions/26336/whats-the-difference-between-feature-class-and-feature-layer Feature Layer]&lt;br /&gt;
а сервисы, создаваемые АркГИС-ом для них называются&lt;br /&gt;
[http://help.arcgis.com/en/arcgisserver/10.0/help/arcgis_server_dotnet_help/index.html#//009300000022000000 Feature Service].&lt;br /&gt;
Протокол доступа к таким слоям несет название&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?featureserver.html ArcGIS Server REST API]&lt;br /&gt;
и позволяет через HTTP/HTTPS получать геометрию и атрибуты объектов слоя.&lt;br /&gt;
Сами передаваемые данные упаковываются в текст формата JSON. Примеры данных я приведу чуть позже.&lt;br /&gt;
Если при создании Feature Service выполнить некоторые условия (например, разместить данные в специальной БД),&lt;br /&gt;
то при использовании такого сервиса можно будет использовать все операции спектра&lt;br /&gt;
[http://en.wikipedia.org/wiki/Create,_read,_update_and_delete CRUD], а не только чтение.&lt;br /&gt;
&lt;br /&gt;
Следует упомянуть, что АркГИС Сервер умеет создавать разные типы сервисов, не только Feature Sevice. К примеру,&lt;br /&gt;
вполне можно опубликовать слой геоданных, доступ к которому будет открыт по протоколу WFS. Но в данной статье нас&lt;br /&gt;
интересует только ArcGIS Server REST API, подраздел Feature Service.&lt;br /&gt;
&lt;br /&gt;
Предпринимаются попытки создать на основе ArcGIS Server REST API всеобщий стандарт на геосервисы.&lt;br /&gt;
Этот стандарт именуется&lt;br /&gt;
[http://wiki.osgeo.org/wiki/Geoservices_REST_API GeoServices REST API] (http://www.opengeospatial.org/standards/requests/89)&lt;br /&gt;
и на данный момент сообщество очень неоднозначно реагирует на его продвижение.&lt;br /&gt;
Насколько мне известно, еще нет ни одной реализации GeoServices REST API.&lt;br /&gt;
&lt;br /&gt;
Существуют и друге протоколы работы с геоданными, несущие модную аббревиатуру&lt;br /&gt;
[http://en.wikipedia.org/wiki/Representational_state_transfer REST]&lt;br /&gt;
в своем названии или описании, например&lt;br /&gt;
[http://trac.mapfish.org/trac/mapfish/wiki/MapFishProtocol MapFish Protocol] или&lt;br /&gt;
[http://geoserver.org/display/GEOS/REST+Overview+Page GeoServer REST API].&lt;br /&gt;
Эти решения тоже заслуживают внимания, но не имеют никакого касательства к Mapfeatureserver.&lt;br /&gt;
&lt;br /&gt;
Что же касается Mapfeatureserver, то это продукт того же семейства, что&lt;br /&gt;
[http://papyrus.readthedocs.org/en/latest/ Papyrus] или&lt;br /&gt;
[http://featureserver.org/ FeatureServer],&lt;br /&gt;
только нацелен на реализацию протокола ArcGIS Server REST API, в отличие от.&lt;br /&gt;
&lt;br /&gt;
К созданию MFS меня подтолкнули следующие соображения и обстоятельства.&lt;br /&gt;
Нашим клиентам очень нравится клиентская часть для веб-ГИС, называемая&lt;br /&gt;
[http://resources.arcgis.com/en/communities/silverlight-viewer/ ArcGIS Viewer for Silverlight], на базе которой&lt;br /&gt;
мы создали специальную сборку&lt;br /&gt;
[http://www.allgis.org/cartobonus/help/ «Картобонус»].&lt;br /&gt;
Разумеется, как детище Esri, такой вьювер лучше всего работает с серверной частью этого же вендора и не очень&lt;br /&gt;
способствует попыткам подружить его с слоями, загружаемыми через сторонние сервисы, в частности WFS.&lt;br /&gt;
Это был первый звоночек - решение задачи «подключение к Картобонусу слоев из WFS». Можно либо во вьювер добавить код,&lt;br /&gt;
транслирующий примитивы WFS в обьекты вьювера&lt;br /&gt;
([https://code.google.com/p/wfst-arcgis-viewer/ как-то так]);&lt;br /&gt;
либо написать некий сервис-прокси, для превращения WFS в ArcGIS Feature Service,&lt;br /&gt;
понимаемый вьювером «из коробки».&lt;br /&gt;
&lt;br /&gt;
Другим пожеланием клиентов была функция «загрузки шейпов» во вьювер. Довольно трудно обьяснить неспециалисту,&lt;br /&gt;
что парсинг и отрисовка данных из шейпа в браузере - весьма не тривиальная задача. Да и зачем? Ведь можно дать пользователю&lt;br /&gt;
кнопку «загрузка шейпа», нажав которую, пользователь сможет создать на некоем сервере таблицу в БД и записать в нее копию шейп-файла.&lt;br /&gt;
После чего подключить к карте во вьювере слой, сформированный из этой таблицы.&lt;br /&gt;
Второй звоночек - нужен сервис, в который мы сможем грузить шейпы и потом выводить их клиентам веб-ГИС.&lt;br /&gt;
&lt;br /&gt;
Кстати, о клиентских вьюверах. Очевидно, лучше всех с геоданными из Feature Service, эмуляцией которого и занимается Mapfeatureserver,&lt;br /&gt;
умеют работать программы от Esri (упоминать приложения типа ArcMap я тут не буду, только веб)&lt;br /&gt;
* [http://resources.arcgis.com/en/tutorials/ ArcGIS Online] - яркий пример картографического вьювера, сделанного на JavaScript и продвигаемого как SaaS.&lt;br /&gt;
* [http://resources.arcgis.com/en/communities/flex-viewer/ ArcGIS Viewer for Flex] - кроссплатформенное приложение типа RIA на технологии Flash/Flex, расширяемое, с открытым кодом.&lt;br /&gt;
* Уже упомянутый [http://resources.arcgis.com/en/communities/silverlight-viewer/ ArcGIS Viewer for Silverlight] - тоже RIA, но работает только под MS Windows. Зато, используя MS Visual Studio, процесс разработки плагинов и расширений заметно ускоряется и упрощается.&lt;br /&gt;
Замечу, что эти вьюверы активно эксплуатируют очень приличный [http://resources.arcgis.com/content/web/web-apis набор API],&lt;br /&gt;
предоставляемый Esri безвозмездно, то есть даром.&lt;br /&gt;
&lt;br /&gt;
И, конечно, всеми любимый [http://openlayers.org/dev/examples/arcgis93rest.html OpenLayers]&lt;br /&gt;
тоже умеет работать со слоями по протоколу ArcGIS Server REST API.&lt;br /&gt;
&lt;br /&gt;
== Mapfeatureserver - что это такое? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис, отвечающий спецификации&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для картографических слоев типа&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer].&lt;br /&gt;
Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве&lt;br /&gt;
части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS DB, что означает необходимость&lt;br /&gt;
а) загрузить данные предполагаемого решения в БД PostGIS;&lt;br /&gt;
б) обеспечить доступ к этой БД сервису MFS.&lt;br /&gt;
На текущий момент, кроме PostGIS, другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
Также, есть планы по использованию служб WFS в качестве источников данных.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования Mapfeatureserver выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру [http://www.allgis.org/cartobonus/help/ Картобонус], добавляем к карте слои точно так же, как обычные FeatureLayer из ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для&lt;br /&gt;
демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html layer metadata] &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fsquery.html layer data query] by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Пример ответа сервера на запрос метаданных слоя&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;currentVersion&amp;quot;: 10.11,&lt;br /&gt;
 &amp;quot;id&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;name&amp;quot;: &amp;quot;Ямочный ремонт&amp;quot;,&lt;br /&gt;
 &amp;quot;type&amp;quot;: &amp;quot;Feature Layer&amp;quot;,&lt;br /&gt;
 &amp;quot;description&amp;quot;: &amp;quot;Места установки заплаток на дорогах&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;supportsAdvancedQueries&amp;quot;: true,&lt;br /&gt;
 &amp;quot;geometryType&amp;quot;: &amp;quot;esriGeometryPoint&amp;quot;,&lt;br /&gt;
 &amp;quot;minScale&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;maxScale&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;extent&amp;quot;: {&lt;br /&gt;
  &amp;quot;xmin&amp;quot;: 27.765770083999996,&lt;br /&gt;
  &amp;quot;ymin&amp;quot;: 52.86936644999997,&lt;br /&gt;
  &amp;quot;xmax&amp;quot;: 36.71166105100002,&lt;br /&gt;
  &amp;quot;ymax&amp;quot;: 62.012733638999975,&lt;br /&gt;
  &amp;quot;spatialReference&amp;quot;: {&lt;br /&gt;
   &amp;quot;wkid&amp;quot;: 4326,&lt;br /&gt;
   &amp;quot;latestWkid&amp;quot;: 4326&lt;br /&gt;
  }&lt;br /&gt;
 },&lt;br /&gt;
 &amp;quot;drawingInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;renderer&amp;quot;: {&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;uniqueValue&amp;quot;,&lt;br /&gt;
   &amp;quot;field1&amp;quot;: &amp;quot;roadcarpet&amp;quot;,&lt;br /&gt;
   &amp;quot;field2&amp;quot;: null,&lt;br /&gt;
   &amp;quot;field3&amp;quot;: null,&lt;br /&gt;
   &amp;quot;fieldDelimiter&amp;quot;: &amp;quot;, &amp;quot;,&lt;br /&gt;
   &amp;quot;defaultSymbol&amp;quot;: null,&lt;br /&gt;
   &amp;quot;defaultLabel&amp;quot;: null,&lt;br /&gt;
   &amp;quot;uniqueValueInfos&amp;quot;: [&lt;br /&gt;
	{&lt;br /&gt;
	 &amp;quot;symbol&amp;quot;: {&lt;br /&gt;
	  &amp;quot;type&amp;quot;: &amp;quot;esriPMS&amp;quot;,&lt;br /&gt;
	  &amp;quot;url&amp;quot;: &amp;quot;http://localhost:5000/static/asfalt.png&amp;quot;,&lt;br /&gt;
	  &amp;quot;imageData&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
	  &amp;quot;contentType&amp;quot;: &amp;quot;image/png&amp;quot;,&lt;br /&gt;
	  &amp;quot;width&amp;quot;: 24,&lt;br /&gt;
	  &amp;quot;height&amp;quot;: 24,&lt;br /&gt;
	  &amp;quot;angle&amp;quot;: 0,&lt;br /&gt;
	  &amp;quot;xoffset&amp;quot;: 0,&lt;br /&gt;
	  &amp;quot;yoffset&amp;quot;: 0&lt;br /&gt;
	 },&lt;br /&gt;
	 &amp;quot;value&amp;quot;: &amp;quot;Асфальт&amp;quot;,&lt;br /&gt;
	 &amp;quot;label&amp;quot;: &amp;quot;Асфальт&amp;quot;,&lt;br /&gt;
	 &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	{&lt;br /&gt;
	 &amp;quot;symbol&amp;quot;: {&lt;br /&gt;
	  &amp;quot;type&amp;quot;: &amp;quot;esriPMS&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
 },&lt;br /&gt;
 &amp;quot;hasM&amp;quot;: false,&lt;br /&gt;
 &amp;quot;hasZ&amp;quot;: false,&lt;br /&gt;
 &amp;quot;allowGeometryUpdates&amp;quot;: true,&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;fields&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;objectid&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeOID&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;OBJECTID&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: false,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: false&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;ptchlenght&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeSmallInteger&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;ДлинаУчастка, м&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: true,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;pthcdeptht&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeSmallInteger&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;ГлубинаУчастка, см&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: true,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;maxRecordCount&amp;quot;: 1000,&lt;br /&gt;
 &amp;quot;supportedQueryFormats&amp;quot;: &amp;quot;JSON, AMF&amp;quot;,&lt;br /&gt;
 &amp;quot;capabilities&amp;quot;: &amp;quot;Create,Delete,Query,Update,Uploads,Editing&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример ответа сервера на запрос данных слоя&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;features&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
        &amp;quot;descr&amp;quot;: &amp;quot;werwre&amp;quot;,&lt;br /&gt;
        &amp;quot;gid&amp;quot;: 8,&lt;br /&gt;
        &amp;quot;ptchlenght&amp;quot;: 500,&lt;br /&gt;
        &amp;quot;pthcdeptht&amp;quot;: 8,&lt;br /&gt;
        &amp;quot;regdaterec&amp;quot;: &amp;quot;2012/08/02&amp;quot;,&lt;br /&gt;
        &amp;quot;regdaterep&amp;quot;: &amp;quot;2012/09/15&amp;quot;,&lt;br /&gt;
        &amp;quot;roadcarpet&amp;quot;: &amp;quot;Асфальт&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
        &amp;quot;x&amp;quot;: 3980475.9450405277,&lt;br /&gt;
        &amp;quot;y&amp;quot;: 6976079.279805333&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;fields&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;OBJECTID&amp;quot;,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;gid&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeOID&amp;quot;&lt;br /&gt;
    },...&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;REGDATEREP&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: 50,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;regdaterep&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeString&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;ROADCARPET&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: 50,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;roadcarpet&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeString&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;geometryType&amp;quot;: &amp;quot;esriGeometryPoint&amp;quot;,&lt;br /&gt;
  &amp;quot;globalIdFieldName&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;objectIdFieldName&amp;quot;: &amp;quot;gid&amp;quot;,&lt;br /&gt;
  &amp;quot;spatialReference&amp;quot;: {&lt;br /&gt;
    &amp;quot;latestWkid&amp;quot;: 3857,&lt;br /&gt;
    &amp;quot;wkid&amp;quot;: 102100&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой,&lt;br /&gt;
кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст.&lt;br /&gt;
Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub&lt;br /&gt;
https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги (в планах есть пункт: сделать нормальный Python distribution):&lt;br /&gt;
* Скачать [https://github.com/vasnake/mapfeatureserver MFS с GitHub].&lt;br /&gt;
* Поправить настройки в файле &amp;lt;pre&amp;gt;mapfeatureserver\wsgi\default_settings.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask&lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои.&lt;br /&gt;
Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так (описания опций и ключей к командам доступны во встроенной в команды справке):&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
Здесь shpdir это папка, где расположены шейп-файлы; flyzone.shp - загружаемый шейп-файл; mfsdata.flyzone - схема данных и таблица,&lt;br /&gt;
в которую будет загружен шейп; postgisdb - имя БД; mfs - учетная запись в БД.&lt;br /&gt;
&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
Идентификатор слоя (любое положительное целое число) надо вписать в список (в примере указаны три слоя)&lt;br /&gt;
&amp;lt;pre&amp;gt;layer.ID.list: 0,1,2&amp;lt;/pre&amp;gt;&lt;br /&gt;
Вписать данные подключения к БД PostGIS, пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;PG.DSN: host=vags101 port=5432 dbname=postgisdb user=mfs password=12345678 connect_timeout=10 client_encoding=utf8&amp;lt;/pre&amp;gt;&lt;br /&gt;
Создать секцию, именованную по идентификатору слоя, скажем «2»&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[2]&lt;br /&gt;
layer.table = flyzone&lt;br /&gt;
layer.geomfield = geom&lt;br /&gt;
layer.oidfield = gid&lt;br /&gt;
layer.name = Зоны полетов с ограничениями&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Находящиеся в конфиге примеры и комментарии помогут не ошибиться.&lt;br /&gt;
&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя Feature Layer ArcGIS и внести в него правки.&lt;br /&gt;
Метаданные слоя из ArcGIS Server доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
если на сервере опубликована служба «flyzone» соответствующего типа.&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS FeatureLayer в веб-картах&lt;br /&gt;
построенных на [http://resources.arcgis.com/content/web/web-apis ArcGIS web API].&lt;br /&gt;
К примеру, есть вьювер&lt;br /&gt;
[http://www.allgis.org/cartobonus/help/ Картобонус], построенный на&lt;br /&gt;
[http://resources.arcgis.com/en/help/silverlight-viewer/concepts/ ArcGIS API for Silverlight],&lt;br /&gt;
именно он использовался для тестирования MFS. Чтобы добавить слой в карту, используйте URL вида&lt;br /&gt;
&amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:Слои Mapfeatureserver в веб-картах Картобонус.png|center|700px|Рабочий скриншот слоев из MFS во вьювере Картобонус]]&lt;br /&gt;
&lt;br /&gt;
Как видите, за исключением файла метаданных, всё достаточно просто.&lt;br /&gt;
Теперь у нас есть свободный и бесплатный сервер Feature Layer-ов для обеспечения работы любого картографического софта,&lt;br /&gt;
использующего спецификации ArcGIS REST API.&lt;br /&gt;
&lt;br /&gt;
=== Оно не работает! ===&lt;br /&gt;
Поскольку, как я уже говорил, проект находится в стадии разработки, вполне вероятно, что вы не сможете заставить его работать&lt;br /&gt;
с вашими данными. Безошибочным признаком того, что MFS не работает как должно, считается наличие Python traceback&lt;br /&gt;
в окне с приложением Flask (модуль mapfs_controller.py).&lt;br /&gt;
К примеру, это может выглядеть так:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;mapfs_controller.py&amp;quot;, line 166, in layerOperations&lt;br /&gt;
    resp = layerdata.layerData(lyrconf, ds, op)&lt;br /&gt;
  File &amp;quot;C:\d\code\git\mapfeatureserver\wsgi\layerdata.py&amp;quot;, line 65, in layerData&lt;br /&gt;
    res = layerDataInBox(datasource.cursor, lyrconf, outSR, inpBox)&lt;br /&gt;
  File &amp;quot;C:\d\code\git\mapfeatureserver\wsgi\layerdata.py&amp;quot;, line 109, in layerDataInBox&lt;br /&gt;
    box = esri.AGGeometryBox(inpBox)&lt;br /&gt;
  File &amp;quot;C:\d\code\git\mapfeatureserver\wsgi\esri.py&amp;quot;, line 47, in __init__&lt;br /&gt;
    box = simplejson.loads(jsontext)&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\__init__.py&amp;quot;, line 461, in loads&lt;br /&gt;
    return _default_decoder.decode(s)&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\decoder.py&amp;quot;, line 374, in decode&lt;br /&gt;
    obj, end = self.raw_decode(s)&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\decoder.py&amp;quot;, line 393, in raw_decode&lt;br /&gt;
    return self.scan_once(s, idx=_w(s, idx).end())&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\scanner.py&amp;quot;, line 119, in scan_once&lt;br /&gt;
    return _scan_once(string, idx)&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\scanner.py&amp;quot;, line 84, in _scan_once&lt;br /&gt;
    raise JSONDecodeError(errmsg, string, idx)&lt;br /&gt;
JSONDecodeError: Expecting value: line 1 column 1 (char 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если вы столкнетесь с чем-то подобным, не пожалейте времени, скопируйте текст traceback-а и отправьте мне.&lt;br /&gt;
По почте или, еще лучше, откройте issue на [https://github.com/vasnake/mapfeatureserver GitHub].&lt;br /&gt;
&lt;br /&gt;
Дополнительные сведения по настройке MFS.&lt;br /&gt;
* Минимальный набор привилегий пользователя в PostgreSQL, пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE USER guest WITH password 'guest';&lt;br /&gt;
ALTER USER guest SET search_path TO mfsdata,public;&lt;br /&gt;
GRANT USAGE ON schema mfsdata TO guest;&lt;br /&gt;
GRANT SELECT ON table mfsdata.patching TO guest;&lt;br /&gt;
GRANT SELECT ON geometry_columns TO guest;&lt;br /&gt;
GRANT SELECT ON geography_columns TO guest;&lt;br /&gt;
GRANT SELECT ON spatial_ref_sys TO guest;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Подразумевается, что пользователь 'guest', от имени которого должен работать Mapfeatureserver,&lt;br /&gt;
должен иметь доступ на чтение к слою, хранимому в таблице 'mfsdata.patching'.&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Спецификации REST API] или, [http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#//02r3000000w6000000 более подробно, здесь]&lt;br /&gt;
* [http://vasnake.blogspot.ru/2013/05/mapfeatureserver-poc.html Статья в блоге автора]&lt;br /&gt;
* [https://github.com/vasnake/mapfeatureserver MFS на GitHub]&lt;br /&gt;
* [http://www.allgis.org/cartobonus/help/ web map viewer Cartobonus]&lt;br /&gt;
&lt;br /&gt;
E-mail: [mailto:vasnake@gmail.com vasnake@gmail.com]&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12698</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12698"/>
		<updated>2013-05-30T23:11:00Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) и реализующий&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для слоев типа&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer].&lt;br /&gt;
MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими&lt;br /&gt;
[http://resources.arcgis.com/content/web/web-apis ArcGIS API],&lt;br /&gt;
равно как и получить дополнительные возможности, отсутствующие в ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет,&lt;br /&gt;
поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
Как open source продукт, MFS может принести дополнительную пользу разработчикам знающим Python.&lt;br /&gt;
&lt;br /&gt;
== Введение в тему ==&lt;br /&gt;
&lt;br /&gt;
Чтобы было понятнее, что такое MFS, нужно иметь представление о стеке технологий, поверх которых он работает.&lt;br /&gt;
&lt;br /&gt;
Как известно, есть такой подкласс ГИС решений как клиент-серверные ГИС. В случае, когда клиент использует для работы с картами&lt;br /&gt;
веб-браузер или мобильный терминал вроде смартфона или планшета, применяется название «веб-ГИС». Вероятно потому, что&lt;br /&gt;
для общения клиент-сервер используются веб технологии. Основные отличающие черты таких решений&lt;br /&gt;
заключаются в применении некоего картографического сервера и использовании HTTP/HTTPS для передачи данных между клиентом и сервером.&lt;br /&gt;
Самый распространенный вариант - это отрисовка клиентом растровых картинок, присылаемых с сервера по запросу. Из этих растровых картинок (тайлов),&lt;br /&gt;
как из мозаики, складывается изображение карты.&lt;br /&gt;
&lt;br /&gt;
На текущий момент известно не так много веб-ГИС решений, которые позволяют не только получать растровые тайлы, но и дают клиенту возможность&lt;br /&gt;
полноценно работать со слоями данных, используя геометрию объектов (features) в слоях карты,&lt;br /&gt;
передавая между клиентом и сервером координаты точек, составляющих фигуры, их атрибуты и сопутствующие метаданные.&lt;br /&gt;
Естественно, передача таких данных, назовем их условно «геометрия», осуществляется согласно определенным протоколам.&lt;br /&gt;
Тут я говорю о форматах передачи данных поверх HTTP/HTTPS. В мире свободного ПО самое большое распространение получили протоколы&lt;br /&gt;
[http://en.wikipedia.org/wiki/Web_Map_Service WMS/WFS] а если точнее, согласно теме данной статьи,&lt;br /&gt;
[http://en.wikipedia.org/wiki/Web_Feature_Service  WFS (Web Feature Service)].&lt;br /&gt;
&lt;br /&gt;
У компании Esri есть свое решение. Продукт под названием&lt;br /&gt;
[http://www.esri.com/software/arcgis/arcgisserver/features ArcGIS for Server] содержит подсистему, которая публикует веб карты,&lt;br /&gt;
слои данных из которых сделаны эти карты, и много чего еще, в данном случае не существенного. В процессе публикации карты или слоя,&lt;br /&gt;
на сервере АркГИС создаются так называемые [http://resources.arcgis.com/content/enterprisegis/10.0/services_webservices «веб сервисы»].&lt;br /&gt;
Нас, согласно теме, интересуют опубликованные слои, из которых собираются карты. В терминологии АркГИС такие слои называются&lt;br /&gt;
[http://gis.stackexchange.com/questions/26336/whats-the-difference-between-feature-class-and-feature-layer Feature Layer]&lt;br /&gt;
а сервисы, создаваемые АркГИС-ом для них называются&lt;br /&gt;
[http://help.arcgis.com/en/arcgisserver/10.0/help/arcgis_server_dotnet_help/index.html#//009300000022000000 Feature Service].&lt;br /&gt;
Протокол доступа к таким слоям несет название&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?featureserver.html ArcGIS Server REST API]&lt;br /&gt;
и позволяет через HTTP/HTTPS получать геометрию и атрибуты объектов слоя.&lt;br /&gt;
Сами передаваемые данные упаковываются в текст формата JSON. Примеры данных я приведу чуть позже.&lt;br /&gt;
Если при создании Feature Service выполнить некоторые условия (например, разместить данные в специальной БД),&lt;br /&gt;
то при использовании такого сервиса можно будет использовать все операции спектра&lt;br /&gt;
[http://en.wikipedia.org/wiki/Create,_read,_update_and_delete CRUD], а не только чтение.&lt;br /&gt;
&lt;br /&gt;
Следует упомянуть, что АркГИС Сервер умеет создавать разные типы сервисов, не только Feature Sevice. К примеру,&lt;br /&gt;
вполне можно опубликовать слой геоданных, доступ к которому будет открыт по протоколу WFS. Но в данной статье нас&lt;br /&gt;
интересует только ArcGIS Server REST API, подраздел Feature Service.&lt;br /&gt;
&lt;br /&gt;
Предпринимаются попытки создать на основе ArcGIS Server REST API всеобщий стандарт на геосервисы.&lt;br /&gt;
Этот стандарт именуется&lt;br /&gt;
[http://wiki.osgeo.org/wiki/Geoservices_REST_API GeoServices REST API] (http://www.opengeospatial.org/standards/requests/89)&lt;br /&gt;
и на данный момент сообщество очень неоднозначно реагирует на его продвижение.&lt;br /&gt;
Насколько мне известно, еще нет ни одной реализации GeoServices REST API.&lt;br /&gt;
&lt;br /&gt;
Существуют и друге протоколы работы с геоданными, несущие модную аббревиатуру&lt;br /&gt;
[http://en.wikipedia.org/wiki/Representational_state_transfer REST]&lt;br /&gt;
в своем названии или описании, например&lt;br /&gt;
[http://trac.mapfish.org/trac/mapfish/wiki/MapFishProtocol MapFish Protocol] или&lt;br /&gt;
[http://geoserver.org/display/GEOS/REST+Overview+Page GeoServer REST API].&lt;br /&gt;
Эти решения тоже заслуживают внимания, но не имеют никакого касательства к Mapfeatureserver.&lt;br /&gt;
&lt;br /&gt;
Что же касается Mapfeatureserver, то это продукт того же семейства, что&lt;br /&gt;
[http://papyrus.readthedocs.org/en/latest/ Papyrus] или&lt;br /&gt;
[http://featureserver.org/ FeatureServer],&lt;br /&gt;
только нацелен на реализацию протокола ArcGIS Server REST API, в отличие от.&lt;br /&gt;
&lt;br /&gt;
К созданию MFS меня подтолкнули следующие соображения и обстоятельства.&lt;br /&gt;
Нашим клиентам очень нравится клиентская часть для веб-ГИС, называемая&lt;br /&gt;
[http://resources.arcgis.com/en/communities/silverlight-viewer/ ArcGIS Viewer for Silverlight], на базе которой&lt;br /&gt;
мы создали специальную сборку&lt;br /&gt;
[http://www.allgis.org/cartobonus/help/ «Картобонус»].&lt;br /&gt;
Разумеется, как детище Esri, такой вьювер лучше всего работает с серверной частью этого же вендора и не очень&lt;br /&gt;
способствует попыткам подружить его с слоями, загружаемыми через сторонние сервисы, в частности WFS.&lt;br /&gt;
Это был первый звоночек - решение задачи «подключение к Картобонусу слоев из WFS». Можно либо во вьювер добавить код,&lt;br /&gt;
транслирующий примитивы WFS в обьекты вьювера&lt;br /&gt;
([https://code.google.com/p/wfst-arcgis-viewer/ как-то так]);&lt;br /&gt;
либо написать некий сервис-прокси, для превращения WFS в ArcGIS Feature Service,&lt;br /&gt;
понимаемый вьювером «из коробки».&lt;br /&gt;
&lt;br /&gt;
Другим пожеланием клиентов была функция «загрузки шейпов» во вьювер. Довольно трудно обьяснить неспециалисту,&lt;br /&gt;
что парсинг и отрисовка данных из шейпа в браузере - весьма не тривиальная задача. Да и зачем? Ведь можно дать пользователю&lt;br /&gt;
кнопку «загрузка шейпа», нажав которую, пользователь сможет создать на некоем сервере таблицу в БД и записать в нее копию шейп-файла.&lt;br /&gt;
После чего подключить к карте во вьювере слой, сформированный из этой таблицы.&lt;br /&gt;
Второй звоночек - нужен сервис, в который мы сможем грузить шейпы и потом выводить их клиентам веб-ГИС.&lt;br /&gt;
&lt;br /&gt;
Кстати, о клиентских вьюверах. Очевидно, лучше всех с геоданными из Feature Service, эмуляцией которого и занимается Mapfeatureserver,&lt;br /&gt;
умеют работать программы от Esri (упоминать приложения типа ArcMap я тут не буду, только веб)&lt;br /&gt;
* [http://resources.arcgis.com/en/tutorials/ ArcGIS Online] - яркий пример картографического вьювера, сделанного на JavaScript и продвигаемого как SaaS.&lt;br /&gt;
* [http://resources.arcgis.com/en/communities/flex-viewer/ ArcGIS Viewer for Flex] - кроссплатформенное приложение типа RIA на технологии Flash/Flex, расширяемое, с открытым кодом.&lt;br /&gt;
* Уже упомянутый [http://resources.arcgis.com/en/communities/silverlight-viewer/ ArcGIS Viewer for Silverlight] - тоже RIA, но работает только под MS Windows. Зато, используя MS Visual Studio, процесс разработки плагинов и расширений заметно ускоряется и упрощается.&lt;br /&gt;
Замечу, что эти вьюверы активно эксплуатируют очень приличный [http://resources.arcgis.com/content/web/web-apis набор API],&lt;br /&gt;
предоставляемый Esri безвозмездно, то есть даром.&lt;br /&gt;
&lt;br /&gt;
И, конечно, всеми любимый [http://openlayers.org/dev/examples/arcgis93rest.html OpenLayers]&lt;br /&gt;
тоже умеет работать со слоями по протоколу ArcGIS Server REST API.&lt;br /&gt;
&lt;br /&gt;
== Mapfeatureserver - что это такое? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис, отвечающий спецификации&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для картографических слоев типа&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer].&lt;br /&gt;
Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве&lt;br /&gt;
части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS DB, что означает необходимость&lt;br /&gt;
а) загрузить данные предполагаемого решения в БД PostGIS;&lt;br /&gt;
б) обеспечить доступ к этой БД сервису MFS.&lt;br /&gt;
На текущий момент, кроме PostGIS, другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
Также, есть планы по использованию служб WFS в качестве источников данных.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования Mapfeatureserver выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру [http://www.allgis.org/cartobonus/help/ Картобонус], добавляем к карте слои точно так же, как обычные FeatureLayer из ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для&lt;br /&gt;
демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html layer metadata] &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fsquery.html layer data query] by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Пример ответа сервера на запрос метаданных слоя&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;currentVersion&amp;quot;: 10.11,&lt;br /&gt;
 &amp;quot;id&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;name&amp;quot;: &amp;quot;Ямочный ремонт&amp;quot;,&lt;br /&gt;
 &amp;quot;type&amp;quot;: &amp;quot;Feature Layer&amp;quot;,&lt;br /&gt;
 &amp;quot;description&amp;quot;: &amp;quot;Места установки заплаток на дорогах&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;supportsAdvancedQueries&amp;quot;: true,&lt;br /&gt;
 &amp;quot;geometryType&amp;quot;: &amp;quot;esriGeometryPoint&amp;quot;,&lt;br /&gt;
 &amp;quot;minScale&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;maxScale&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;extent&amp;quot;: {&lt;br /&gt;
  &amp;quot;xmin&amp;quot;: 27.765770083999996,&lt;br /&gt;
  &amp;quot;ymin&amp;quot;: 52.86936644999997,&lt;br /&gt;
  &amp;quot;xmax&amp;quot;: 36.71166105100002,&lt;br /&gt;
  &amp;quot;ymax&amp;quot;: 62.012733638999975,&lt;br /&gt;
  &amp;quot;spatialReference&amp;quot;: {&lt;br /&gt;
   &amp;quot;wkid&amp;quot;: 4326,&lt;br /&gt;
   &amp;quot;latestWkid&amp;quot;: 4326&lt;br /&gt;
  }&lt;br /&gt;
 },&lt;br /&gt;
 &amp;quot;drawingInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;renderer&amp;quot;: {&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;uniqueValue&amp;quot;,&lt;br /&gt;
   &amp;quot;field1&amp;quot;: &amp;quot;roadcarpet&amp;quot;,&lt;br /&gt;
   &amp;quot;field2&amp;quot;: null,&lt;br /&gt;
   &amp;quot;field3&amp;quot;: null,&lt;br /&gt;
   &amp;quot;fieldDelimiter&amp;quot;: &amp;quot;, &amp;quot;,&lt;br /&gt;
   &amp;quot;defaultSymbol&amp;quot;: null,&lt;br /&gt;
   &amp;quot;defaultLabel&amp;quot;: null,&lt;br /&gt;
   &amp;quot;uniqueValueInfos&amp;quot;: [&lt;br /&gt;
	{&lt;br /&gt;
	 &amp;quot;symbol&amp;quot;: {&lt;br /&gt;
	  &amp;quot;type&amp;quot;: &amp;quot;esriPMS&amp;quot;,&lt;br /&gt;
	  &amp;quot;url&amp;quot;: &amp;quot;http://localhost:5000/static/asfalt.png&amp;quot;,&lt;br /&gt;
	  &amp;quot;imageData&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
	  &amp;quot;contentType&amp;quot;: &amp;quot;image/png&amp;quot;,&lt;br /&gt;
	  &amp;quot;width&amp;quot;: 24,&lt;br /&gt;
	  &amp;quot;height&amp;quot;: 24,&lt;br /&gt;
	  &amp;quot;angle&amp;quot;: 0,&lt;br /&gt;
	  &amp;quot;xoffset&amp;quot;: 0,&lt;br /&gt;
	  &amp;quot;yoffset&amp;quot;: 0&lt;br /&gt;
	 },&lt;br /&gt;
	 &amp;quot;value&amp;quot;: &amp;quot;Асфальт&amp;quot;,&lt;br /&gt;
	 &amp;quot;label&amp;quot;: &amp;quot;Асфальт&amp;quot;,&lt;br /&gt;
	 &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	{&lt;br /&gt;
	 &amp;quot;symbol&amp;quot;: {&lt;br /&gt;
	  &amp;quot;type&amp;quot;: &amp;quot;esriPMS&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
 },&lt;br /&gt;
 &amp;quot;hasM&amp;quot;: false,&lt;br /&gt;
 &amp;quot;hasZ&amp;quot;: false,&lt;br /&gt;
 &amp;quot;allowGeometryUpdates&amp;quot;: true,&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;fields&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;objectid&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeOID&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;OBJECTID&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: false,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: false&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;ptchlenght&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeSmallInteger&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;ДлинаУчастка, м&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: true,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;pthcdeptht&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeSmallInteger&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;ГлубинаУчастка, см&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: true,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;maxRecordCount&amp;quot;: 1000,&lt;br /&gt;
 &amp;quot;supportedQueryFormats&amp;quot;: &amp;quot;JSON, AMF&amp;quot;,&lt;br /&gt;
 &amp;quot;capabilities&amp;quot;: &amp;quot;Create,Delete,Query,Update,Uploads,Editing&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример ответа сервера на запрос данных слоя&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;features&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
        &amp;quot;descr&amp;quot;: &amp;quot;werwre&amp;quot;,&lt;br /&gt;
        &amp;quot;gid&amp;quot;: 8,&lt;br /&gt;
        &amp;quot;ptchlenght&amp;quot;: 500,&lt;br /&gt;
        &amp;quot;pthcdeptht&amp;quot;: 8,&lt;br /&gt;
        &amp;quot;regdaterec&amp;quot;: &amp;quot;2012/08/02&amp;quot;,&lt;br /&gt;
        &amp;quot;regdaterep&amp;quot;: &amp;quot;2012/09/15&amp;quot;,&lt;br /&gt;
        &amp;quot;roadcarpet&amp;quot;: &amp;quot;Асфальт&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
        &amp;quot;x&amp;quot;: 3980475.9450405277,&lt;br /&gt;
        &amp;quot;y&amp;quot;: 6976079.279805333&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;fields&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;OBJECTID&amp;quot;,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;gid&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeOID&amp;quot;&lt;br /&gt;
    },...&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;REGDATEREP&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: 50,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;regdaterep&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeString&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;ROADCARPET&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: 50,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;roadcarpet&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeString&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;geometryType&amp;quot;: &amp;quot;esriGeometryPoint&amp;quot;,&lt;br /&gt;
  &amp;quot;globalIdFieldName&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;objectIdFieldName&amp;quot;: &amp;quot;gid&amp;quot;,&lt;br /&gt;
  &amp;quot;spatialReference&amp;quot;: {&lt;br /&gt;
    &amp;quot;latestWkid&amp;quot;: 3857,&lt;br /&gt;
    &amp;quot;wkid&amp;quot;: 102100&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой,&lt;br /&gt;
кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст.&lt;br /&gt;
Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub&lt;br /&gt;
https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги (в планах есть пункт: сделать нормальный Python distribution):&lt;br /&gt;
* Скачать [https://github.com/vasnake/mapfeatureserver MFS с GitHub].&lt;br /&gt;
* Поправить настройки в файле &amp;lt;pre&amp;gt;mapfeatureserver\wsgi\default_settings.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask&lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои.&lt;br /&gt;
Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так (описания опций и ключей к командам доступны во встроенной в команды справке):&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
Здесь shpdir это папка, где расположены шейп-файлы; flyzone.shp - загружаемый шейп-файл; mfsdata.flyzone - схема данных и таблица,&lt;br /&gt;
в которую будет загружен шейп; postgisdb - имя БД; mfs - учетная запись в БД.&lt;br /&gt;
&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
Идентификатор слоя (любое положительное целое число) надо вписать в список (в примере указаны три слоя)&lt;br /&gt;
&amp;lt;pre&amp;gt;layer.ID.list: 0,1,2&amp;lt;/pre&amp;gt;&lt;br /&gt;
Вписать данные подключения к БД PostGIS, пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;PG.DSN: host=vags101 port=5432 dbname=postgisdb user=mfs password=12345678 connect_timeout=10 client_encoding=utf8&amp;lt;/pre&amp;gt;&lt;br /&gt;
Создать секцию, именованную по идентификатору слоя, скажем «2»&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[2]&lt;br /&gt;
layer.table = flyzone&lt;br /&gt;
layer.geomfield = geom&lt;br /&gt;
layer.oidfield = gid&lt;br /&gt;
layer.name = Зоны полетов с ограничениями&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Находящиеся в конфиге примеры и комментарии помогут не ошибиться.&lt;br /&gt;
&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя Feature Layer ArcGIS и внести в него правки.&lt;br /&gt;
Метаданные слоя из ArcGIS Server доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
если на сервере опубликована служба «flyzone» соответствующего типа.&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS FeatureLayer в веб-картах&lt;br /&gt;
построенных на [http://resources.arcgis.com/content/web/web-apis ArcGIS web API].&lt;br /&gt;
К примеру, есть вьювер&lt;br /&gt;
[http://www.allgis.org/cartobonus/help/ Картобонус], построенный на&lt;br /&gt;
[http://resources.arcgis.com/en/help/silverlight-viewer/concepts/ ArcGIS API for Silverlight],&lt;br /&gt;
именно он использовался для тестирования MFS. Чтобы добавить слой в карту, используйте URL вида&lt;br /&gt;
&amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:Слои Mapfeatureserver в веб-картах Картобонус.png|center|700px|Рабочий скриншот слоев из MFS во вьювере Картобонус]]&lt;br /&gt;
&lt;br /&gt;
Как видите, за исключением файла метаданных, всё достаточно просто.&lt;br /&gt;
Теперь у нас есть свободный и бесплатный сервер Feature Layer-ов для обеспечения работы любого картографического софта,&lt;br /&gt;
использующего спецификации ArcGIS REST API.&lt;br /&gt;
&lt;br /&gt;
=== Оно не работает! ===&lt;br /&gt;
Поскольку, как я уже говорил, проект находится в стадии разработки, вполне вероятно, что вы не сможете заставить его работать&lt;br /&gt;
с вашими данными. Безошибочным признаком того, что MFS не работает как должно, считается наличие Python traceback&lt;br /&gt;
в окне с приложением Flask (модуль mapfs_controller.py).&lt;br /&gt;
К примеру, это может выглядеть так:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;mapfs_controller.py&amp;quot;, line 166, in layerOperations&lt;br /&gt;
    resp = layerdata.layerData(lyrconf, ds, op)&lt;br /&gt;
  File &amp;quot;C:\d\code\git\mapfeatureserver\wsgi\layerdata.py&amp;quot;, line 65, in layerData&lt;br /&gt;
    res = layerDataInBox(datasource.cursor, lyrconf, outSR, inpBox)&lt;br /&gt;
  File &amp;quot;C:\d\code\git\mapfeatureserver\wsgi\layerdata.py&amp;quot;, line 109, in layerDataInBox&lt;br /&gt;
    box = esri.AGGeometryBox(inpBox)&lt;br /&gt;
  File &amp;quot;C:\d\code\git\mapfeatureserver\wsgi\esri.py&amp;quot;, line 47, in __init__&lt;br /&gt;
    box = simplejson.loads(jsontext)&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\__init__.py&amp;quot;, line 461, in loads&lt;br /&gt;
    return _default_decoder.decode(s)&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\decoder.py&amp;quot;, line 374, in decode&lt;br /&gt;
    obj, end = self.raw_decode(s)&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\decoder.py&amp;quot;, line 393, in raw_decode&lt;br /&gt;
    return self.scan_once(s, idx=_w(s, idx).end())&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\scanner.py&amp;quot;, line 119, in scan_once&lt;br /&gt;
    return _scan_once(string, idx)&lt;br /&gt;
  File &amp;quot;c:\d\Python27\lib\site-packages\simplejson\scanner.py&amp;quot;, line 84, in _scan_once&lt;br /&gt;
    raise JSONDecodeError(errmsg, string, idx)&lt;br /&gt;
JSONDecodeError: Expecting value: line 1 column 1 (char 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если вы столкнетесь с чем-то подобным, не пожалейте времени, скопируйте текст traceback-а и отправьте мне.&lt;br /&gt;
По почте или, еще лучше, откройте issue на [https://github.com/vasnake/mapfeatureserver GitHub].&lt;br /&gt;
&lt;br /&gt;
Дополнительные сведения по настройке MFS.&lt;br /&gt;
* Минимальный набор привилегий пользователя в PostgreSQL, пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE USER guest WITH password 'guest';&lt;br /&gt;
ALTER USER guest SET search_path TO mfsdata,public;&lt;br /&gt;
GRANT USAGE ON schema mfsdata TO guest;&lt;br /&gt;
GRANT SELECT ON table mfsdata.patching TO guest;&lt;br /&gt;
GRANT SELECT ON geometry_columns TO guest;&lt;br /&gt;
GRANT SELECT ON geography_columns TO guest;&lt;br /&gt;
GRANT SELECT ON spatial_ref_sys TO guest;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Подразумевается, что пользователь 'guest', от имени которого должен работать Mapfeatureserver,&lt;br /&gt;
должен иметь доступ на чтение к слою, хранимому в таблице 'mfsdata.patching'.&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Спецификации REST API]&lt;br /&gt;
* [http://vasnake.blogspot.ru/2013/05/mapfeatureserver-poc.html Статья в блоге автора]&lt;br /&gt;
* [https://github.com/vasnake/mapfeatureserver MFS на GitHub]&lt;br /&gt;
* [http://www.allgis.org/cartobonus/help/ web map viewer Cartobonus]&lt;br /&gt;
&lt;br /&gt;
E-mail: [mailto:vasnake@gmail.com vasnake@gmail.com]&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12680</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12680"/>
		<updated>2013-05-28T10:53:51Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) и реализующий&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для слоев типа&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer].&lt;br /&gt;
MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими&lt;br /&gt;
[http://resources.arcgis.com/content/web/web-apis ArcGIS API],&lt;br /&gt;
равно как и получить дополнительные возможности, отсутствующие в ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет,&lt;br /&gt;
поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
Как open source продукт, MFS может принести дополнительную пользу разработчикам знающим Python.&lt;br /&gt;
&lt;br /&gt;
== Введение в тему ==&lt;br /&gt;
&lt;br /&gt;
Чтобы было понятнее, что такое MFS, нужно иметь представление о стеке технологий, поверх которых он работает.&lt;br /&gt;
&lt;br /&gt;
Как известно, есть такой подкласс ГИС решений как клиент-серверные ГИС. В случае, когда клиент использует для работы с картами&lt;br /&gt;
веб-браузер или мобильный терминал вроде смартфона или планшета, применяется название «веб-ГИС». Вероятно потому, что&lt;br /&gt;
для общения клиент-сервер используются веб технологии. Основные отличающие черты таких решений&lt;br /&gt;
заключаются в применении некоего картографического сервера и использовании HTTP/HTTPS для передачи данных между клиентом и сервером.&lt;br /&gt;
Самый распространенный вариант - это отрисовка клиентом растровых картинок, присылаемых с сервера по запросу. Из этих растровых картинок (тайлов),&lt;br /&gt;
как из мозаики, складывается изображение карты.&lt;br /&gt;
&lt;br /&gt;
На текущий момент известно не так много веб-ГИС решений, которые позволяют не только получать растровые тайлы, но и дают клиенту возможность&lt;br /&gt;
полноценно работать со слоями данных, используя геометрию объектов (features) в слоях карты,&lt;br /&gt;
передавая между клиентом и сервером координаты точек, составляющих фигуры, их атрибуты и сопутствующие метаданные.&lt;br /&gt;
Естественно, передача таких данных, назовем их условно «геометрия», осуществляется согласно определенным протоколам.&lt;br /&gt;
Тут я говорю о форматах передачи данных поверх HTTP/HTTPS. В мире свободного ПО самое большое распространение получили протоколы&lt;br /&gt;
[http://en.wikipedia.org/wiki/Web_Map_Service WMS/WFS] а если точнее, согласно теме данной статьи,&lt;br /&gt;
[http://en.wikipedia.org/wiki/Web_Feature_Service  WFS (Web Feature Service)].&lt;br /&gt;
&lt;br /&gt;
У компании Esri есть свое решение. Продукт под названием&lt;br /&gt;
[http://www.esri.com/software/arcgis/arcgisserver/features ArcGIS for Server] содержит подсистему, которая публикует веб карты,&lt;br /&gt;
слои данных из которых сделаны эти карты, и много чего еще, в данном случае не существенного. В процессе публикации карты или слоя,&lt;br /&gt;
на сервере АркГИС создаются так называемые [http://resources.arcgis.com/content/enterprisegis/10.0/services_webservices «веб сервисы»].&lt;br /&gt;
Нас, согласно теме, интересуют опубликованные слои, из которых собираются карты. В терминологии АркГИС такие слои называются&lt;br /&gt;
[http://gis.stackexchange.com/questions/26336/whats-the-difference-between-feature-class-and-feature-layer Feature Layer]&lt;br /&gt;
а сервисы, создаваемые АркГИС-ом для них называются&lt;br /&gt;
[http://help.arcgis.com/en/arcgisserver/10.0/help/arcgis_server_dotnet_help/index.html#//009300000022000000 Feature Service].&lt;br /&gt;
Протокол доступа к таким слоям несет название&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?featureserver.html ArcGIS Server REST API]&lt;br /&gt;
и позволяет через HTTP/HTTPS получать геометрию и атрибуты объектов слоя.&lt;br /&gt;
Сами передаваемые данные упаковываются в текст формата JSON. Примеры данных я приведу чуть позже.&lt;br /&gt;
Если при создании Feature Service выполнить некоторые условия (например, разместить данные в специальной БД),&lt;br /&gt;
то при использовании такого сервиса можно будет использовать все операции спектра&lt;br /&gt;
[http://en.wikipedia.org/wiki/Create,_read,_update_and_delete CRUD], а не только чтение.&lt;br /&gt;
&lt;br /&gt;
Следует упомянуть, что АркГИС Сервер умеет создавать разные типы сервисов, не только Feature Sevice. К примеру,&lt;br /&gt;
вполне можно опубликовать слой геоданных, доступ к которому будет открыт по протоколу WFS. Но в данной статье нас&lt;br /&gt;
интересует только ArcGIS Server REST API, подраздел Feature Service.&lt;br /&gt;
&lt;br /&gt;
Предпринимаются попытки создать на основе ArcGIS Server REST API всеобщий стандарт на геосервисы.&lt;br /&gt;
Этот стандарт именуется&lt;br /&gt;
[http://wiki.osgeo.org/wiki/Geoservices_REST_API GeoServices REST API] (http://www.opengeospatial.org/standards/requests/89)&lt;br /&gt;
и на данный момент сообщество очень неоднозначно реагирует на его продвижение.&lt;br /&gt;
Насколько мне известно, еще нет ни одной реализации GeoServices REST API.&lt;br /&gt;
&lt;br /&gt;
Существуют и друге протоколы работы с геоданными, несущие модную аббревиатуру&lt;br /&gt;
[http://en.wikipedia.org/wiki/Representational_state_transfer REST]&lt;br /&gt;
в своем названии или описании, например&lt;br /&gt;
[http://trac.mapfish.org/trac/mapfish/wiki/MapFishProtocol MapFish Protocol] или&lt;br /&gt;
[http://geoserver.org/display/GEOS/REST+Overview+Page GeoServer REST API].&lt;br /&gt;
Эти решения тоже заслуживают внимания, но не имеют никакого касательства к Mapfeatureserver.&lt;br /&gt;
&lt;br /&gt;
Что же касается Mapfeatureserver, то это продукт того же семейства, что&lt;br /&gt;
[http://papyrus.readthedocs.org/en/latest/ Papyrus] или&lt;br /&gt;
[http://featureserver.org/ FeatureServer],&lt;br /&gt;
только нацелен на реализацию протокола ArcGIS Server REST API, в отличие от.&lt;br /&gt;
&lt;br /&gt;
К созданию MFS меня подтолкнули следующие соображения и обстоятельства.&lt;br /&gt;
Нашим клиентам очень нравится клиентская часть для веб-ГИС, называемая&lt;br /&gt;
[http://resources.arcgis.com/en/communities/silverlight-viewer/ ArcGIS Viewer for Silverlight], на базе которой&lt;br /&gt;
мы создали специальную сборку&lt;br /&gt;
[http://www.allgis.org/cartobonus/help/ «Картобонус»].&lt;br /&gt;
Разумеется, как детище Esri, такой вьювер лучше всего работает с серверной частью этого же вендора и не очень&lt;br /&gt;
способствует попыткам подружить его с слоями, загружаемыми через сторонние сервисы, в частности WFS.&lt;br /&gt;
Это был первый звоночек - решение задачи «подключение к Картобонусу слоев из WFS». Можно либо во вьювер добавить код,&lt;br /&gt;
транслирующий примитивы WFS в обьекты вьювера&lt;br /&gt;
([https://code.google.com/p/wfst-arcgis-viewer/ как-то так]);&lt;br /&gt;
либо написать некий сервис-прокси, для превращения WFS в ArcGIS Feature Service,&lt;br /&gt;
понимаемый вьювером «из коробки».&lt;br /&gt;
&lt;br /&gt;
Другим пожеланием клиентов была функция «загрузки шейпов» во вьювер. Довольно трудно обьяснить неспециалисту,&lt;br /&gt;
что парсинг и отрисовка данных из шейпа в браузере - весьма не тривиальная задача. Да и зачем? Ведь можно дать пользователю&lt;br /&gt;
кнопку «загрузка шейпа», нажав которую, пользователь сможет создать на некоем сервере таблицу в БД и записать в нее копию шейп-файла.&lt;br /&gt;
После чего подключить к карте во вьювере слой, сформированный из этой таблицы.&lt;br /&gt;
Второй звоночек - нужен сервис, в который мы сможем грузить шейпы и потом выводить их клиентам веб-ГИС.&lt;br /&gt;
&lt;br /&gt;
Кстати, о клиентских вьюверах. Очевидно, лучше всех с геоданными из Feature Service, эмуляцией которого и занимается Mapfeatureserver,&lt;br /&gt;
умеют работать программы от Esri (упоминать приложения типа ArcMap я тут не буду, только веб)&lt;br /&gt;
* [http://resources.arcgis.com/en/tutorials/ ArcGIS Online] - яркий пример картографического вьювера, сделанного на JavaScript и продвигаемого как SaaS.&lt;br /&gt;
* [http://resources.arcgis.com/en/communities/flex-viewer/ ArcGIS Viewer for Flex] - кроссплатформенное приложение типа RIA на технологии Flash/Flex, расширяемое, с открытым кодом.&lt;br /&gt;
* Уже упомянутый [http://resources.arcgis.com/en/communities/silverlight-viewer/ ArcGIS Viewer for Silverlight] - тоже RIA, но работает только под MS Windows. Зато, используя MS Visual Studio, процесс разработки плагинов и расширений заметно ускоряется и упрощается.&lt;br /&gt;
Замечу, что эти вьюверы активно эксплуатируют очень приличный [http://resources.arcgis.com/content/web/web-apis набор API],&lt;br /&gt;
предоставляемый Esri безвозмездно, то есть даром.&lt;br /&gt;
&lt;br /&gt;
И, конечно, всеми любимый [http://openlayers.org/dev/examples/arcgis93rest.html OpenLayers]&lt;br /&gt;
тоже умеет работать со слоями по протоколу ArcGIS Server REST API.&lt;br /&gt;
&lt;br /&gt;
== Mapfeatureserver - что это такое? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис, отвечающий спецификации&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для картографических слоев типа&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer].&lt;br /&gt;
Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве&lt;br /&gt;
части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS DB, что означает необходимость&lt;br /&gt;
а) загрузить данные предполагаемого решения в БД PostGIS;&lt;br /&gt;
б) обеспечить доступ к этой БД сервису MFS.&lt;br /&gt;
На текущий момент, кроме PostGIS, другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
Также, есть планы по использованию служб WFS в качестве источников данных.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования Mapfeatureserver выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру [http://www.allgis.org/cartobonus/help/ Картобонус], добавляем к карте слои точно так же, как обычные FeatureLayer из ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для&lt;br /&gt;
демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html layer metadata] &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fsquery.html layer data query] by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Пример ответа сервера на запрос метаданных слоя&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;currentVersion&amp;quot;: 10.11,&lt;br /&gt;
 &amp;quot;id&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;name&amp;quot;: &amp;quot;Ямочный ремонт&amp;quot;,&lt;br /&gt;
 &amp;quot;type&amp;quot;: &amp;quot;Feature Layer&amp;quot;,&lt;br /&gt;
 &amp;quot;description&amp;quot;: &amp;quot;Места установки заплаток на дорогах&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;supportsAdvancedQueries&amp;quot;: true,&lt;br /&gt;
 &amp;quot;geometryType&amp;quot;: &amp;quot;esriGeometryPoint&amp;quot;,&lt;br /&gt;
 &amp;quot;minScale&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;maxScale&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;extent&amp;quot;: {&lt;br /&gt;
  &amp;quot;xmin&amp;quot;: 27.765770083999996,&lt;br /&gt;
  &amp;quot;ymin&amp;quot;: 52.86936644999997,&lt;br /&gt;
  &amp;quot;xmax&amp;quot;: 36.71166105100002,&lt;br /&gt;
  &amp;quot;ymax&amp;quot;: 62.012733638999975,&lt;br /&gt;
  &amp;quot;spatialReference&amp;quot;: {&lt;br /&gt;
   &amp;quot;wkid&amp;quot;: 4326,&lt;br /&gt;
   &amp;quot;latestWkid&amp;quot;: 4326&lt;br /&gt;
  }&lt;br /&gt;
 },&lt;br /&gt;
 &amp;quot;drawingInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;renderer&amp;quot;: {&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;uniqueValue&amp;quot;,&lt;br /&gt;
   &amp;quot;field1&amp;quot;: &amp;quot;roadcarpet&amp;quot;,&lt;br /&gt;
   &amp;quot;field2&amp;quot;: null,&lt;br /&gt;
   &amp;quot;field3&amp;quot;: null,&lt;br /&gt;
   &amp;quot;fieldDelimiter&amp;quot;: &amp;quot;, &amp;quot;,&lt;br /&gt;
   &amp;quot;defaultSymbol&amp;quot;: null,&lt;br /&gt;
   &amp;quot;defaultLabel&amp;quot;: null,&lt;br /&gt;
   &amp;quot;uniqueValueInfos&amp;quot;: [&lt;br /&gt;
	{&lt;br /&gt;
	 &amp;quot;symbol&amp;quot;: {&lt;br /&gt;
	  &amp;quot;type&amp;quot;: &amp;quot;esriPMS&amp;quot;,&lt;br /&gt;
	  &amp;quot;url&amp;quot;: &amp;quot;http://localhost:5000/static/asfalt.png&amp;quot;,&lt;br /&gt;
	  &amp;quot;imageData&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
	  &amp;quot;contentType&amp;quot;: &amp;quot;image/png&amp;quot;,&lt;br /&gt;
	  &amp;quot;width&amp;quot;: 24,&lt;br /&gt;
	  &amp;quot;height&amp;quot;: 24,&lt;br /&gt;
	  &amp;quot;angle&amp;quot;: 0,&lt;br /&gt;
	  &amp;quot;xoffset&amp;quot;: 0,&lt;br /&gt;
	  &amp;quot;yoffset&amp;quot;: 0&lt;br /&gt;
	 },&lt;br /&gt;
	 &amp;quot;value&amp;quot;: &amp;quot;Асфальт&amp;quot;,&lt;br /&gt;
	 &amp;quot;label&amp;quot;: &amp;quot;Асфальт&amp;quot;,&lt;br /&gt;
	 &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	{&lt;br /&gt;
	 &amp;quot;symbol&amp;quot;: {&lt;br /&gt;
	  &amp;quot;type&amp;quot;: &amp;quot;esriPMS&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
 },&lt;br /&gt;
 &amp;quot;hasM&amp;quot;: false,&lt;br /&gt;
 &amp;quot;hasZ&amp;quot;: false,&lt;br /&gt;
 &amp;quot;allowGeometryUpdates&amp;quot;: true,&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;fields&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;objectid&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeOID&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;OBJECTID&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: false,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: false&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;ptchlenght&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeSmallInteger&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;ДлинаУчастка, м&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: true,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;pthcdeptht&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeSmallInteger&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;ГлубинаУчастка, см&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: true,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;maxRecordCount&amp;quot;: 1000,&lt;br /&gt;
 &amp;quot;supportedQueryFormats&amp;quot;: &amp;quot;JSON, AMF&amp;quot;,&lt;br /&gt;
 &amp;quot;capabilities&amp;quot;: &amp;quot;Create,Delete,Query,Update,Uploads,Editing&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример ответа сервера на запрос данных слоя&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;features&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
        &amp;quot;descr&amp;quot;: &amp;quot;werwre&amp;quot;,&lt;br /&gt;
        &amp;quot;gid&amp;quot;: 8,&lt;br /&gt;
        &amp;quot;ptchlenght&amp;quot;: 500,&lt;br /&gt;
        &amp;quot;pthcdeptht&amp;quot;: 8,&lt;br /&gt;
        &amp;quot;regdaterec&amp;quot;: &amp;quot;2012/08/02&amp;quot;,&lt;br /&gt;
        &amp;quot;regdaterep&amp;quot;: &amp;quot;2012/09/15&amp;quot;,&lt;br /&gt;
        &amp;quot;roadcarpet&amp;quot;: &amp;quot;Асфальт&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
        &amp;quot;x&amp;quot;: 3980475.9450405277,&lt;br /&gt;
        &amp;quot;y&amp;quot;: 6976079.279805333&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;fields&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;OBJECTID&amp;quot;,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;gid&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeOID&amp;quot;&lt;br /&gt;
    },...&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;REGDATEREP&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: 50,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;regdaterep&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeString&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;ROADCARPET&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: 50,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;roadcarpet&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeString&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;geometryType&amp;quot;: &amp;quot;esriGeometryPoint&amp;quot;,&lt;br /&gt;
  &amp;quot;globalIdFieldName&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;objectIdFieldName&amp;quot;: &amp;quot;gid&amp;quot;,&lt;br /&gt;
  &amp;quot;spatialReference&amp;quot;: {&lt;br /&gt;
    &amp;quot;latestWkid&amp;quot;: 3857,&lt;br /&gt;
    &amp;quot;wkid&amp;quot;: 102100&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой,&lt;br /&gt;
кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст.&lt;br /&gt;
Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub&lt;br /&gt;
https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги (в планах есть пункт: сделать нормальный Python distribution):&lt;br /&gt;
* Скачать [https://github.com/vasnake/mapfeatureserver MFS с GitHub].&lt;br /&gt;
* Поправить настройки в файле &amp;lt;pre&amp;gt;mapfeatureserver\wsgi\default_settings.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask&lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои.&lt;br /&gt;
Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так (описания опций и ключей к командам доступны во встроенной в команды справке):&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
Здесь shpdir это папка, где расположены шейп-файлы; flyzone.shp - загружаемый шейп-файл; mfsdata.flyzone - схема данных и таблица,&lt;br /&gt;
в которую будет загружен шейп; postgisdb - имя БД; mfs - учетная запись в БД.&lt;br /&gt;
&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
Идентификатор слоя (любое положительное целое число) надо вписать в список (в примере указаны три слоя)&lt;br /&gt;
&amp;lt;pre&amp;gt;layer.ID.list: 0,1,2&amp;lt;/pre&amp;gt;&lt;br /&gt;
Вписать данные подключения к БД PostGIS, пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;PG.DSN: host=vags101 port=5432 dbname=postgisdb user=mfs password=12345678 connect_timeout=10 client_encoding=utf8&amp;lt;/pre&amp;gt;&lt;br /&gt;
Создать секцию, именованную по идентификатору слоя, скажем «2»&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[2]&lt;br /&gt;
layer.table = flyzone&lt;br /&gt;
layer.geomfield = geom&lt;br /&gt;
layer.oidfield = gid&lt;br /&gt;
layer.name = Зоны полетов с ограничениями&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Находящиеся в конфиге примеры и комментарии помогут не ошибиться.&lt;br /&gt;
&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя Feature Layer ArcGIS и внести в него правки.&lt;br /&gt;
Метаданные слоя из ArcGIS Server доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
если на сервере опубликована служба «flyzone» соответствующего типа.&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS FeatureLayer в веб-картах&lt;br /&gt;
построенных на [http://resources.arcgis.com/content/web/web-apis ArcGIS web API].&lt;br /&gt;
К примеру, есть вьювер&lt;br /&gt;
[http://www.allgis.org/cartobonus/help/ Картобонус], построенный на&lt;br /&gt;
[http://resources.arcgis.com/en/help/silverlight-viewer/concepts/ ArcGIS API for Silverlight],&lt;br /&gt;
именно он использовался для тестирования MFS. Чтобы добавить слой в карту, используйте URL вида&lt;br /&gt;
&amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:Слои Mapfeatureserver в веб-картах Картобонус.png|center|700px|Рабочий скриншот слоев из MFS во вьювере Картобонус]]&lt;br /&gt;
&lt;br /&gt;
Как видите, за исключением файла метаданных, всё достаточно просто.&lt;br /&gt;
Теперь у нас есть свободный и бесплатный сервер Feature Layer-ов для обеспечения работы любого картографического софта,&lt;br /&gt;
использующего спецификации ArcGIS REST API.&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Спецификации REST API]&lt;br /&gt;
* [http://vasnake.blogspot.ru/2013/05/mapfeatureserver-poc.html Статья в блоге автора]&lt;br /&gt;
* [https://github.com/vasnake/mapfeatureserver MFS на GitHub]&lt;br /&gt;
* [http://www.allgis.org/cartobonus/help/ web map viewer Cartobonus]&lt;br /&gt;
&lt;br /&gt;
E-mail: [mailto:vasnake@gmail.com vasnake@gmail.com]&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12679</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12679"/>
		<updated>2013-05-27T22:29:39Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) и реализующий&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для слоев типа&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer].&lt;br /&gt;
MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими&lt;br /&gt;
[http://resources.arcgis.com/content/web/web-apis ArcGIS API],&lt;br /&gt;
равно как и получить дополнительные возможности, отсутствующие в ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет,&lt;br /&gt;
поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
Как open source продукт, MFS может принести дополнительную пользу разработчикам знающим Python.&lt;br /&gt;
&lt;br /&gt;
== Введение в тему ==&lt;br /&gt;
&lt;br /&gt;
Чтобы было понятнее, что такое MFS, нужно иметь представление о стеке технологий, поверх которых он работает.&lt;br /&gt;
&lt;br /&gt;
Как известно, есть такой подкласс ГИС решений как клиент-серверные ГИС. В случае, когда клиент использует для работы с картами&lt;br /&gt;
веб-браузер или мобильный терминал вроде смартфона или планшета, применяется название «веб-ГИС». Вероятно потому, что&lt;br /&gt;
для общения клиент-сервер используются веб технологии. Основные отличающие черты таких решений&lt;br /&gt;
заключаются в применении некоего картографического сервера и использовании HTTP/HTTPS для передачи данных между клиентом и сервером.&lt;br /&gt;
Самый распространенный вариант - это отрисовка клиентом растровых картинок, присылаемых с сервера по запросу. Из этих растровых картинок (тайлов),&lt;br /&gt;
как из мозаики, складывается изображение карты.&lt;br /&gt;
&lt;br /&gt;
На текущий момент известно не так много веб-ГИС решений, которые позволяют не только получать растровые тайлы, но и дают клиенту возможность&lt;br /&gt;
полноценно работать со слоями данных, используя геометрию объектов (features) в слоях карты,&lt;br /&gt;
передавая между клиентом и сервером координаты точек, составляющих фигуры, их атрибуты и сопутствующие метаданные.&lt;br /&gt;
Естественно, передача таких данных, назовем их условно «геометрия», осуществляется согласно определенным протоколам.&lt;br /&gt;
Тут я говорю о форматах передачи данных поверх HTTP/HTTPS. В мире свободного ПО самое большое распространение получили протоколы&lt;br /&gt;
[http://en.wikipedia.org/wiki/Web_Map_Service WMS/WFS] а если точнее, согласно теме данной статьи,&lt;br /&gt;
[http://en.wikipedia.org/wiki/Web_Feature_Service  WFS (Web Feature Service)].&lt;br /&gt;
&lt;br /&gt;
У компании Esri есть свое решение. Продукт под названием&lt;br /&gt;
[http://www.esri.com/software/arcgis/arcgisserver/features ArcGIS for Server] содержит подсистему, которая публикует веб карты,&lt;br /&gt;
слои данных из которых сделаны эти карты, и много чего еще, в данном случае не существенного. В процессе публикации карты или слоя,&lt;br /&gt;
на сервере АркГИС создаются так называемые [http://resources.arcgis.com/content/enterprisegis/10.0/services_webservices «веб сервисы»].&lt;br /&gt;
Нас, согласно теме, интересуют опубликованные слои, из которых собираются карты. В терминологии АрГИС такие слои называются&lt;br /&gt;
[http://gis.stackexchange.com/questions/26336/whats-the-difference-between-feature-class-and-feature-layer Feature Layer]&lt;br /&gt;
а сервисы, создаваемые АркГИС-ом для них называются&lt;br /&gt;
[http://help.arcgis.com/en/arcgisserver/10.0/help/arcgis_server_dotnet_help/index.html#//009300000022000000 Feature Service].&lt;br /&gt;
Протокол доступа к таким слоям несет название&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?featureserver.html ArcGIS Server REST API]&lt;br /&gt;
и позволяет через HTTP/HTTPS получать геометрию и атрибуты объектов слоя.&lt;br /&gt;
Сами передаваемые данные упаковываются в текст формата JSON. Примеры данных я приведу чуть позже.&lt;br /&gt;
Если при создании Feature Service выполнить некоторые условия (например, разместить данные в специальной БД),&lt;br /&gt;
то при использовании такого сервиса можно будет использовать все операции спектра&lt;br /&gt;
[http://en.wikipedia.org/wiki/Create,_read,_update_and_delete CRUD], а не только чтение.&lt;br /&gt;
&lt;br /&gt;
Следует упомянуть, что АркГИС Сервер умеет создавать разные типы сервисов, не только Feature Sevice. К примеру,&lt;br /&gt;
вполне можно опубликовать слой геоданных, доступ к которому будет открыт по протоколу WFS. Но в данной статье нас&lt;br /&gt;
интересует только ArcGIS Server REST API, подраздел Feature Service.&lt;br /&gt;
&lt;br /&gt;
Предпринимаются попытки создать на основе ArcGIS Server REST API всеобщий стандарт на геосервисы.&lt;br /&gt;
Этот стандарт именуется&lt;br /&gt;
[http://wiki.osgeo.org/wiki/Geoservices_REST_API GeoServices REST API] (http://www.opengeospatial.org/standards/requests/89)&lt;br /&gt;
и на данный момент сообщество очень неоднозначно реагирует на его продвижение.&lt;br /&gt;
Насколько мне известно, еще нет ни одной реализации GeoServices REST API.&lt;br /&gt;
&lt;br /&gt;
Существуют и друге протоколы работы с геоданными, несущие модную аббревиатуру&lt;br /&gt;
[http://en.wikipedia.org/wiki/Representational_state_transfer REST]&lt;br /&gt;
в своем названии или описании, например&lt;br /&gt;
[http://trac.mapfish.org/trac/mapfish/wiki/MapFishProtocol MapFish Protocol] или&lt;br /&gt;
[http://geoserver.org/display/GEOS/REST+Overview+Page GeoServer REST API].&lt;br /&gt;
Эти решения тоже заслуживают внимания, но не имеют никакого касательства к Mapfeatureserver.&lt;br /&gt;
&lt;br /&gt;
Что же касается Mapfeatureserver, то это продукт того же семейства, что&lt;br /&gt;
[http://papyrus.readthedocs.org/en/latest/ Papyrus] или&lt;br /&gt;
[http://featureserver.org/ FeatureServer],&lt;br /&gt;
только нацелен на реализацию протокола ArcGIS Server REST API, в отличие от.&lt;br /&gt;
&lt;br /&gt;
К созданию MFS меня подтолкнули следующие соображения и обстоятельства.&lt;br /&gt;
Нашим клиентам очень нравится клиентская часть для веб-ГИС, называемая&lt;br /&gt;
[http://resources.arcgis.com/en/communities/silverlight-viewer/ ArcGIS Viewer for Silverlight], на базе которой&lt;br /&gt;
мы создали специальную сборку&lt;br /&gt;
[http://www.allgis.org/cartobonus/help/ «Картобонус»].&lt;br /&gt;
Разумеется, как детище Esri, такой вьювер лучше всего работает с серверной частью этого же вендора и не очень&lt;br /&gt;
способствует попыткам подружить его с слоями, загружаемыми через сторонние сервисы, в частности WFS.&lt;br /&gt;
Это был первый звоночек - решение задачи «подключение к Картобонусу слоев из WFS». Можно либо во вьювер добавить код,&lt;br /&gt;
транслирующий примитивы WFS в обьекты вьювера&lt;br /&gt;
([https://code.google.com/p/wfst-arcgis-viewer/ как-то так]);&lt;br /&gt;
либо написать некий сервис-прокси, для превращения WFS в ArcGIS Feature Service,&lt;br /&gt;
понимаемый вьювером «из коробки».&lt;br /&gt;
&lt;br /&gt;
Другим пожеланием клиентов была функция «загрузки шейпов» во вьювер. Довольно трудно обьяснить неспециалисту,&lt;br /&gt;
что парсинг и отрисовка данных из шейпа в браузере - весьма не тривиальная задача. Да и зачем? Ведь можно дать пользователю&lt;br /&gt;
кнопку «загрузка шейпа», нажав которую, пользователь сможет создать на некоем сервере таблицу в БД и записать в нее копию шейп-файла.&lt;br /&gt;
После чего подключить к карте во вьювере слой, сформированный из этой таблицы.&lt;br /&gt;
Второй звоночек - нужен сервис, в который мы сможем грузить шейпы и потом выводить их клиентам веб-ГИС.&lt;br /&gt;
&lt;br /&gt;
Кстати, о клиентских вьюверах. Очевидно, лучше всех с геоданными из Feature Service, эмуляцией которого и занимается Mapfeatureserver,&lt;br /&gt;
умеют работать программы от Esri (упоминать приложения типа ArcMap я тут не буду, только веб)&lt;br /&gt;
* [http://resources.arcgis.com/en/tutorials/ ArcGIS Online] - яркий пример картографического вьювера, сделанного на JavaScript и продвигаемого как SaaS.&lt;br /&gt;
* [http://resources.arcgis.com/en/communities/flex-viewer/ ArcGIS Viewer for Flex] - кроссплатформенное приложение типа RIA на технологии Flash/Flex, расширяемое, с открытым кодом.&lt;br /&gt;
* Уже упомянутый [http://resources.arcgis.com/en/communities/silverlight-viewer/ ArcGIS Viewer for Silverlight] - тоже RIA, но работает только под MS Windows. Зато, используя MS Visual Studio, процесс разработки плагинов и расширений заметно ускоряется и упрощается.&lt;br /&gt;
Замечу, что эти вьюверы активно эксплуатируют очень приличный [http://resources.arcgis.com/content/web/web-apis набор API],&lt;br /&gt;
предоставляемый Esri безвозмездно, то есть даром.&lt;br /&gt;
&lt;br /&gt;
И, конечно, всеми любимый [http://openlayers.org/dev/examples/arcgis93rest.html OpenLayers]&lt;br /&gt;
тоже умеет работать со слоями по протоколу ArcGIS Server REST API.&lt;br /&gt;
&lt;br /&gt;
== Mapfeatureserver - что это такое? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис, отвечающий спецификации&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для картографических слоев типа&lt;br /&gt;
[http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer].&lt;br /&gt;
Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве&lt;br /&gt;
части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS DB, что означает необходимость&lt;br /&gt;
а) загрузить данные предполагаемого решения в БД PostGIS;&lt;br /&gt;
б) обеспечить доступ к этой БД сервису MFS.&lt;br /&gt;
На текущий момент, кроме PostGIS, другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
Также, есть планы по использованию служб WFS в качестве источников данных.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования Mapfeatureserver выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру [http://www.allgis.org/cartobonus/help/ Картобонус], добавляем к карте слои точно так же, как обычные FeatureLayer из ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для&lt;br /&gt;
демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html layer metadata] &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fsquery.html layer data query] by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Пример ответа сервера на запрос метаданных слоя&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;currentVersion&amp;quot;: 10.11,&lt;br /&gt;
 &amp;quot;id&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;name&amp;quot;: &amp;quot;Ямочный ремонт&amp;quot;,&lt;br /&gt;
 &amp;quot;type&amp;quot;: &amp;quot;Feature Layer&amp;quot;,&lt;br /&gt;
 &amp;quot;description&amp;quot;: &amp;quot;Места установки заплаток на дорогах&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;supportsAdvancedQueries&amp;quot;: true,&lt;br /&gt;
 &amp;quot;geometryType&amp;quot;: &amp;quot;esriGeometryPoint&amp;quot;,&lt;br /&gt;
 &amp;quot;minScale&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;maxScale&amp;quot;: 0,&lt;br /&gt;
 &amp;quot;extent&amp;quot;: {&lt;br /&gt;
  &amp;quot;xmin&amp;quot;: 27.765770083999996,&lt;br /&gt;
  &amp;quot;ymin&amp;quot;: 52.86936644999997,&lt;br /&gt;
  &amp;quot;xmax&amp;quot;: 36.71166105100002,&lt;br /&gt;
  &amp;quot;ymax&amp;quot;: 62.012733638999975,&lt;br /&gt;
  &amp;quot;spatialReference&amp;quot;: {&lt;br /&gt;
   &amp;quot;wkid&amp;quot;: 4326,&lt;br /&gt;
   &amp;quot;latestWkid&amp;quot;: 4326&lt;br /&gt;
  }&lt;br /&gt;
 },&lt;br /&gt;
 &amp;quot;drawingInfo&amp;quot;: {&lt;br /&gt;
  &amp;quot;renderer&amp;quot;: {&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;uniqueValue&amp;quot;,&lt;br /&gt;
   &amp;quot;field1&amp;quot;: &amp;quot;roadcarpet&amp;quot;,&lt;br /&gt;
   &amp;quot;field2&amp;quot;: null,&lt;br /&gt;
   &amp;quot;field3&amp;quot;: null,&lt;br /&gt;
   &amp;quot;fieldDelimiter&amp;quot;: &amp;quot;, &amp;quot;,&lt;br /&gt;
   &amp;quot;defaultSymbol&amp;quot;: null,&lt;br /&gt;
   &amp;quot;defaultLabel&amp;quot;: null,&lt;br /&gt;
   &amp;quot;uniqueValueInfos&amp;quot;: [&lt;br /&gt;
	{&lt;br /&gt;
	 &amp;quot;symbol&amp;quot;: {&lt;br /&gt;
	  &amp;quot;type&amp;quot;: &amp;quot;esriPMS&amp;quot;,&lt;br /&gt;
	  &amp;quot;url&amp;quot;: &amp;quot;http://localhost:5000/static/asfalt.png&amp;quot;,&lt;br /&gt;
	  &amp;quot;imageData&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
	  &amp;quot;contentType&amp;quot;: &amp;quot;image/png&amp;quot;,&lt;br /&gt;
	  &amp;quot;width&amp;quot;: 24,&lt;br /&gt;
	  &amp;quot;height&amp;quot;: 24,&lt;br /&gt;
	  &amp;quot;angle&amp;quot;: 0,&lt;br /&gt;
	  &amp;quot;xoffset&amp;quot;: 0,&lt;br /&gt;
	  &amp;quot;yoffset&amp;quot;: 0&lt;br /&gt;
	 },&lt;br /&gt;
	 &amp;quot;value&amp;quot;: &amp;quot;Асфальт&amp;quot;,&lt;br /&gt;
	 &amp;quot;label&amp;quot;: &amp;quot;Асфальт&amp;quot;,&lt;br /&gt;
	 &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	{&lt;br /&gt;
	 &amp;quot;symbol&amp;quot;: {&lt;br /&gt;
	  &amp;quot;type&amp;quot;: &amp;quot;esriPMS&amp;quot;,&lt;br /&gt;
...&lt;br /&gt;
 },&lt;br /&gt;
 &amp;quot;hasM&amp;quot;: false,&lt;br /&gt;
 &amp;quot;hasZ&amp;quot;: false,&lt;br /&gt;
 &amp;quot;allowGeometryUpdates&amp;quot;: true,&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;fields&amp;quot;: [&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;objectid&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeOID&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;OBJECTID&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: false,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: false&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;ptchlenght&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeSmallInteger&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;ДлинаУчастка, м&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: true,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;pthcdeptht&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeSmallInteger&amp;quot;,&lt;br /&gt;
   &amp;quot;alias&amp;quot;: &amp;quot;ГлубинаУчастка, см&amp;quot;,&lt;br /&gt;
   &amp;quot;domain&amp;quot;: null,&lt;br /&gt;
   &amp;quot;editable&amp;quot;: true,&lt;br /&gt;
   &amp;quot;nullable&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
...&lt;br /&gt;
 &amp;quot;maxRecordCount&amp;quot;: 1000,&lt;br /&gt;
 &amp;quot;supportedQueryFormats&amp;quot;: &amp;quot;JSON, AMF&amp;quot;,&lt;br /&gt;
 &amp;quot;capabilities&amp;quot;: &amp;quot;Create,Delete,Query,Update,Uploads,Editing&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пример ответа сервера на запрос данных слоя&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;features&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
        &amp;quot;descr&amp;quot;: &amp;quot;werwre&amp;quot;,&lt;br /&gt;
        &amp;quot;gid&amp;quot;: 8,&lt;br /&gt;
        &amp;quot;ptchlenght&amp;quot;: 500,&lt;br /&gt;
        &amp;quot;pthcdeptht&amp;quot;: 8,&lt;br /&gt;
        &amp;quot;regdaterec&amp;quot;: &amp;quot;2012/08/02&amp;quot;,&lt;br /&gt;
        &amp;quot;regdaterep&amp;quot;: &amp;quot;2012/09/15&amp;quot;,&lt;br /&gt;
        &amp;quot;roadcarpet&amp;quot;: &amp;quot;Асфальт&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;geometry&amp;quot;: {&lt;br /&gt;
        &amp;quot;x&amp;quot;: 3980475.9450405277,&lt;br /&gt;
        &amp;quot;y&amp;quot;: 6976079.279805333&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;fields&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;OBJECTID&amp;quot;,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;gid&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeOID&amp;quot;&lt;br /&gt;
    },...&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;REGDATEREP&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: 50,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;regdaterep&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeString&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;alias&amp;quot;: &amp;quot;ROADCARPET&amp;quot;,&lt;br /&gt;
      &amp;quot;length&amp;quot;: 50,&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;roadcarpet&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;esriFieldTypeString&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;geometryType&amp;quot;: &amp;quot;esriGeometryPoint&amp;quot;,&lt;br /&gt;
  &amp;quot;globalIdFieldName&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;objectIdFieldName&amp;quot;: &amp;quot;gid&amp;quot;,&lt;br /&gt;
  &amp;quot;spatialReference&amp;quot;: {&lt;br /&gt;
    &amp;quot;latestWkid&amp;quot;: 3857,&lt;br /&gt;
    &amp;quot;wkid&amp;quot;: 102100&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой,&lt;br /&gt;
кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст.&lt;br /&gt;
Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub&lt;br /&gt;
https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги (в планах есть пункт: сделать нормальный Python distribution):&lt;br /&gt;
* Скачать [https://github.com/vasnake/mapfeatureserver MFS с GitHub].&lt;br /&gt;
* Поправить настройки в файле &amp;lt;pre&amp;gt;mapfeatureserver\wsgi\default_settings.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask&lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои.&lt;br /&gt;
Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так (описания опций и ключей к командам доступны во встроенной в команды справке):&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
Здесь shpdir это папка, где расположены шейп-файлы; flyzone.shp - загружаемый шейп-файл; mfsdata.flyzone - схема данных и таблица,&lt;br /&gt;
в которую будет загружен шейп; postgisdb - имя БД; mfs - учетная запись в БД.&lt;br /&gt;
&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
Идентификатор слоя (любое положительное целое число) надо вписать в список (в примере указаны три слоя)&lt;br /&gt;
&amp;lt;pre&amp;gt;layer.ID.list: 0,1,2&amp;lt;/pre&amp;gt;&lt;br /&gt;
Вписать данные подключения к БД PostGIS, пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;PG.DSN: host=vags101 port=5432 dbname=postgisdb user=mfs password=12345678 connect_timeout=10 client_encoding=utf8&amp;lt;/pre&amp;gt;&lt;br /&gt;
Создать секцию, именованную по идентификатору слоя, скажем «2»&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[2]&lt;br /&gt;
layer.table = flyzone&lt;br /&gt;
layer.geomfield = geom&lt;br /&gt;
layer.oidfield = gid&lt;br /&gt;
layer.name = Зоны полетов с ограничениями&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Находящиеся в конфиге примеры и комментарии помогут не ошибиться.&lt;br /&gt;
&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя Feature Layer ArcGIS и внести в него правки.&lt;br /&gt;
Метаданные слоя из ArcGIS Server доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
если на сервере опубликована служба «flyzone» соответствующего типа.&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS FeatureLayer в веб-картах&lt;br /&gt;
построенных на [http://resources.arcgis.com/content/web/web-apis ArcGIS web API].&lt;br /&gt;
К примеру, есть вьювер&lt;br /&gt;
[http://www.allgis.org/cartobonus/help/ Картобонус], построенный на&lt;br /&gt;
[http://resources.arcgis.com/en/help/silverlight-viewer/concepts/ ArcGIS API for Silverlight],&lt;br /&gt;
именно он использовался для тестирования MFS. Чтобы добавить слой в карту, используйте URL вида&lt;br /&gt;
&amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:Слои Mapfeatureserver в веб-картах Картобонус.png|center|700px|Рабочий скриншот слоев из MFS во вьювере Картобонус]]&lt;br /&gt;
&lt;br /&gt;
Как видите, за исключением файла метаданных, всё достаточно просто.&lt;br /&gt;
Теперь у нас есть свободный и бесплатный сервер Feature Layer-ов для обеспечения работы любого картографического софта,&lt;br /&gt;
использующего спецификации ArcGIS REST API.&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Спецификации REST API]&lt;br /&gt;
* [http://vasnake.blogspot.ru/2013/05/mapfeatureserver-poc.html Статья в блоге автора]&lt;br /&gt;
* [https://github.com/vasnake/mapfeatureserver MFS на GitHub]&lt;br /&gt;
* [http://www.allgis.org/cartobonus/help/ web map viewer Cartobonus]&lt;br /&gt;
&lt;br /&gt;
E-mail: [mailto:vasnake@gmail.com vasnake@gmail.com]&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12645</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12645"/>
		<updated>2013-05-24T11:51:02Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) и реализующий [http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для слоев типа [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer]. MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими [http://resources.arcgis.com/content/web/web-apis ArcGIS API].&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет, поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
== Что это, Mapfeatureserver? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис отвечающий спецификации [http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для картографических слоев типа [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer]. Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS DB, что означает необходимость а) загрузить данные предполагаемого решения в БД PostGIS; б) обеспечить доступ к этой БД сервису MFS. На текущий момент, кроме PostGIS, другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования MFS выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру [http://www.allgis.org/cartobonus/help/ Картобонус], добавляем к карте слои точно так же, как обычные FeatureLayer из ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html layer metadata] &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fsquery.html layer data query] by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой, кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст. Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги:&lt;br /&gt;
* Скачать [https://github.com/vasnake/mapfeatureserver MFS с GitHub].&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask &lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои. Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так:&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
находящиеся там примеры и комментарии помогут не ошибиться.&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя ArcGIS и внести в него правки. Метаданные слоя из ArcGIS доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS Feature Layer в веб-картах построенных на ArcGIS web API. К примеру, есть вьювер [http://www.allgis.org/cartobonus/help/ Картобонус], построенный на [http://resources.arcgis.com/en/help/silverlight-viewer/concepts/ ArcGIS API for Silverlight], именно он использовался для тестирования MFS. Чтобы добавить слой в карту, используйте URL вида &amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:Слои Mapfeatureserver в веб-картах Картобонус.png|center|700px|Рабочий скриншот слоев из MFS в вьювере Картобонус]]&lt;br /&gt;
&lt;br /&gt;
Как видите, за исключением файла метаданных, всё достаточно просто.&lt;br /&gt;
Теперь у нас есть свободный и бесплатный сервер Feature Layer-ов для обеспечения работы любого картографического софта, использующего спецификации ArcGIS REST API.&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://vasnake.blogspot.ru/2013/05/mapfeatureserver-poc.html Статья в блоге автора]&lt;br /&gt;
* [https://github.com/vasnake/mapfeatureserver MFS на GitHub]&lt;br /&gt;
* [http://www.allgis.org/cartobonus/help/ web map viewer Cartobonus]&lt;br /&gt;
&lt;br /&gt;
E-mail: [mailto:vasnake@gmail.com vasnake@gmail.com]&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12644</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12644"/>
		<updated>2013-05-23T22:49:55Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) и реализующий [http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для слоев типа [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer]. MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими [http://resources.arcgis.com/content/web/web-apis ArcGIS API].&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет, поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
== Что это, Mapfeatureserver? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис отвечающий спецификации [http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для картографических слоев типа [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer]. Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS DB, что означает необходимость а) загрузить данные предполагаемого решения в БД PostGIS; б) обеспечить доступ к этой БД сервису MFS. На текущий момент, кроме PostGIS, другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования MFS выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру [http://www.allgis.org/cartobonus/help/ Картобонус], добавляем к карте слои точно так же, как обычные FeatureLayer из ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html layer metadata] &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fsquery.html layer data query] by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой, кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст. Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги:&lt;br /&gt;
* Скачать [https://github.com/vasnake/mapfeatureserver MFS с GitHub].&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask &lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои. Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так:&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
находящиеся там примеры и комментарии помогут не ошибиться.&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя ArcGIS и внести в него правки. Метаданные слоя из ArcGIS доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS Feature Layer в веб-картах построенных на ArcGIS web API. К примеру, есть вьювер [http://www.allgis.org/cartobonus/help/ Картобонус], построенный на [http://resources.arcgis.com/en/help/silverlight-viewer/concepts/ ArcGIS API for Silverlight], именно он использовался для тестирования MFS. Чтобы добавить слой в карту, используйте URL вида &amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:Слои Mapfeatureserver в веб-картах Картобонус.png|thumb|center|upright=2.0|Рабочий скриншот слоев из MFS в вьювере Картобонус]]&lt;br /&gt;
&lt;br /&gt;
Как видите, за исключением файла метаданных, всё достаточно просто.&lt;br /&gt;
Теперь у нас есть свободный и бесплатный сервер Feature Layer-ов для обеспечения работы любого картографического софта, использующего спецификации ArcGIS REST API.&lt;br /&gt;
&lt;br /&gt;
См. также&lt;br /&gt;
* [http://vasnake.blogspot.ru/2013/05/mapfeatureserver-poc.html Статья в блоге автора]&lt;br /&gt;
* [https://github.com/vasnake/mapfeatureserver MFS на GitHub]&lt;br /&gt;
* [http://www.allgis.org/cartobonus/help/ web map viewer Cartobonus]&lt;br /&gt;
&lt;br /&gt;
E-mail: [mailto:vasnake@gmail.com vasnake@gmail.com]&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12643</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12643"/>
		<updated>2013-05-23T22:39:40Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) и реализующий [http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для слоев типа [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer]. MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими [http://resources.arcgis.com/content/web/web-apis ArcGIS API].&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет, поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
== Что это, Mapfeatureserver? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис отвечающий спецификации [http://resources.arcgis.com/en/help/rest/apiref/index.html?overview.html ArcGIS Server REST API] для картографических слоев типа [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html Feature Layer]. Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS DB, что означает необходимость а) загрузить данные предполагаемого решения в БД PostGIS; б) обеспечить доступ к этой БД сервису MFS. На текущий момент, кроме PostGIS, другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования MFS выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру [http://www.allgis.org/cartobonus/help/ Картобонус], добавляем к карте слои точно так же, как обычные FeatureLayer из ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fslayer.html layer metadata] &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* [http://resources.arcgis.com/en/help/rest/apiref/fsquery.html layer data query] by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой, кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст. Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги:&lt;br /&gt;
* Скачать [https://github.com/vasnake/mapfeatureserver MFS с GitHub].&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask &lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои. Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так:&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
находящиеся там примеры и комментарии помогут не ошибиться.&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя ArcGIS и внести в него правки. Метаданные слоя из ArcGIS доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS Feature Layer в веб-картах построенных на ArcGIS web API. К примеру, есть вьювер [http://www.allgis.org/cartobonus/help/ Картобонус], построенный на [http://resources.arcgis.com/en/help/silverlight-viewer/concepts/ ArcGIS API for Silverlight], именно он использовался для тестирования MFS. Чтобы добавить слой в карту, используйте URL вида &amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:Слои Mapfeatureserver в веб-картах Картобонус.png|мини|центр|750|Рабочий скриншот]]&lt;br /&gt;
&lt;br /&gt;
Как видите, за исключением файла метаданных, всё достаточно просто.&lt;br /&gt;
Теперь у нас есть свободный и бесплатный сервер Feature Layer-ов для обеспечения работы любого картографического софта, использующего спецификации ArcGIS REST API.&lt;br /&gt;
&lt;br /&gt;
См. также&lt;br /&gt;
* [http://vasnake.blogspot.ru/2013/05/mapfeatureserver-poc.html Статья в блоге автора]&lt;br /&gt;
* [https://github.com/vasnake/mapfeatureserver MFS на GitHub]&lt;br /&gt;
* [http://www.allgis.org/cartobonus/help/ web map viewer Cartobonus]&lt;br /&gt;
&lt;br /&gt;
E-mail: [mailto:vasnake@gmail.com vasnake@gmail.com]&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A1%D0%BB%D0%BE%D0%B8_Mapfeatureserver_%D0%B2_%D0%B2%D0%B5%D0%B1-%D0%BA%D0%B0%D1%80%D1%82%D0%B0%D1%85_%D0%9A%D0%B0%D1%80%D1%82%D0%BE%D0%B1%D0%BE%D0%BD%D1%83%D1%81.png&amp;diff=12642</id>
		<title>Файл:Слои Mapfeatureserver в веб-картах Картобонус.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%A1%D0%BB%D0%BE%D0%B8_Mapfeatureserver_%D0%B2_%D0%B2%D0%B5%D0%B1-%D0%BA%D0%B0%D1%80%D1%82%D0%B0%D1%85_%D0%9A%D0%B0%D1%80%D1%82%D0%BE%D0%B1%D0%BE%D0%BD%D1%83%D1%81.png&amp;diff=12642"/>
		<updated>2013-05-23T22:34:09Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: Скриншот демонстрирующий работу слоев Mapfeatureserver в веб-карте Картобонус&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Скриншот демонстрирующий работу слоев Mapfeatureserver в веб-карте Картобонус&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12637</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12637"/>
		<updated>2013-05-23T15:30:05Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) реализующий REST API ArcGIS Server для слоев типа Feature Layer. MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими ArcGIS API.&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет, поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
== Что это, Mapfeatureserver? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис отвечающий спецификации ArcGIS REST API для картографических слоев типа Feature Layer. Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS, что означает необходимость а) загрузить данные предполагаемого решения в БД PostGIS; б) обеспечить доступ к этой БД сервису MFS. На текущий момент кроме PostGIS другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования MFS выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру Картобонус, добавляем к карте слои также, как обычные FeatureLayer из ArcGIS.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* layer metadata &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* layer data query by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой, кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст. Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги:&lt;br /&gt;
* Скачать MFS с GitHub.&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask &lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои. Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так:&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;pre&amp;gt;&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
находящиеся там примеры и комментарии помогут не ошибиться.&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя ArcGIS и внести в него правки. Метаданные слоя из ArcGIS доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS Feature Layer в веб-картах построенных на ArcGIS web API. К примеру, есть вьювер Картобонус, построенный на ArcGIS API for Silverlight, именно он использовался для тестирования MFS.&lt;br /&gt;
Чтобы добавить слой в карту, используйте URL вида &amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
продолжение следует...&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12636</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12636"/>
		<updated>2013-05-23T15:29:15Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) реализующий REST API ArcGIS Server для слоев типа Feature Layer. MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими ArcGIS API.&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет, поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
== Что это, Mapfeatureserver? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис отвечающий спецификации ArcGIS REST API для картографических слоев типа Feature Layer. Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS, что означает необходимость а) загрузить данные предполагаемого решения в БД PostGIS; б) обеспечить доступ к этой БД сервису MFS. На текущий момент кроме PostGIS другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования MFS выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру Картобонус, добавляем к карте слои также, как обычные FeatureLayer из ArcGIS.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* layer metadata &amp;lt;pre&amp;gt;http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* layer data query by box &amp;lt;pre&amp;gt;http://&amp;lt;featurelayer-url&amp;gt;/query&amp;lt;/pre&amp;gt;&lt;br /&gt;
причем запрос данных может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой, кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст. Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub https://github.com/vasnake/mapfeatureserver&lt;br /&gt;
&lt;br /&gt;
Чтобы запустить сервис MFS вам понадобится выполнить следующие шаги:&lt;br /&gt;
* Скачать MFS с GitHub.&lt;br /&gt;
* Установить Python 2.7 и необходимые библиотки, к примеру для MS Windows&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\d\Python27;c:\d\Python27\Scripts&lt;br /&gt;
pip install Flask flask-login blinker psycopg2 simplejson&amp;lt;/pre&amp;gt;&lt;br /&gt;
[http://www.stickpeople.com/projects/python/win-psycopg/ psycopg2 for Windows]&lt;br /&gt;
* Запустить приложение Flask &lt;br /&gt;
&amp;lt;pre&amp;gt;pushd mapfeatureserver\wsgi&lt;br /&gt;
python mapfs_controller.py&amp;lt;/pre&amp;gt;&lt;br /&gt;
URL веб-службы будет таким http://localhost:5000/&lt;br /&gt;
Если вы откроете эту страницу в браузере вы увидите служебную страницу со ссылками на тестовые слои. Эти ссылки работать не будут, так как у вас нет таких слоев. Удалить лишнее и добавить свое вы можете поправив файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\wsgi\templates\servlets.html&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы создать новый слой, вам нужно выполнить следующие шаги:&lt;br /&gt;
* Получить доступ к БД PostGIS, к примеру, установив БД на свой хост.&lt;br /&gt;
* Загрузить шейп-файл с нужными данными в БД, к примеру так:&lt;br /&gt;
&amp;lt;pre&amp;gt;set path=%path%;c:\Program Files\PostgreSQL\9.0\bin&lt;br /&gt;
pushd c:\t\shpdir&lt;br /&gt;
shp2pgsql.exe -d -I -s 4326 -W cp1251 flyzone.shp mfsdata.flyzone &amp;gt; flyzone.dump.sql&lt;br /&gt;
psql -f flyzone.dump.sql postgisdb mfs&amp;lt;pre&amp;gt;&lt;br /&gt;
* Записать сведения о слое в конфигурационный файл&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layers.config.ini&amp;lt;/pre&amp;gt;&lt;br /&gt;
находящиеся там примеры и комментарии помогут не ошибиться.&lt;br /&gt;
* Создать файл метаданных для слоя. Это самая трудная часть.&lt;br /&gt;
&amp;lt;pre&amp;gt;mapfeatureserver\config\layer.&amp;lt;layer id&amp;gt;.config.json&amp;lt;/pre&amp;gt;&lt;br /&gt;
Чтобы было легче, можно скопировать метаданные из аналогичного существующего слоя ArcGIS и внести в него правки. Метаданные слоя из ArcGIS доступны по URL типа &amp;lt;pre&amp;gt;http://testags/arcgis/rest/services/flyzone/FeatureServer/2?f=pjson&amp;lt;/pre&amp;gt;&lt;br /&gt;
Также, в MFS есть специальные страницы, типа &amp;lt;pre&amp;gt;http://localhost:5000/admin/dsn/flyzone?oidfield=gid&amp;amp;geomfield=geom&amp;lt;/pre&amp;gt;&lt;br /&gt;
для помощи в составлении файла метаданных.&lt;br /&gt;
&lt;br /&gt;
После выполнения этих шагов, можно использовать слои MFS как обычные слои ArcGIS Feature Layer в веб-картах построенных на ArcGIS web API. К примеру, есть вьювер Картобонус, построенный на ArcGIS API for Silverlight, именно он использовался для тестирования MFS.&lt;br /&gt;
Чтобы добавить слой в карту, используйте URL вида &amp;lt;pre&amp;gt;http://hostname:5000/&amp;lt;layer id&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12635</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12635"/>
		<updated>2013-05-23T15:06:00Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) реализующий REST API ArcGIS Server для слоев типа Feature Layer. MFS был задуман как средство, позволяющее избавиться от дорогостоящего ArcGIS Server при работе с веб-картами, использующими ArcGIS API.&lt;br /&gt;
&lt;br /&gt;
Mapfeatureserver будет полезен разработчикам ГИС решений для веб и интранет, поскольку позволяет получить веб-карты красивые и функциональные как в ArcGIS, но без затрат на приобретение ArcGIS Server.&lt;br /&gt;
&lt;br /&gt;
== Что это, Mapfeatureserver? ==&lt;br /&gt;
&lt;br /&gt;
Как я уже упомянул, MFS это open source программа на Python, которая после запуска создает веб-сервис отвечающий спецификации ArcGIS REST API для картографических слоев типа Feature Layer. Веб модуль MFS написан с использованием фреймворка Flask и отвечает спецификации WSGI, что позволяет использовать MFS в качестве части более крупных веб-решений.&lt;br /&gt;
&lt;br /&gt;
Геоданные MFS считывает из PostGIS, что означает необходимость а) загрузить данные предполагаемого решения в БД PostGIS; б) обеспечить доступ к этой БД сервису MFS. На текущий момент кроме PostGIS другие БД не поддерживаются, но есть планы добавить поддержку MySQL и MongoDB.&lt;br /&gt;
&lt;br /&gt;
Общая картина использования MFS выглядит примерно так.&lt;br /&gt;
* Геоданные (шейп-файлы, к примеру) загружаем в PostGIS.&lt;br /&gt;
* Для каждого слоя данных вписываем сведения в конфигурационные файлы MFS.&lt;br /&gt;
* Запускаем веб-сервис.&lt;br /&gt;
* В клиентской программе, к примеру Картобонус, добавляем к карте слои также, как обычные FeatureLayer из ArcGIS.&lt;br /&gt;
&lt;br /&gt;
Теперь о недостатках и ограничениях MFS.&lt;br /&gt;
&lt;br /&gt;
На текущий момент программа находится в стадии «Proof of Concept», то есть обладает функциональностью минимально достаточной для демонстрации работоспособности подхода.&lt;br /&gt;
Из всего многообразия запросов декларированных в API, наш сервис пока реализует два:&lt;br /&gt;
* layer metadata http://&amp;lt;featureservice-url&amp;gt;/&amp;lt;layerId&amp;gt;&lt;br /&gt;
* layer data query by box http://&amp;lt;featurelayer-url&amp;gt;/query&lt;br /&gt;
причем запрос http://&amp;lt;featurelayer-url&amp;gt;/query может быть только одного типа - запрос на выборку по ограничивающему боксу (box).&lt;br /&gt;
Этого достаточно, чтобы загрузить слой в карту и делать zoom, pan, просмотр атрибутов для features, но и только.&lt;br /&gt;
&lt;br /&gt;
Остальная часть API будет реализована несколько позже. Хорошая новость заключается в том, что проект - open source и любой, кто обладает соответствующими навыками, может ускорить реализацию недостающих функций.&lt;br /&gt;
&lt;br /&gt;
== Инструкция по использованию Mapfeatureserver ==&lt;br /&gt;
&lt;br /&gt;
Изложенная здесь информация может устареть к тому времени как вы читаете этот текст. Наиболее свежую информацию о проекте вы всегда можете найти на странице проекта в GitHub https://github.com/vasnake/mapfeatureserver&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12634</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12634"/>
		<updated>2013-05-23T14:27:51Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание веб-сервиса Mapfeatureserver как замены ArcGIS Server}}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) реализующий REST API ArcGIS Server для слоев типа Feature Layer.&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
	<entry>
		<id>https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12633</id>
		<title>Mapfeatureserver как замена ArcGIS Server</title>
		<link rel="alternate" type="text/html" href="https://wiki.gis-lab.info/index.php?title=Mapfeatureserver_%D0%BA%D0%B0%D0%BA_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD%D0%B0_ArcGIS_Server&amp;diff=12633"/>
		<updated>2013-05-23T14:04:01Z</updated>

		<summary type="html">&lt;p&gt;Vasnake: Новая страница: «{{Статья|Черновик}} {{Аннотация|Описание программы-сервиса Mapfeatureserver }}  [https://github.com/vasnake/mapfeat…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Статья|Черновик}}&lt;br /&gt;
{{Аннотация|Описание программы-сервиса Mapfeatureserver }}&lt;br /&gt;
&lt;br /&gt;
[https://github.com/vasnake/mapfeatureserver Mapfeatureserver] (далее MFS) - это веб-сервис, написанный на Python (WSGI, Flask) реализующий REST API ArcGIS Server для слоев типа Feature Layer.&lt;/div&gt;</summary>
		<author><name>Vasnake</name></author>
	</entry>
</feed>