Data-Driven Styling with OpenLayers
OpenLayersStyle vector features dynamically based on data properties using OpenLayers style functions.
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: '© <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.Styleobjects on every call without caching: this causes garbage collection pressure on large datasets - Forgetting to handle missing property values:
feature.get()returnsundefinedif the property does not exist - Using
ol.proj.fromLonLat()for feature coordinates but forgetting it for the map view center
Build maps using OpenLayers with AI
Generate code like this data-driven styling with openlayers example using the OpenLayers skill in your IDE.
Related Examples
- Choropleth Map with OpenLayers
- Load GeoJSON in OpenLayers
- See how to do this in MapLibre GL JS or MapTiler SDK