OpenLayers 3 Beginner’s Guide

Using properties to style features

Open sample in a new windows

<!doctype html>
<html>
  <head>
    <title>Vector Style Examples</title>
    <link rel="stylesheet" href="../assets/ol3/css/ol.css" type="text/css" />
    <link rel="stylesheet" href="../assets/css/samples.css" type="text/css" />
  </head>
  <body>
    <div id="map" class="map"></div>
    <script src="../assets/ol3/js/ol.js"></script>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script>
      // define some colours matching some arbitrary divisions of the
      // OECD income data
      var high = [64,196,64,1];
      var mid = [108,152,64,1];
      var low = [152,108,64,1];
      var poor = [196,32,32,1];
      // map the income level codes to a colour value, grouping them
      var incomeLevels = {
        'HIC': high, // high income
        'OEC': high, // high income OECD
        'NOC': high, // high income, non-OECD
        'UMC': mid, // upper middle income
        'MIC': mid, // middle income
        'LMC': mid, // lower middle income
        'LIC': low, // low income
        'LMY': low, // low and middle income
        'HPC': poor // heavily indebted poor country
      };

      // a default style is good practice!
      var defaultStyle = new ol.style.Style({
        fill: new ol.style.Fill({
          color: [250,250,250,1]
        }),
        stroke: new ol.style.Stroke({
          color: [220,220,220,1],
          width: 1
        })
      });

      // a javascript object literal can be used to cache
      // previously created styles. Its very important for
      // performance to cache styles.
      var styleCache = {};

      // the style function returns an array of styles
      // for the given feature and resolution.
      // Return null to hide the feature.
      function styleFunction(feature, resolution) {
        // get the incomeLevel from the feature properties
        var level = feature.get('incomeLevel');
        // if there is no level or its one we don't recognize,
        // return the default style (in an array!)
        if (!level || !incomeLevels[level]) {
          return [defaultStyle];
        }
        // check the cache and create a new style for the income
        // level if its not been created before.
        if (!styleCache[level]) {
          styleCache[level] = new ol.style.Style({
            fill: new ol.style.Fill({
              color: incomeLevels[level]
            }),
            stroke: defaultStyle.stroke
          });
        }
        // at this point, the style for the current level is in the cache
        // so return it (as an array!)
        return [styleCache[level]];
      }

      var source = new ol.source.GeoJSON({
        projection: 'EPSG:3857',
        url: '../assets/data/countries.geojson'
      });

      var countries = new ol.layer.Vector({
        source: source,
        style: styleFunction
      });
      var center = ol.proj.transform([0, 0], 'EPSG:4326', 'EPSG:3857');
      var view = new ol.View({
        center: center,
        zoom: 1
      });
      var map = new ol.Map({
        target: 'map',
        layers: [countries],
        view: view
      });

      // we want to merge the country data with the income level data. After
      // the country data is 'ready', we can load the income level data and
      // the add a new property by linking the two sets of data on the
      // ISO country code that is present in both data sets.
      var key = source.on('change', function(event) {
        if (source.getState() == 'ready') {
          source.unByKey(key);
          $.ajax('../assets/data/income_levels.json').done(function(data) {
            countries.getSource().forEachFeature(function(feature) {
              var code = feature.get('iso_a2');
              if (data[code]) {
                feature.set('incomeLevel', data[code]);
              }
            });
          });
        }
      });

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