Java 两个纬度和经度之间的中点

Java 两个纬度和经度之间的中点,java,math,maps,Java,Math,Maps,我正在尝试将本文中给出的代码片段转换为java。但我并没有得到和网站相同的结果。这是我的代码,用于找到给定纬度和经度的两点之间的中点 midPoint(12.870672,77.658964,12.974831,77.60935); public static void midPoint(double lat1,double lon1,double lat2,double lon2) { double dLon = Math.toRadians(lon2-lon1);

我正在尝试将本文中给出的代码片段转换为java。但我并没有得到和网站相同的结果。这是我的代码,用于找到给定纬度和经度的两点之间的中点

midPoint(12.870672,77.658964,12.974831,77.60935);
    public static void midPoint(double lat1,double lon1,double lat2,double lon2)
    {
   double dLon = Math.toRadians(lon2-lon1);
        double Bx = Math.cos(lat2) * Math.cos(dLon);
        double By = Math.cos(lat2) * Math.sin(dLon);
        double lat3 = Math.atan2(Math.sin(lat1)+Math.sin(lat2),Math.sqrt( (Math.cos(lat1)+Bx)*(Math.cos(lat1)+Bx) + By*By) );
        double lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);
        System.out.print(lat3 +" " + lon3 );
    }

我不确定这个数字是否正确。所以请帮我想一想。另外,我需要找到中点的纬度和经度

您还需要将其他公式中使用的纬度和经度值转换为弧度。您可以在页面下方代码的3/5处看到这一点。在余弦球面定律距离公式的末尾给出了线索:

(请注意,在这里以及所有后续代码片段中,为了简单起见,我没有显示从度到弧度的转换;完整版本请参见下文)


你需要转换成弧度。将其更改为以下内容:

public static void midPoint(double lat1,double lon1,double lat2,double lon2){

    double dLon = Math.toRadians(lon2 - lon1);

    //convert to radians
    lat1 = Math.toRadians(lat1);
    lat2 = Math.toRadians(lat2);
    lon1 = Math.toRadians(lon1);

    double Bx = Math.cos(lat2) * Math.cos(dLon);
    double By = Math.cos(lat2) * Math.sin(dLon);
    double lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By));
    double lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);

    //print out in degrees
    System.out.println(Math.toDegrees(lat3) + " " + Math.toDegrees(lon3));
}

我的上一份工作是制作一个跟踪模块,我用这个公式来计算两个坐标之间的距离

//Location lat and lon
double locLat = -23.548333;
double locLon = -46.636111;

//Destination lat and lon
double dstLat = -22.902778;
double dstLon = -43.206667;

double arcoAB = 90 - (dstLat);
double arcoAC = 90 - (locLat);

double difLon = locLon - (dstLon);

double cosA = Math.cos(Math.toRadians(arcoAC)) * Math.cos(Math.toRadians(arcoAB)) + Math.sin(Math.toRadians(arcoAC)) * Math.sin(Math.toRadians(arcoAB)) * Math.cos(Math.toRadians(difLon));
double acosCosA = Math.toDegrees(Math.acos(cosA));

double raio = 2 * Math.PI * 6371;
double distance = (raio * acosCosA) / 360;

return distance; //Distance in KM, convert to anything else (miles, meters..) if you need..
可以得到距离除以2的中点

啊,这又是一个公式:

double dLat = Math.toRadians(dstLat - locLat);
double dLon = Math.toRadians(dstLon - locLon);

double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
           + Math.cos(Math.toRadians(locLat)) * Math.cos(Math.toRadians(dstLat))
           * Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = 6371 * c;

return d; //Distance in KM
更容易使用:

更新: 更好地使用生成器(有关原因,请参见):


如果您想正确处理反梅里迪亚(经度+/-180)的违规行为,请与建设者而不是建设者一起使用LatLngBounds

以下是说明问题的测试:

LatLng mp = midPoint(new LatLng(-43.95139,-176.56111),new LatLng(-36.397816,174.663496));
public static LatLng midPoint (LatLng SW, LatLng NE) {
    LatLngBounds bounds = new LatLngBounds(SW, NE);
    Log.d("BAD!", bounds.toString() + " CENTRE: " + bounds.getCenter().toString());
    bounds = LatLngBounds.builder().include(SW).include(NE).build();
    Log.d("GOOD", bounds.toString() + " CENTRE: " + bounds.getCenter().toString());
    return bounds.getCenter();
}
实际结果:

BAD!: LatLngBounds{southwest=lat/lng: (-43.95139,-176.56111), northeast=lat/lng: (-36.397816,174.663496)} CENTRE: lat/lng: (-40.174603,-0.948807)
GOOD: LatLngBounds{southwest=lat/lng: (-43.95139,174.663496), northeast=lat/lng: (-36.397816,-176.56111)} CENTRE: lat/lng: (-40.174603,179.051193)

构造器技术产生一个180度的中心经度

以下是@dogbane的
java
代码转换为
Kotlin

private fun midPoint(lat1: Double, lon1: Double, lat2: Double, lon2: Double) : String {
    var lat1 = lat1
    var lon1 = lon1
    var lat2 = lat2
    val dLon: Double = Math.toRadians(lon2 - lon1)
    //convert to radians
    lat1 = Math.toRadians(lat1)
    lat2 = Math.toRadians(lat2)
    lon1 = Math.toRadians(lon1)
    val Bx: Double = Math.cos(lat2) * Math.cos(dLon)
    val By: Double = Math.cos(lat2) * Math.sin(dLon)
    val lat3: Double = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By))
    val lon3: Double = lon1 + Math.atan2(By, Math.cos(lat1) + Bx)
    var result: String = ""
    result = Math.toDegrees(lat3).toString() + "," + Math.toDegrees(lon3).toString()
    return result;
}

下面是@dogbane的
Java
代码转换成
TypeScript

type LatLng = {
  lat: number;
  lng: number;
};

function calculateMidPoint(latLngA: LatLng, latLngB: LatLng) {
  function toRadians(degress: number): number {
    return degress * (Math.PI / 180);
  }

  function toDegrees(radians: number): string {
    return (radians * (180 / Math.PI)).toFixed(4);
  }

  const lngDiff = toRadians(latLngB.lng - latLngA.lng);
  const latA = toRadians(latLngA.lat);
  const latB = toRadians(latLngB.lat);
  const lngA = toRadians(latLngA.lng);

  const bx = Math.cos(latB) * Math.cos(lngDiff);
  const by = Math.cos(latB) * Math.sin(lngDiff);

  const latMidway = toDegrees(
    Math.atan2(
      Math.sin(latA) + Math.sin(latB),
      Math.sqrt((Math.cos(latA) + bx) * (Math.cos(latA) + bx) + by * by)
    )
  );
  const lngMidway = toDegrees(lngA + Math.atan2(by, Math.cos(latA) + bx));

  console.log(
    `Midway point between ${latLngA} and ${latLngB} is: Lat: ${latMidway}, lng: ${lngMidway}`
  );
}

但我需要找到中点的经纬度。怎么做?@scooby你找到解决方法了吗?嗨@dogbane我需要一个帮助。工作正常,并为我节省了一些代码。谢谢。@leonardkraemer好的,但不是完美的[反间谍犯罪未处理]-见下面我的答案。谢谢你让我走上正轨。据我记忆所及,当你把NE放在SW之前时,构造器甚至会抱怨,所以一定要使用构造器。我的答案可能过于简单,只是为了给人们指出正确的方向。谢谢你的提示。非常感谢你的“更新”部分。解决了我的问题。
private fun midPoint(lat1: Double, lon1: Double, lat2: Double, lon2: Double) : String {
    var lat1 = lat1
    var lon1 = lon1
    var lat2 = lat2
    val dLon: Double = Math.toRadians(lon2 - lon1)
    //convert to radians
    lat1 = Math.toRadians(lat1)
    lat2 = Math.toRadians(lat2)
    lon1 = Math.toRadians(lon1)
    val Bx: Double = Math.cos(lat2) * Math.cos(dLon)
    val By: Double = Math.cos(lat2) * Math.sin(dLon)
    val lat3: Double = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By))
    val lon3: Double = lon1 + Math.atan2(By, Math.cos(lat1) + Bx)
    var result: String = ""
    result = Math.toDegrees(lat3).toString() + "," + Math.toDegrees(lon3).toString()
    return result;
}
type LatLng = {
  lat: number;
  lng: number;
};

function calculateMidPoint(latLngA: LatLng, latLngB: LatLng) {
  function toRadians(degress: number): number {
    return degress * (Math.PI / 180);
  }

  function toDegrees(radians: number): string {
    return (radians * (180 / Math.PI)).toFixed(4);
  }

  const lngDiff = toRadians(latLngB.lng - latLngA.lng);
  const latA = toRadians(latLngA.lat);
  const latB = toRadians(latLngB.lat);
  const lngA = toRadians(latLngA.lng);

  const bx = Math.cos(latB) * Math.cos(lngDiff);
  const by = Math.cos(latB) * Math.sin(lngDiff);

  const latMidway = toDegrees(
    Math.atan2(
      Math.sin(latA) + Math.sin(latB),
      Math.sqrt((Math.cos(latA) + bx) * (Math.cos(latA) + bx) + by * by)
    )
  );
  const lngMidway = toDegrees(lngA + Math.atan2(by, Math.cos(latA) + bx));

  console.log(
    `Midway point between ${latLngA} and ${latLngB} is: Lat: ${latMidway}, lng: ${lngMidway}`
  );
}