MapSnippets logoMapSnippets logo

Data-Driven Styling with OpenLayers

OpenLayers

Style vector features dynamically based on data properties using OpenLayers style functions.

progress_activityLoading map...
var features = [];
for (var i = 0; i < 50; i++) {
  features.push(new ol.Feature({
    geometry: new ol.geom.Point(ol.proj.fromLonLat([2.2 + Math.random() * 0.3, 48.8 + Math.random() * 0.1])),
    category: ['restaurant', 'hotel', 'museum'][Math.floor(Math.random() * 3)],
    rating: Math.floor(Math.random() * 5) + 1
  }));
}
var colors = { restaurant: '#e63946', hotel: '#2196F3', museum: '#9C27B0' };
var layer = new ol.layer.Vector({
  source: new ol.source.Vector({ features: features }),
  style: function(feature) {
    var cat = feature.get('category');
    var r = feature.get('rating');
    return new ol.style.Style({
      image: new ol.style.Circle({
        radius: 4 + r * 2,
        fill: new ol.style.Fill({ color: colors[cat] }),
        stroke: new ol.style.Stroke({ color: '#fff', width: 1.5 })
      })
    });
  }
});
var map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'https://api.maptiler.com/maps/streets-v4/256/{z}/{x}/{y}.png?key=YOUR_MAPTILER_KEY', attributions: '&copy; <a href="https://www.maptiler.com/copyright/">MapTiler</a>' }) }),
    layer
  ],
  view: new ol.View({ center: ol.proj.fromLonLat([2.35, 48.85]), zoom: 13 })
});

How it works

OpenLayers uses style functions for data-driven styling. Instead of an expression DSL like MapLibre, you pass a plain JavaScript function to the layer’s style option. This function receives the feature (and resolution) as arguments and returns an ol.style.Style object.

In this example, 50 random points are generated around Paris with category and rating properties. The style function reads each feature’s properties with feature.get() and returns a circle whose color depends on the category (red for restaurants, blue for hotels, purple for museums) and whose radius scales with the rating.

Because the style function is plain JavaScript, you have full control over the styling logic. You can use conditionals, lookups, calculations, or even async data: anything that returns a valid ol.style.Style.

Key APIs

API Description Docs
style function Style callback receiving feature and resolution openlayers.org
feature.get() Read a property value from a feature openlayers.org
ol.style.Circle Circle image symbolizer for point features openlayers.org
ol.style.Style Container for fill, stroke, image, and text symbolizers openlayers.org

FAQ

How is this different from MapLibre’s expression-based styling?

MapLibre uses a declarative JSON expression language (interpolate, match, step). OpenLayers uses imperative JavaScript functions. The function approach is more flexible but does not benefit from WebGL optimization the way MapLibre expressions do.

Can I return different style types for different geometry types?

Yes. Check feature.getGeometry().getType() inside the style function and return appropriate styles: circles for points, strokes for lines, fills for polygons.

Does the style function run on every render frame?

It runs whenever the layer needs to be re-rendered. For large datasets, cache style objects to avoid creating new instances on every call.

Common mistakes

  • Creating new ol.style.Style objects on every call without caching: this causes garbage collection pressure on large datasets
  • Forgetting to handle missing property values: feature.get() returns undefined if the property does not exist
  • Using ol.proj.fromLonLat() for feature coordinates but forgetting it for the map view center
auto_awesome

Build maps using OpenLayers with AI

Generate code like this data-driven styling with openlayers example using the OpenLayers skill in your IDE.