Помощь: Работа с геопорталом через программный интерфейс (API)

В муниципальном геопортале существует API для работы с векторными слоями. API базируется на протоколе Web Feature Service версии 2.0.0, в чем-то расширяя его. С помощью такого API можно интегрировать внешнее программное обеспечение с геопорталом, например, для автоматического наполнения слоев, геокодирования или наблюдения за общедоступными данными.

Взаимодействие с геопорталом производится с помощью HTTP-запросов методами GET и POST. Запросы делаются на URL WFS-источника, который для каждого картографического раздела отдельный. Правильные URL можно узнать справочным запросом http://geoportal.samregion.ru/info

Предпочтительнее пользоваться POST-запросами. Тело запроса и тело ответа являются XML-структурами, формат которых будет описан далее.

Для большинства операций необходима сессионная авторизация, поэтому при проведении последовательности запросов следует обрабатывать получаемые Cookies и сохранять их на время сессии.

Авторизация

Авторизация происходит сразу для всего сервера геопортала, а не для отдельного WFS-источника. Для авторизации используются те же e-mail и пароль от учетной записи, что и при входе на сайт через форму.

Перед авторизацией следует сделать GET-запрос специальной пустой страницы, для заведения новой сессии:

/user/empty.do

Затем, сохранить полученный из ответа ключ Cookies под названием JSESSIONID и использовать его при всех последующих запросах.

Сам запрос авторизации производится методом POST и Content-Type "application/x-www-form-urlencoded", имитируя отправку формы, на адрес:

/user/j_security_check

с параметрами:

j_username={username}
j_password={password}

Если авторизация удалась, ответ будет иметь 302 HTTP-статус. Следовать переходу не обязательно - можно просто быть уверенным, что в рамках сессии можно проводить операции, дозволенные аккаунту. В случае ошибки ответ будет иметь 200 HTTP-статус и тело ответа такого формата:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/auth/auth_template.do"?>
<result>
	<name>invalidpassword</name>
	<description>Ошибка! Данная комбинация логина и пароля не найдена, либо не указан пароль</description>
</result>

Запрос объектов - WFS Query

Запрос позволяет получить описание объектов, отобранных по набору условий.

Условия называются «фильтрами» и могут образовывать логическое выражение с несколькими видами условий с операторами конъюнкции, дизъюнкции и отрицания.

Общий формат тела запроса Query следующий:

<wfs:GetFeature 
	service="WFS" 
	version="2.0.0" 
	outputFormat="application/gml+xml; version=3.2" 
	xmlns:geosmr="http://www.geosamara.ru/wfs/geosmr/namespace" 
	xmlns:wfs="http://www.opengis.net/wfs/2.0" 
	xmlns:fes="http://www.opengis.net/fes/2.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd"> 
	<wfs:Query typeNames="geosmr:{layerId}">
		<fes:Filter>
			...
		</fes:Filter>
	</wfs:Query>
</wfs:GetFeature>

Комбинации фильтров логическими операторами имеют формат:

<fes:Filter>
	<fes:Or>
		<fes:Not>
			...
		</fes:Not>
		<fes:And>
			...
			...
		</fes:And>				
	</fes:Or>
</fes:Filter>

Ответ на запрос Query имеет формат:

<?xml version="1.0"?>
<wfs:FeatureCollection
	timeStamp="2010-02-01T22:56:09"
	numberMatched="3"
	numberReturned="3"
	xmlns="http://www.geosamara.ru/wfs/geosmr/namespace"
	xmlns:wfs="http://www.opengis.net/wfs/2.0"
	xmlns:gml="http://www.opengis.net/gml/3.2"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.geosamara.ru/wfs/geosmr/style.xsd
				   http://www.opengis.net/wfs/2.0
				   http://schemas.opengis.net/wfs/2.0.0/wfs.xsd
				   http://www.opengis.net/gml/3.2
				   http://schemas.opengis.net/gml/3.2.1/gml.xsd">
	<wfs:member>
		<{layerId} gml:id="{gmlId}">
			<id>{id}</id>
			<name>{name}</name>
			<description>
				<text>{text}</text>
				<resource>{resource}</resource>
				<image>{image}</image>
				<extra>{extra}</extra>
			</description>
			<style>
				{styleName}
			</style>
			<status>{status}</status>
			<author>{author}</author>
			<operations>
				<update>{update}</update>
				<delete>{delete}</delete>
				<moderate>{moderate}</moderate>
			</operations>
			<transaction>
				<mine>{mine}</mine>
				<locker>{locker}</locker>
				<expireIn>{expireIn}</expireIn>
			</transaction>
			<geometry>
				{geometry}
			</geometry>
		</{layerId}>
	</wfs:member>
</wfs:FeatureCollection>

Геометрия точечного объекта:

<gml:Point gml:id="{id}" srsName="urn:ogc:def:crs:EPSG::4326">
	<gml:pos>{x y}</gml:pos>
</gml:Point>

Возможны и другие системы координат: WGS-84 для данных геолокации, например.

Геометрия линейного объекта:

<gml:LineString>
	<gml:posList>{x} {y} {x} {y} ...</c:forEach></gml:posList>
</gml:LineString>

Геометрия площадного объекта:

<gml:Polygon>
	<gml:exterior>
		<gml:LinearRing>
			<gml:posList>{x} {y} {x} {y} ...</gml:posList>
		</gml:LinearRing>
	</gml:exterior>
</gml:Polygon>

Условие отбора объекта по принадлежности к слою указывается аттрибутом:

<wfs:Query typeNames="geosmr:{ID слоя}"/>

Условие отбора объекта по его уникальному идентификатору имеет формат:

<fes:Filter>
	<fes:PropertyIsEqualTo xmlns:fes="http://www.opengis.net/fes/2.0">
		<fes:ValueReference>geosmr:id</fes:ValueReference>
		<fes:Literal>{ID объекта}</fes:Literal>
	</fes:PropertyIsEqualTo>
</fes:Filter>

Условие отбора объекта по названию стиля имеет формат:

<fes:Filter>
	<fes:PropertyIsEqualTo xmlns:fes="http://www.opengis.net/fes/2.0">
		<fes:ValueReference>geosmr:style</fes:ValueReference>
		<fes:Literal>{ID стиля}</fes:Literal>
	</fes:PropertyIsEqualTo>
</fes:Filter>

Условие отбора объекта по семантическим полям: названию (geosmr:name), описанию (geosmr:description/geosmr:text), гиперссылке (geosmr:description/geosmr:resource), URL изображения (geosmr:description/geosmr:image) имеет формат:

<fes:Filter>
	<fes:PropertyIsLike xmlns:fes="http://www.opengis.net/fes/2.0">
		<fes:ValueReference>{название поля}</fes:ValueReference>
		<fes:Literal>{шаблон поиска}</fes:Literal>
	</fes:PropertyIsLike>
</fes:Filter>

Запирание объекта на транзакцию - WFS LockFeature

Операции, изменяющие объекты из векторных слоев, требуют соблюдения транзакционности. Для начала «длинной» транзакции используется запрос LockFeature. Пока не будет успешна начала транзакция над объектом — нет смысла пытаться провести операции Insert и Update.

Тело запроса имеет формат:

<LockFeature
	version="2.0.0"
	service="WFS"
	lockId=""
	expiry=""
	lockAction="ALL"
	xmlns="http://www.opengis.net/wfs/2.0"
	xmlns:geosmr="http://www.geosamara.ru/wfs/geosmr/namespace"
	xmlns:wfs="http://www.opengis.net/wfs/2.0"
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">
	<Query typeNames="">
		<fes:Filter>
			<fes:Or>
				<fes:PropertyIsEqualTo>
					<fes:ValueReference>geosmr:id</fes:ValueReference>
					<fes:Literal>{идентификаторы объектов через запятую}</fes:Literal>
				</fes:PropertyIsEqualTo>
				...
			</fes:Or>
		</fes:Filter>
	</Query>
</LockFeature>

Ответ на запрос LockFeature имеет формат:

<LockFeatureResponse
	lockId=""
	xmlns="http://www.opengis.net/wfs/2.0"
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.opengis.net/wfs/2.0
					   http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">
	<FeaturesLocked>
	   <fes:ResourceId rid="{id}"/>
	   ...
	</FeaturesLocked>
	<FeaturesNotLocked>
	   <fes:ResourceId rid="${id}"/>
	   ...
	</FeaturesNotLocked>
</LockFeatureResponse>

Отпирание объекта из транзакции - WFS UnlockFeature

Операция прекращает транзакцию над объектом.

Тело запроса имеет формат:

<UnlockFeature version="2.0.0" 
	service="WFS" xmlns="http://www.opengis.net/wfs/2.0" 
	xmlns:geosmr="http://www.geosamara.ru/wfs/geosmr/namespace" 
	xmlns:wfs="http://www.opengis.net/wfs/2.0" 
	xmlns:fes="http://www.opengis.net/fes/2.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://www.opengis.net/wfs/2.0 
	http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">
	<Query typeNames="">
		<fes:Filter>
			<fes:Or>
				<fes:PropertyIsEqualTo>
					<fes:ValueReference>geosmr:id</fes:ValueReference>
					<fes:Literal>{objectIds[0]}}</fes:Literal>
				</fes:PropertyIsEqualTo>
				...
			</fes:Or>
		</fes:Filter>
	</Query>
</UnlockFeature>

Ответ на запрос UnlockFeature имеет формат:

<UnlockFeatureResponse
        lockId=""
        xmlns="http://www.opengis.net/wfs/2.0"
        xmlns:fes="http://www.opengis.net/fes/2.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.opengis.net/wfs/2.0
                       http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">

    <LockId>{userid}</LockId>
    <FeaturesUnlocked>
        <fes:ResourceId rid="${id}"/>
		...
    </FeaturesUnlocked>
    <FeaturesNotUnlocked>
        <FeaturesLockedByAnotherUsers>
            <fes:ResourceId rid="${id}"/>
			...
        </FeaturesLockedByAnotherUsers>
        <FeaturesNotLocked>
            <fes:ResourceId rid="${id}"/>
			...
        </FeaturesNotLocked>
    </FeaturesNotUnlocked>

</UnlockFeatureResponse>

Добавление объекта - WFS Insert

Операция позволяет создать новый объект в одном из существующих слоев. Для успешного проведения операции у авторизованного аккаунта должно быть такое право по отношению к слою.

Тело запроса имеет формат:

<wfs:Transaction
   version="2.0.0"
   service="WFS"
   handle=""
   lockId=""
   releaseAction=""
   srsName=""
   xmlns="http://www.geosamara.ru/wfs/geosmr/namespace"
   xmlns:wfs="http://www.opengis.net/wfs/2.0"
   xmlns:fes="http://www.opengis.net/fes/2.0"
   xmlns:gml="http://www.opengis.net/gml/3.2"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.opengis.net/wfs/2.0 
   	http://schemas.opengis.net/wfs/2.0.0/wfs.xsd 
   	http://www.opengis.net/gml/3.2 http://www.opengis.net/gml/3.2.1/gml.xsd">
	<wfs:Insert>
		<{layerId} xmlns:gml="http://www.opengis.net/gml/3.2">
			<id></id>
			<name>{name}</name>
			<description>
				<text>{description}</text>
				<resource>{link}</resource>
				<image>{imageUrl}</image>
			 </description>
			<style>{styleName}</style>
			<status>{_moderationStatus}</status>
			<operations>
				<update>{isEditable}</update>;
				<delete>{isDeletable}</delete>
				<moderate>{isModeratable}</moderate>
			</operations>
			<transactions>
				<mine>{isLockedByUser}</mine>
				<locker>{lockerUsername}</locker>
				<expireIn>{lockExpiration}</expireIn>
			</transactions>
            <geometry>{geometry}</geometry>
		</{layerId}>
		...
	</wfs:Insert>
</wfs:Transaction>

Геометрия точечного, линейного и площадного объекта описываются в том же формате, как это было указано в формате ответа на операцию Query.

Ответ на запрос Insert имеет формат:

<wfs:TransactionResponse
version="2.0.0"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs/2.0
				   http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">
	<wfs:TransactionSummary>
		<wfs:totalInserted>{num}</wfs:totalInserted>
		<wfs:totalUpdated>{num}</wfs:totalUpdated>
		<wfs:totalReplaced>{num}</wfs:totalReplaced>
		<wfs:totalDeleted>{num}</wfs:totalDeleted>
	</wfs:TransactionSummary>
	<wfs:InsertResults>
		<wfs:Feature handle=" ">
			<fes:ResourceId rid="{rid}"/>
		</wfs:Feature>
	</wfs:InsertResults>
	<wfs:UpdateResults></wfs:UpdateResults>
	<wfs:DeleteResults></wfs:DeleteResults>
</wfs:TransactionResponse>

Изменение объекта - WFS Update

Операция позволяет изменить геометрическую форму или семантическую информацию одного из существующих объектов. Для успешного проведения операции у авторизованного аккаунта должно быть такое право по отношению к слою, в котором находится объект, и объект должен быть заперт на транзакцию тем же аккаунтом.

Тело запроса имеет формат:

<wfs:Transaction
   version="2.0.0"
   service="WFS"
   handle=""
   lockId=""
   releaseAction=""
   srsName=""
   xmlns="http://www.geosamara.ru/wfs/geosmr/namespace"
   xmlns:wfs="http://www.opengis.net/wfs/2.0"
   xmlns:fes="http://www.opengis.net/fes/2.0"
   xmlns:gml="http://www.opengis.net/gml/3.2"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.opengis.net/wfs/2.0
 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd 
 http://www.opengis.net/gml/3.2 http://www.opengis.net/gml/3.2.1/gml.xsd">
	<wfs:Update typeName="geosmr:{layerId}">
		<wfs:Property xmlns:wfs="http://www.opengis.net/wfs/2.0">
			<wfs:ValueReference>geosmr:name</wfs:ValueReference>
			<wfs:Value>{name}</wfs:Value>
		</wfs:Property>
		<wfs:Property xmlns:wfs="http://www.opengis.net/wfs/2.0">
			<wfs:ValueReference>geosmr:description/geosmr:text</wfs:ValueReference>
			<wfs:Value>{description}</wfs:Value>
		</wfs:Property>
		<wfs:Property xmlns:wfs="http://www.opengis.net/wfs/2.0">
			<wfs:ValueReference>geosmr:description/geosmr:resource</wfs:ValueReference>
			<wfs:Value>{link}</wfs:Value>
		</wfs:Property>
		<wfs:Property xmlns:wfs="http://www.opengis.net/wfs/2.0">
			<wfs:ValueReference>geosmr:description/geosmr:image</wfs:ValueReference>
			<wfs:Value>{imageUrl}</wfs:Value>
		</wfs:Property>
		<wfs:Property xmlns:wfs="http://www.opengis.net/wfs/2.0">
			<wfs:ValueReference>geosmr:style</wfs:ValueReference>
			<wfs:Value>{styleName}</wfs:Value>
		</wfs:Property>
		<fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0">
			<fes:Or>
				<fes:PropertyIsEqualTo>
					<fes:ValueReference>geosmr:id</fes:ValueReference>
					<fes:Literal>{marker.id}</fes:Literal>
				</fes:PropertyIsEqualTo>
			</fes:Or>
		</fes:Filter>
	</wfs:Update>
</wfs:Transaction>

Геометрия точечного, линейного и площадного объекта описываются в том же формате, как это было указано в формате ответа на операцию Query.

При операции может проводиться изменение только некоторого подмножества свойств объекта, таким образом, количество дочерних нод у wfs:Update будет меньше.

Ответ на запрос Update имеет формат:

<wfs:TransactionResponse
version="2.0.0"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">
	<wfs:TransactionSummary>
		<wfs:totalInserted>{num}</wfs:totalInserted>
		<wfs:totalUpdated>{num}</wfs:totalUpdated>
		<wfs:totalReplaced>{num}</wfs:totalReplaced>
		<wfs:totalDeleted>{num}</wfs:totalDeleted>
	</wfs:TransactionSummary>
	<wfs:InsertResults></wfs:InsertResults>
	<wfs:UpdateResults>
	<wfs:Feature handle=" ">
    <fes:ResourceId rid="{rid}"/>
    </wfs:Feature>
	</wfs:UpdateResults>
	<wfs:DeleteResults></wfs:DeleteResults>
</wfs:TransactionResponse>

Удаление объекта - WFS Delete

Операция позволяет удалить существующие объекты. Для успешного проведения операции у авторизованного аккаунта должно быть такое право по отношению к слою, в котором находится объект, и объект должен быть заперт на транзакцию тем же аккаунтом.

Обратите внимание - операция Delete отбирает объекты по условию Filter общего вида, если задать неправильное условие, можно удалить сразу множество объектов.

Тело запроса имеет формат:

<wfs:Transaction
	version="2.0.0"
	service="WFS"
	xmlns="http://www.geosamara.ru/wfs/geosmr/namespace"
	xmlns:wfs="http://www.opengis.net/wfs/2.0"
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:gml="http://www.opengis.net/gml/3.2"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.opengis.net/wfs/2.0 
		http://schemas.opengis.net/wfs/2.0.0/wfs.xsd 
		http://www.opengis.net/gml/3.2 http://www.opengis.net/gml/3.2.1/gml.xsd">
	<wfs:Delete typeName="">
		<fes:Filter>
			<fes:PropertyIsEqualTo>
				<fes:ValueReference>geosmr:id</fes:ValueReference>
				<fes:Literal>{objectIds[0]}</fes:Literal>
			</fes:PropertyIsEqualTo>
			...
		</fes:Filter>
	</wfs:Delete>
</wfs:Transaction>

Ответ на запрос Delete имеет формат:

<wfs:TransactionResponse
version="2.0.0"
xmlns:wfs="http://www.opengis.net/wfs/2.0"
xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd">
	<wfs:TransactionSummary>
		<wfs:totalInserted>{num}</wfs:totalInserted>
		<wfs:totalUpdated>{num}</wfs:totalUpdated>
		<wfs:totalReplaced>{num}</wfs:totalReplaced>
		<wfs:totalDeleted>{num}</wfs:totalDeleted>
	</wfs:TransactionSummary>
	<wfs:InsertResults></wfs:InsertResults>
	<wfs:UpdateResults></wfs:UpdateResults>
	<wfs:DeleteResults>
		<wfs:Feature handle=" ">
        <fes:ResourceId rid="{rid}"/>
        </wfs:Feature>
	</wfs:DeleteResults>
</wfs:TransactionResponse>

Замечания и предложения по содержанию справки можно подать через форму сервиса Reformal.