/** * Class to work with locations, and lat/lon pairs. * @version 2009-03-31 18:33 * @url http://code.calum.org/ * @author calum */ public class LocationUtils { /** * Gets the distance in miles between two javax.microedition.location.Locations * Just a wrapper that extracts the lat and lon from the Locations, and calls getDistanceInMiles(oldlat, oldlon, newlat, newlon) * @param lastLocation The previous location * @param currentLocation The current location * @return null if either location is null, or there's a problem */ public static Double getDistanceInMiles(javax.microedition.location.Location lastLocation, javax.microedition.location.Location currentLocation) { if (lastLocation == null || currentLocation == null) { System.err.println("getDistanceInMiles(Location, Location) - one of the Locations is null"); return null; } double oldlat = lastLocation.getQualifiedCoordinates().getLatitude(); double oldlon = lastLocation.getQualifiedCoordinates().getLongitude(); double newlat = currentLocation.getQualifiedCoordinates().getLatitude(); double newlon = currentLocation.getQualifiedCoordinates().getLongitude(); System.out.println("getdistanceInMiles from " + newlat + ", " + newlon + ", " + oldlat + ", " + oldlon); return getDistanceInMiles(oldlat, oldlon, newlat, newlon); } /** * Calculates the distance in miles between two sets of lat, lon coordinates. * @param oldlat The old lat * @param oldlon The old lon * @param newlat The new lat * @param newlon The new lon * @return The distance in miles from the old lat,lon to the new lat,lon */ public static Double getDistanceInMiles(double oldlat, double oldlon, double newlat, double newlon) { System.out.println("getDistanceInMiles(" + oldlat + "," + oldlon + " to " + newlat + "," + newlon + ")"); //DebugForm_old.getInstance().debug("getdistance " + newlat + ", " + newlon + ", " + oldlat + ", " + oldlon, 1); // acos( // cos(radians($1)) * cos(radians($2)) *cos(radians($3)) * cos(radians($4)) + // cos(radians($1))*sin(radians($2)) *cos(radians($3))*sin(radians($4)) + // sin(radians($1))*sin(radians($3)) // ) * 3963.1 double dnewlatrads = java.lang.Math.toRadians(newlat); double dnewlonrads = java.lang.Math.toRadians(newlon); double doldlatrads = java.lang.Math.toRadians(oldlat); double doldlonrads = java.lang.Math.toRadians(oldlon); double milesd = mMath.acos( java.lang.Math.cos(dnewlatrads) * java.lang.Math.cos(dnewlonrads) * java.lang.Math.cos(doldlatrads) * java.lang.Math.cos(doldlonrads) + java.lang.Math.cos(dnewlatrads) * java.lang.Math.sin(dnewlonrads) * java.lang.Math.cos(doldlatrads) * java.lang.Math.sin(doldlonrads) + java.lang.Math.sin(dnewlatrads) * java.lang.Math.sin(doldlatrads)) * 3963.1f; Double miles = new Double(milesd); System.out.println("getDistanceInMiles(lat, lon, lat, lon) is returning " + miles + " miles."); return miles; } /** * Gets the speed in MPH between two javax.microedition.location.Locations * @param lastLocation The previous location (used for elapsed time calculations) * @param currentLocation The current location (used for elapsed time calculations) * @param distanceMiles the distance travelled in said time * @return null if either location is null, or there's a problem */ public static Double getCalcedSpeedMPH( javax.microedition.location.Location lastLocation, javax.microedition.location.Location currentLocation, Double distanceMiles) { if (lastLocation == null || currentLocation == null) { return null; } double hours = (currentLocation.getTimestamp() - lastLocation.getTimestamp()) / 3600000D; return new Double(distanceMiles.doubleValue() / hours); } /** * This is some of Nicky's wizardry. * It calculates the heading from 1 lat/lon to another lat/lon */ public static int getHeading(double oldlat, double oldlon, double newlat, double newlon) { System.out.println("Called with " + Double.toString(newlat) + "," + Double.toString(newlon) + " : " + Double.toString(oldlat) + "," + Double.toString(oldlon)); if (newlon == oldlon) { if (newlat < oldlat) { return 180; } else { return 0; } } if (newlat == oldlat) { if (newlon > oldlon) { return 90; } else if (newlon < oldlon) { return 270; } } if ((newlat > oldlat) && (newlon > oldlon)) { double difflat = java.lang.Math.abs(newlat - oldlat); double difflon = java.lang.Math.abs(newlon - oldlon); double ratio = difflon / difflat; double tmp = mMath.atan(ratio); return (int) java.lang.Math.toDegrees(tmp); } else if ((newlon > oldlon) && (newlat < oldlat)) { return 180 - (int) java.lang.Math.toDegrees(mMath.atan(java.lang.Math.abs(newlon - oldlon) / java.lang.Math.abs(newlat - oldlat))); } else if ((newlat < oldlat) && (newlon < oldlon)) { double difflat = java.lang.Math.abs(newlat - oldlat); double difflon = java.lang.Math.abs(newlon - oldlon); double ratio = difflon / difflat; double tmp = mMath.atan(ratio); return 180 + (int) java.lang.Math.toDegrees(tmp); } else { double difflat = java.lang.Math.abs(newlat - oldlat); double difflon = java.lang.Math.abs(newlon - oldlon); double ratio = difflon / difflat; double tmp = mMath.atan(ratio); return 360 - (int) java.lang.Math.toDegrees(tmp); } } /** * Returns a friendly heading - e.g. SouthWest * @param degrees The heading to convert */ public static String getFriendlyHeadingString(int degrees) { if (degrees == -999) { return "?"; } if (degrees >= 337 || degrees < 22) { return "N"; } if (degrees >= 22 && degrees < 67) { return "NE"; } if (degrees >= 67 && degrees < 112) { return "E"; } if (degrees >= 112 && degrees < 157) { return "SE"; } if (degrees >= 157 && degrees < 202) { return "S"; } if (degrees >= 202 && degrees < 247) { return "SW"; } if (degrees >= 247 && degrees < 292) { return "W"; } if (degrees >= 292 && degrees < 337) { return "NW"; } return "?" + degrees; } public static double calumround(double arg, int places) { //System.out.println("calumround("+ Double.toString(arg) +"," + Integer.toString(places)+ ")"); double tmp = (double) arg * (pow(10, places)); int tmp1 = (int) Math.floor(tmp + 0.5); double tmp2 = (double) tmp1 / (pow(10, places)); return tmp2; } public static int pow(int arg, int times) { int ret = 1; for (int i = 1; i <= times; i++) { ret = ret * arg; } return ret; } }