Javascript 通过大量横向/纵向坐标优化搜索以找到匹配项

Javascript 通过大量横向/纵向坐标优化搜索以找到匹配项,javascript,performance,search,google-maps-api-3,geolocation,Javascript,Performance,Search,Google Maps Api 3,Geolocation,我需要创建一个页面 将2个地址发送至和发送至, 绘制路线和该路线1英里范围内的区域, 然后计算出数千个横向/纵向坐标的预定义列表中是否有任何一个位于该路线沿线1英里的区域内 我正在使用GoogleMapsV3API和RouteBox类。 下面是一个很好的例子: 如您所见,1和2基本上由这个RouteBox示例处理 我的问题是如何有效地处理3。 Routeboxer提供一系列箱型坐标,从东北纬度/长角到西南纬度/长角。我可以逐框循环,然后在每个预定义的lat/long坐标内循环,以查看列表中是否有

我需要创建一个页面

将2个地址发送至和发送至, 绘制路线和该路线1英里范围内的区域, 然后计算出数千个横向/纵向坐标的预定义列表中是否有任何一个位于该路线沿线1英里的区域内 我正在使用GoogleMapsV3API和RouteBox类。 下面是一个很好的例子: 如您所见,1和2基本上由这个RouteBox示例处理

我的问题是如何有效地处理3。 Routeboxer提供一系列箱型坐标,从东北纬度/长角到西南纬度/长角。我可以逐框循环,然后在每个预定义的lat/long坐标内循环,以查看列表中是否有坐标位于RouteBox区域内,但这是一个冗长、低效的过程

我正在寻找一种方法来优化这3个搜索部分。 一些想法:

二进制搜索;将需要按lat排序协调列表,然后按long排序,但可能会加快排序速度 mySQL查询:这将用户SPC的处理剥离,并将其放到我们的服务器上; 我将查询每个routeBox:从myListOfLatLongs where lat box_latwest和lng boxlngsouth中选择* 哪一种对速度和稳定性更为理想?有没有更好的想法/意见?
底线是,如果不进行优化,理论上会返回许多框,然后需要将每个框与数千个坐标进行比较,这可能会成为一个漫长的过程。任何需要帮助的地方

都可以将横向/纵向空间细分为适当大小的单元格,并将位置排序为这些单元格

然后,对于路线上的每个点,在单元格中向外螺旋搜索,以找到最近的邻居

还有螺旋搜索。你可以在正方形、砖块或六边形上这样做。如果瓷砖足够大,可以包含一些点,但不会太多,If会快速找到邻居

只需将纬度和经度转换为上述坐标系,将它们四舍五入到最近的中心,并为每个单元制作一个桶。 然后用你的搜索点找到它的桶。 如果在它的桶中没有找到任何有用的东西,则在半径1处搜索六个桶,依此类推,直到找到合适的邻居集合,然后选择最好的一个。 单元格序列如下所示,假设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.
< P>编辑:一些C++代码来做< /P>
// 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

补充:有可能得到一个不是最近的点,因为一个六边形边缘外的点可能比一个角内的点更近。如果这是一个问题,请转到另一层。

您可以使用空间索引并搜索二维范围,即边界框。例如MySQL空间扩展。您也可以尝试我的hilbert曲线类phpclasses.org,它使用带范围搜索的四键,这是一个纯php解决方案。你也可以试试四叉树,它比r-树有更好的性能。

@Mke:也许一些代码会很有用?这仍然是一个非常宽泛的答案。