通过加倍对角线计算新矩形的角(两个地理点)

时间:2018-04-12 13:53:04

标签: java math geometry geo

我有两个地理位置定义的矩形:

1 -> 54.2749558,18.4287748 (lat, lng)
2 -> 54.4472187,18.9512795 (lat, lng)

这两点之间的距离(对角线)为39km(使用this算法计算)。 现在我需要加倍我的对角线:39km * 2 = 78km并找到新的扩展矩形的坐标(中间与第一个矩形相同)。

有人可以帮助我在Java中创建该算法吗?

编辑: 我的代码使用 Mbo' 回答:

public static void main(String[] args) {
    //example data
    double lat1d = 54.2749558;
    double lng1d = 18.4287748;
    double lat2d = 54.4472187;
    double lng2d = 18.9512795;
    Coordinate lat1 = Coordinate.fromDegrees(lat1d);
    Coordinate lng1 = Coordinate.fromDegrees(lng1d);
    Point point1 = Point.at(lat1, lng1);

    Coordinate lat2 = Coordinate.fromDegrees(lat2d);
    Coordinate lng2 = Coordinate.fromDegrees(lng2d);
    Point point2 = Point.at(lat2, lng2);
    System.out.println("Point1: " + point1);
    System.out.println("Point2: " + point2);

    double distance = EarthCalc.gcdDistance(point1, point2); //in meters
    System.out.println("Current distance between points 1 and 2: " + distance);
    double newDistance = distance * 2;
    System.out.println("Needed distance between points 3 and 4: " + newDistance);


    double y = Math.sin(lng2d - lng1d) * Math.cos(lat2d);
    double x = Math.cos(lat1d) * Math.sin(lat2d) - Math.sin(lat1d) * Math.cos(lat2d) * Math.cos(lng2d - lng1d);
    double brng4 = Math.toDegrees(Math.atan2(y, x)); // bearing for calculating point 4

    double earthRadiusInMeters = EarthCalc.EARTH_DIAMETER / 2;
    double distanceByRadius4 = distance * 1.5 / (earthRadiusInMeters / 2);

    double lat4d = Math.asin(Math.sin(lat1d) * Math.cos(distanceByRadius4) +
            Math.cos(lat1d) * Math.sin(distanceByRadius4) * Math.cos(brng4));
    double lng4d = lng1d + Math.atan2(Math.sin(brng4) * Math.sin(distanceByRadius4) * Math.cos(lat1d), Math.cos(distanceByRadius4) - Math.sin(lat1d) * Math.sin(lat2d));
    Point point4 = Point.at(Coordinate.fromDegrees(lat4d), Coordinate.fromDegrees(lng4d));


    double brng3 = brng4 + Math.PI; // bearing for calculating point 3
    double distanceByRadius3 = distance * 0.5 / (earthRadiusInMeters / 2);

    double lat3d = Math.asin(Math.sin(lat1d) * Math.cos(distanceByRadius3) +
            Math.cos(lat1d) * Math.sin(distanceByRadius3) * Math.cos(brng3));
    double lng3d = lng1d + Math.atan2(Math.sin(brng3) * Math.sin(distanceByRadius3) * Math.cos(lat1d),
            Math.cos(distanceByRadius3) - Math.sin(lat1d) * Math.sin(lat2d));

    Point point3 = Point.at(Coordinate.fromDegrees(lat3d), Coordinate.fromDegrees(lng3d));

    System.out.println("Point3: " + point3);
    System.out.println("Point4: " + point4);

    double actualDistance = EarthCalc.gcdDistance(point3, point4); //in meters
    System.out.println("Actual distance:" + actualDistance);
}

和控制台输出:

Point1: Point{latitude=54.2749558, longitude=18.4287748}
Point2: Point{latitude=54.4472187, longitude=18.9512795}
Current distance between points 1 and 2: 38896.62579783285
Needed distance between points 3 and 4: 77793.2515956657
Point3: Point{latitude=-0.8693568850955943, longitude=18.451667950625396}
Point4: Point{latitude=-0.8624187436224934, longitude=18.360085243458784}
Actual distance:10211.570252961072

1 个答案:

答案 0 :(得分:1)

对于小区域,您可以使用“平坦”近似值:

   lat3 = lat1 - 0.5*(lat2 - lat1)
   lat4 = lat1 + 1.5*(lat2 - lat1)
   and similar for longitude

快速检查:

  1 -> 54.2749558,18.4287748 (lat, lng)  
  2 -> 54.4472187,18.9512795 (lat, lng)    
  dlat = 54.4472187 - 54.2749558 = 0.172
  dlon = 18.9512795 - 18.4287748  = 0.553
  lat3 = 54.2749558 - 0.086 = 54.189
  lon3 = 18.9512795 - 0.276 = 18.675
  lat4 = 54.2749558 + 3 * 0.086 = 54.533
  lon4 = 18.9512795 + 3 * 0.276 = 19.779

由于我的粗糙圆角和球面扭曲,距离计算得出81.11 km

考虑球形几何,使用latlong page中的公式:

我认为“中间”是大圆弧中心(角之间的中间) - 它与坐标平均值不同

不要忘记以弧度变换坐标值

从第一点开始:

 y = Math.sin(λ2-λ1) * Math.cos(φ2);
 x = Math.cos(φ1)*Math.sin(φ2) - Math.sin(φ1)*Math.cos(φ2)*Math.cos(λ2-λ1);
 brng = Math.atan2(y, x).toDegrees();

其中φ1,λ1是起点,φ2,λ2是终点

对于一个新角落 - 目的地点给定距离并从起点开始承载:

φ4 = Math.asin( Math.sin(φ1)*Math.cos(d/R) +
                Math.cos(φ1)*Math.sin(d/R)*Math.cos(brng) );
λ4 = λ1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(φ1),
                     Math.cos(d/R)-Math.sin(φ1)*Math.sin(φ2));

其中R是地球半径,d是所需距离 - 这里是1.5 * 39 = 58.5

和第二个角落 - 同一目标点公式d = 0.5*39 = 19.5和反向承载brng+Pi