0

私は現在、アプリケーションのサーバー側を開発しています。アプリでは、大きな領域(1000ポイント以上)に多くの関心ポイントがあり、ユーザーデバイスに最も近いポイントを見つけたいと思っています。私は使用しようとしました:

.GetDistanceTo(GeoCoordinate);

ライブラリから:

 System.Device.Location;

クエリの例:

  from point in db.Points
  where ((new GeoCoordinate(point.lat,point.lng)).GetDistanceTo(new GeoCoordinate(coordinates[0],coordinates[1]))<1000)) 
  select point

しかし、Linqクエリではサポートされておらず、List <>または配列で使用しようとすると、時間がかかりすぎます...

どうすればそれをより良くそしてより速くすることができますか?ありがとう

4

1 に答える 1

1

この計算を頻繁に実行していると思います。そうでない場合、1,000ポイントを超える反復は、長い時間(確かに1秒未満)かかることはありません。

距離を計算するのではなく、時間の大部分がメモリの割り当てとオブジェクトのインスタンス化に費やされる可能性があると推測しているため、メモリ内のポイントをGeoCoordinatesとしてキャッシュすることを検討してください。次に、GeoCoordinatesの既存のリストから、すでにインスタンス化されている既存のGeocoordinateに対して計算を実行できます。

例:アプリケーションのロード時に、すべてのポイントをメモリに、場合によってはバックグラウンドスレッドに保存します。

List<GeoCoordinate> points = from point in db.Points select new GeoCoordinate(point.lat, point.lng);

次に、検索しようとしているポイントを取得して、ポイントをループします

var gcSearch = new GeoCoordinate(coordinates[0], coordinates[1]);
var searchDistance = 1000;
var results = from pSearch in points 
              where pSearch.GetDistanceTo(gcSearch) < searchDistance
              select pSearch;

それでも十分な速度が得られない場合は、最後に検索されたポイントをキャッシュし、新しい検索が同じ範囲内にある場合は既知のリストを再取得することを検討してください。

// in class definition
static GeoCoordinate lastSearchedPoint = null;
static List<GeoCoordinate> lastSearchedResults = null
const searchFudgeDistance = 100;

//in search method
var gcSearch = new GeoCoordinate(coordinates[0], coordinates[1]);
if (lastSearchedPoint != null && gcSearch.GetDistanceTo(lastSearchedPoint) < searchFudgeDistance)
    return lastSearchedResults;
lastSearchedPoint = gcSearch;

var searchDistance = 1000;
var results = from pSearch in points 
              where pSearch.GetDistanceTo(gcSearch) < searchDistance
              select pSearch;
//store the results for future searches
lastSearchedResults = results;
于 2012-10-06T21:14:03.903 に答える