Este post foi publicado originalmente para o OL 3.5 por Dennis Bauszus. Não há uma boa razão para não usar a versão mais recente do OpenLayers, mas caso você utilize uma versão mais atual do OL, veja se não precisará realizar alguns ajustes.

Neste teste foi utilizado o GeoServer 2.8, e o armazenamento de dados é realizado em um banco de dados PostGIS 2.1.

Para o serviço de teste, é utilizada uma tabela muito simples, apenas com uma ID e geometria. A geometria é definida como geometry, sem tipo nem projeção. É importante que o campo de geometria seja chamado de geometria. Caso contrário, as inserções podem criar registros com campos de geometria vazios. Uma restrição deve ser definida no ID ou o GeoServer não poderá inserir registros na tabela.

CREATE TABLE wfs_geom
(
  id bigint NOT NULL,
  geometry geometry,
  CONSTRAINT wfs_geom_pkey PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE wfs_geom
  OWNER TO geoserver;
 
CREATE INDEX sidx_wfs_geom
  ON wfs_geom
  USING gist
  (geometry);

No núcleo dos snippets de javascript do OL está a função ol.format.WFS.writeTransaction, que recebe 4 parâmetros de entrada. Os 3 primeiros parâmetros definem se os dados devem ser inseridos, atualizados ou excluídos da fonte de dados. O quarto parâmetro assume a forma de ol.format.GML e transmite informações sobre o tipo de recurso, namespace e projeção dos dados.

O nó writeTransaction deve ser serializado com um XMLSerializer para ser usado em uma postagem do WFS-T.

Os três casos de uso (insert/update/delete) e a chamada AJAX são mostrados no seguinte trecho de código.

var formatWFS = new ol.format.WFS();

var formatGML = new ol.format.GML({
    featureNS: 'https://gsx.geolytix.net/geoserver/geolytix_wfs',
    featureType: 'wfs_geom',
    srsName: 'EPSG:3857'
});

var xs = new XMLSerializer();

var transactWFS = function (mode, f) {
    var node;
    switch (mode) {
        case 'insert':
            node = formatWFS.writeTransaction([f], null, null, formatGML);
            break;
        case 'update':
            node = formatWFS.writeTransaction(null, [f], null, formatGML);
            break;
        case 'delete':
            node = formatWFS.writeTransaction(null, null, [f], formatGML);
            break;
    }
    var payload = xs.serializeToString(node);
    $.ajax('https://gsx.geolytix.net/geoserver/geolytix_wfs/ows', {
        service: 'WFS',
        type: 'POST',
        dataType: 'xml',
        processData: false,
        contentType: 'text/xml',
        data: payload
    }).done(function() {
        sourceWFS.clear();
    });
};

Inserções são chamadas a partir do evento de “drawend” da interação do OL. A função .clear() no sourceWFS recarrega a fonte após cada transação. Isso garante que os IDs de recurso estejam corretos para os novos recursos e que os recursos excluídos sejam removidos da exibição.

O ID de um recurso modificado é armazenado e a transação de atualização é lançada quando o recurso é desmarcado. Para publicar com êxito uma transação de atualização, a propriedade boundedBy deve ser removida das propriedades do recurso. Um clone do recurso é usado para conseguir isso.

map.addInteraction(interactionSelect);
interaction = new ol.interaction.Modify({
    features: interactionSelect.getFeatures()
});
map.addInteraction(interaction);
map.addInteraction(interactionSnap);
dirty = {};
interactionSelect.getFeatures().on('add', function (e) {
    e.element.on('change', function (e) {
        dirty[e.target.getId()] = true;
    });
});
interactionSelect.getFeatures().on('remove', function (e) {
    var f = e.element;
    if (dirty[f.getId()]) {
        delete dirty[f.getId()];
        var featureProperties = f.getProperties();
        delete featureProperties.boundedBy;
        var clone = new ol.Feature(featureProperties);
        clone.setId(f.getId());
        transactWFS('update', clone);
    }
});

Você pode ver o exemplo completo (na versão 3.16 do OL) no jsFiddle.

Fonte: Medium – Dennis Bauszus