jQuery 仅限 Google Map v3 自动刷新标记

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14771422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:54:10  来源:igfitidea点击:

Google Map v3 auto refresh Markers only

jqueryhtmlajax

提问by chillers

I'm using Google Maps V3 to display some pins. I want to be able to refresh markers without affecting where you're at on the map or the zoom level. I want the markers to be updated every x seconds.

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

How would I go about doing this? I don't have that much experience with jQuery/ajax.

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

A working example of my map is below.

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

http://jsfiddle.net/dLWNc/

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));
}

Thank you

谢谢

回答by Beetroot-Beetroot

OK, I've got something working - largely a heavy refactoring of your original code - you will recognize various chunks.

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

$(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);
    */
    // *******************
});

At the bottom of the code, you'll find a testLocsdataset, demonstrating the range of possibilities for adding/removing/updating markers after the initial dataset has been applied.

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

I've not tested the ajax fully, but have simulated it with the testLocsdataset.

我还没有完全测试 ajax,但已经用testLocs数据集模拟了它。

See DEMO

演示

After 10 seconds, testLocswill be applied and you will see various changes to the markers (and the info displayed in the infowindow). Note in particular that update data doesn't need to be complete - just specify the changes.

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

You will need to arrange for your server to :

您需要安排您的服务器:

  • build the initial dataset, following my locsexample.
  • return JSON-encoded datasets, following the general format of my testLocsexample.
  • 按照我的locs示例构建初始数据集。
  • 返回 JSON 编码的数据集,遵循我的testLocs示例的一般格式。

EDIT 1

编辑 1

I have included all the client-side code necessary for fetching new datasets. All you need to do is :

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

  • create a server-side script (eg. "get_markers.php") which returns a json-encoded dataset of the right format (as already exaplined).
  • edit the line url: "........",to point to the server-side script, eg url: "get_markers.php".
  • activate the cyclic ajax process by uncommenting the line ajaxObj.get();.
  • ensure the "simulated ajax" code block is commented out or removed.
  • 创建一个服务器端脚本(例如“get_markers.php”),它返回一个正确格式的 json 编码数据集(如已经解释过的)。
  • 编辑该行url: "........",以指向服务器端脚本,例如url: "get_markers.php".
  • 通过取消注释行来激活循环 ajax 进程ajaxObj.get();
  • 确保“模拟 ajax”代码块被注释掉或删除。

EDIT 2

编辑 2

I have added a boolean "behavioural switch" named auto_remove. When set to true, a small additional block of code will run, causing all markers for unreported locs to be removed.

我添加了一个名为auto_remove. 当设置为 true 时,将运行一小段额外的代码块,导致所有未报告位置的标记被删除。

This will allow you to report all activemarkers at every iteration. Removals will happen automatically, without needing to actively command them.

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

The code which responds to { remove: true }is still in place, so (with auto_removeset to false) removals can be expressly commanded if you ever need to do so.

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

Updated DEMO

更新的演示

EDIT 3

编辑 3

The PHP script should build an array of the following form :

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();
%>

I'm not sure whether PHP will handle numeric keys. If not, then try strings, '1', '2'etc. It's probably safest to give all keys an alphabetic prefix, eg. 'loc1', 'loc2'etc. Whatever you choose to do, make sure the keys in the javascript locsobject are of the same type and composition.

我不确定 PHP 是否会处理数字键。如果没有,那么试试字符串'1''2'等等。这也可能是最安全的给所有按键字母前缀,例如。'loc1''loc2'等等。无论你选择做什么,请务必在JavaScript的按键locs对象是同一类型和组成。