我需要创建一个页面
我正在使用google-maps v3 api和routeboxer类。
这是一个很好的例子:http://google-maps-utility-library-v3.googlecode.com/svn/trunk/routeboxer/examples/routeboxer-v3.html
如您所见,#1和#2基本上由此路由器示例处理。
我的问题是如何有效地处理#3。 Routeboxer提供一系列箱形电缆(东北纬/长至西南纬/长角)。我可以逐框循环,然后在每个预定义的纬度/长度坐标系内循环,看看列表中是否有任何坐标位于路径盒的范围内,但这是一个冗长,低效的过程。
我正在寻找一种优化此(#3)搜索部分的方法。 一些想法:
哪个更适合速度和速度稳定性?有没有更好的想法/优化? 最重要的是,如果没有优化,这理论上可以返回多个盒子,然后需要将每个盒子与成千上万的线圈进行比较 - 这可能会成为一个漫长的过程。任何帮助表示赞赏
答案 0 :(得分:1)
将您的纬度/经度空间细分为适当大小的单元格,并将位置分类到这些单元格中。
然后,对于沿着路线的每个点,在单元格中向外进行螺旋搜索以找到最近的邻居。
P.S。螺旋搜索。你可以像这样在正方形,砖块或六边形上做。如果瓷砖大到足以包含一些点但不会太多,如果快速找到邻居。
将纬度和经度转换为上述坐标系,将它们四舍五入到最近的中心,并为每个单元格制作一个桶。 然后拿你的搜索点找到它的桶。 如果在其桶中找不到任何有用的东西,则在半径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.
编辑:要做的一些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
补充:获得一个不是最接近的点的可能性很小,因为六边形边缘外的点可能比角落内的点更近。如果这是一个问题,请转到额外的层。
答案 1 :(得分:0)
您可以使用空间索引并搜索2d范围,即。边界框。例如,使用MySQL空间扩展。您也可以尝试我的希尔伯特曲线类(phpclasses.org),它使用带有范围搜索的四核,它是纯粹的PHP解决方案。您还可以尝试使用四叉树,它在r树上具有更好的性能。