[GIS] Drawing box arround text in OpenLayers 3

javascriptopenlayersstyle

I need text labels with surrounding a box and a specific fill color. Actually I have the following function which only shows the text but I don't know how to draw a box around the text. Text length is always different, so it must consider the text length. Can anybody show me how to implement it?

function showLabel(mapPos) {
  var textStop = replaceAll(mapPos['text'],"|","");
  //textStop = replaceAll(textStop," "," ");
  //textStop = replaceAll(textStop,"-","–");
  var lblFeature = new ol.Feature({
    geometry: new ol.geom.Point(ol.proj.transform([mapPos['lng'],mapPos['lat']],'EPSG:4326','EPSG:3857'))
  });
  var textPos = new ol.style.Text({
    textAlign: 'left',
    textBaseline: 'middle',
    //font: 'bold 16px arial',
    font: '16px arial',
    text: textStop,
    fill: new ol.style.Fill({color: '#000000'}),
    //stroke has bad performance
    //stroke: new ol.style.Stroke({color: mapPos['color'], width: 1}),
    offsetX: 16,
    offsetY: -16,
    rotation: 0
  });
  //TODO: Draw a box arround the text
  var lblStyle = new ol.style.Style({
    text: textPos
  });
  lblFeature.setStyle(lblStyle);
  return lblFeature;
} //End showLabel()

So far I do not get any error in the console.log. I guess it must be done near my TODO Label. mapPos is an array where in mapPos['text'] is text available.

In version 2 I was able to do it like this function:

var markerFlag = new Array();
function showPosition(mapPos) {
  var size = new OpenLayers.Size(24,24);
  var icon = new OpenLayers.Icon('../images/map24/'+mapPos['symbolid']+'.gif',size);
  var myLonLat = new OpenLayers.LonLat(mapPos['lng'],mapPos['lat']).transform(
    proj4326, //Transform from WGS 1984
    projmerc //To Spherical Mercator Projection
  );
  var textPos = replaceAll(mapPos['text'],"|","");
  textPos = replaceAll(textPos," "," ");
  textPos = replaceAll(textPos,"-","–");
  var myOptionsText = {
    mouseOver: false,
    labelOffsetTop: '-58px',
    labelOffsetLeft: '22px',
    backGroundColor: mapPos['color']
  };
  layer_position.addMarker(new OpenLayers.Marker(myLonLat,icon.clone(),myOptionsText));
  if (mapPos['text']) {
    layer_banner.addMarker(new OpenLayers.Marker.Label(myLonLat,icon.clone(),textPos,myOptionsText));
  }
} //End showPosition()

Best Answer

You may be able to achieve the desired effect using the ol.Overlay class of OpenLayers:

Here is a small snippet:

// a coordinate in the view projection
var pos = ol.proj.fromLonLat([16.3725, 48.208889]);

// Vienna label
var vienna = new ol.Overlay({
  position: pos,
  element: document.getElementById('vienna')
});
map.addOverlay(vienna);

In your HTML you'll need a matching element:

<a class="overlay" id="vienna" target="_blank" 
  href="http://en.wikipedia.org/wiki/Vienna">Vienna</a>

And in the CSS the following styles:

#vienna {
  text-decoration: none;
  color: white;
  font-size: 11pt;
  font-weight: bold;
  text-shadow: black 0.1em 0.1em 0.2em;
  padding: 0.2em;
  background-color: rgba(255,255,255,0.3);
  border: 1px solid rgba(255,255,255,0.8);
}

This looks as follows

The rendered ol.Overlay

Here is the running jsfiddle, which is just the original overlay example with a bit of CSS added.

Related Question