[GIS] Problems using geoserver and postgis to perform wfs transaction

geoserveropenlayers-2wfs-t

I have been following the tutorial for transaction.

I am using apache webserver and jetty powered geoserver for hosting and using proxy.cgi file for bypassing XHR requests. as described in tutorial I have made necessary changes to my file. I can display the layer, add, edit and delete new features but not able to save them. I have checked the state of new features and it says 'INSERT'(using alert). the line saveStrategy.save() is also called as the alert line immidiately after is working (an XHR transaction returns successful response). but whenever I refresh the page the new features do not show up, and they are not saved in postgis also.

OpenLayers.ProxyHost= "/cgi-bin/proxy.cgi?url=";
//variables
var host = "http://127.0.0.1";
var port = ':8888';
var centerX = 85.33333;//9497800;
var centerY = 27.68888;//3212000;
var range = .5;//10000;
var map_bound = [centerX-range,centerY-range,centerX+range,centerY+range];
var map_wd = 390;
var map_ht = 400;
var legend_wd = 100;
var legend_ht = map_ht;
var tbar_wd = map_wd + legend_wd;
var tbar_ht = 25;
var zoom = 15;

var DeleteFeature = OpenLayers.Class(OpenLayers.Control, {
    initialize: function(layer, options) {
        OpenLayers.Control.prototype.initialize.apply(this, [options]);
        this.layer = layer;
        this.handler = new OpenLayers.Handler.Feature(
            this, layer, {click: this.clickFeature}
        );
    },
    clickFeature: function(feature) {
        // if feature doesn't have a fid, destroy it
        if(feature.fid == undefined) {
            this.layer.destroyFeatures([feature]);
        } else {
            feature.state = OpenLayers.State.DELETE;
            this.layer.events.triggerEvent("afterfeaturemodified", 
                {feature: feature});
            feature.renderIntent = "select";
            this.layer.drawFeature(feature);
        }
    },
    setMap: function(map) {
        this.handler.setMap(map);
        OpenLayers.Control.prototype.setMap.apply(this, arguments);
    },
    CLASS_NAME: "OpenLayers.Control.DeleteFeature"
});
Ext.onReady(function() {    

    var saveStrategy = new OpenLayers.Strategy.Save();
    /*saveStrategy.events.register("start", '', alert('saving'));
    saveStrategy.events.register("success", '', alert('save success'));
    saveStrategy.events.register("failure", '', alert('save failure'));
    */
    //map configuration
    var map_options = {
        allOverlays:true,
        maxExtent:new OpenLayers.Bounds(map_bound[0],map_bound[1],map_bound[2],map_bound[3]),
        numZoomLevels: zoom+10,
        controls: [new OpenLayers.Control.PanZoomBar(),
            new OpenLayers.Control.MousePosition(),
            new OpenLayers.Control.ScaleLine(),
            //new OpenLayers.Control.Scale()
        ],
        projection: "EPSG:4326"
    }
    var map = new OpenLayers.Map(map_options);
    var navi = new OpenLayers.Control.NavigationHistory();
    map.addControl(navi);

    //layers configuration

    var roadswgs = new OpenLayers.Layer.WMS(
        "roadswgs"
        ,host+port+"/geoserver/wms"
        ,{  layers: "postgis:trans_ln_8"
            ,transparent: true
            //,styles: "line"
        },
        {isBaseLayer: false}
    );

    var portwgs = new OpenLayers.Layer.WMS(
        "airportwgs"
        ,host+port+"/geoserver/wms"
        ,{  layers: "RIS:airport_runway_wgs"
            ,transparent : true
            ,styles: "simple_roads"/*,visibility: false*/},
        {isBaseLayer: false}
    );

    //var vector = new OpenLayers.Layer.Vector('editable');

    var vector = new OpenLayers.Layer.Vector('editable'
        ,{  strategies: [new OpenLayers.Strategy.BBOX(),saveStrategy]
            ,protocol: new OpenLayers.Protocol.WFS({
                url:  "http://127.0.0.1:8888/geoserver/wfs",
                featureType: "airport_runway",
                featureNS: "http://localhost:8888",
                //version: "1.1.0",
                //geometryName: "geom"
            })
            ,styleMap: new OpenLayers.StyleMap({
                pointRadius: 20,
                strokeColor: "#ff0000",
                strokeWidth: 1,
                fillOpacity: 1
            })
        }
    );

    var wfsroads = new OpenLayers.Layer.Vector("PostgisWFS", 
        {   strategies: [new OpenLayers.Strategy.BBOX()],
            protocol: new OpenLayers.Protocol.WFS({
                url:  "http://127.0.0.1:8888/geoserver/wfs",
                featurePrefix: "postgis",
                featureType: "trans_ln_8",
                version: "1.1.0"                 
            }),
            styleMap: new OpenLayers.StyleMap({
                pointRadius: 3,
                strokeColor: "#ff00ff",
                strokeWidth: 3,
                fillOpacity: 0
            })
        }
    );

    var osm = new OpenLayers.Layer.OSM("OSM");

    //var gsat = new OpenLayers.Layer.Google("Google Satellite",{type:G_SATELLITE_MAP, numZoomLevels: 22});

    map.addLayers([wfsroads,roadswgs,vector,portwgs/*gsat*/]);

    //mappanel configuration
    var mapPanel = new GeoExt.MapPanel({
        renderTo: 'gxmap',
        height: map_ht,
        width: map_wd,
        map: map,
        title: 'A Simple GeoExt Map',
        centre: [centerX,centerY],
        zoom: zoom-2
    });
    //layer tree configuration
    var layerList = new GeoExt.tree.LayerContainer({
        text: 'All Layers',
        layerStore: mapPanel.layers,
        leaf: true,
        expanded: true
    });

    var layerTree = new Ext.tree.TreePanel({
        title: 'Layers',
        renderTo: 'layerTree',
        root: layerList,
        width: tbar_wd,
        height: '*'
    });

    //legend configuration
    var legendPanel = new GeoExt.LegendPanel({
        title:'Legend',
        layerStore: mapPanel.layers,
        renderTo: "legend",
        border: true,
        width: legend_wd,
        height: legend_ht
    });
    //toolbars
    toolbars(map,navi,vector,mapPanel); //this part puts simple tools like zoomin, zoomout, maxextent and it is working fine
    var nav = new GeoExt.Action({
        text: "nav",
        control: new OpenLayers.Control.Navigation(),
        map: map,
        // button options
        toggleGroup: editor,
        allowDepress: false,
        pressed: false,
        tooltip: "navigate",
        // check item options
        //group: "draw",
        checked: false
    });
    //editor toolbar
    var editor = "editor tools";

    var snaproad = new OpenLayers.Control.Snapping({
        layer: vector,
        targets: [{
            layer: wfsroads,
            tolerance: 15,
            greedy: true
        }]
    });
    snaproad.activate();
    var snapvector = new OpenLayers.Control.Snapping({
        layer: vector,
        targets: [{
            layer: vector,
            tolerance: 50,
            greedy: true
        }]
    });
    snapvector.activate();
    var draw = new OpenLayers.Control.DrawFeature(
        vector,     //layer
        OpenLayers.Handler.Path, //Handler
        {   multi:true,
            type: OpenLayers.Control.TYPE_TOOL,
        }//options
    );
    // DrawFeature control, a "toggle" control
    draw_ac = new GeoExt.Action({
        text: "draw",
        control: draw,
        map: map,
        // button options
        enableToggle: true,
        tooltip: "select feature",
        toggleGroup: editor
    });
    /*draw.featureAdded = function(feature) {
        feature.layer.eraseFeatures([feature]);
        // cast to multilinestring
        feature.geometry = new OpenLayers.Geometry.MultiLineString(
            feature.geometry
        );
        feature.style.strokeColor = "#ff0000";
        feature.state = OpenLayers.State.INSERT;
        feature.layer.drawFeature(feature);
    }
    */


    var modify = new OpenLayers.Control.ModifyFeature(vector,{type: OpenLayers.Control.TYPE_TOGGLE});
    var select = new OpenLayers.Control.SelectFeature(vector,{hover:true});
    map.addControl(select);
    select.activate();

    var modify_ac = new GeoExt.Action({
        text: "modify",
        control: modify,
        map: map,
        // button options
        enableToggle: true,
        tooltip: "modify feature",
        toggleGroup: editor
    });


    var del = new DeleteFeature(vector, {title: "Delete Feature"});
    var del_ac = new GeoExt.Action({
        text: "delete",
        control: del,
        map: map,
        // button options
        enableToggle: true,
        tooltip: "delete feature",
        toggleGroup: editor
    });


    //add controls to map
    mapPanel.map.addControls([draw,modify,del,select]);
    /*
    // SelectFeature control, a "toggle" control
    select_ac = new GeoExt.Action({
        text: "select",
        control: new OpenLayers.Control.SelectFeature(vector, {
            type: OpenLayers.Control.TYPE_TOGGLE,
            hover: true
        }),
        map: map,
        // button options
        enableToggle: true,
        tooltip: "select feature"
    });

    var draw_but = new Ext.Button({                 //associate tool with button
        text: 'Draw Line',
        enableToggle: true,
        toggleGroup: toggleEditor,
        handler: function(toggled){
            if (toggled) {
                snaproad.activate();
                draw.activate();
            } else {
                draw.deactivate();
            }
        }
    });

    var modify_but = new Ext.Button({                   //associate tool with button
        text: 'Edit Line',
        enableToggle: true,
        toggleGroup: editor,
        handler: function(toggled){
            if (toggled) {
                draw.deactivate();
                snapvector.activate();
                select.activate();
                modify.activate();
            } else {
                modify.deactivate();
            }
        }
    }); 


    var delete_but = new Ext.Button({                   //associate tool with button
        text: 'Delete Line',
        enableToggle: true,
        toggleGroup: editor,
        handler: function(toggled){
            if (toggled) {
                draw.deactivate();
                select.activate();
                modify.deactivate();
                del.activate();
            } else {
                del.deactivate();
            }
        }
    });
    */
    var save = new GeoExt.Action({
        text: "save",
        //icon: 'icons/icon_zoomnext.png',
        //control: saveStrategy.save(),
        onClick: function(){
            saveStrategy.save();
            alert('saved');
        },
        disabled: false,
        //deactivateOnDisable: true,
        //activateOnEnable: true,
        tooltip: "save road"
    });

    /*var save_but = new Ext.Button({
        text: "Save Changes",
        enableToggle: false,
        toggleGroup: toggleEditor,
        click: function() {
            alert('sve atart');
            map.layer[2].commit();
            alert('not saved');
        }
    });*/

    var toolbar = new Ext.Toolbar({                 //embed tool in toolbar
        renderTo: 'tools_editor',
        width: tbar_wd,
        height: tbar_ht,
        autoScroll : false,
        autoWidth : true,
        autoHeight : true,
        buttonAlign: 'left',
        fieldLabel : 'Editor tools',
        items: [draw_ac,'-',modify_ac,'-',del_ac,'-',save]
    });

    // the part below is just to make the bounds show up on the page
    function updateBounds(){
        var bbox = map.getExtent().toArray();
        code = "Bounds      lower left: "+bbox[0]+','+bbox[1]+"     upper right"+bbox[2]+','+bbox[3];
        document.getElementById('bounds').innerHTML = code;
    }
    // update the bounds with each map move
    map.events.register('moveend', map, updateBounds);
    // and update the bounds on first load
    updateBounds();

});

I am using openlayers and geoext, and this script is called from a php file.

there has been some development

when this code

    draw.featureAdded = function(feature) {
        feature.layer.eraseFeatures([feature]);
        // cast to multilinestring
        feature.geometry = new OpenLayers.Geometry.MultiLineString(
            feature.geometry
        );
        alert(feature.state);
        //feature.style.strokeColor = "#ff0000";
        feature.state = OpenLayers.State.INSERT;
        feature.layer.drawFeature(feature);
    }

is enabled, after saving the postgis table shows increase in no.of row but the geometry is empty. the request generated is

<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<wfs:Insert><feature:airport_runway xmlns:feature="http://geoserver/postgis">
<feature:geom>
<gml:MultiCurve xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"/>  
</feature:geom>
</feature:airport_runway>
</wfs:Insert>
</wfs:Transaction>

and the response is

<wfs:transactionresponse version="1.1.0" xsi:schemalocation="http://www.opengis.net/wfs http://localhost:8888/geoserver/schemas/wfs/1.1.0/wfs.xsd" xmlns:ogc="http://www.opengis.net/ogc" xmlns:tiger="http://www.census.gov" xmlns:cite="http://www.opengeospatial.net/cite" xmlns:nurc="http://www.nurc.nato.int" xmlns:sde="http://geoserver.sf.net" xmlns:postgis="http://geoserver/postgis" xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:geoserver_tomcat_amrit="http://localhost:8080/geoserver" xmlns:it.geosolutions="http://www.geo-solutions.it" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="http://www.openplans.org/spearfish" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:ris="http://localhost:8888/geoserver" xmlns:xlink="http://www.w3.org/1999/xlink">
<wfs:transactionsummary>
<wfs:totalinserted>
1
</wfs:totalinserted>
<wfs:totalupdated>
0
</wfs:totalupdated>
<wfs:totaldeleted>
0
</wfs:totaldeleted>
</wfs:transactionsummary>
<wfs:transactionresults>
<wfs:insertresults>
<wfs:feature>
<ogc:featureid fid="airport_runway.65"/>
</wfs:feature>
</wfs:insertresults>
</wfs:transactionresults>
</wfs:transactionresponse>

if the above code is commented then transaction returns this error

<ows:exceptionreport version="1.0.0" xsi:schemalocation="http://www.opengis.net/ows http://127.0.0.1:8888/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xmlns:ows="http://www.opengis.net/ows">
<ows:exception exceptioncode="InvalidParameterValue">
<ows:exceptiontext>
Error performing insert: Error inserting features
</ows:exceptiontext>
</ows:exception>
</ows:exceptionreport>

Best Answer

I think it is because of postgis2.0. I degraded to postgres 9.0.1 and postgis 1.5 and it is working fine.