I am building an application where the user retrieves all the features of a geoserver layer (store: postgres) and display them on a table. For doing this I use the OWSLib (get_feature).
Now I need to add the functionality of editing the data (WFS-T). As far as I know OWSLib doesn’t provide an add/update feature functionality.
What would be the way to implement this kind of functionality?
As suggested I use python requests lib in order to implement the WFS-T and updated values on the layer:
This is part of my code:
import requests url = 'http://localhost:8080/geoserver/wfs' xml = """<wfs:Transaction service="WFS" version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs"> <wfs:Update typeName="geonode:tjk_nhr_shockriskscore"> <wfs:Property> <wfs:Name>Adm2_NAME</wfs:Name> <wfs:Value>test_2dsfdsfsdfdsfds</wfs:Value> </wfs:Property> <ogc:Filter> <ogc:FeatureId fid="tjk_nhr_shockriskscore.1"/> </ogc:Filter> </wfs:Update> </wfs:Transaction>""" headers = {'Content-Type': 'application/xml'} # set what your server accepts print requests.post(url, data=xml, headers=headers).text
When I run this xml through the geoserver Demo pages, it works fine. The property of the layer gets update. When I execute it through my python script I get a service exception as:
<?xml version="1.0" ?> <ServiceExceptionReport version="1.2.0" xmlns="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd"> <ServiceException> {http://www.geonode.org/}tjk_nhr_shockriskscore is read-only </ServiceException></ServiceExceptionReport>
Advertisement
Answer
The error message (unusually) is actually helpful here – if the layer is read only you can’t run an update against it. So the question then becomes why is the layer read only? The most likely reason (especially if the transaction works in the demo page) is that your python script didn’t authenticate with the server. From this page it looks like you need to add:
auth=("admin","geoserver")
to your request (assuming you haven’t changed the default password).