I am developing an web application, where the user is able to view and update some feature attribute of a WFS layer. My problem: the edited data is not saved at all.
Here's the situation:
- GeoServer v2.5
- PostGIS / PostgreSQL database v9.1
- pgAdmin III v1.18.1
- Firefox 31.0 with FireBug extension
The web application uses OpenLayers (v2.13.1) to display OpenStreetMap (OSM) data. A WFS layer is added to the OSM base layer:
fwSaveStrategy = new OpenLayers.Strategy.Save();
fwSaveStrategy.events.register("success", '', showSuccessMsg);
fwSaveStrategy.events.register("failure", '', showFailureMsg);
var layerFootway = new OpenLayers.Layer.Vector("WFS OSM Footway", {
strategies: [new OpenLayers.Strategy.BBOX(), fwSaveStrategy],
protocol: new OpenLayers.Protocol.WFS({
version: '1.1.0',
url: 'http://<the-server-address>/wfs',
featureType: 'view_footway',
srsName: 'EPSG:3857'
}),
extractAttributes: true,
visibility: true,
styleMap: new OpenLayers.StyleMap({
"default": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
fillColor: "#ff00ff",
fillOpacity: 0.5,
strokeColor: "#ff00ff",
strokeOpacity: 0.75,
strokeWidth: 25
}, OpenLayers.Feature.Vector.style["default"])),
"select": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
fillColor: "#00ffff",
fillOpacity: 0.75,
strokeColor: "#00ffff",
strokeOpacity: 0.75,
strokeWidth: 25
}, OpenLayers.Feature.Vector.style["select"]))
})
});
This layer is a specific view in PostgreSQL: the view combines footways/pedestrian sidewalk vector data from OSM with own data of footway attributes (for example surface, type, inclination etc.). Both data sets are joined via the unique OSM ID that is assigned to every object (street, way etc) inside OSM.
For interaction purposes, a user can click/touch on a footway and gets confronted with a popup stating some feature attributes and way attributes. First, the code to achieve this:
var selectControlTouch = new OpenLayers.Control.SelectFeature(layerFootway, {
hover: false,
autoActivate: true,
onSelect: function(feature) {addPopup(feature);},
onUnselect: function(feature) {saveAttributes(feature); deletePopup(feature);}
});
So, by click/touch on a footway, a popup is initiated and displayed on the screen (see picture below). There the user is able to alter a value of the footway attributes (just a few numbers right now to get it working). If the user clicks elsewhere on the map, the changed attribute value will (hopefully) be saved and the popup will be closed.
To be able to store data to the view, I added specific rules to it in PostgreSQL:
The save function of my application looks like this:
function saveAttributes(feature) {
feature.state = OpenLayers.State.INSERT;
feature.attributes.wn_test = document.getElementById('iWn_test').value;
fwSaveStrategy.save(feature);}
So far, so good. Just a roundup:
- I've created a view in PostgreSQL.
- This view is published via GeoServer.
- In OpenLayers it is initiated as a WFS layer and displays correctly inside my browsers.
- If the user clicks on a footway, a popup comes up with some informations about that way.
- Inside the popup lies an
<input>
field. Goal: write that (edited) data back to the database. - Once the user clicks elsewhere on the map, the data from the
<input>
field would be saved and the popup closes.
BUT:
- If I call
fwSaveStrategy.save(feature);
, the transfer seems to execute correctly, but no data will be transfered though giving me an alert message "Everything went fine". - If I call
fwSaveStrategy.save([feature]);
, the response from the server is:view_footway is read-only
.
From my web search, the last message seems common among WFS-T users. So I clicked through several pages, tutorials and message boards (including this one) to find a solution. It seemed, that I needed a Primary Key Metadata table to get updatable views. So I added one with the name gt_pk_metadata_table
to my database:
Then I referenced that table in my GeoServer data store (under "Primary key metadata table") and saved. Unfortunately, that procedure has not solved my problems, it's gotten worse. Before, I could ask for the osm_id
via feature.attributes.osm_id
as this field belongs to the view. Now, with the metadata table, the result for requesting the osm_id
is undefined
. Therefore, the saving function won't execute correctly:
<ows:Exception exceptionCode=InvalidParameterValue>
<ows:ExceptionText>Error performing insert: Source was null in trying to create a reprojected feature collection!</ows:ExceptionText>
Does anyone has any idea, how to solve this and get the application to save the attributes edited via popup? I am dealing with this issue for 3 days now and am more and more willing to write a .php file with an SQL script instead of using WFS-T.
UPDATE 26.08.2014
Just played around a little bit without complicated views and specific rules, but all comes down to one error message:
- created a new table containing OSM data (copied several columns from existing table into new one via
SELECT INTO
) - added a primary key column to that table to get unique ids because osm_id is not unique (via
ALTER TABLE
andSERIAL
) - checked GRANTS in pgAdmin and set
public
and the owner to ALL - tested UPDATE/SELECT in pgAdmin on that new table
- published the table as new layer in GeoServer
- added the new layer in OpenLayers
- all data shows up fine
But as soon as the fwSaveStrategy.save()
function is called, the XML output reads
<ows:Exception exceptionCode="InvalidParameterValue">
<ows:ExceptionText>Update error: Invalid output dimension (must be 2 or 3)</ows:ExceptionText>
I've searched the web for it but found nothing useful. Any ideas?
UPDATE 27.08.2014
Here's the WFS exception:
<ows:ExceptionReport xmlns:ows="http://www.opengis.net/ows"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0.0" xsi:schemaLocation="http://www.opengis.net/ows http://<serveraddress>/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd">
<ows:Exception exceptionCode="InvalidParameterValue">
<ows:ExceptionText>Update error: Invalid output dimension (must be 2 or 3)</ows:ExceptionText>
</ows:Exception>
</ows:ExceptionReport>
osm_id
vanishes from theview_footway
layer. Tried restarting GeoServer and recreating the layer, but nothing helps. So it's obvious, that OpenLayers can't find theosm_id
but I don't understand, where it's gone and how I could refer to it again.my_footways_data
manually via pgAdmin. Surprisingly, that data shows up in the popup although there is nofeature.attributes.osm_id
. So the metadata table seems to function, but I am not able to write to the database. The XML output of Firebug shows this WFS error:Update error: Invalid output dimension (must be 2 or 3)
n auto-incrementing PK column to
my_footway_data` table and to have theosm_id
inserted like any other data?