mapboxdirectionmapbox-gl-jsheadingbearing

Mapbox GL JS Bearing


Is it possible in Mapbox GL JS to get the users bearing? I would like to show the direction in which the user is facing, to assist them in navigating to nearby POI. I understand that it is possible to set the bearing of the map and also get the current bearing of it, but i need the actual real life bearing of the user. Kind of the same thing as on Google Maps: enter image description here

The service is intended to run as an Ionic app on iOS and Android, and the assistance in bearing is a key feature in helping them locate nearby POI on a well populated map.


Solution

  • So, after some time spend on this, i thought I'd show how i ended up doing this, in case someone else needs it or have a better solution.

    It seems cordova has a built in "heading" property in the position object. https://github.com/apache/cordova-plugin-geolocation

    var heading = $rootScope.position.heading;
    

    First, i make sure that the marker is always pointing in the heading direction, even when the user turns the map, by subtracting the mapBearing(degrees the map has turned from North), from the user heading.

    map.on('rotate', function(){
        map.setLayoutProperty('drone', 'icon-rotate', heading - map.getBearing())
    });
    

    I create an icon, at the users position, add the source and add the layer with the source.

    map.on('load', function () {
      var point = {"type": "Point", "coordinates": [$rootScope.position.long, $rootScope.position.lat]};
      map.addSource('drone', {type: 'geojson', data: point });
      map.addLayer({
        "id": "drone",
        "type": "symbol",
        "source": "drone"
      }
    });
    

    Next i check that heading is actually available, since it only appears to return a value, when the user is moving(only tested on Android so far), and if it is, update the heading of the point.

    if($rootScope.position.heading){
        var heading = $rootScope.position.heading; 
        map.setLayoutProperty('drone', 'icon-rotate', $rootScope.position.heading);
    };
    

    Finally i update the position of the point, in a "$watch" position.

    map.getSource('drone').setData(point);
    

    This way, i can watch the users heading, and the point keeps on track, even when the user rotates the map.