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>

  • I think it might be the problem of the coordinate tranformations, but I can't say which – ylka Apr 17 '13 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 '13 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 '13 at 8:39
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, privacy policy and cookie policy

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