Вот моя попытка, это всего лишь фрагмент моего кода:
final double RADIUS = 6371.01;
double temp = Math.cos(Math.toRadians(latA))
* Math.cos(Math.toRadians(latB))
* Math.cos(Math.toRadians((latB) - (latA)))
+ Math.sin(Math.toRadians(latA))
* Math.sin(Math.toRadians(latB));
return temp * RADIUS * Math.PI / 180;
Я использую эти формулы, чтобы получить широту и долготу:
x = Deg + (Min + Sec / 60) / 60)
java
math
latitude-longitude
m4design
источник
источник
a
иc
? Это стороны прямоугольного треугольника с традиционными надписямиa
,b
иc
?Вот функция Java, которая вычисляет расстояние между двумя точками широты и долготы, размещенная ниже, на случай, если она снова исчезнет.
private double distance(double lat1, double lon1, double lat2, double lon2, char unit) { double theta = lon1 - lon2; double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta)); dist = Math.acos(dist); dist = rad2deg(dist); dist = dist * 60 * 1.1515; if (unit == 'K') { dist = dist * 1.609344; } else if (unit == 'N') { dist = dist * 0.8684; } return (dist); } /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ /*:: This function converts decimal degrees to radians :*/ /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ private double deg2rad(double deg) { return (deg * Math.PI / 180.0); } /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ /*:: This function converts radians to decimal degrees :*/ /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ private double rad2deg(double rad) { return (rad * 180.0 / Math.PI); } System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'M') + " Miles\n"); System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'K') + " Kilometers\n"); System.out.println(distance(32.9697, -96.80322, 29.46786, -98.53506, 'N') + " Nautical Miles\n");
источник
Примечание: это решение работает только на короткие расстояния.
Я попытался использовать опубликованную формулу dommer для приложения и обнаружил, что она хорошо работает на больших расстояниях, но в моих данных я использовал все очень короткие расстояния, а сообщение dommer очень плохо работало. Мне нужна была скорость, и более сложные геологические вычисления работали хорошо, но были слишком медленными. Итак, в случае, если вам нужна скорость и все вычисления, которые вы делаете, короткие (возможно, <100 м или около того). Я обнаружил, что это небольшое приближение отлично работает. он предполагает, что мир плоский, поэтому не используйте его для больших расстояний, он работает, аппроксимируя расстояние одной широты и долготы на заданной широте и возвращая расстояние Пифагора в метрах.
public class FlatEarthDist { //returns distance in meters public static double distance(double lat1, double lng1, double lat2, double lng2){ double a = (lat1-lat2)*FlatEarthDist.distPerLat(lat1); double b = (lng1-lng2)*FlatEarthDist.distPerLng(lat1); return Math.sqrt(a*a+b*b); } private static double distPerLng(double lat){ return 0.0003121092*Math.pow(lat, 4) +0.0101182384*Math.pow(lat, 3) -17.2385140059*lat*lat +5.5485277537*lat+111301.967182595; } private static double distPerLat(double lat){ return -0.000000487305676*Math.pow(lat, 4) -0.0033668574*Math.pow(lat, 3) +0.4601181791*lat*lat -1.4558127346*lat+110579.25662316; } }
источник
Будущие читатели, которые наткнутся на эту статью SOF.
Очевидно, этот вопрос был задан в 2010 году, а сейчас - в 2019 году. Но он возникает рано при поиске в Интернете. Исходный вопрос не обесценивает использование сторонней библиотеки (когда я писал этот ответ).
public double calculateDistanceInMeters(double lat1, double long1, double lat2, double long2) { double dist = org.apache.lucene.util.SloppyMath.haversinMeters(lat1, long1, lat2, long2); return dist; }
а также
<dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-spatial</artifactId> <version>8.2.0</version> </dependency>
https://mvnrepository.com/artifact/org.apache.lucene/lucene-spatial/8.2.0
Пожалуйста, прочтите документацию по "SloppyMath" перед тем, как погрузиться в нее!
https://lucene.apache.org/core/8_2_0/core/org/apache/lucene/util/SloppyMath.html
источник
Вот страница с примерами javascript для различных сферических вычислений. Самый первый на странице должен дать вам то, что вам нужно.
http://www.movable-type.co.uk/scripts/latlong.html
Вот код Javascript
var R = 6371; // km var dLat = (lat2-lat1).toRad(); var dLon = (lon2-lon1).toRad(); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * Math.sin(dLon/2) * Math.sin(dLon/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c;
Где d будет держать расстояние.
источник
package distanceAlgorithm; public class CalDistance { public static void main(String[] args) { // TODO Auto-generated method stub CalDistance obj=new CalDistance(); /*obj.distance(38.898556, -77.037852, 38.897147, -77.043934);*/ System.out.println(obj.distance(38.898556, -77.037852, 38.897147, -77.043934, "M") + " Miles\n"); System.out.println(obj.distance(38.898556, -77.037852, 38.897147, -77.043934, "K") + " Kilometers\n"); System.out.println(obj.distance(32.9697, -96.80322, 29.46786, -98.53506, "N") + " Nautical Miles\n"); } public double distance(double lat1, double lon1, double lat2, double lon2, String sr) { double theta = lon1 - lon2; double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta)); dist = Math.acos(dist); dist = rad2deg(dist); dist = dist * 60 * 1.1515; if (sr.equals("K")) { dist = dist * 1.609344; } else if (sr.equals("N")) { dist = dist * 0.8684; } return (dist); } public double deg2rad(double deg) { return (deg * Math.PI / 180.0); } public double rad2deg(double rad) { return (rad * 180.0 / Math.PI); } }
источник
Было предоставлено много отличных ответов, однако я обнаружил некоторые недостатки в производительности, поэтому позвольте мне предложить версию с учетом производительности. Каждая константа вычисляется заранее, и вводятся переменные x, y, чтобы не вычислять одно и то же значение дважды. Надеюсь, это поможет
private static final double r2d = 180.0D / 3.141592653589793D; private static final double d2r = 3.141592653589793D / 180.0D; private static final double d2km = 111189.57696D * r2d; public static double meters(double lt1, double ln1, double lt2, double ln2) { final double x = lt1 * d2r; final double y = lt2 * d2r; return Math.acos( Math.sin(x) * Math.sin(y) + Math.cos(x) * Math.cos(y) * Math.cos(d2r * (ln1 - ln2))) * d2km; }
источник
Слегка обновленный ответ от @David George:
public static double distance(double lat1, double lat2, double lon1, double lon2, double el1, double el2) { final int R = 6371; // Radius of the earth double latDistance = Math.toRadians(lat2 - lat1); double lonDistance = Math.toRadians(lon2 - lon1); double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); double distance = R * c * 1000; // convert to meters double height = el1 - el2; distance = Math.pow(distance, 2) + Math.pow(height, 2); return Math.sqrt(distance); } public static double distanceBetweenLocations(Location l1, Location l2) { if(l1.hasAltitude() && l2.hasAltitude()) { return distance(l1.getLatitude(), l2.getLatitude(), l1.getLongitude(), l2.getLongitude(), l1.getAltitude(), l2.getAltitude()); } return l1.distanceTo(l2); }
Функция расстояния такая же, но я создал небольшую функцию-оболочку, которая принимает 2 объекта Location . Благодаря этому я использую функцию расстояния только в том случае, если оба местоположения действительно имеют высоту, потому что иногда это не так. И это может привести к странным результатам (если местоположение не знает, его высота будет возвращена 0). В этом случае я возвращаюсь к классической функции distanceTo .
источник
Эта статья в Википедии предоставляет формулы и пример. Текст на немецком языке, но расчеты говорят сами за себя.
источник