C#解决方案以在纬度/经度多线上找到最接近的点



我需要在JavaScript中使用的某些代码的C#解决方案,该代码采用形成区域或区域的一系列纬度和经度位置。还有一个对象x和y位置,并返回对象最接近点的x和y。该代码在JavaScript中的功能非常完美,但是当我现在在C#中重写我的工作时,我无法找到可行的解决方案,并且可以执行此功能。

JavaScript函数在下面,该函数采用2个参数PXY,这是您位置和轴的X和Y位置,它是X和Y位置的数组,形成了一个区域的polyline。

    var getClosestPointOnLines = function(pXy, aXys) {
        var minDist;
        var fTo;
        var fFrom;
        var x;
        var y;
        var i;
        var dist;
        if (aXys.length > 1) {
            for (var n = 1 ; n < aXys.length ; n++) {
                if (aXys[n].x != aXys[n - 1].x) {
                    var a = (aXys[n].y - aXys[n - 1].y) / (aXys[n].x - aXys[n - 1].x);
                    var b = aXys[n].y - a * aXys[n].x;
                    dist = Math.abs(a * pXy.x + b - pXy.y) / Math.sqrt(a * a + 1);
                }
                else
                    dist = Math.abs(pXy.x - aXys[n].x)
                // length^2 of line segment 
                var rl2 = Math.pow(aXys[n].y - aXys[n - 1].y, 2) + Math.pow(aXys[n].x - aXys[n - 1].x, 2);
                // distance^2 of pt to end line segment
                var ln2 = Math.pow(aXys[n].y - pXy.y, 2) + Math.pow(aXys[n].x - pXy.x, 2);
                // distance^2 of pt to begin line segment
                var lnm12 = Math.pow(aXys[n - 1].y - pXy.y, 2) + Math.pow(aXys[n - 1].x - pXy.x, 2);
                // minimum distance^2 of pt to infinite line
                var dist2 = Math.pow(dist, 2);
                // calculated length^2 of line segment
                var calcrl2 = ln2 - dist2 + lnm12 - dist2;
                // redefine minimum distance to line segment (not infinite line) if necessary
                if (calcrl2 > rl2)
                    dist = Math.sqrt(Math.min(ln2, lnm12));
                if ((minDist == null) || (minDist > dist)) {
                    if (calcrl2 > rl2) {
                        if (lnm12 < ln2) {
                            fTo = 0;//nearer to previous point
                            fFrom = 1;
                        }
                        else {
                            fFrom = 0;//nearer to current point
                            fTo = 1;
                        }
                    }
                    else {
                        // perpendicular from point intersects line segment
                        fTo = ((Math.sqrt(lnm12 - dist2)) / Math.sqrt(rl2));
                        fFrom = ((Math.sqrt(ln2 - dist2)) / Math.sqrt(rl2));
                    }
                    minDist = dist;
                    i = n;
                }
            }
            var dx = aXys[i - 1].x - aXys[i].x;
            var dy = aXys[i - 1].y - aXys[i].y;
            x = aXys[i - 1].x - (dx * fTo);
            y = aXys[i - 1].y - (dy * fTo);
        }
        return { 'x': x, 'y': y, 'i': i, 'fTo': fTo, 'fFrom': fFrom };
    }

如何在C#?

中复制上述内容

感谢xdttransform。我没有使用Visual Studio,因此没有意识到CTRL 空间。安装后,我设法自己转换了代码。我将其包括在这里,将来会从中受益的任何人。

我从一堂课开始,以保留点的纬度和经度细节。


namespace Classes
{
    public class AppGeoPoint
    {
        public double X { get; set; }
        public double Y { get; set; }
    }
}

和函数转换为


        public static Classes.AppGeoPoint getClosestPointOnLines(Classes.AppGeoPoint pXy, Classes.AppGeoPoint[] aXys)
        {
            double? minDist = null;
            double fTo = 0.0;
            double fFrom;
            double x = 0.0;
            double y = 0.0;
            int i = 0;
            double dist;
            if (aXys.Length > 1)
            {
                for (var n = 1; n < aXys.Length; n++)
                {
                    if (aXys[n].X != aXys[n - 1].X)
                    {
                        var a = (aXys[n].Y - aXys[n - 1].Y) / (aXys[n].X - aXys[n - 1].X);
                        var b = aXys[n].Y - a * aXys[n].X;
                        dist = Math.Abs(a * pXy.X + b - pXy.Y) / Math.Sqrt(a * a + 1);
                    }
                    else
                        dist = Math.Abs(pXy.X - aXys[n].X);
                    // length^2 of line segment 
                    double rl2 = Math.Pow(aXys[n].Y - aXys[n - 1].Y, 2) + Math.Pow(aXys[n].X - aXys[n - 1].X, 2);
                    // distance^2 of pt to end line segment
                    double ln2 = Math.Pow(aXys[n].Y - pXy.Y, 2) + Math.Pow(aXys[n].X - pXy.X, 2);
                    // distance^2 of pt to begin line segment
                    double lnm12 = Math.Pow(aXys[n - 1].Y - pXy.Y, 2) + Math.Pow(aXys[n - 1].X - pXy.X, 2);
                    // minimum distance^2 of pt to infinite line
                    double dist2 = Math.Pow(dist, 2);
                    // calculated length^2 of line segment
                    double calcrl2 = ln2 - dist2 + lnm12 - dist2;
                    // redefine minimum distance to line segment (not infinite line) if necessary
                    if (calcrl2 > rl2)
                        dist = Math.Sqrt(Math.Min(ln2, lnm12));
                    if ((minDist == null) || (minDist > dist))
                    {
                        if (calcrl2 > rl2)
                        {
                            if (lnm12 < ln2)
                            {
                                fTo = 0;//nearer to previous point
                                fFrom = 1;
                            }
                            else
                            {
                                fFrom = 0;//nearer to current point
                                fTo = 1;
                            }
                        }
                        else
                        {
                            // perpendicular from point intersects line segment
                            fTo = ((Math.Sqrt(lnm12 - dist2)) / Math.Sqrt(rl2));
                            fFrom = ((Math.Sqrt(ln2 - dist2)) / Math.Sqrt(rl2));
                        }
                        minDist = dist;
                        i = n;
                    }
                }
                var dx = aXys[i - 1].X - aXys[i].X;
                var dy = aXys[i - 1].Y - aXys[i].Y;
                x = aXys[i - 1].X - (dx * fTo);
                y = aXys[i - 1].Y - (dy * fTo);
            }
            return new Classes.AppGeoPoint { X = x, Y = y };
        }

最后,构建一个数组列表并检查最接近的点


            Classes.AppGeoPoint YourLocation= new Classes.AppGeoPoint { X = 50.83737, Y = -1.07428 };
            Classes.AppGeoPoint[] AreaCheck = new[] {
                new Classes.AppGeoPoint { X = 50.847550000000005, Y = -1.0863200000000002 },
                new Classes.AppGeoPoint { X = 50.83975, Y = -1.0859800000000002 },
                new Classes.AppGeoPoint { X = 50.83845, Y = -1.06487 },
                new Classes.AppGeoPoint { X = 50.84723, Y = -1.0645200000000001 }
            };
            Classes.AppGeoPoint ReturnVal = getClosestPointOnLines(YourLocation, AreaCheck);
            Console.WriteLine("X " + ReturnVal.X);
            Console.WriteLine("Y " + ReturnVal.Y);

returnVal.x和returnVal.y将返回最接近的点纬度和经度。

希望这可能对他人有帮助。

最新更新