After reading a very good tutorial on how to edit WFS with OpenLayers, I've tried replicating it but with my own WFS layer from Geoserver. Need some Javascript help finding what's wrong with it.
I managed to load the WFS and my basemap successfully and managed to get the buttons to show up. The buttons appear correctly like in the working example from that page but, for some reason the geometry data isn't being saved. Every time a user draws something, a new id is created on the table but its associated geometry column is left empty
The bit for posting is:
var formatWFS = new ol.format.WFS();
var formatGML = new ol.format.GML({
featureNS: 'http://geoserver.org/bftchamber',
featureType: 'bft',
srsName: 'EPSG:27700'
});
var transactWFS = function(p,f) {
switch(p) {
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;
}
s = new XMLSerializer();
str = s.serializeToString(node);
$.ajax('http://localhost:8080/geoserver/wfs',{
type: 'POST',
dataType: 'xml',
processData: false,
contentType: 'text/xml',
data: str
}).done();
}
Fiddle with the whole code (apologies if it looks messy, most of it comes from the working example 2 )
https://jsfiddle.net/Luffydude/ex06jr1e/6/
The app looks like this:
Also even though my WFS appears correctly along the river Thames when I load it in QGIS, in my app it appears somewhere else in the ocean even though I specified EPSG 27700 (though this is just a minor annoyance at the moment).
My main problem now is how to make the edit buttons save user edits to the WFS layer?
I haven't really looked at OpenLayers in anger for a while and I kind of let slip updating my working examples. I just put together a new JSFiddle with simple WFS-T insert for polygons.
I use Geoserver 2.8 in production (2.9 in dev and testing).
Database backend is PostGIS 2.1 in production (2.2 dev).
The fiddle uses OpenLayers 3.16.
A few notes to my setup. I tend to have all geometries in EPSG:3857 and I do not specify the SRS in PostGIS. Haters gonna hate but I simply set my geometry column to geometry. This way I can get lines, points and polygons in the same table. I cannot see the mixed geometry in QGIS but this is a simple test setup. It's important that the geometry field is called geometry. It's probably possible but I could not make this work with the field being called the_geom or geom. In that case a record is inserted but the geometry field is empty as described in the post. I believe this is the problem.
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;
Here is the code bit from the jsfiddle.
var formatWFS = new ol.format.WFS();
var formatGML = new ol.format.GML({
featureNS: 'https://geolytix.net/wfs',
featureType: 'wfs_geom',
srsName: 'EPSG:3857'
});
var s = new XMLSerializer();
var sourceWFS = new ol.source.Vector({
loader: function (extent) {
$.ajax('https://maps.geolytix.net/geoserver/geolytix.wfs/wfs', {
type: 'GET',
data: {
service: 'WFS',
version: '1.1.0',
request: 'GetFeature',
typename: 'wfs_geom',
srsname: 'EPSG:3857',
bbox: extent.join(',') + ',EPSG:3857'
}
}).done(function (response) {
sourceWFS.addFeatures(formatWFS.readFeatures(response));
});
},
strategy: ol.loadingstrategy.bbox,
projection: 'EPSG:3857'
});
var layerWFS = new ol.layer.Vector({
source: sourceWFS
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
url: 'https://cartodb-basemaps-{a-d}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png',
opaque: false,
attributions: []
})
}),
layerWFS
],
view: new ol.View({
center: ol.proj.fromLonLat([-0.1, 51.50]),
zoom: 13
})
});
var interaction = new ol.interaction.Draw({
type: 'Polygon',
source: layerWFS.getSource()
});
map.addInteraction(interaction);
interaction.on('drawend', function (e) {
$.ajax('https://maps.geolytix.net/geoserver/geolytix.wfs/wfs', {
type: 'POST',
dataType: 'xml',
contentType: 'text/xml',
data: s.serializeToString(formatWFS.writeTransaction([e.feature], null, null, formatGML))
}).done();
});