0

そのようなページを作成する必要があります

  1. 2 つのアドレス (to と from) を受け取ります。
  2. ルートと、このルートから 1 マイル以内のエリアをプロットします。
  3. 次に、何千もの緯度/経度座標の事前定義されたリストのいずれかがこの領域内にあるかどうかを調べます (ルートに沿って 1 マイル)

私は google-maps v3 api と routeboxer クラスを使用しています。
ここに良い例があります: http://google-maps-utility-library-v3.googlecode.com/svn/trunk/routeboxer/examples/routeboxer-v3.html ご覧
のとおり、#1 と #2 は基本的に使用されますこのルートボクサーの例で気をつけてください。

私の質問は、#3 の効率的な処理についてです。Routeboxer は、一連のボックス座標 (北東緯度/経度から南西緯度/経度のコーナー) を提供します。ボックスごとにループしてから、事前定義された緯度/経度の各座標内でループして、リスト内のいずれかの座標が routeBoxes の領域内にあるかどうかを確認できますが、これは時間のかかる非効率的なプロセスです。

この (#3) 検索部分を最適化する手段を探しています。いくつかのアイデア:

  1. 二分探索; 座標リストを緯度、次に経度でソートする必要がありますが、速度が上がる可能性があります
  2. mySQL クエリ: これにより、usersPC から処理が取り除かれ、サーバーに配置されます。各 routeBox に対してクエリを実行します:
    select * from myListOfLatLongs where lat box_latwest && lng box)lngsouth

速度と安定性の点でどちらがより理想的ですか? より良いアイデア/最適化はありますか? 肝心なのは、最適化を行わないと、理論的には多数のボックスが返される可能性があり、各ボックスを数千の座標と比較する必要があり、これは長いプロセスになる可能性があるということです。どんな助けでも大歓迎

4

2 に答える 2

1

緯度/経度空間を適切なサイズのセルに分割し、それらのセルに位置を並べ替えます。

次に、ルートに沿った各ポイントについて、セル間で外側に向かってらせん状の検索を行い、最近傍を見つけます。

PSスパイラル検索。このように、正方形、レンガ、または六角形で行うことができます。タイルがいくつかの点を含むのに十分な大きさであるが、多すぎない場合、隣接点がすぐに見つかる場合。

ここに画像の説明を入力

緯度と経度を上記の座標系に変換し、それらを最も近い中心に丸めて、各セルのバケットを作成するだけです。次に、検索ポイントを取り、そのバケットを見つけます。バケットに有用なものが見つからない場合は、半径 1 の 6 つのバケットを検索し、適切な近隣のコレクションが見つかるまで同様に検索し、最適なものを選択します。0,0 が開始セルであると仮定すると、セルのシーケンスは次のようになります。

look in 0,0
++x

++y
--x
--x,--y
--y
++x
++y,x+=2

++y twice
--x twice
--x,--y twice
--y twice
++x twice
++x,++y
++y,x+=2

etc. etc.

編集:それを行うためのいくつかのC++コード

// for each point x,y, do this (d is diameter of a cell)
double x1 = (x + y/2)/d;  // transform x coordinate
double y1 = (y / 0.866)/d;  // transform y coordinate (it's shortened a bit)
int ix = (int)floor(x1 + 0.5);  // find corresponding bucket
int iy = (int)floor(y1 + 0.5);
// then put point into bucket at ix,iy

// to search, enumerate over the cells
// first at distance 0, then 1, then 2, etc.
bool bPointsFound = false;
// collect points in bucket at 0,0
if (/* there are any points in the collection */){
  bPointsFound = true;
}
for (n = 1; n < upper_limit && !bPointsFound; n++){
  iy = 0; ix = n;
  // upper right edge
  for (i = 0; i < n; i++){
    // collect points in bucket at ix, iy
    iy++;
  }
  // top edge
  for (i = 0; i < n; i++){
    // collect points in bucket at ix, iy
    ix--;
  }
  // upper left edge
  for (i = 0; i < n; i++){
    // collect points in bucket at ix, iy
    ix--; iy--;
  }
  // lower left edge
  for (i = 0; i < n; i++){
    // collect points in bucket at ix, iy
    iy--;
  }
  // bottom edge
  for (i = 0; i < n; i++){
    // collect points in bucket at ix, iy
    ix++;
  }
  // lower right edge
  for (i = 0; i < n; i++){
    // collect points in bucket at ix, iy
    ix++; iy++;
  }
  if (/* there are any points in the collection */){
    bPointsFound = true;
  }
}
// pick the closest point in the collection

追加: 六角形の端のすぐ外側の点は角のすぐ内側の点よりも近い可能性があるため、最も近い点ではない点が取得される可能性がわずかにあります。それが懸念される場合は、余分なレイヤーに出てください。

于 2013-08-09T09:28:53.407 に答える
0

空間インデックスを使用して、2D 範囲、つまりバウンディング ボックスを検索できます。たとえば、MySQL 空間拡張を使用します。私のヒルベルト曲線クラス (phpclasses.org) を試すこともできます。これは、範囲検索でクワッドキーを使用し、純粋な php ソリューションです。また、R ツリーよりもパフォーマンスが優れている四分木を試すこともできます。

于 2013-08-09T11:13:44.727 に答える