2017-02-14 11 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 KMまたはユーザー1の20 KMの範囲内にあるすべてのユーザーを取得する必要があり、そのようなユーザーを取得するための最も太っている方法はありますか?私はバックエンドでSQLサーバーを利用しています。お知らせ下さい。

+0

距離を比較すると便利なのは、計算された高価な平方根を、距離の自乗を比較することによって排除することです。したがって、現在のユーザから10 km以内のすべてのユーザを見つけるには、 '(x1-x0)^ 2 +(y1-y0)^ 2'(距離自乗)を計算し、それを100km^2と比較します。 (これらの計算は緯度/経度では機能しませんので、投影で作業する必要があります)。 – adv12

+0

@VMAtmこの質問は全く重複していません。 – eocron

+0

@eocronあなたは人を納得させるために "重複しない"よりも多くの説明が必要です。なぜなら、それは非常に似ているからです(2つの緯度/経度の間の距離を得る)。 –

答えて

0

SQL Serverでは、地理空間型を使用できます。これにより、データベースと距離による距離を問い合わせることができます。

がこれをチェックアウト:別のユーザーが指定した距離の下に配置されている場合は100nmの下の範囲で

https://technet.microsoft.com/en-us/library/cc280766(v=sql.100).aspx

https://www.mssqltips.com/sqlservertip/2690/calculate-the-geographical-distance-between-two-cities-in-sql-server/

-1

このタスクは「空間インデックス構築」と呼ばれます。このタスクにはR-treeを使用できます。そのようなデータをさらに検索するために索引付けするのが唯一の目的です。 More here

実装のフレームワークはかなり人気のあるSharpMapプロジェクトにあります。

+0

多分、いくつかの議論、downvoter? – eocron

-1

可能であれば、ユーザーの最新の事前計算された距離情報を一定の固定ポイントに更新しておくことをお勧めします。これは、キーとしてのkmでの切り捨て距離を持つ単純な辞書である可能性があります。新しいユーザーが登録されるたびに、あらかじめ計算された距離キャッシュを更新するだけです。

何のためですか?まあ、RフォームのユーザーXのユーザーを評価する必要がある場合は、Xの距離を単純に評価してDとし、参照との事前計算距離がD + Rより大きく、またはD - Rより小さいユーザーをすべて破棄してください。ユーザーの数が多い場合、これはパフォーマンスに大きな影響を与える可能性があります。

これは、ユーザーの場所が非常に動的な場合は不可能です。あらかじめ計算された距離を自由に更新しなければならない場合、解決策は自己敗北です。しかし、文脈がなくても、ここでの使用のためのアイディアです。

0

を、次のコードは、(良い精度と優れた性能で)あなたを示します。

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 ; 
} 
関連する問題