In the next example, called ch08_styling, we improve our touch device version with another vector layer and some styling. We display the current position of the user and the accuracy of the position in meters, and style the geocaches based on the height difference of our position and the caches. Firstly, we create a layer containing our position and give it a static style:
if (ol.has.TOUCH) {
[…]
var positionLyr = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: [255, 255, 255, 1]
}),
stroke: new ol.style.Stroke({
color: [0, 0, 0, 1],
width: 2
}),
radius: 6
}),
stroke: new ol.style.Stroke({
color: [255, 0, 0, 1],
width: 2
})
})
});
map.addLayer(positionLyr);We will have two kinds of features in this layer. If we have to deal with a point feature, it will be our position that we style with the image property. Every other layer, regardless of its type, will be displayed with a red line or an outline. Next, we update our layer every time we receive a new position:
geoloc.on('change', function (evt) {
[…]
var positionSrc = positionLyr.getSource();
positionSrc.clear(true);
positionSrc.addFeatures([
new ol.Feature({
geometry: new ol.geom.Point(evt.target.getPosition())
}),
new ol.Feature({
geometry: new ol.geom.Circle(evt.target.getPosition(), evt.target.getAccuracy())
})
]);
geoCaching.setStyle(geoCaching.getStyleFunction());
});The first part is simple: we fast-clear our new layer's source by providing a true value to its clear method. This way, no removefeature events get dispatched, increasing the performance of our application. After this, we add two new features, one for our position and one to display the accuracy of it. Next, we update the style of our geocaches, as styles returned by style functions become static after evaluation.
Finally, we provide the style function that will be updated regularly. In this function, we evaluate some common values based on the feature's and the position's altitude. If a cache is almost on the same elevation as us, we symbolize it as a yellow square. If it lies higher, it will be a red triangle pointing upwards. If it is lower than us, it's shape will be a green triangle pointing downwards:
geoCaching.setStyle(function (feature, res) {
if (geoloc.getAltitude()) {
var altitude = geoloc.getAltitude();
var zCoord = feature.getGeometry().getCoordinates()[2];
var shapePts, shapeColor, shapeAngle;
if (Math.abs(altitude - zCoord) < 1) {
shapePts = 4;
shapeColor = [255, 255, 0, 1];
shapeAngle = Math.PI / 4;
} else if (zCoord < altitude) {
shapePts = 3;
shapeColor = [0, 255, 0, 1];
shapeAngle = Math.PI;
} else {
shapePts = 3;
shapeColor = [255, 0, 0, 1];
shapeAngle = 0;
}Now we can return the appropriate style object for our cache. If we can get an altitude from our Geolocation object, we return a style evaluated previously; otherwise, if the GPS signal is not adequate to give an altitude value, we display our caches with red X symbols. We can create such a shape by creating a star with four tips and a great difference between its inner and outer radii:
return [new ol.style.Style({
image: new ol.style.RegularShape({
fill: new ol.style.Fill({
color: shapeColor
}),
stroke: new ol.style.Stroke({
color: [0, 0, 0, 1],
width: 1
}), points: shapePts,
radius: 10,
angle: shapeAngle
})
})];
} else {
return [new ol.style.Style({
image: new ol.style.RegularShape({
fill: new ol.style.Fill({
color: [255, 0, 0, 1]
}),
stroke: new ol.style.Stroke({
color: [0, 0, 0, 1],
width: 1
}),
points: 4,
radius1: 5,
radius2: 10,
angle: Math.PI / 2
})
})];
}
});
}If you save the code and look it up from your smartphone, you will see the dynamic rendering of our position and symbols:
