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>
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.