Google maps 使用Google Maps API v3进行地理编码-将原始请求链接到响应

Google maps 使用Google Maps API v3进行地理编码-将原始请求链接到响应,google-maps,asynchronous,google-maps-api-3,jquery-deferred,Google Maps,Asynchronous,Google Maps Api 3,Jquery Deferred,我有一个学校的名单,我想在谷歌地图上绘制。我正在使用查找给定邮政编码的lng/lat,成功检索此信息后,我希望删除一个标记,并添加相应的事件侦听器,当单击给定标记时,该事件侦听器将打开一个信息框 当我向地理编码器发出请求时,它是在学校的上下文中,当我收到回调时,我就失去了这个上下文。您将从下面的代码中看到,我提出了一个笨拙的解决方案,尽管当地理编码器结果截断邮政编码时,它偶尔会失败 我应该用类似的方法来解决这个问题吗 var geocoder; var map; var infowindow v

我有一个学校的名单,我想在谷歌地图上绘制。我正在使用查找给定邮政编码的lng/lat,成功检索此信息后,我希望删除一个标记,并添加相应的事件侦听器,当单击给定标记时,该事件侦听器将打开一个信息框

当我向地理编码器发出请求时,它是在学校的上下文中,当我收到回调时,我就失去了这个上下文。您将从下面的代码中看到,我提出了一个笨拙的解决方案,尽管当地理编码器结果截断邮政编码时,它偶尔会失败

我应该用类似的方法来解决这个问题吗

var geocoder;
var map;
var infowindow
var iterator = 0;
geosearch = new Array();

function drop() {
  for (var i = 0; i < schools.length; i++) {
    setTimeout(function() { // delay added to prevent being throttled
      addMarker();
      iterator++;
    }, i * 1000);
  }
}

function addMarker() {
  address = schools[iterator].addresses[0].address.zip;
  geosearch[address] = schools[iterator]; // this is how I'm keeping track of initial request

  geocoder.geocode( { 'address': address }, function(results, status) {
    var school = geosearch[results[0].address_components[0].short_name]; // loading the school associated with the initial request, which only works if the postcode completely matches up - clunky!

    if (status == google.maps.GeocoderStatus.OK) {

      // each school has tags, I want to set a marker if certain tags exist
      if ($.inArray('D', school.tags) > 0) {
        var image = 'map_markers/brown_MarkerD.png';
      } else if ($.inArray('C', school.tags) > 0) {
        var image = 'map_markers/red_MarkerC.png';
      } else if ($.inArray('B', school.tags) > 0) {
        var image = 'map_markers/yellow_MarkerB.png';
      } else if ($.inArray('A', school.tags) > 0) {
        var image = 'map_markers/green_MarkerA.png';
      } else {
        var image = 'map_markers/blue_MarkerZ.png';
      }

      // add the marker to the map, using result
      var marker = new google.maps.Marker({
          map: map,
          position: results[0].geometry.location,
          draggable: false,
          icon: image,
          shadow: 'http://www.google.com/mapfiles/arrowshadow.png',
          animation: google.maps.Animation.DROP
      });

      // adds listening on marker so that popup box appears when clicked
      google.maps.event.addListener(marker, 'click', (function(marker, school) {
        return function() {
          infowindow.setContent(
            '<a href="https://vitalcpd.highrisehq.com/companies/'+school.id+'" target="_blank">'+school.name+'</a>'
            +'<address>'
            +school.addresses[0].address.street+'<br />'
            +school.addresses[0].address.city+'<br />'
            +school.addresses[0].address.state+'<br />'
            +school.addresses[0].address.zip+'<br />'
            +school.addresses[0].address.country+'<br />'
            +'</address>');
          infowindow.open(map, marker);
        }
      })(marker, school));

    } else {
      console.log("* NOT found: " + status);
    }
  });
}

function initialise() {
  geocoder = new google.maps.Geocoder();
  infowindow = new google.maps.InfoWindow();
  var latlng = new google.maps.LatLng(54.82659788452641,-3.417279296874991);
  var mapOptions = {
    zoom: 6,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  drop(); // loops through schools to add marker
}
var地理编码器;
var映射;
var信息窗口
var迭代器=0;
geosearch=新数组();
函数drop(){
for(var i=0;i0){
var image='map_markers/brown_MarkerD.png';
}如果($.inArray('C',school.tags)>0,则为else){
var image='map_markers/red_MarkerC.png';
}如果($.inArray('B',school.tags)>0,则为else){
var image='map_markers/yellow_MarkerB.png';
}如果($.inArray('A',school.tags)>0,则为else){
var image='map_markers/green_MarkerA.png';
}否则{
var image='map_markers/blue_MarkerZ.png';
}
//使用结果将标记添加到地图
var marker=new google.maps.marker({
地图:地图,
位置:结果[0]。geometry.location,
可拖动:错误,
图标:图像,
影子:'http://www.google.com/mapfiles/arrowshadow.png',
动画:google.maps.animation.DROP
});
//添加监听标记,以便在单击时显示弹出框
google.maps.event.addListener(标记,'点击',(函数(标记,学校){
返回函数(){
infowindow.setContent(
''
+''
+学校。地址[0]。地址。街道+“
” +学校。地址[0]。地址。城市+“
” +school.address[0]。address.state+“
” +school.addresses[0]。address.zip+“
” +学校。地址[0]。地址。国家+“
” +''); 信息窗口。打开(地图、标记); } })(马克,学校); }否则{ console.log(“*未找到:+状态”); } }); } 函数初始化(){ geocoder=新的google.maps.geocoder(); infowindow=new google.maps.infowindow(); var latlng=new google.maps.latlng(54.82659788452641,-3.417279296874991); 变量映射选项={ 缩放:6, 中心:拉特林, mapTypeId:google.maps.mapTypeId.ROADMAP } map=new google.maps.map(document.getElementById(“map_canvas”),mapOptions); drop();//在学校中循环以添加标记 }
我建议脱机对地址进行地理编码,并将坐标存储在数据库中(或存储地址的任何位置)。然后使用坐标显示标记

我还建议进行审查


为了回答您的问题,我建议使用javascript函数闭包将地址与回调函数关联。

我在这里遇到的问题只是范围问题,特别是我在
addMarker()函数中引用学校的方式。我没有使用全局
迭代器
变量引用
学校
数组中的学校,而是传入该学校,这样在该范围内创建的回调上始终引用正确的学校

var geocoder;
var map;
var infowindow
var iterator = 0;

function drop() {
  for (var i = 0; i < schools.length; i++) {
    setTimeout(function() {
      addMarker(schools[iterator]); // pass in the school as an argument
      iterator++;
      $('#current_school').text(iterator); // taken this out of addMarker()
    }, i * 1000);
  }
}

function addMarker(school) {
  geocoder.geocode( { 'address': school.addresses[0].address.zip }, function(results, status) {
    ... // the inners from here remain the same
  });
}
var地理编码器;
var映射;
var信息窗口
var迭代器=0;
函数drop(){
for(var i=0;i
谢谢您的回答。我同意缓存坐标会更明智。目前,我更关心的是将回调响应与我用来发起地理编码请求的学校联系起来。我知道这与作用域/闭包有关,我是一个特别关注这一点的人。我想知道jQuery是否是组织这个范围的框架?对于提供回调的非阻塞请求,解决方案必须是通用的。函数闭包(一个geocodeAddress函数,它获取地址和任何其他必需信息,并将它们保存在函数闭包中)是我过去使用过的解决方案,并建议其他人解决此问题。jQuery Deferred似乎没有什么帮助(除非它真的减慢了地理编码过程),但我对此一无所知。我实际上不需要使用闭包,它实际上比我在回答中详细介绍的更简单。