1

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

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

标记和信息窗口

但是,当我尝试实现 Google Maps MarkerClusterer 方法时,标记消失了。我按照 Google Map 的“ 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}];
4

2 回答 2

1

终于想通了:

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

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

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

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

于 2012-06-26T23:33:14.670 回答
0

我觉得可能有几个问题:

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

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

于 2012-06-26T00:29:26.133 回答