[GIS] User defined Polygon disappears with featureadded and selectfeature

geoserverjavascriptopenlayers-2

I am trying to achieve the following functionality:
1. User draws a polygon.
2. Once complete, fetch features in that polygon( Using WFS).
3. On Select polygon, show the features that intersect that polygon.

My issue is: Once user draws a polygon, I use featureadded to fetch the features within the polygon. Once fetched, I can see the details using alert with no issue. But the circle/polygon disappears once I start zooming in /out. I want the polygon to be still visible.

Again on select, the polygon disappears as soon as the polygon is selected.

I want the polygon to be visible at all times and only be removed when I delete it.
I am using this example as reference : http://openlayers.org/dev/examples/draw-feature.html

Any inputs on how I can have the polygon to not disappear?

Here is the code I am using:

var map, drawControls, polygonLayer;
var url = "http://localhost:8080/geoserver/wms";
var wfsurl = "http://localhost:8080/geoserver/wfs";
var bounds = new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34,20037508.34);
var EPSG4326 = new OpenLayers.Projection("EPSG:4326");
var EPSG900913 = new OpenLayers.Projection("EPSG:900913");

function init() {
 var options = {
     controls: [],
     maxExtent: bounds,
     restrictedExtent: bounds,
     maxExtent: bounds,
     numZoomLevels: 4,
     maxResolution: 156543.0339,
     projection: EPSG900913,
     units: "m",
     displayProjection: EPSG4326

 };
 map = new OpenLayers.Map('map', options);
 // Using OSM as base map
 var layer = new OpenLayers.Layer.OSM(
     "OpenStreet Maps");


 states = new OpenLayers.Layer.WMS(
     "NA states", url, {
     layers: 'topp:states',
     tiled: true,
     styles: '',
     transparent: true,
     format: 'image/png'
 }, {
     isBaseLayer: false,
     displayOutsideMaxExtent: false,
     ratio: 1,
     buffer: 0,
     yx: {
         'EPSG:4326': true
     }
 });

 polygonLayer = new OpenLayers.Layer.Vector("Polygon Layer", {
     displayInLayerSwitcher: false
 });
 circleLayer = new OpenLayers.Layer.Vector("Circle Layer", {
     displayInLayerSwitcher: false
 });
 map.addLayers([layer, states, polygonLayer, circleLayer]);
 map.addControl(new OpenLayers.Control.PanZoomBar({
     position: new OpenLayers.Pixel(2, 15)
 }));
 map.setCenter((new OpenLayers.LonLat(4, 47).transform(EPSG4326, EPSG900913)), 3);
 map.addControl(new OpenLayers.Control.Navigation());
 map.addControl(new OpenLayers.Control.MousePosition());
 map.addControl(new OpenLayers.Control.Scale($('scale')));
 map.addControl(new OpenLayers.Control.ScaleLine({
     geodesic: true
 }));
 map.addControl(new OpenLayers.Control.LayerSwitcher());

 selectControl = new OpenLayers.Control.SelectFeature([polygonLayer, circleLayer], {
     onSelect: onFeatureSelect,
     // onUnselect: onFeatureUnselect
 });
 drawControls = {
     polygon: new OpenLayers.Control.DrawFeature(polygonLayer,
     OpenLayers.Handler.Polygon),
     circle: new OpenLayers.Control.DrawFeature(circleLayer,
     OpenLayers.Handler.RegularPolygon, {
         handlerOptions: {
             sides: 40

         }
     }),
     select: selectControl
 };
 for (var key in drawControls) {
     map.addControl(drawControls[key]);
     drawControls[key].events.register('featureadded', drawControls[key], function (f) {
         onFeatureAdded(f.feature);
     });
 }
 map.events.register('click', map, function (e) {
     var bounds = map.getExtent().clone();
     bounds = bounds.transform(EPSG900913, EPSG4326);
     mouseLoc = map.getLonLatFromPixel(e.xy);

     OpenLayers.Request.GET({
         url: url,
         params: {
             REQUEST: "GetFeatureInfo",
             EXCEPTIONS: "application/vnd.ogc.se_xml",
             BBOX: bounds.toBBOX(),
             SERVICE: "WMS",
             INFO_FORMAT: 'text/html',
             QUERY_LAYERS: [map.layers[1].params.LAYERS],
             FEATURE_COUNT: 50,
             Layers: [map.layers[1].params.LAYERS],
             WIDTH: map.size.w,
             HEIGHT: map.size.h,
             x: Math.floor(e.xy.x),
             y: Math.floor(e.xy.y),
             buffer: 0,


             //format: format,
             styles: map.layers[0].params.STYLES,
             srs: map.layers[0].params.SRS
         },
         success: setHTML
     });

     OpenLayers.Event.stop(e);

 });
}

function setHTML(response) {

 document.getElementById('nodelist').innerHTML = response.responseText;

}

  function toggleControl(element) {
   for (key in drawControls) {
       var control = drawControls[key];
       if (element.value == key && element.checked) {
           control.activate();
       } else {
           control.deactivate();
       }
   }
   if (element.value == "delete") {
     polygonLayer.destroyFeatures();
     polygonLayer.redraw();
     circleLayer.destroyFeatures();
     circleLayer.redraw();
 }

 }

function onFeatureAdded(e) {

 var wfsProtocol = new OpenLayers.Protocol.WFS({
     url: wfsurl,
     featureType: 'states',
     featureNS: "http://www.openplans.org/topp",
     srsName: EPSG4326,

     geometryName: "the_geom"
 });


 var pfilter = new OpenLayers.Filter.Spatial({
     type: OpenLayers.Filter.Spatial.INTERSECTS,
     value: e.geometry.transform(EPSG900913, EPSG4326)
 });

 wfsProtocol.read({
     filter: pfilter,
     callback: processSpatialBboxQuery,
     scope: new OpenLayers.Strategy.BBOX()


 });


   }
   function onFeatureSelect(e) {

 var cql = "INTERSECTS(the_geom," + e.geometry + ")"
 alert(cql);
 states.mergeNewParams({
     'CQL_FILTER': cql
 });

}
// Process the features fetched. For the time being we are just showing  POS Name of first feature
    function processSpatialBboxQuery(e) {
 alert("hi");
 };

</head>
<body onload="init()">


    <div id="map" class="smallmap"></div>

    <ul id="controlToggle">
        <input type="radio" name="type" value="none" id="noneToggle"
            onclick="toggleControl(this);" checked="checked" />
            <label for="noneToggle">Navigate</label><br>
            <input type="radio" name="type" value="polygon" id="polygonToggle"
            onclick="toggleControl(this);" />
            <label for="polygonToggle">Draw Polygon</label><br>
            <input type="radio" name="type" value="circle" id="circle"
            onclick="toggleControl(this);" />
            <label for="polygonToggle">Draw Circle</label><br>
            <input type="radio" name="type" value="select" id="selectToggle"
            onclick="toggleControl(this);" />
            <label for="selectToggle">Select feature </label><br>
            <input type="radio" name="type" value="delete"
            id="delete" onclick="toggleControl(this);" />
            <label for="noneToggle">Delete feature</label><br>
           <input type="checkbox" name="allow-pan" value="allow-pan" id="allowPanCheckbox" checked=true onclick="allowPan(this);" />
            <label for="allowPanCheckbox">allow pan while drawing</label><br>


    </ul>
     <div id="nodelist" ></div>

</body>

Best Answer

The polygon is disappering because you have a problem with coordinate transformations.

There are two things you could try:

  1. bounds = bounds.transform(EPSG900913, EPSG4326); --> I think you dont need this line

  2. or here: srs: map.layers[0].params.SRS --> change the 0 to 1, so that you have the coordinate system of the layer you are querying, not from the base layer.

Else I would recommend to use the google mercator everywhere you can (e.g. set the wfs and wms layers to it also in geoserver). Also you should use the EPSG:3857 instead of EPSG:900913. They are the same thing but the 900913 is not official.