This (silly) picture summarizes the issue I'm having:
These are rendered in a vector layer.
Below these shields is a line string that I render once as-is (i.e. as a line), and on top of it I also render it using a style that has a geometry
function defined. In that function, I return a ol.geom.MultiPoint
containing the coordinates where I want shields to be added alongside the line.
My above demonstration is silly, I know (i.e. in my real use case, the gap between the shields is way bigger, so I know I won't have any collision).
The thing is, I'm aware that there's normally a way to avoid this kind of behaviour with the zIndex
property of the ol.style.Style
, i.e. if each feature has its own style defining a different zIndex, then each shield+text would be correctly rendered with text below overlapping shields. But, this can't work with a geometry
method, as the same style is used multiple times for the same feature to render it multiple times.
Like I said, since I'll define a big enough gap to avoid collisions anyway I don't really need to figure a way to fix this issue, but I'm curious if there is one, for my future self and other people that would like to know.
Each point on a multipoint can be given its own style. Take this OpenLayers example http://openlayers.org/en/v4.6.5/examples/polygon-styles.html If you replace the styles array with this function each point on the multipoints can be given a different radius and different shade of yellow. It also works for zIndex, as can be seen where the first and last coordinates of the polygons coincide.
function styles(feature) {
var multipoint = new ol.geom.MultiPoint(feature.getGeometry().getCoordinates()[0]);
var styles = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.1)'
})
})
];
multipoint.getCoordinates().forEach(function(coordinates, index) {
var shade = (index+1)*50;
var radius = (index+1)*5;
var zIndex = 10-index;
styles.push(new ol.style.Style({
zIndex: zIndex,
image: new ol.style.Circle({
radius: radius,
fill: new ol.style.Fill({
color: 'rgba(' + shade + ',' + shade + ', 0, 1)'
})
}),
geometry: new ol.geom.Point(coordinates)
}));
});
return styles;
}