我需要在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将返回最接近的点纬度和经度。
希望这可能对他人有帮助。