【问题标题】:Google Maps API V3: Simple Marker Cluster Not Showing UpGoogle Maps API V3:未显示简单标记集群
【发布时间】:2012-06-25 22:56:32
【问题描述】:

我正在使用 PHP、MongoDB、Javascript 和 Google Maps API V3 开发一个基于 Web 的应用程序。

通过使用 json_encode 转换 MongoDB 数组,我能够轻松地在谷歌地图上生成和显示标记。这是带有标记和信息窗口的示例地图。

Markers and InfoWindow

但是,当我尝试实现 Google Maps MarkerClusterer 方法时,标记消失了。我按照谷歌地图的“A Simple MarkerClusterer Example”作为指导。

我也尝试声明一个全局集群对象,传递一个空数组,

var markerCluster = new MarkerClustrer(map, markers);

然后使用markerCluster.addMarkers(markers, true); 作为没有运气的替代方法。

看起来很简单,但不知何故,它没有显示标记。我还尝试注释掉整个 infoWindow/OnClick 事件部分,所以我认为它与此无关。任何帮助是极大的赞赏。

PHP MongoDB 查询:

<?php

// Connect to Mongo and set DB and Collection
try
{
    $mongo = new Mongo();
    $db = $mongo->selectDB('twitter');
    $collection = $db->selectCollection('tweets');
}
catch(MongoConnectionException $e)
{
    die("Failed to connect to Twitter Database ". $e->getMessage());
}

// The hotspots array will contain the data that will be returned
$tweets = array();

// Return a cursor of tweets from MongoDB
$cursor = $collection->find();

// Try catch for catching whether there are tweets to display
$count = 0;
try 
{
    $count = $cursor->count();
} 
catch (MongoCursorException $e) 
{
    die(json_encode(array('error'=>'error message:' .$e->getMessage())));
}

// Loops through the cursor again specifically for querying all geo locations
// Unlike table display of tweets, this cursor is not limited by pages. 
foreach($cursor as $id => $value)
{ 
    $mapLocations[] = array
    (
        'id'=>$value['_id'],
        'screen_name'=>$value['screen_name'],
        'name'=>$value['name'],
        'tweet'=>$value['tweet'],
        'hashtags'=>$value['hashtags'],
        'lat'=>$value['geo']['lat'],
        'long'=>$value['geo']['long'],
        'date'=>$value['date'],
        'img'=>$value['img'],
        'specImg'=>$value['specImg']
    );
}
// var_dump($mapLocations);
?>

Javascript 函数:

function initialize() 
{
    // Converts MongoDB information to JSON, ready for Javascript
    var tweets = <?php echo json_encode($mapLocations); ?>;

    // Sets google maps options
    var myOptions = 
    {
        // Centers on Maui...
        center: new google.maps.LatLng(20.80362, -156.321716),
        zoom: 7,
        mapTypeId: google.maps.MapTypeId.TERRAIN
    };

    // Sets Marker Clusterer Options
    var mcOptions =
    {
        gridSize: 50, maxZoom: 15
    };

    // Generates Google Map and applies the defined options above.
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

    // Infowindow for displaying information for onClick event  
    // Content must be inside the google.maps.event function 
    // Otherwise the same content will be entered on all markers    
    var infoWindow = new google.maps.InfoWindow({});

    var markerCluster = null;   // Initializes markerCluster
    var markers = [];           //Array needed to pass to MarkerClusterer

    // Loops through each tweet and draws the marker on the map.    
    for (var i = 0; i < tweets.length; i++)
    {
        var tweet = tweets[i];

        if(tweet.lat != null || tweet.long != null) 
        {
            var myLatLng = new google.maps.LatLng(tweet.lat, tweet.long);
            //document.write(" Latitude: " + tweet.lat + " Longitude: " + tweet.long + " <br> ");
            var marker = new google.maps.Marker({ 
                position: myLatLng,
                //icon: "markers/flag.png",
                //map: map,
            });

            markers.push(marker);

            google.maps.event.addListener(marker, 'click', (function(marker, i) 
            {
                return function() 
                {
                    // Generates a table for infoWindow
                    var content = "<table class='popup'>";

                    // Check if image exits, otherwise show no image icon
                    if(tweets[i].specImg != null) 
                    {
                        content += "<tr><th width=75 ><a href=" + tweets[i].specImg + ">";
                        content += "<img height=75 width=75 src=" + tweets[i].specImg + "></a>";
                    }
                    else
                    {
                        content += "<tr><th width=75><img height=75 width=75 src=images/noimage.jpg>";
                    }
                    // Concatanate screen name and tweet
                    // Will work on trimming information
                    content += "</th><td>" + tweets[i].screen_name + " says...<br>"; 
                    content += "''" + tweets[i].tweet +  "''<br>";
                    content += "on " + tweets[i].date + "</td>";
                    content += "</table>";

                    // Zoom into marker on click
                    map.setZoom(15);
                    map.setCenter(marker.getPosition());

                    // Sets the infoWindow content to the marker
                    infoWindow.setContent(content);
                    infoWindow.open(map, marker);
                }
            })(marker, i)); 
        }
    } 
    var markerCluster = new MarkerClusterer(map, markers);
}

@罗比:

JSONned $mapLocations 变成了一个多维数组,但我将 $mapLocations 简化为仅存储 2D 纬度和经度。 javascript源代码如下。

var tweets = [{"lat":20.87179594,"long":-156.47718775},{"lat":20.87195633,"long":-156.47714356},{"lat":20.87138419,"long":-156.47719744},{"lat":21.3320704,"long":-157.8685716},{"lat":null,"long":null},{"lat":21.36509415,"long":-157.92824454},{"lat":21.3320825,"long":-157.8684742},{"lat":null,"long":null},{"lat":21.33673131,"long":-157.86824},{"lat":21.332507,"long":-157.86635342},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":37.36520709,"long":-121.92386941},{"lat":37.2499758,"long":-121.86462506},{"lat":37.36278955,"long":-121.90521146},{"lat":null,"long":null},{"lat":37.36278955,"long":-121.90521146},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":20.88944108,"long":-156.4761887},{"lat":37.36273157,"long":-121.90479984},{"lat":20.85102618,"long":-156.65936351},{"lat":20.88949978,"long":-156.4762491},{"lat":null,"long":null},{"lat":21.3320168,"long":-157.8685715},{"lat":null,"long":null},{"lat":null,"long":null},{"lat":null,"long":null}];

【问题讨论】:

  • 我怀疑错误是您正在执行var tweets = &lt;?php echo json_encode($mapLocations); ?&gt;;,然后将推文视为 JavaScript 数组。 JSON是用于数据交换的序列化JavaScript;如果要将 JSON 转换为 JavaScript 对象,则需要 eval() JSON。
  • 我使用这个网站Convert PHP array to Javascript 将 PHP 数组转换为 javascript 数组。似乎可以正确获取数据。我还尝试使用 eval(tweet.lat)、eval(tweet.long),但我仍然可以让标记正常工作。但是,当我尝试实现 Marker Clusterer 时,标记消失了。

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


【解决方案1】:

终于想通了:

正如我所料,这是一件非常简单的事情。 显然您需要从Google Maps Utility Library 下载markerclusterer.js 文件。我认为集群器已经内置在 API 本身中。

我通过将脚本下载到服务器并像这样引用它来修复它

<script type="text/javascript" src="markerclusterer.js"></script>

无论如何,谢谢大家的帮助!

【讨论】:

  • 感谢分享。我正在研究这种类型的东西:)
【解决方案2】:

我认为可能有几个问题:

  1. 每个标记都需要信息窗口,您为所有标记共享一个信息窗口并反复更改其内容。

  2. 还要检查您是否落入关闭陷阱。我可以全部重复,但您基本上需要从闭包中创建一个函数。在http://www.robertbolton.com/blog/google-maps-v3-multiple-markers-and-infowindows-in-a-loop

  3. 有关于如何执行此操作的说明

【讨论】:

  • 信息窗口在没有 MarkerClusterer 的情况下工作正常。但是,当我尝试实现集群时,所有标记都没有显示出来。地图出现了,所以可能是由于我正在传递函数的标记数组?
  • 我实际上无法测试,但我认为信息窗口应该仍然适用于其中一个标记。用两个标记试试看会发生什么?如果您可以将 JSONned $mapLocations 粘贴到您的问题中,我可以使用它尝试 JS 并检查我的想法。
  • 它适用于多个标记并显示每个标记的信息窗口。我更新了上面的问题,并附上了一个没有聚类的工作示例的屏幕截图。我还粘贴了 JSONed javascript 输出。非常感谢您的帮助。
猜你喜欢
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 2011-05-23
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多