Search code examples
htmlcssopenlayersstroke

Openlayers: How to add a colored border around a line features


I want to assign a border to line feature. In the below code, I am able to assign stroke color as per the type of road but I want to assign another border on it. for e.g. I want to assign a border to the last else statement. whatever features fall in that category should border along with the stroke color. how I can achieve this?

img: enter image description here

<!doctype html>
<html>
  <head>
    <title>Vector Tiles</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v5.3.0/css/ol.css" type="text/css" />
    <style>
      .map {
        width: 100%;
        height: 100vh;
      }
      body {
        margin: 0;
      }
    </style>
  </head>
  <body>
  <body>
    <div id="map" class="map">
      <div id="popup"></div>
    </div>
    <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
    <script>

      var popup = new ol.Overlay({
        element: document.getElementById('popup')
      });

      var osmLayer = new ol.layer.Tile({
        source: new ol.source.OSM()
      });

      var styleFunction = function(feature) {
       console.log(feature);
     //assign symbology of roads based on road type
      var color;
      if (feature.get("type")=='primary' && 'secondary' && 'trunk'){
      color = 'rgba(252, 214, 112, 1)';
      } else if (feature.get("type")=='motorway'){
      color = 'rgba(245, 171, 53, 1)';
      }else if (feature.get("type")=='cycleway'){
      color = 'rgba(3, 166, 120, 1)';
      } else {
      color = 'rgba(236, 236, 236, 1)'  
      }
      
      var retStyle =   new ol.style.Style({
          stroke: new ol.style.Stroke({ 
            color: color,
            width: 5
          })
        });
       return retStyle;

      };
      
      var vectorLayer1 = new ol.layer.VectorTile({
            source: new ol.source.VectorTile({
            format: new ol.format.MVT(),
            url: 'http://localhost:8080/tiles/roads/{z}/{x}/{y}.mvt'
        }),
        style: styleFunction 
       
      })

        var selectInteraction = new ol.interaction.Select({
        layers: function (layer) {
          return layer.get('name');
        }
      });

        
      var map = new ol.Map({
        target: 'map',
        layers: [osmLayer,vectorLayer1],
        view: new ol.View({
          center: ol.proj.fromLonLat([103.8198,1.3521]),
          zoom: 13
          })
      });

        map.addOverlay(popup);

      function pickRandomProperty() {
        var prefix = ['bottom', 'center', 'top'];
        var randPrefix = prefix[Math.floor(Math.random() * prefix.length)];
        var suffix = ['left', 'center', 'right'];
        var randSuffix = suffix[Math.floor(Math.random() * suffix.length)];
        return randPrefix + '-' + randSuffix;
      }

      var container = document.getElementById('popup');
      var displayFeatureInfo = function(pixel, coordinate) {
        var features = [];
        map.forEachFeatureAtPixel(pixel, function(feature, layer) {
          features.push(feature);
        });
        if (features.length > 0) {
          var info = [];
          for (var i = 0, ii = features.length; i < ii; ++i) {
            info.push(features[i].get('name'));
          }
          container.innerHTML = info.join(', ') || '(unknown)';
          var randomPositioning = pickRandomProperty();
          popup.setPositioning(randomPositioning);
          popup.setPosition(coordinate);
        } else {
          container.innerHTML = '&nbsp;';
        }
      };

      map.on('click', function(evt) {
        var coordinate = evt.coordinate;
        displayFeatureInfo(evt.pixel, coordinate);
      });

    </script>
  </body>
</html>

Solution

  • As long as you don't have any transparency in the inner color you can use an array of overlapping stroke styles

      var retStyle = [
        new ol.style.Style({
          stroke: new ol.style.Stroke({ 
            color: outerColor,
            width: 7,
          }),
          zIndex: 0,
        }),
        new ol.style.Style({
          stroke: new ol.style.Stroke({ 
            color: color,
            width: 5,
          }),
          zIndex: 1,
        })
      ];