2017-02-14 97 views
0

我正在用C#編寫WCF服務。我需要根據當前用戶登錄來計算用戶的距離。例如,我需要當前用戶10 KM內的所有用戶。數據量過大時計算距離的最佳和最快的方法?

數據看起來像這樣。

User Longitude Latitude 
1 71.23232 31.23232 
2 69.23232 30.23232 
3 68.23232 28.23232 
4 67.23232 27.23232 
. 
. 
1000 23.22332 45.22323 

我正在用下面的方法來計算距離。

public static double Distance(double sLatitude, double sLongitude, double dLatitude, double dLongitude, char unit='m') 
{ 
    var sCoord = new GeoCoordinate(sLatitude, sLongitude); 
    var dCoord = new GeoCoordinate(dLatitude, dLongitude); 

    if(unit == 'm') 
     return sCoord.GetDistanceTo(dCoord); 
    else if(unit == 'k') 
     return (sCoord.GetDistanceTo(dCoord))/1000; 
} 

用戶1登錄,我需要得到誰在10公里或用戶1. 20公里的範圍內有沒有fatest方式來獲得這些用戶的所有用戶?我在後端usig SQL服務器。請指教。

+0

比較距離時的一個便利技巧是通過比較平方距離來消除計算昂貴的平方根。因此,要找到距離當前用戶10公里內的所有用戶,計算'(x1 - x0)^ 2 +(y1 - y0)^ 2'(距離平方),並將其與100平方公里比較。 (請注意,這些計算不適用於緯度/經度值;您需要在投影中工作。) – adv12

+0

@VMAtm根本不重複這個問題。 – eocron

+0

@eocron你需要更多的解釋,而不是「不重複」來說服人們不是,因爲它看起來非常相似(獲得兩個緯度/長度座標之間的距離)。 –

回答

-1

這個任務被稱爲'空間索引建設'。您可以使用R-tree完成此任務。唯一的目的是爲了進一步搜索索引這些數據。更多here

具有實現的框架可以在相當流行的SharpMap項目中找到。

+0

也許一些爭論,downvoter? – eocron

-1

一個很酷的想法,如果可能的話,是保持用戶的預先計算的距離信息更新到某個固定點。這可能是一個簡單的字典,以km爲倒數的距離作爲關鍵字。每次註冊新用戶時,只需更新預先計算的距離緩存即可。

什麼?那麼,當您需要評估R表單用戶X範圍內的用戶時,只需評估X與參考的距離,即可將其稱爲D,然後放棄所有預計算出的距離大於D + R或小於D - R的用戶。當用戶數量很高時,這可能會對性能產生重大影響。

如果用戶位置非常動態,這將不可能;如果你必須頻繁地更新預先計算的距離,那麼解決方案就是自我失敗。但是,沒有上下文,這裏是它的任何用途的想法。

0

在100NM下一個範圍,下面的代碼會指示你,如果另一個用戶位於下指定的距離(以很高的精度,性能優良) 。

public static bool IsWithinRadius(double radius,double sLatitude, double sLongitude, 
            double dLatitude, double dLongitude, char unit='m') 
{ // [sLatitude,sLongitude] defines the "center", i.e. the location of the current user. 
    if(unit == 'm') radius=radius/1000 ; 
    double deltalat = (sLatitude -dLatitude)*40000f/360f ; 
    double deltalon = (sLongitude-dLongitude)*40000f/360f ; 
    if (deltalon>20000f) deltalon=40000f-deltalon ; // Points on both sides of meridian 0 
    double loncorrection = Math.Cos(sLatitude*Math.PI/180); 
    deltalon = deltalon*loncorrection ; 
    return Math.Sqrt(deltalat*deltalat+deltalon*deltalon)<radius ; 
} 
相關問題