Работа с WFS (Web Feature Service) в OpenLayers основана на стандарте OGC, который позволяет получать географические объекты (features) с сервера в формате GML или GeoJSON через HTTP-запросы. WFS предоставляет доступ не к тайлам изображений, а к «живым» геообъектам с атрибутами и геометрией, что делает его ключевым механизмом для аналитических и редактируемых ГИС-приложений.
WFS работает по принципу запрос-ответ:
OpenLayers не реализует протокол WFS напрямую как отдельный клиент, но предоставляет инструменты через:
ol/format/WFS — формирование XML-запросовol/format/GML — парсинг ответовol/source/Vector — источник данныхol/strategy/bbox — стратегия подгрузки по рамкеНаиболее распространённая схема — использование
VectorSource с ручной генерацией запроса
GetFeature.
import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
const source = new VectorSource({
format: new GeoJSON(),
loader: function (extent, resolution, projection) {
const url =
'https://example.com/geoserver/wfs?' +
'service=WFS&' +
'version=2.0.0&' +
'request=GetFeature&' +
'typeName=workspace:layer&' +
'outputFormat=application/json&' +
'srsname=EPSG:3857&' +
'bbox=' + extent.join(',') + ',EPSG:3857';
fetch(url)
.then(response => response.json())
.then(data => {
const features = source.getFormat().readFeatures(data, {
featureProjection: projection
});
source.addFeatures(features);
});
}
});
Ключевой момент — использование bbox, который
ограничивает объём загружаемых данных текущим видимым экстентом
карты.
Для производительных приложений применяется стратегия
bbox:
import {bbox as bboxStrategy} from 'ol/loadingstrategy';
const source = new VectorSource({
format: new GeoJSON(),
url: function (extent) {
return (
'https://example.com/geoserver/wfs?' +
'service=WFS&version=2.0.0&request=GetFeature&' +
'typeName=workspace:layer&outputFormat=application/json&' +
'srsname=EPSG:3857&bbox=' +
extent.join(',') +
',EPSG:3857'
);
},
strategy: bboxStrategy
});
Стратегия обеспечивает автоматическую подгрузку данных при изменении области видимости карты.
WFS традиционно возвращает GML, однако GeoJSON стал де-факто стандартом в веб-картографии.
ol/format/WFSimport WFS from 'ol/format/WFS';
const wfsFormat = new WFS();
const featureRequest = wfsFormat.writeGetFeature({
srsName: 'EPSG:3857',
featurePrefix: 'workspace',
featureTypes: ['layer'],
outputFormat: 'application/json'
});
import GML2 from 'ol/format/GML2';
const format = new GML2();
const features = format.readFeatures(xmlResponse, {
featureProjection: 'EPSG:3857'
});
WFS поддерживает фильтрацию данных на сервере, что критично для производительности.
const url =
'https://example.com/geoserver/wfs?' +
'service=WFS&version=2.0.0&request=GetFeature&' +
'typeName=workspace:layer&' +
'cql_filter=population>10000';
const cql =
'INTERSECTS(geom, POLYGON((...)))';
import WFS from 'ol/format/WFS';
import Filter from 'ol/format/filter';
const filter = Filter.and(
Filter.like('name', 'Park*'),
Filter.greaterThan('area', 500)
);
const wfs = new WFS();
const request = wfs.writeGetFeature({
featureTypes: ['layer'],
filter: filter
});
WFS-T (Transaction) позволяет изменять данные на сервере: добавлять, обновлять и удалять геометрию.
const wfs = new WFS();
const insertFeature = wfs.writeTransaction(
[feature],
null,
null,
{
featureType: 'layer',
featureNS: 'http://example.com/workspace',
srsName: 'EPSG:3857'
}
);
wfs.writeTransaction(
null,
[feature],
null,
{
featureType: 'layer',
featureNS: 'http://example.com/workspace'
}
);
wfs.writeTransaction(
null,
null,
[feature],
{
featureType: 'layer',
featureNS: 'http://example.com/workspace'
}
);
Отправка запроса:
fetch('https://example.com/geoserver/wfs', {
method: 'POST',
headers: {
'Content-Type': 'text/xml'
},
body: new XMLSerializer().serializeToString(transaction)
});
Наиболее частый сервер WFS — GeoServer. Он поддерживает:
Пример запроса с ограничением атрибутов:
propertyName=geom,name,type
Это уменьшает объём передаваемых данных.
WFS часто хранит данные в EPSG:4326, тогда как веб-карты используют EPSG:3857.
srsname=EPSG:3857
OpenLayers выполняет репроекцию автоматически при указании:
featureProjection: 'EPSG:3857'
Ошибки в CRS приводят к смещению объектов, что является одной из самых частых проблем при интеграции WFS.
Работа с WFS требует контроля объёма данных:
bboxcql_filter)propertyName)ol/source/Cluster)Кластеризация:
import Cluster from 'ol/source/Cluster';
const clusterSource = new Cluster({
distance: 40,
source: vectorSource
});
При изменении карты запросы WFS могут выполняться часто. Используются подходы:
AbortControllerconst controller = new AbortController();
fetch(url, { signal: controller.signal });
controller.abort();
WFS-запросы выполняются через HTTP, поэтому требуется:
Пример заголовка:
headers: {
'Authorization': 'Bearer token'
}
Типовая архитектура слоя:
import VectorLayer from 'ol/layer/Vector';
const layer = new VectorLayer({
source: source,
style: styleFunction
});
Стилизация может зависеть от атрибутов WFS-объектов:
function styleFunction(feature) {
const type = feature.get('type');
return new Style({
stroke: new Stroke({
color: type === 'road' ? 'red' : 'blue'
})
});
}
WFS часто комбинируется с другими источниками:
Такая архитектура разделяет визуализацию и данные, снижая нагрузку на клиент.
При больших наборах данных применяется:
WFS сохраняет актуальность в сценариях, где требуется точная геометрия и возможность редактирования, несмотря на появление более лёгких форматов передачи данных.