In the final example, called ch08_interact, we extend the touch device part of our application and make it more interactive. We want to know our heading when we search for geocaches. Furthermore, it would be a nice feature if our application could give some extra information about a given cache that we could select manually.
Firstly, we extend our listener on the Geolocation object's change event with some necessary modifications. As we would like to track our position and heading, we modify our map's view on every change:
geoloc.on('change', function (evt) {
[…]
map.getView().setCenter(this.getPosition());
if (this.getHeading()) {
map.getView().setRotation(this.getHeading());
}Just like an altitude value, heading is also a GPS-only feature. As receiving a heading is not guaranteed, you should always put the code responsible for rotating the map in an if clause. You can provide the heading to the map's view directly, as it is already in radians that are measured clockwise from north.
Next, we check whether we have a selected feature. Don't worry about the selectInteraction object; we will add it to the map just after this part. If we have a selected cache, we grab its coordinates. As our caches have a Z coordinate, we can calculate an elevation delta from it and also our position's altitude data. However, we cannot create a geometry with coordinates having different strides. To solve this problem, we simply remove the Z coordinate from our cache's position after we calculate the height difference:
if (selectInteraction.getFeatures().getLength() === 1) {
var selectedFeat = selectInteraction.getFeatures().item(0);
var selectedCoords = selectedFeat.getGeometry().getCoordinates();
var height = selectedCoords[2] - this.getAltitude();
selectedCoords.pop();Now, we are ready to create a new line between our position and the selected cache, representing the as-the-crow-flies distance between the two locations. We don't have to worry about the styling of our new feature, as we symbolize everything other than a point with a red line:
positionSrc.addFeature(new ol.Feature({
geometry: new ol.geom.LineString([evt.target.getPosition(), selectedCoords])
}));Next, we give some more feedback about the cache by extending our output with some new lines. We display the distance between the two locations, the height difference, and the possible loot of the given cache. If we can't get an altitude value, we change the resulting NaN to N/A for added consistency:
var extDataString = '\nDistance: ' + positionSrc.getFeatures()[2].getGeometry().getLength() + 'm\nHeight: ' + height + 'm\nPossible loot: ' + selectedFeat.get('loot');
geolocData.textContent += extDataString.replace(/NaN/g, 'N/A');
}
});Finally, we add a select interaction to our map, so we can select arbitrary caches from the cache layer:
var selectInteraction = new ol.interaction.Select({
layers: [geoCaching]
});
map.addInteraction(selectInteraction);If you save and load up the code, you will be able to select caches and get some information about them:
