2014-09-05 140 views
2

这里是我有的问题:GPS计算器转换,计算新点的纬度/经度值

我用C#加载图像。在该图像上,我必须通过点击随机拍摄的鼠标来插入2点:点A和点B.

点A有它从程序中读取的线(Xa,Ya),我需要手动插入它的GPS坐标(LatitudeA和LongtudeA)。

B点有它自己的电线(Xb,Yb),它也从程序中读取,我需要手动插入它的GPS坐标(LatitudeB和LongtudeB)。

所以主要的问题是下一步:在屏幕上每下一次点击,我必须知道GPS点。对于那个点C也有(Xc,Yc)。

这是我的ComputeLatitudeAndLogitude方法,但它似乎并不完美。我需要这个街道级别的大小。

实施例:

A(487,361,45.252464,19.850337)

B(1167,397,45.252026,19.853990)

C(810,513,...,?? ?);结果应该是C(810,513,45.251592,19.852075)

请随时与我联系,以便我们能够解决问题,mymailis [email protected]

public void ComputeLatitudeAndLogitud (Wpf_Maps.Point point) 
{ 
     int diffX = pointA.X - pointB.X; 
     int diffY = pointA.Y - pointB.Y; 
     double diffLatitude = pointA.Latitude - pointB.Latitude; 
     double diffLongitude = pointA.Longitude - pointB.Longitude; 
     double latitudePerPixel = Math.Abs(diffLatitude/diffX); 
     double longitudePerPixel = Math.Abs(diffLongitude/diffY); 

     int diffXforA = pointA.X - point.X; 
     int diffYforA = pointA.Y - point.Y; 
     int diffXforB = pointB.X - point.X; 
     int diffYforB = pointB.Y - point.Y; 

     double newLatitudeFromA = pointA.Latitude + (diffXforA * latitudePerPixel); 
     double newLatitudeFromB = pointB.Latitude + (diffXforB * latitudePerPixel); 

     double newLongitudeFromA = pointA.Longitude + (diffYforA * longitudePerPixel); 
     double newLongitudeFromB = pointB.Longitude + (diffYforB * longitudePerPixel); 

     point.Latitude = (newLatitudeFromA + newLatitudeFromB)/2; 
     point.Longitude = (newLongitudeFromA + newLongitudeFromB)/2; 
    } 

回答

0

我假定点A和pointB处于相反在地图中,A是左下角的角落...这意味着每一个C点,并且它的A点

权试试这个简化(或左上):

public void ComputeLatitudeAndLogitud (Wpf_Maps.Point point) 
    { 
     int diffX = pointA.X - pointB.X; 
     int diffY = pointA.Y - pointB.Y; 
     double diffLatitude = pointA.Latitude - pointB.Latitude; 
     double diffLongitude = pointA.Longitude - pointB.Longitude; 
     double latitudePerPixel = Math.Abs(diffLatitude/diffX); 
     double longitudePerPixel = Math.Abs(diffLongitude/diffY); 

     int diffXforC = point.X - pointA.X; 
     int diffYforC = point.Y - pointA.Y; 

     point.Latitude = pointA.Latitude + (diffXforC * latitudePerPixel); 
     point.Longitude = pointA.Longitude + (diffYforC * longitudePerPixel); 
    } 
+0

我点击加载图像随机它是地图点A,并随意在地图上的点B. 需要输入经纬度对于A和B. 程序需要重新计算经度和纬度的每一个点,我随机点击我的图像。 – 2014-09-05 13:31:19

+0

嗯...现在我重新读你的文章,你说A和B是随机的。如果他们具有相同的X或Y会怎么样?各种各样的事情都会出错。没有增量,你不能计算latPerPixel。 – Sandy 2014-09-05 13:31:24

+0

您是如何设置pointA和pointB的纬度和经度属性的?为什么你不能这样设置pointC? – Sandy 2014-09-05 13:33:40

1

依赖新生根据你需要覆盖的距离,线性推断不会太好;地球不平坦,纬度距离随经度而变化。

一个近似值将是一个球体,您可以在其上计算Great-circle distance。 (GPS)坐标通常是相对于地球的(非球体)模型记录的,现在最常见的是椭球体()。因此,为了获得最大精度,您必须根据相应的参考模型计算距离。

此外,如果图像的参考模型与GPS坐标的参考模型不同,则可能需要两个以上的参考点才能确定准确的映射。

+0

我需要它在街道上,所以线性推断可以正常工作。 – 2014-09-05 13:37:06

0

这是我的完整代码。我有三个测试案例。第一个是pointC随机的地方,第二个是pointC匹配pointA,第三个是pointC匹配pointB。

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 

      ComputeLatitudeAndLongitude(new MyPoint(0, 0, 10, 10), new MyPoint(100, 100, 40, 40), new MyPoint(20, 40)); 
      ComputeLatitudeAndLongitude(new MyPoint(0, 0, 10, 10), new MyPoint(100, 100, 40, 40), new MyPoint(0, 0)); 
      ComputeLatitudeAndLongitude(new MyPoint(0, 0, 10, 10), new MyPoint(100, 100, 40, 40), new MyPoint(100, 100)); 
     } 

     public void ComputeLatitudeAndLongitude(MyPoint pointA, MyPoint pointB, MyPoint pointC) 
     { 
      int diffX = pointA.X - pointB.X; 
      int diffY = pointA.Y - pointB.Y; 
      double diffLatitude = pointA.Latitude - pointB.Latitude; 
      double diffLongitude = pointA.Longitude - pointB.Longitude; 
      double latitudePerPixel = Math.Abs(diffLatitude/diffX); 
      double longitudePerPixel = Math.Abs(diffLongitude/diffY); 

      int diffXforC = pointC.X - pointA.X; 
      int diffYforC = pointC.Y - pointA.Y; 

      pointC.Latitude = pointA.Latitude + (diffXforC * latitudePerPixel); 
      pointC.Longitude = pointA.Longitude + (diffYforC * longitudePerPixel); 

      LogResults(String.Format("pointA X:{0} Y:{1} Lat:{2} Long:{3}", pointA.X, pointA.Y, pointA.Latitude, pointA.Longitude), true); 
      LogResults(String.Format("pointB X:{0} Y:{1} Lat:{2} Long:{3}", pointB.X, pointB.Y, pointB.Latitude, pointB.Longitude), true); 
      LogResults(String.Format("pointC X:{0} Y:{1} Lat:{2} Long:{3}", pointC.X, pointC.Y, pointC.Latitude, pointC.Longitude), true); 
      LogResults(String.Empty, true); 
     } 

     public void LogResults(string message, bool insertNewline) 
     { 
      txtResults.Text += message + (insertNewline ? Environment.NewLine : String.Empty); 
     } 
    } 

    public class MyPoint 
    { 
     public int X; 
     public int Y; 
     public double Latitude = 0; 
     public double Longitude = 0; 

     public MyPoint(int x, int y) 
     { 
      X = x; 
      Y = y; 
     } 

     public MyPoint(int x, int y, double latitude, double longitude) : this(x, y) 
     { 
      Latitude = latitude; 
      Longitude = longitude; 
     } 
    } 

结果:

pointA X:0 Y:0 Lat:10 Long:10 
pointB X:100 Y:100 Lat:40 Long:40 
pointC X:20 Y:40 Lat:16 Long:22 // C.X is 20% of the way from A.X to B.X, so C.Lat is 20% of the way from A.Lat to B.Lat, Y/Long are 40% 

pointA X:0 Y:0 Lat:10 Long:10 
pointB X:100 Y:100 Lat:40 Long:40 
pointC X:0 Y:0 Lat:10 Long:10 // C.X = A.X and C.Y = A.Y, therefore C.Lat and C.Long = A.Lat and A.Long 

pointA X:0 Y:0 Lat:10 Long:10 
pointB X:100 Y:100 Lat:40 Long:40 
pointC X:100 Y:100 Lat:40 Long:40 // C.X = B.X and C.Y = B.Y, therefore C.Lat and C.Long = B.Lat and B.Long 
+0

无论如何,我可以联系你,所以我给你我的项目?我的邮件:[email protected]。 我需要这些街道上的电线:所以你应该尝试输入例如:答:(45.252164 19.850331)乙:(45.252028 19.853984)。 – 2014-09-06 08:08:29

+0

我测试了你的公式,我的测试实例和结果如下: A(487,361,45.252164,19.850337); B(1169,397,45.252026,19.853990); 计算开始: C = A是(487,361,45.252164,19.850337)右值; C = B是(1169,397,45.252302,19.853990)Lat是错的; 随机在地图上(810,513,45.252229,19。Lat/Lon错误; 865344) C的真值应该是(810,513,45.251592,19.852075) – 2014-09-08 06:29:13

+0

@NemanjaDjokic是的,我现在看到你的观点了。我不知道发生了什么事。算法中或者我们对问题的理解都有一个愚蠢的小错误。我稍后再看看它。让我知道你是否想出了一个解决方案。 – Sandy 2014-09-09 13:17:59

0

它不能用代码来完成上面我写的。如果我们想获得高精度(至少6位数字:n,mmmmmm),必须将EARTH_RADIUS常量用于计算。接下来的代码将按比例缩放适当的纬度/经度,所以当我们放置A和B所具有的(X,Y)线时,计算的点C将匹配参考点A和B.

公共无效ComputeLatitudeAndLogitude(Wpf_Maps.Point点){

 double diffLatAB = pointB.Latitude - pointA.Latitude; 
     double diffLonAB = pointB.Longitude - pointA.Longitude; 

     int diffXAB = pointB.X - pointA.X; 
     int diffYAB = pointB.Y - pointA.Y; 

     int diffXAC = point.X - pointA.X; 
     int diffYAC = point.Y - pointA.Y; 

     point.Latitude = diffLatAB/diffXAB * diffXAC + pointA.Latitude; 
     point.Longitude = diffLonAB/diffYAB * diffYAC + pointA.Longitude; 
    }