Question to Activity.Info.bearingFromStart

In my Edge datafield I want implement an arrow pointing to the start location of the activity and write the (direct) distance to the start point.

I‘m wondering if I can use Activity.Info.bearingFromStart. The description is not clear (for me):
Bearing from start is the direction of desired track from the start of navigation to the destination in radians. This is only dependent on your location when a course is set, and it is not dependent on where you may have moved to during an activity.

I think, it might be the bearing from my current location to the destination and has less to do with the start location…?

To achieve my goal: do I have to set a location at the start point and then calculate the direction and the distance to that point from my current position - Activity.Info.currentLocation? Or is there any other - simpler - way?

Thank you!

  • If you have coordinates of the start and current point then the task is to resolve the "geodetic inverse".

    As a first step, you have to convert (lat, lon) coordinates into rectangular easting-northing (x, y), let's say into the UTM projection (or, alternatively, into the Mercator projection - formulas should be a bit easier than for UTM). This task is pretty tedious but there should be a lot of information in the network on how to do this.

    So you will get the current point position as (x1, y1), and the start point position as (x2, y2).

    Then the distance to the start point in meters will be calculated as

    d = sqrt((x2-x1)^2 + (y2-y1)^2)

    The rhumb to the start point will be calculated as

    r = atan((x2-x1)/(y2-y1))

    The actual north-based direction to the start point in degrees will be calculated as follows:

    if (y2-y1) > 0 and (x2-x1) > 0 then alpha = r

    if (y2-y1) < 0 and (x2-x1) > 0 then alpha = 180 - r

    if (y2-y1) < 0 and (x2-x1) < 0 then alpha = 180 + r

    if (y2-y1) > 0 and (x2-x1) < 0 then alpha = 360 - r

  • I‘m wondering if I can use Activity.Info.bearingFromStart. The description is not clear (for me):
    Bearing from start is the direction of desired track from the start of navigation to the destination in radians. This is only dependent on your location when a course is set, and it is not dependent on where you may have moved to during an activity.

    I think, it might be the bearing from my current location to the destination and has less to do with the start location…?

    If you believe the docs, bearing is the bearing from your current location to destination and bearingFromStart is the bearing from the start to destination.

    Here's a Monkey C function for geodetic distance between two lat/lon points:

    	//http://www.movable-type.co.uk/scripts/latlong.html
    	// And garmin forums (travis.vitek)
    	function Geodetic_distance_rad(lat1, lon1, lat2, lon2) {
    		var dy = (lat2-lat1);
    		var dx = (lon2-lon1);
    		
    		var sy = Math.sin(dy / 2);
    		sy *= sy;
    		
    		var sx = Math.sin(dx / 2);
    		sx *= sx;
    		
    		var a = sy + Math.cos(lat1) * Math.cos(lat2) * sx;
    		
    		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    		
    		return 6371000 * c; // radius of earth in meters * c
    	}

    	function getDistanceDelta(currentLocation, destinationLocation) {
    		if (destinationLocation != null && currentLocation != null) {
    			var dest = destinationLocation.toRadians();
    			var cur = currentLocation.toRadians();
    			return Geodetic_distance_rad(cur[0], cur[1], dest[0], dest[1]);
    		}
    		return null;
    	}
    
    	var distanceToStart = getDistanceDelta(activityInfo.currentLocation, activityInfo.startLocation);

  • That description doesn’t make any sense. 

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Activity/Info.html

    The bearing from the starting location to the destination in radians.”

    This doesn’t do what you want.

    Calculate the bearing youself from currentLocation and startLocation.

     

  • Thank you,  !  Distance works perfectly on simulator with loaded activity fit file (we have winter and snow - no outdoor tests...)

    Regarding course direction: Thanks  !
    Sounds more complicated...  I will dig in.

    Are there any code snippets for direction, too?

  • Found my own old code for coordinates conversion to the Mercator projection (written in Java though):

    static double[] degreesToPlanar(double aLat, double aLon) {
    // semi-major axis    
    double a = 6378137;    
    // ellipsoid compression  
    double f = 1/298.257223563;     
    // ellipsoid eccentricity   
    double e = sqrt(2*f-f*f); 
       
    double lat = toRadians(aLat);    
    double lon = toRadians(aLon);  
       
    double x = a * lon;    
    double y = a * log(tan(PI / 4 + lat / 2) * pow(((1 - e * sin(lat)) / (1 + e * sin(lat))), (e / 2)));  
     
    double[] planarCoords = new double[2];    
    planarCoords[0] = x;    
    planarCoords[1] = y;
       
    return planarCoords;   
    }

    The thing is that it should be more precise in distance and direction calculation since it uses an ellipsoid as an Earth mathematical model (it's not explicitly stated in the Connect IQ API docs, but usually GPS coordinates are referenced to this model), whereas FlowState's formulas use a simple spheroid with 6371 km radius as an Earth model.

    I don't know how much exactly will be the difference in distance, but I believe not greater than a few meters, so for your practical task both calculation methods are acceptable

  • Thank you very much!

    In Wikipedia I found a description ORTHODROME which seems to be simple...
    (my calculation needs not to be exactly because it is about bicycle activities of about 30 tom 50 km)

    It is written in German ( sorry ) but the Englich Wiki page is not the same...

    On base of this formulas I coded following ( but it does not work for course direction - but it works for distance!

    Something's I'm doing wrong...
    (variables "cDegree" and "mDirection" are declared on top)

        function Geodetic_direction(lat1, lon1, lat2, lon2) {
            //lat, lon in Degrees
            cDegree = Math.acos( (Math.sin(lat1)*Math.sin(lat2)) + (Math.cos(lat1)*Math.cos(lat2)*Math.cos(lon2-lon1)) ); 
            System.println( cDegree * 6371000 * Math.PI/180);  // distance in m
            return Math.acos( (Math.sin(lat2) - Math.sin(lat1)*Math.cos(cDegree)) / Math.cos(lat2)*Math.sin(cDegree) );
            
        }
    

        function getCourseDirection(currentLocation, destinationLocation) {
    		if (destinationLocation != null && currentLocation != null) {
    			var destD = destinationLocation.toDegrees();
    			var curD = currentLocation.toDegrees();
                return Geodetic_direction(curD[0], curD[1], destD[0], destD[1]);
    		}
    		return null;
    	}
    

    mDirection = getCourseDirection(info.currentLocation, info.startLocation);  // result in Degrees

  • Why are you passing degrees to a distance function (a function that that locations)?


    Look up the formula for bearing.

    There’s no reason other people have to do that for you.

    https://www.igismap.com/what-is-bearing-angle-and-calculate-between-two-points/

    You have to use radians (not degrees), by the way.

  • I've finally managed to get the test project up and running.

    Thanks to everyone who gave me suggestions!