1

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>

3
  • I think it might be the problem of the coordinate tranformations, but I can't say which
    – ylka
    Apr 17, 2013 at 7:34
  • @ylka, you are right. If I use the base layer as var layer= new OpenLayers.Layer.WMS( "OpenLayers WMS", "vmap0.tiles.osgeo.org/wms/vmap0?", {layers: 'basic'});, it solves the problem. But I have to use OSM. Any inputs on how this can be resolved in the code with OSM?
    – vyh
    Apr 17, 2013 at 7:54
  • Well I'm not sure but there are two things you could try: bounds = bounds.transform(EPSG900913, EPSG4326); I think you dont need this line, 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.
    – ylka
    Apr 17, 2013 at 8:39

1 Answer 1

1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.