Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 根据起点和终点地理坐标在指定的间隔内划分地理线_C#_Google Maps_Geolocation_Geometry_Gmap.net - Fatal编程技术网

C# 根据起点和终点地理坐标在指定的间隔内划分地理线

C# 根据起点和终点地理坐标在指定的间隔内划分地理线,c#,google-maps,geolocation,geometry,gmap.net,C#,Google Maps,Geolocation,Geometry,Gmap.net,我有两个地理坐标(起点和终点),我能够在它们之间创建一条线。假设这两个坐标的距离为30米,那么我需要以3米的间隔找到每个点的地理位置。因此,有10点是必需的 我可以通过一些公式找到这些点,但这些点与起点和终点形成的线的方向不同 到目前为止,我所做的如下 using System; namespace Test { public class AzimuthCalculator { public const double range = 0.00186411F; // in Miles

我有两个地理坐标(起点和终点),我能够在它们之间创建一条线。假设这两个坐标的距离为30米,那么我需要以3米的间隔找到每个点的地理位置。因此,有10点是必需的

我可以通过一些公式找到这些点,但这些点与起点和终点形成的线的方向不同

到目前为止,我所做的如下

using System;

namespace Test
{
public class AzimuthCalculator
{
    public const double range = 0.00186411F; // in Miles
    public const double rangeInMeter = 3F;
    public const double factor = 0.003F;
    public static void Main(String[] args)
    {
        double sLatitude = 28.6187763214111F;
        double sLongitude = 77.2093048095703F;

        double eLatitude = 28.6191763153134F;
        double eLongitude = 77.2097146511078F;

        Console.WriteLine($"Start Point : {sLatitude}, {sLongitude}");
        Console.WriteLine($"End Point : {eLatitude},{eLongitude}"); 

        double distance = CalculateDistance(sLatitude, sLongitude, eLatitude, eLongitude);
        Console.WriteLine($"Distance : {distance} miles, {MilesToMeter(distance)} meter, {(distance * 1.60934)} kilometer");
        distance = distance * 1.60934;

        double numberOfIDS = distance/factor;

        double azimuthAngle = DegreeBearing(sLatitude, sLongitude, eLatitude, eLongitude);
        Console.WriteLine($"Azimuth : {azimuthAngle}");
        Console.WriteLine($"IDS : {numberOfIDS}");

        double constantAzimuth = (azimuthAngle/numberOfIDS);

        azimuthAngle = constantAzimuth;
        Console.WriteLine($"Original Azimuth : {azimuthAngle}");

        double[] getAnotherPoint = pointRadialDistance(sLatitude, sLongitude, azimuthAngle, distance);
        Console.WriteLine($"End Point : {getAnotherPoint[0]},{getAnotherPoint[1]}");

        distance = 0.003;   // 3 meter

        getAnotherPoint = pointRadialDistance(sLatitude, sLongitude, azimuthAngle, distance);


        int totalIDS = (Int32)(numberOfIDS);

        for(int i=0;i<totalIDS;i++)
        {
            sLatitude = getAnotherPoint[0];
            sLongitude = getAnotherPoint[1];
            distance = 0.003;
            Console.WriteLine($"new PointLatLng({getAnotherPoint[0]},{getAnotherPoint[1]}),");
            getAnotherPoint = pointRadialDistance(sLatitude, sLongitude, azimuthAngle, distance);
        }
        Console.ReadLine();
    }       

    static double rEarth = 6371.01F; // Earth radius in km
    static double epsilon = 0.000001F;

    public static double[] pointRadialDistance(double lat1, double lon1, double bearing, double distance)
    {
        double rlat1 = ToRad(lat1);
        double rlon1 = ToRad(lon1);
        double rbearing = ToRad(bearing);
        double rdistance = distance / rEarth; // normalize linear distance to radian angle

        double rlat = Math.Asin( Math.Sin(rlat1) * Math.Cos(rdistance) + Math.Cos(rlat1) * Math.Sin(rdistance) * Math.Cos(rbearing));
        double rlon = 0.0F;

        if ( Math.Cos(rlat) == 0 || Math.Abs(Math.Cos(rlat)) < epsilon) // Endpoint a pole
            rlon=rlon1;
        else
            rlon = ((rlon1 - Math.Asin( Math.Sin(rbearing) * Math.Sin(rdistance) / Math.Cos(rlat) ) + Math.PI ) % (2*Math.PI) ) - Math.PI;

        double lat = ToDegrees(rlat);
        double lon = ToDegrees(rlon);

        double[] listNew = new double[2];
        listNew[0] = lat;
        listNew[1] = lon;
        return (listNew);
    }

    public static GeoLocation FindPointAtDistanceFrom(GeoLocation startPoint, double initialBearingRadians, double distanceKilometres)
    {
        const double radiusEarthKilometres = 6371.01;
        var distRatio = distanceKilometres / radiusEarthKilometres;
        var distRatioSine = Math.Sin(distRatio);
        var distRatioCosine = Math.Cos(distRatio);

        var startLatRad = DegreesToRadians(startPoint.Latitude);
        var startLonRad = DegreesToRadians(startPoint.Longitude);

        var startLatCos = Math.Cos(startLatRad);
        var startLatSin = Math.Sin(startLatRad);

        var endLatRads = Math.Asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.Cos(initialBearingRadians)));

        var endLonRads = startLonRad
            + Math.Atan2(
                Math.Sin(initialBearingRadians) * distRatioSine * startLatCos,
                distRatioCosine - startLatSin * Math.Sin(endLatRads));

        return new GeoLocation
        {
            Latitude = RadiansToDegrees(endLatRads),
            Longitude = RadiansToDegrees(endLonRads)
        };
    }

    public struct GeoLocation
    {
        public double Latitude { get; set; }
        public double Longitude { get; set; }
    }

    public static double DegreesToRadians(double degrees)
    {
        const double degToRadFactor = Math.PI / 180;
        return degrees * degToRadFactor;
    }

    public static double RadiansToDegrees(double radians)
    {
        const double radToDegFactor = 180 / Math.PI;
        return radians * radToDegFactor;
    }

    public static double CalculateDistance(double sLatitude, double sLongitude, double eLatitude, double eLongitude)
    {
        var radiansOverDegrees = (Math.PI / 180.0);

        var sLatitudeRadians = sLatitude * radiansOverDegrees;
        var sLongitudeRadians = sLongitude * radiansOverDegrees;
        var eLatitudeRadians = eLatitude * radiansOverDegrees;
        var eLongitudeRadians = eLongitude * radiansOverDegrees;

        var dLongitude = eLongitudeRadians - sLongitudeRadians;
        var dLatitude = eLatitudeRadians - sLatitudeRadians;

        var result1 = Math.Pow(Math.Sin(dLatitude / 2.0), 2.0) + Math.Cos(sLatitudeRadians) * Math.Cos(eLatitudeRadians) * Math.Pow(Math.Sin(dLongitude / 2.0), 2.0);

        // Using 3956 as the number of miles around the earth
        var result2 = 3956.0 * 2.0 * Math.Atan2(Math.Sqrt(result1), Math.Sqrt(1.0 - result1));

        return result2;
    }   

    static double DegreeBearing(double lat1, double lon1,double lat2, double lon2)
    {
        var dLon = ToRad(lon2 - lon1);
        var dPhi = Math.Log(Math.Tan(ToRad(lat2) / 2 + Math.PI / 4) / Math.Tan(ToRad(lat1) / 2 + Math.PI / 4));
        if (Math.Abs(dLon) > Math.PI)
        dLon = dLon > 0 ? - (2 * Math.PI - dLon) : (2 * Math.PI + dLon);
        return ToBearing(Math.Atan2(dLon, dPhi));            
    }

    public static double ToRad(double degrees)
    {
        return degrees * (Math.PI / 180);
    }

    public static double ToDegrees(double radians)
    {
        return radians * 180 / Math.PI;
    }

    public static double ToBearing(double radians)
    {
        // convert radians to degrees (as bearing: 0...360)
        return (ToDegrees(radians) + 360) % 360;
    }

    public static double MeterToMiles(double meter)
    {
        return (meter / 1609.344);
    }

    public static double MilesToMeter(double miles)
    {
        return (miles * 1609.344);
    }
}
使用系统;
名称空间测试
{
公共类方位计算器
{
公共常数双量程=0.00186411F;//以英里为单位
公共常数双量程表=3F;
公共常数双因子=0.003F;
公共静态void Main(字符串[]args)
{
双板条=28.6187763214111F;
双慢度=77.2093048095703F;
双相关性=28.6191763153134F;
双长度=77.2097146511078F;
WriteLine($“起点:{sLatitude},{sLongitude}”);
WriteLine($“端点:{elativement},{eLongitude}”);
双倍距离=计算距离(sLatitude、sLongitude、eLatitude、eLongitude);
Console.WriteLine($“距离:{Distance}英里,{MilesToMeter(Distance)}米,{(Distance*1.60934)}公里”);
距离=距离*1.60934;
double numberOfIDS=距离/系数;
双方位角航向=航向(sLatitude、sLongitude、elagitude、eLongitude);
Console.WriteLine($“方位角:{azimuthAngle}”);
WriteLine($“id:{numberOfIDS}”);
双康斯坦塔齐茅斯=(方位角/数字);
方位角=constantAzimuth;
Console.WriteLine($“原始方位:{azimuthAngle}”);
double[]getAnotherPoint=点径向距离(sLatitude、sLongitude、方位角、距离);
WriteLine($“端点:{getAnotherPoint[0]},{getAnotherPoint[1]}”);
距离=0.003;//3米
getAnotherPoint=点径向距离(sLatitude、sLongitude、方位角、距离);
inttotalids=(Int32)(numberOfIDS);
for(int i=0;i Math.PI)
dLon=dLon>0?-(2*Math.PI-dLon):(2*Math.PI+dLon);
返回轴承(数学Atan2(dLon,dPhi));
}
公共静态双ToRad(双度)
{
返回度*(数学PI/180);
}
公共静态双ToDegrees(双弧度)
{
返回弧度*180/Math.PI;
}
公共静态双ToBearing(双弧度)
{
//将弧度转换为度(方向角:0…360)
返回角度(弧度)+360)%360;
}
公共静态双表英里(双表)
{
返回(仪表/1609.344);
}
公共静态双里程计(双英里)
{
返回(英里*1609.344);
}
}

}

为什么在这里从右方向计算错误的方位
constantAzimuth=(方位角/数字)以后再使用它

您可以使用该方法计算大圆路径上的中间点(本质上是SLERP-球面线性插值)


但是当我没有写constantAzimuth=(azimuthAngle/numberOfIDS)时,我仍然有同样的问题,所以你可以计算距离为3,6,9,给定距离和方位的终点。。。米和给定的
sLatitude/sLongitude
未经修改的这些坐标(我怀疑你为什么一次又一次地改变一切)
Formula:    
a = sin((1−f)⋅δ) / sin δ
b = sin(f⋅δ) / sin δ
x = a ⋅ cos φ1 ⋅ cos λ1 + b ⋅ cos φ2 ⋅ cos λ2
y = a ⋅ cos φ1 ⋅ sin λ1 + b ⋅ cos φ2 ⋅ sin λ2
z = a ⋅ sin φ1 + b ⋅ sin φ2
φi = atan2(z, √x² + y²)
λi = atan2(y, x)
where   
    f is fraction along great circle route (f=0 is point 1, f=1 is point 2), 
    δ is the angular distance d/R between the two points.