Here you can find the source of calculateEte(boolean useBearing, double distance, double speed, double bearing, double heading)
Parameter | Description |
---|---|
distance | - how far to the target |
speed | - how fast we are moving |
bearing | - direction to target |
heading | - direction of movement |
public static String calculateEte(boolean useBearing, double distance, double speed, double bearing, double heading)
//package com.java2s; import java.util.Locale; import android.text.format.Time; public class Main { /***//from w w w . ja v a 2 s. c om * Fetch the estimate travel time to the indicated target * @param distance - how far to the target * @param speed - how fast we are moving * @param bearing - direction to target * @param heading - direction of movement * @return String - "HH:MM" or "MM.SS" time to the target */ public static String calculateEte(boolean useBearing, double distance, double speed, double bearing, double heading) { // If no speed, then return the empty display value if (0 == speed) { return "--:--"; } // Fetch the eteRaw value Time eteRaw = fetchRawEte(useBearing, distance, speed, bearing, heading); // If an invalid eteRaw, then return the empty display value if (null == eteRaw) { return "--:--"; } // Break the eteRaw out into hours and minutes int eteHr = eteRaw.hour; int eteMin = eteRaw.minute; int eteSecond = eteRaw.second; // Hours greater than 99 are not displayable if (eteHr > 99) { return "XX:XX"; } // If hours is non zero then return HH:MM if (eteHr > 0) { // Format the hours and minutes en router String hr = String.format(Locale.getDefault(), "%02d", eteHr); String min = String.format(Locale.getDefault(), "%02d", eteMin); // Build the string for return return hr + ":" + min; } // Hours is zero, so return MM.SS String min = String.format(Locale.getDefault(), "%02d", eteMin); String sec = String.format(Locale.getDefault(), "%02d", eteSecond); // Build the string for return return min + "." + sec; } /*** * Fetch the raw estimated time enroute given the input parameters * @param distance - how far to the target * @param speed - how fast we are moving * @param bearing - direction to target * @param heading - direction of movement * @return int value of HR * 100 + MIN for the ete, -1 if not applicable */ private static Time fetchRawEte(boolean useBearing, double distance, double speed, double bearing, double heading) { double xFactor = 1; if (useBearing) { // We can't assume that we are heading DIRECTLY for the destination, so // we need to figure out the multiply factor by taking the COS of the difference // between the bearing and the heading. double angDif = angularDifference(heading, bearing); // If the difference is 90 or greater, then ETE means nothing as we are not // closing on the target if (angDif >= 90) return null; // Calculate the actual relative speed closing on the target xFactor = Math.cos(angDif * Math.PI / 180); } // Calculate the travel time in seconds double eteTotal = (distance / (speed * xFactor)) * 3600; // Allocate an empty time object Time ete = new Time(); // Extract the hours ete.hour = (int) (eteTotal / 3600); // take whole int value as the hours eteTotal -= (ete.hour * 3600); // Remove the hours that we extracted // Convert what's left to fractional minutes ete.minute = (int) (eteTotal / 60); // Get the int value as the minutes now eteTotal -= (ete.minute * 60); // remove the minutes we just extracted // What's left is the remaining seconds ete.second = Math.round((int) eteTotal); // round as appropriate // Account for the seconds being 60 if (ete.second >= 60) { ete.minute++; ete.second -= 60; } // account for the minutes being 60 if (ete.minute >= 60) { ete.hour++; ete.minute -= 60; } // Time object is good to go now return ete; } /** Calculate the absolute angular difference between the two headings * * @param hdg angle 1 in degrees (typically the heading) * @param brg angle 2 in degrees (typically the bearing) * @return difference between hdg and brg in degrees */ public static double angularDifference(double hdg, double brg) { double absDiff = Math.abs(hdg - brg); if (absDiff > 180) { return 360 - absDiff; } return absDiff; } }