可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I implemented the "bearing" formula from http://www.movable-type.co.uk/scripts/latlong.html. But it seems highly inaccurate - I suspect some mistakes in my implementation. Could you help me with finding it? My code is below:
protected static double bearing(double lat1, double lon1, double lat2, double lon2){ double longDiff= lon2-lon1; double y = Math.sin(longDiff)*Math.cos(lat2); double x = Math.cos(lat1)*Math.sin(lat2)-Math.sin(lat1)*Math.cos(lat2)*Math.cos(longDiff); return Math.toDegrees((Math.atan2(y, x))+360)%360; }
回答1:
You just have your parentheses ()
in the wrong place.
You are adding degrees to a value in radians, which won't work. toDegrees()
will do the conversion from radians to degrees for you, then you do the normalisation once you have a value in degrees.
You have:
Math.toDegrees( (Math.atan2(y, x))+360 ) % 360;
But you need:
( Math.toDegrees(Math.atan2(y, x)) + 360 ) % 360;
Remember also that all inputs to Math.sin()
, Math.cos()
and all the other trigonometric functions must be in radians. If your inputs are degrees you'll need to convert them using Math.toRadians()
first.
回答2:
Here is the final code:
protected static double bearing(double lat1, double lon1, double lat2, double lon2){ double longitude1 = lon1; double longitude2 = lon2; double latitude1 = Math.toRadians(lat1); double latitude2 = Math.toRadians(lat2); double longDiff= Math.toRadians(longitude2-longitude1); double y= Math.sin(longDiff)*Math.cos(latitude2); double x=Math.cos(latitude1)*Math.sin(latitude2)-Math.sin(latitude1)*Math.cos(latitude2)*Math.cos(longDiff); return (Math.toDegrees(Math.atan2(y, x))+360)%360; }
回答3:
Bearing from one coordinate to another And Find North,East,south,weast :)
public class FindBearing { public static void main(String[] args) { System.out.println(" Your Result >>> "+FindBearing.bearing(19.2859590, 73.4966430, 19.2861020, 73.4988090)); } protected static String bearing(double lat1, double lon1, double lat2, double lon2){ double longitude1 = lon1; double longitude2 = lon2; double latitude1 = Math.toRadians(lat1); double latitude2 = Math.toRadians(lat2); double longDiff= Math.toRadians(longitude2-longitude1); double y= Math.sin(longDiff)*Math.cos(latitude2); double x=Math.cos(latitude1)*Math.sin(latitude2)-Math.sin(latitude1)*Math.cos(latitude2)*Math.cos(longDiff); double resultDegree= (Math.toDegrees(Math.atan2(y, x))+360)%360; String coordNames[] = {"N","NNE", "NE","ENE","E", "ESE","SE","SSE", "S","SSW", "SW","WSW", "W","WNW", "NW","NNW", "N"}; double directionid = Math.round(resultDegree / 22.5); // no of array contain 360/16=22.5 if (directionid
回答4:
A little bit cleaned up version of @IvanT answer:
public static double bearingInRadians(LatLng src, LatLng dst) { double srcLat = Math.toRadians(src.getLatitude()); double dstLat = Math.toRadians(dst.getLatitude()); double dLng = Math.toRadians(dst.getLongitude() - src.getLongitude()); return Math.atan2(Math.sin(dLng) * Math.cos(dstLat), Math.cos(srcLat) * Math.sin(dstLat) - Math.sin(srcLat) * Math.cos(dstLat) * Math.cos(dLng)); } public static double bearingInDegrees(LatLng src, LatLng dst) { return Math.toDegrees((bearingInRadians(src, dst) + Math.PI) % Math.PI); }
Where LatLng
is:
public final class LatLng { private final double latitude; private final double longitude; public LatLng(double latitude, double longitude) { this.latitude = latitude; this.longitude = longitude; } public double getLatitude() { return latitude; } public double getLongitude() { return longitude; } }