服务器端标记聚类PHP& MongoDB的

时间:2014-04-11 12:58:53

标签: javascript php mongodb google-maps google-maps-api-3

我已按照此链接中的说明实施了服务器端标记群集 http://www.appelsiini.net/2008/introduction-to-marker-clustering-with-google-maps

这适用于小于5,000的标记。但是当我的标记增加到17,000 它会导致所有内存耗尽,因为有很大的循环在运行。 我正在使用mongodb来存储我的所有记录,其中包括lat n long,

我可以使用mongodb的空间查询功能进行聚类吗?

我希望每次用户拖动地图时,我希望服务器负载计算群集的次数少得多, 到目前为止,我正在进行如下聚类

while (count($markers)) {
        $marker  = array_pop($markers);
        $cluster = array();
        /* Compare against all markers which are left. */
        foreach ($markers as $key => $target) {
            $pixels = $this->pixelDistance($marker['lat'], $marker['long'],
                                    $target['lat'], $target['long'],
                                    $zoom);
        if ($distance > $pixels && $zoom < 18) {
           unset($markers[$key]);
                $cluster[] = $target;
        }
       if (count($cluster) > 0) {
                $cluster[] = $marker;
                $clustered[] = $cluster;
            } else {
                $clustered[] = $marker;
            }
        }
    $newarray = array();
    foreach($clustered as $key => $cluster) {
        $centroid = array('lat' => 0, 'long' => 0, 'count' => 0);
        if(isset($cluster[0]) && is_array($cluster[0])){            
            foreach($cluster as $marker) {    
            //echo "{$key} =>"; printArray($marker);
                //if($key != 10){
                    $centroid['lat'] += $marker['lat']; // Sum up the Lats
                    $centroid['long'] += $marker['long']; // Sum up the Lngs
                    $centroid['count']++;
                //}
            }
            //if($centroid['count'] != 0){
                $centroid['lat'] /= $centroid['count']; // Average Lat
                $centroid['long'] /= $centroid['count']; // Average Lng
                $clustered[$key] = $centroid; // Overwrite the cluster with the single point.
            //}
        }
    }
    return $clustered;

非常感谢任何帮助。 提前致谢

1 个答案:

答案 0 :(得分:1)

您可以使用边界框来缩小搜索范围。经度为111公里:http://en.m.wikipedia.org/wiki/Longitude。使用3个变量x,y,z计算图块。它使用具有x和y轴以及缩放级别z的二维网格。请在此处阅读:http://msdn.microsoft.com/en-us/library/bb259689.aspx。基本上你需要将lat-lng对转换为像素坐标。然后你可以从中获取tile-number。最大像素是2个数的幂。因此,最大缩放级别的大数字。因为你坚持使用bing瓦片系统:

  

为了优化图块的索引和存储,二维图块XY坐标被组合成称为四叉树键的一维字符串,或简称为“四键”。每个四元组唯一地标识特定细节级别的单个区块,并且它可以用作公共数据库B树索引中的密钥。要将切片坐标转换为四元组,Y和X坐标的位是交错的,结果将被解释为基数为4的数字(保持前导零)并转换为字符串。例如,给定级别3处的瓦片XY坐标(3,5),如下确定四键:

     

tileX = 3 = 011 2

     

tileY = 5 = 101 2

     

quadkey = 100111 2 = 213 4 =“213”

     

Quadkeys有几个有趣的属性。首先,四核的长度(数字   (数字)等于相应图块的细节级别。第二,&gt;四元组任何图块都以其父图块的四元组开头(包含该图块的图块)   上一级)。

它非常类似于四叉树或r树,对于读者来说它应该是一个很好的练习,但你已经拥有了bing tile代码。