2011-10-06 89 views
2

對於我的應用程序,我必須在Google地圖上找到一個點的位置,只知道它位於2個其他點和座標被捕獲時的時間(以毫秒爲單位) 。如何找到兩個其他點之間的地理點

在我的代碼,假設A和B點給出X爲找點,我:A和B之間

  1. 計算距離

  2. 築底時間我發現了的速度(以微度/ MS)從A行進到B

  3. 我發現從點A和點X的距離(使用時間和速度)

  4. 使用類似三角形的規則,我計算緯度和X點的經度從A點

此工作流程帶來了錯誤的地圖上,所以,往往在X標記不是在A和B標記之間的界線。

我該如何讓它更好用?這是全球球形的問題嗎?

謝謝大家。

下面是代碼:

int ax = oldPoint.getLatitude(); 
    int ay = oldPoint.getLongitude(); 

    int bx = currentPoint.getLatitude(); 
    int by = currentPoint.getLongitude(); 

    long at = oldPoint.getDataRilevamento(); //get time first point 
    long bt = currentPoint.getDataRilevamento(); // get time second point 
    long xt = x.getDate(); // time of point to find 

    int c1 = bx-ax; 
    int c2 = by-ay; 
    double hyp = Math.sqrt(Math.pow(c1, 2) + Math.pow(c2, 2)); 

    double vel = hyp/(bt-at); 

    double pos = vel*(xt - at); 

    int posx = (int)((pos*c1)/hyp); 
    int posy = (int)((pos*c2)/hyp); 

    x.setLatitude(ax+posx); //set the latitude of X 
    x.setLongitude(ay+posy); // set the longitude of X 

回答

13

你的問題可以通過採取下列步驟來解決。

  • 計算從點A和B(使用Haversine formula,這是足夠好的這裏,或更復雜的Vincenty formula)的距離。正確使用 式,Android的微度,這是getLatitude 和getLongitude返回,必須使用這樣的公式轉換爲弧度, :從點A

    double radians = Math.toRadians((double)microdegrees/1000000); 
    
  • 計算軸承(方向)和B(在同一頁上使用公式 )。這將與畢達哥拉斯公式不同,因爲地球是圓形的,而不是平坦的。

  • 然後你可以選擇一個新的距離,並計算點X給出 點A和在上一步驟(見或者「目標點一定距離,並從起始點軸承」在同一頁上,或Vincenty's direct formula)中發現的軸承。
  • 轉換從產生點的弧度爲微度使用這個公式:

    int microdegrees = (int)(Math.toDegrees(radians)*1000000); 
    

全部放在一起,我們有以下的功能,這是我在公共領域的地方:

public static int[] getIntermediatePoint(
     int startLatMicroDeg, 
     int startLonMicroDeg, 
     int endLatMicroDeg, 
     int endLonMicroDeg, 
     double t // How much of the distance to use, from 0 through 1 
    ){ 
     // Convert microdegrees to radians 
     double alatRad=Math.toRadians((double)startLatMicroDeg/1000000); 
     double alonRad=Math.toRadians((double)startLonMicroDeg/1000000); 
     double blatRad=Math.toRadians((double)endLatMicroDeg/1000000); 
     double blonRad=Math.toRadians((double)endLonMicroDeg/1000000); 
     // Calculate distance in longitude 
     double dlon=blonRad-alonRad; 
     // Calculate common variables 
     double alatRadSin=Math.sin(alatRad); 
     double blatRadSin=Math.sin(blatRad); 
     double alatRadCos=Math.cos(alatRad); 
     double blatRadCos=Math.cos(blatRad); 
     double dlonCos=Math.cos(dlon); 
     // Find distance from A to B 
     double distance=Math.acos(alatRadSin*blatRadSin + 
            alatRadCos*blatRadCos * 
            dlonCos); 
     // Find bearing from A to B 
     double bearing=Math.atan2(
      Math.sin(dlon) * blatRadCos, 
      alatRadCos*blatRadSin - 
      alatRadSin*blatRadCos*dlonCos); 
     // Find new point 
     double angularDistance=distance*t; 
     double angDistSin=Math.sin(angularDistance); 
     double angDistCos=Math.cos(angularDistance); 
     double xlatRad = Math.asin(alatRadSin*angDistCos + 
            alatRadCos*angDistSin*Math.cos(bearing)); 
     double xlonRad = alonRad + Math.atan2(
      Math.sin(bearing)*angDistSin*alatRadCos, 
      angDistCos-alatRadSin*Math.sin(xlatRad)); 
     // Convert radians to microdegrees 
     int xlat=(int)Math.round(Math.toDegrees(xlatRad)*1000000); 
     int xlon=(int)Math.round(Math.toDegrees(xlonRad)*1000000); 
     if(xlat>90000000)xlat=90000000; 
     if(xlat<-90000000)xlat=-90000000; 
     while(xlon>180000000)xlon-=360000000; 
     while(xlon<=-180000000)xlon+=360000000; 
     return new int[]{xlat,xlon}; 
    } 

下面是如何使用它:

int ax = oldPoint.getLatitude(); 
int ay = oldPoint.getLongitude(); 

int bx = currentPoint.getLatitude(); 
int by = currentPoint.getLongitude(); 

long at = oldPoint.getDataRilevamento(); //get time first point 
long bt = currentPoint.getDataRilevamento(); // get time second point 
long xt = x.getDate(); // time of point to find 

// Find relative time from point A to point B 
double t=(bt==at) ? 0 : ((double)(xt-at))/((double)(bt-at)); 
// Find new point given the start and end points and the relative time 
int[] xpos=getIntermediatePoint(ax,ay,bx,by,t); 
x.setLatitude(xpos[0]); //set the latitude of X 
x.setLongitude(xpos[1]); // set the longitude of X 
+0

你真棒!真的非常感謝你! –

+0

感謝您發佈此算法。我需要爲我的項目做類似的事情,我相信這樣做會的!你介意我把它包裝起來並將它作爲npm模塊發佈嗎? –

+0

即使超過三年:起首! – 2014-12-11 20:53:18

相關問題