【问题标题】:Google Map v3 auto refresh Markers only仅限 Google Map v3 自动刷新标记
【发布时间】:2013-01-24 03:37:40
【问题描述】:

我正在使用 Google Maps V3 来显示一些图钉。我希望能够在不影响您在地图上的位置或缩放级别的情况下刷新标记。我希望标记每 x 秒更新一次。

我该怎么做呢?我对 jQuery/ajax 没有太多经验。

我的地图的一个工作示例如下。

http://jsfiddle.net/dLWNc/

 var locations = [
  ['some random info here', -37.8139, 144.9634, 1],
  ['some random info here', 46.0553, 14.5144, 2],
  ['some random info here', -33.7333, 151.0833, 3],
  ['some random info here', 27.9798, -81.731, 4],    ];


var map = new google.maps.Map(document.getElementById('map_2385853'), {
  zoom: 1,
  maxZoom: 8, 
  minZoom: 1, 
  streetViewControl: false,
  center: new google.maps.LatLng(40, 0),
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

var infowindow = new google.maps.InfoWindow();

var marker, i;

for (i = 0; i < locations.length; i++) {  
  marker = new google.maps.Marker({
    position: new google.maps.LatLng(locations[i][1], locations[i][2]),
    map: map
  });

  google.maps.event.addListener(marker, 'click', (function(marker, i) {
    return function() {
      infowindow.setContent(locations[i][0]);
      infowindow.open(map, marker);
    }
  })(marker, i));
}

谢谢

【问题讨论】:

  • 您想刷新标记(删除它们然后添加新标记)还是只更新它们的位置?
  • 据我所知,您所要做的就是用新数据覆盖位置数组
  • 要对现有的locations 进行更改,您需要为每个人安排一个唯一的 ID,以便对其进行处理。 id 需要由服务器生成。如果你不能这样做,那么你将不得不在每次迭代中替换所有locations(尽管不一定是所有相应的标记)。
  • 只要 (a) 你的 1 - 4 是 id 而不仅仅是索引,并且 (b) 服务器总是可以在每个场合通过相同的唯一 id 寻址每个位置(因此关联的标记),那么你就有了进行选择性更新的基础,而不是完全替换。选择性更新将需要更多的编程工作,因此如果位置数量很少,选择完全替换可能更现实。
  • Daniel,是的,假设每次迭代只会影响少数标记,那么对于 2000 个标记,您绝对应该执行选择性更新。您对 id generation 的评价很好。现有的标记总是可以用相同的 id 重新寻址,新的标记将收到一个新的以前未分配的 id - 完美。我现在没有时间帮助编写代码,但会在今天晚些时候(几个小时后)查看。

标签: jquery html ajax


【解决方案1】:

好的,我有一些工作 - 主要是对原始代码的大量重构 - 你会识别出各种块。

$(function() {
    var locations = {};//A repository for markers (and the data from which they were constructed).

    //initial dataset for markers
    var locs = {
        1: { info:'11111. Some random info here', lat:-37.8139, lng:144.9634 },
        2: { info:'22222. Some random info here', lat:46.0553, lng:14.5144 },
        3: { info:'33333. Some random info here', lat:-33.7333, lng:151.0833 },
        4: { info:'44444. Some random info here', lat:27.9798, lng:-81.731 }
    };
    var map = new google.maps.Map(document.getElementById('map_2385853'), {
        zoom: 1,
        maxZoom: 8,
        minZoom: 1,
        streetViewControl: false,
        center: new google.maps.LatLng(40, 0),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    var infowindow = new google.maps.InfoWindow();

var auto_remove = true;//When true, markers for all unreported locs will be removed.

function setMarkers(locObj) {
    if(auto_remove) {
        //Remove markers for all unreported locs, and the corrsponding locations entry.
        $.each(locations, function(key) {
            if(!locObj[key]) {
                if(locations[key].marker) {
                    locations[key].marker.setMap(null);
                }
                delete locations[key];
            }
        });
    }

        $.each(locObj, function(key, loc) {
            if(!locations[key] && loc.lat!==undefined && loc.lng!==undefined) {
                //Marker has not yet been made (and there's enough data to create one).

                //Create marker
                loc.marker = new google.maps.Marker({
                    position: new google.maps.LatLng(loc.lat, loc.lng),
                    map: map
                });

                //Attach click listener to marker
                google.maps.event.addListener(loc.marker, 'click', (function(key) {
                    return function() {
                        infowindow.setContent(locations[key].info);
                        infowindow.open(map, locations[key].marker);
                    }
                })(key));

                //Remember loc in the `locations` so its info can be displayed and so its marker can be deleted.
                locations[key] = loc;
            }
            else if(locations[key] && loc.remove) {
                //Remove marker from map
                if(locations[key].marker) {
                    locations[key].marker.setMap(null);
                }
                //Remove element from `locations`
                delete locations[key];
            }
            else if(locations[key]) {
                //Update the previous data object with the latest data.
                $.extend(locations[key], loc);
                if(loc.lat!==undefined && loc.lng!==undefined) {
                    //Update marker position (maybe not necessary but doesn't hurt).
                    locations[key].marker.setPosition(
                        new google.maps.LatLng(loc.lat, loc.lng)
                    );
                }
                //locations[key].info looks after itself.
            }
        });
    }

    var ajaxObj = {//Object to save cluttering the namespace.
        options: {
            url: "........",//The resource that delivers loc data.
            dataType: "json"//The type of data tp be returned by the server.
        },
        delay: 10000,//(milliseconds) the interval between successive gets.
        errorCount: 0,//running total of ajax errors.
        errorThreshold: 5,//the number of ajax errors beyond which the get cycle should cease.
        ticker: null,//setTimeout reference - allows the get cycle to be cancelled with clearTimeout(ajaxObj.ticker);
        get: function() { //a function which initiates 
            if(ajaxObj.errorCount < ajaxObj.errorThreshold) {
                ajaxObj.ticker = setTimeout(getMarkerData, ajaxObj.delay);
            }
        },
        fail: function(jqXHR, textStatus, errorThrown) {
            console.log(errorThrown);
            ajaxObj.errorCount++;
        }
    };

    //Ajax master routine
    function getMarkerData() {
        $.ajax(ajaxObj.options)
          .done(setMarkers) //fires when ajax returns successfully
          .fail(ajaxObj.fail) //fires when an ajax error occurs
          .always(ajaxObj.get); //fires after ajax success or ajax error
    }

    setMarkers(locs);//Create markers from the initial dataset served with the document.
    //ajaxObj.get();//Start the get cycle.

    // *******************
    //test: simulated ajax
    /*
    var testLocs = {
        1: { info:'1. New Random info and new position', lat:-37, lng:124.9634 },//update info and position and 
        2: { lat:70, lng:14.5144 },//update position
        3: { info:'3. New Random info' },//update info
        4: { remove: true },//remove marker
        5: { info:'55555. Added', lat:-37, lng:0 }//add new marker
    };
    setTimeout(function() {
        setMarkers(testLocs);
    }, ajaxObj.delay);
    */
    // *******************
});

在代码的底部,您会找到一个 testLocs 数据集,展示了在应用初始数据集后添加/删除/更新标记的可能性范围。

我尚未完全测试 ajax,但已使用 testLocs 数据集对其进行了模拟。

DEMO

10 秒后,testLocs 将被应用,您将看到标记的各种变化(以及信息窗口中显示的信息)。请特别注意,更新数据不需要完整 - 只需指定更改即可。

您需要安排您的服务器:

  • 按照我的locs 示例构建初始数据集。
  • 按照我的testLocs 示例的一般格式返回 JSON 编码的数据集。

编辑 1

我已包含获取新数据集所需的所有客户端代码。您需要做的就是:

  • 创建一个服务器端脚本(例如“get_markers.php”),它返回正确格式的 json 编码数据集(如前所述)。
  • 编辑url: "........", 行以指向服务器端脚本,例如url: "get_markers.php"
  • 通过取消注释 ajaxObj.get(); 行来激活循环 ajax 进程。
  • 确保“模拟 ajax”代码块被注释掉或删除。

编辑 2

我添加了一个名为auto_remove 的布尔“行为开关”。设置为 true 时,将运行一小段额外的代码块,从而删除所有未报告位置的标记。

这将允许您在每次迭代时报告所有 活动 标记。移除将自动发生,无需主动命令它们。

响应{ remove: true } 的代码仍然存在,因此(将auto_remove 设置为false)可以在需要时明确命令删除。

更新DEMO

编辑 3

PHP 脚本应构建以下形式的数组:

<%php
$testLocs = array(
    'loc1' => array( 'info' => '1. New Random info and new position', 'lat' => 0, 'lng' => 144.9634 ),
    'loc2' => array( 'lat'  => 0, 'lng' => 14.5144 ),
    'loc3' => array( 'info' => '3. New Random info' ),
    'loc5' => array( 'info' => '55555. Added', 'lat' => 0, 'lng' => 60 )
);
echo json_encode($testLocs);
exit();
%>

我不确定 PHP 是否会处理数字键。如果不是,请尝试字符串,'1''2' 等。给所有键一个字母前缀可能是最安全的,例如。 'loc1''loc2' 等。无论您选择做什么,请确保 javascript locs 对象中的键具有相同的类型和组成。

【讨论】:

  • 我想更新特定标记取决于 json 对象 id 并保留其他标记位置。
  • 不是,不是吗?
  • 不知何故,我从来没有让 php 部分工作。我看到 php 从服务器中拉出,但它没有更新标记(只是删除了所有)。我也将 php 输出作为 test.json 并且再次,我看到它作为 mime 类型 json 从网络服务器中提取,但地图中没有任何反应。它不会在控制台中显示任何错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 2012-04-21
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 2013-12-28
相关资源
最近更新 更多