从起始点、终点和距离计算坐标

3

我有两个地图上的点,并且知道它们之间的距离。现在,我需要在起点和终点之间获取一个新点,距离起点X米。但是,我无法找到如何找到新坐标。

var nextTrazadoPoint = new Coord {Lat = ....,  Lng=...., Alt=...};
var previousTrazadoPoint = new Coord {Lat = ....,  Lng=...., Alt...};
var fromCoords = new GeoCoordinate(nextTrazadoPoint.Lat, nextTrazadoPoint.Lng, nextTrazadoPoint.Alt);
var toCoords = new GeoCoordinate(previousTrazadoPoint .Lat, previousTrazadoPoint .Lng, previousTrazadoPoint .Alt);
var distance = fromCoords.GetDistanceTo(toCoords); //Let's say 1000 ¿meters?

现在我想从previousTrazadoPoint走200米到nextTrazadoPoint

//Vector from previousTrazadoPoint to nextTrazadoPoint
var vectorDireccion = new Vector(
    (double)(nextTrazadoPoint.Latitud - previousTrazadoPoint.Latitud), 
    (double)(nextTrazadoPoint.Longitud - previousTrazadoPoint.Longitud)
    );

//Normalize
vectorDireccion.Normalize();

//meters from previousTrazadoPoint 
var distanciaARecorrer = 200;

//New coords
var vectorDestino = distanciaARecorrer * vectorDireccion;
point.Latitud = (decimal)vectorDestino.X + previousTrazadoPoint.Latitud;
point.Longitud = (decimal)vectorDestino.Y + previousTrazadoPoint.Longitud;

然而,当我在 Gmaps 上绘制新点时,它并没有放置在两者之间。有任何想法吗?

2个回答

1

感谢 @HansKilian 和 @cletus(计算两个GPS坐标之间的距离),我找到了解决方案。

private const double EARTH_RADIUS = 6378.1;
private static double ConvertToRadians(double angle)
{
    return (Math.PI / 180) * angle;
}
private static double ConvertToDegree(double angle)
{
    return angle * (180.0 / Math.PI);
}

private static double CalculateBearing(CoordsDto from, CoordsDto to)
{
    var from_lat_rad = ConvertToRadians(from.Latitud);
    var to_lat_rad = ConvertToRadians(to.Latitud);

    var dif_lng_rad = ConvertToRadians(to.Longitud - from.Longitud);

    double x = Math.Cos(from_lat_rad) * Math.Sin(to_lat_rad) - Math.Sin(from_lat_rad) * Math.Cos(to_lat_rad) * Math.Cos(dif_lng_rad);
    double y = Math.Sin(dif_lng_rad) * Math.Cos(to_lat_rad);

    // Math.Atan2 can return negative value, 0 <= output value < 2*PI expected 
    return (Math.Atan2(y, x) + Math.PI * 2) % (Math.PI * 2);
}

public static CoordsDto GetPointFarAway(CoordsDto from, CoordsDto to, double meterAwayFromStart)
{
    var resp = new CoordsDto();
    var bearing_rad = CalculateBearing(from, to);
    var d = meterAwayFromStart * 0.001; //KM

    var input_lat1_rad = ConvertToRadians(from.Latitud);
    var input_lon1_rad = ConvertToRadians(from.Longitud);

    var newPoint_lat_rad = Math.Asin(
        Math.Sin(input_lat1_rad) * Math.Cos(d / EARTH_RADIUS) + Math.Cos(input_lat1_rad) * Math.Sin(d / EARTH_RADIUS) * Math.Cos(bearing_rad)
    );
    var newPoint_lon_rad = input_lon1_rad + Math.Atan2(
        Math.Sin(bearing_rad) * Math.Sin(d / EARTH_RADIUS) * Math.Cos(input_lat1_rad),
        Math.Cos(d / EARTH_RADIUS) - Math.Sin(input_lat1_rad) * Math.Sin(newPoint_lat_rad)
    );

    resp.Latitud = ConvertToDegree(newPoint_lat_rad);
    resp.Longitud = ConvertToDegree(newPoint_lon_rad);

    return resp;
}

0

我看不出你代码有什么问题。你没有提供足够的信息让我能够拿起你的代码编译并找到问题,所以我尝试使用类从头开始编码。我不能使用,因为它在.NET core中不可用,而我的沙盒项目是一个.NET core项目。

这是我得到的结果

var origin = new Vector2(100.0f, 100.0f);
var destination = new Vector2(0.0f, 400.0f);
var direction = destination - origin;
var movement = Vector2.Normalize(direction) * 200.0f;
var movementdestination = origin + movement;
Console.WriteLine($"X: {movementdestination.X}, Y: {movementdestination.Y}");

它打印

X: 36.75444, Y: 289.7367

就我所知,这是正确的。希望能对你有所帮助。


你应该确保移动量不大于方向(从而不会超过目标)。 - Radosław Cybulski
这跟我正在做的有些相似,但是我认为问题可能出在单位上。我的意思是,比如说我想要将目标移动200米、200千米或者200英里。var movement = Vector2.Normalize(direction) * 200.0f; 这行代码对于所有情况都一样。但是在某些时候,必须进行转换,转换成什么度量单位呢?是弧度还是角度?是米吗? - Rumpelstinsk
@Rumpelstinsk 是的,这可能是一个问题。使用经度和纬度计算向量长度并不是真正的距离。长度为10的向量在靠近极地时比靠近赤道时要短。 - Hans Kilian
1
也许这可以帮助:https://dev59.com/enRC5IYBdhLWcg3wP-dh(请参见下面几页的.NET答案) - Hans Kilian
1
@HansKilian 感谢您的帮助。您指出了正确的方向,我终于解决了它。正如您所说,使用坐标会更加复杂,因为您需要处理地球曲率以及弧度与角度之间的转换... - Rumpelstinsk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接