Как мне написать программу на Java, которая рассчитывает расстояние между двумя точками на земле?
Я знаю, как начать, и я знаю, как вставить в сканеры и все такое, но в школе я никогда не узнал о формулах долготы и широты и как преобразовать эти точки в радианы. Так что я в значительной степени застрял на этой проблеме Java. Вот что у меня так далеко:
import java.util.*;
class DistanceCalculator {
// Radius of the earth in km; this is the class constant.
public static final double Radius = 6372.795;
/**
* This program computes the spherical distance between two points on the surface of the Earth.
*/
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
intro();
System.out.print("Longitude (degrees.minutes) ");
double Longitude = console.nextDouble();
System.out.print("Latitude (degrees.minutes) ");
double Latitude = console.nextDouble();
}
public static double distFrom(double lat1, double lng1, double lat2, double lng2);
double Latitude = Math.toRadians(...);
}
public static void intro() {
System.out.println("This program computes the spherical distance between two points on the surface of the Earth.");
System.out.println("\tPlease start by entering the longitude and the latitude of location 1.");
}
}
В Java IDE говорят, что точки долготы и широты (те, что под intro();
) не используются, и я знаю, почему, поскольку я еще не определил их. Я знаю, что мне не хватает формулы для долготы и широты. В моей книге он хочет, чтобы я использовал сферический закон косинусов, и, так как я никогда не изучал это в школе, независимо от того, насколько усердно я изучаю формулу с сайтов, которые я искал, я не знаю, как передать это в язык Java.
Другая проблема заключается в том, как перенести градусы и минуты из точки долготы / широты в радианы? Должен ли я использовать Math.toRadians
вещь? Ах да, и мой ответ должен быть в километрах.
Обновлено: математические функции, о которых некоторые из вас, ребята, говорят, меня сильно смущают. В школе (я учусь в старших классах), даже в Math IB SL мой учитель никогда не учил нас, как найти лонг / лат. пункты... пока. Так что мне трудно это понять. Поскольку сферическая формула закона косинусов находится в сети, могу ли я просто взять эту формулу и преобразовать ее в "язык Java" и включить ее в свою программу?
3 ответа
Ключевое слово, которое вам нужно найти, это "формула Haversine".
Более простой для понимания метод, но не совсем точный для небольших расстояний, состоит в том, чтобы напомнить, что угол между двумя векторами A
а также B
можно рассчитать с помощью точечного произведения:
A ⋅ B = | A | * | B | * cos (тета)
так что если вы конвертируете свои полярные пары широта / долгота в трехмерные декартовы координаты (и да, вам нужно будет использовать Math.toRadians()
, Math.cos()
а также Math.sin()
чтобы сделать это, а затем рассчитать скалярное произведение, вы получите cos(theta)
так что пользуйтесь Math.acos()
получить theta
,
Вы можете рассчитать расстояние просто как D = R * theta
, где R
это радиус Земли, и theta
остается в радианах.
Я предлагаю прочитать больше о WGS84.
import java.util.*;
public class SphericalDistance {
public static void main(String[] args){
System.out.println(" This program computes the spherical distance\n between two points, 1 and 2.");
System.out.println(" Please enter the latitude and longitude for \n each point as a pair of integers, degrees \n followed by minutes:");
System.out.print("Latitude 1:");
Scanner s=new Scanner(System.in);
double latangledeg = s.nextDouble();
double latanglemin = s.nextDouble()/60;
double phideg = latangledeg + latanglemin;
double phi1 = phideg * Math.PI/180;
System.out.print("Longitude 1:");
double lonangledeg = s.nextDouble();
double lonanglemin = s.nextDouble()/60;
double lambdadeg = lonangledeg + lonanglemin;
double lambda1 = lambdadeg * Math.PI/180;
System.out.println("Latitude 2:");
double latangledeg2 = s.nextDouble();
double latanglemin2 = s.nextDouble()/60;
double phideg2 = latangledeg2 + latanglemin2;
double phi2 = phideg2 * Math.PI/180;
System.out.println("Longitude 2:");
double lonangledeg2 = s.nextDouble();
double lonanglemin2 = s.nextDouble()/60;
double lambdadeg2 = lonangledeg2 + lonanglemin2;
double lambda2 = lambdadeg2 * Math.PI/180;
double lambdaf = lambda2 - lambda1;
double angdistance = Math.acos(Math.sin(phi1)*Math.sin(phi2) + Math.cos(phi1)*Math.cos(phi2)*Math.cos(lambdaf));
System.out.println("Angular Distance = " + angdistance + " radians");
int distancekm = (int)(angdistance * 6372.795);
int distancemi = (int) (distancekm * .621371);
System.out.println("Distance = " + distancekm + " kilometers");
System.out.println("Distance = " + distancemi + " miles");
s.close();
}
}
Вы можете посмотреть на эту ссылку для логики.
Функция в PHP... Я не знаю Java. Так что кто-то редактирует мой пост. Вот функция PHP:
function getDistanceBetweenPointsNew($latitude1, $longitude1,
$latitude2, $longitude2, $unit = 'Mi')
{
$theta = $longitude1 - $longitude2;
$distance = (sin(deg2rad($latitude1)) *
sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) *
cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
$distance = acos($distance);
$distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
switch($unit)
{
case 'Mi': break;
case 'Km' : $distance = $distance *1.609344;
}
return (round($distance,2));
}
также получить значение из базы данных MySQL:
Рассчитать расстояние с учетом 2 точек, широты и долготы
Я пытался создать функцию Java, я не знаю, работает она или нет.
попробуй это. Если кто-то может помочь, попробуйте отредактировать мой код Java.
import java.math.BigDecimal;
public static double round(double unrounded, int precision, int roundingMode)
{
BigDecimal bd = new BigDecimal(unrounded);
BigDecimal rounded = bd.setScale(precision, roundingMode);
return rounded.doubleValue();
}
public static double distFrom(double lat1, double lng1, double lat2, double lng2, String unit)
{
double theta = lng1 - lng2;
double distance = (
Math.sin(Math.toRadians(lat1)) * Math.sin(Math.toRadians(lat2))
)+(
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.cos(Math.toRadians(theta))
);
distance = Math.acos(distance);
distance = Math.toDeg(distance);
distance = distance * 60 * 1.1515;
switch(unit)
{
/* Mi = miles, Km = Kilometers */
case "Mi" :
break;
case "Km" :
distance = distance *1.609344;
break;
}
distance = round(distance, 2, BigDecimal.ROUND_HALF_UP);
return distance;
}