OpenLayers – Preventing Polygons from Zooming

markersopenlayers-2vector

I have a simple OpenStreetMap for which I want to display a series of circles. Each circle represents readership for that area, so its radius will change based on the numbers.

However, when I create the circle and zoom in the map, the circle zooms in as well – it seems like OpenLayers assumes the circle is "glued" to the map and represents a piece of it, when really it's more like a programmatically created marker.

How can I get the circle to stay the same pixel radius no matter what the zoom level of the map? Or is there some way to get a marker to be created as a Vector instead of an image?

var map = new OpenLayers.Map({
  div: 'geomap',
  projection: "EPSG:900913"
});
map.addLayer(new OpenLayers.Layer.OSM());

var epsg4326 = new OpenLayers.Projection("EPSG:4326"); // WGS 1984 projection
var projectTo = map.getProjectionObject(); // The map projection (Spherical Mercator)
// test point
var lonLat = new OpenLayers.LonLat(-74.265982, 40.665443).
    transform(epsg4326, projectTo);

var vectorLayer = new OpenLayers.Layer.Vector("Overlay");
var point = new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat);

var mycircle = OpenLayers.Geometry.Polygon.createRegularPolygon
    (
        point,
        50000,
        40,
        0
    );

var featurecircle = new OpenLayers.Feature.Vector(mycircle);
vectorLayer.addFeatures([featurecircle]);

map.addLayer(vectorLayer);
map.zoomToExtent(vectorLayer.getDataExtent());

UPDATE: Here is the final answer (thanks Rene)!

var map = new OpenLayers.Map({
    div: 'geomap',
    projection: "EPSG:900913"
  });
  map.addLayer(new OpenLayers.Layer.OSM());

  var epsg4326 = new OpenLayers.Projection("EPSG:4326"); // WGS 1984 projection
  var projectTo = map.getProjectionObject(); // The map projection (Spherical Mercator)
  var lonLat = new OpenLayers.LonLat(-74.265982, 40.665443).
      transform(epsg4326, projectTo);

  var vectorLayer = new OpenLayers.Layer.Vector('FSA', {
    styleMap: new OpenLayers.StyleMap({
      "default": new OpenLayers.Style({
        pointRadius: "${radius}",
        fillColor: '#ff0000',
        fillOpacity: 1.0,
        strokeColor: '#000000',
        strokeWidth: 2,
        strokeOpacity: 1.0
      })
    })
  });
  map.addLayer(vectorLayer);

  var feature = new OpenLayers.Feature.Vector(
      new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat),
      {
        radius: 10
      }
  );
  vectorLayer.addFeatures([feature]);

  map.zoomToExtent(vectorLayer.getDataExtent());

Best Answer

The reason that it is "glued" to the map is that you are creating geometries. These geometries have a size and shape based on the projection, not on your zoomlevel. The zoomlevel will then tell the system how big they should be displayed.

What you want is to draw circles that stay the same. To do this, you can display points as circles and then apply a dynamic stle to them.

So first create a vecotr layer with a style:

var vectorLayer = vectorLayer = new OpenLayers.Layer.Vector('Locations (interactive)', {
    styleMap: new OpenLayers.StyleMap({
        "default": new OpenLayers.Style({
            pointRadius: {radius},
            fillColor: '#ff0000',
            fillOpacity: 1.0,
            strokeColor: '#000000',
            strokeWidth: 2,
            strokeOpacity: 1.0
        })
    })
}

As you can see, the radius is not set to a fixed value, but should be dictated by your data. To do so, make a Feature

var feature = new OpenLayers.Feature.Vector(
    new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat),
    {
        radius: 10
    }
);

Now add the feature to your layer:

vectorLayer.addFeatures([ feature ]);

So no need to create a polygon, but make a feature out of it and style it the way you want to display it using the styleMap of your layer.

Related Question