2012-07-04 126 views
4

我想要做的是加載了一堆使用AJAX和JSON的地址,找出每個地址的經度和緯度,把標記在地圖上,然後用fitBounds()放大以便所有標記都可見。聽起來很簡單。谷歌地圖API V3 - 多個地理編碼後fitBounds請求

我已經得到了大部分的打包,但我的問題是fitBounds()部分。

基本上看來,發生的事情是在循環每個地址並查找經度和緯度的同時,似乎在循環下面加載了fitBounds()函數。

所以它調用fitBounds(),但不具備marker_bounds陣列中的任何東西。我以爲它會在完成fitBounds()函數之前完成循環,但我認爲geocoder.geocode()函數必須使它在繼續加載其餘的JavaScript代碼時確定經度和緯度。

我的代碼如下:

var geocoder; 
var map; 
var marker_bounds = []; 

var myOptions = { 
    zoom: 12, 
    mapTypeId: google.maps.MapTypeId.ROADMAP 
} 
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);  

$.post('addresses.php', function(data) { 

    var next_filter = '';   
    for(var x=0;x<data.addresses.length;x++) { 

     geocoder.geocode({ 'address': data.addresses[x].address}, function(results, status) { 

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

       marker = new google.maps.Marker({ 
        map: map, 
        position: results[0].geometry.location 
       }); 

       var latLng = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng()); 
       marker_bounds.push(latLng);    
      } 

     });    
    } 

    var latlngbounds = new google.maps.LatLngBounds(); 
    for (var i = 0; i < marker_bounds.length; i++) { 
     latlngbounds.extend(marker_bounds[i]); 
    } 
    map.setCenter(latlngbounds.getCenter()); 
    map.fitBounds(latlngbounds); 

}, 'json'); 

是否有所有地理編碼完成後,我可以調用一個函數?

+0

我一直在做更多的挖掘,似乎地理編碼方法使一個asynchonous調用,它可以解釋爲什麼我的功能是整理和地理編碼完成之前返回長。有沒有辦法確定所有地理編碼方法何時完成? –

回答

6

好的,這是我學到的東西。

  1. 地理編碼方法,使一個asynchonous調用,這樣做是在地理編碼前在該過程中查找地址地理編碼方法是在頁面將完成長。
  2. 您需要調用運行地理編碼方法實施後的功能(addressBounds)和指望它有多少地址地理編碼(address_count)。
  3. 每次調用addressBounds函數時,檢查是否查找了所有地址(if (total_addresses == address_count)),然後運行fitBounds()函數。

我的最終代碼

var geocoder; 
var map; 
var markerBounds = []; 

var myOptions = { 
    zoom: 4, 
    mapTypeId: google.maps.MapTypeId.ROADMAP 
} 
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);  

google.maps.event.addListenerOnce(map, 'idle', function(){ 

    $.post('addresses.php', function(data) { 

     var total_addresses = data.addresses.length;    
     var address_count = 0; 
     for(var x=0;x<total_addresses;x++) {  

      geocoder.geocode({ 'address': data.addresses[x].address }, function(results, status) { 

       address_count++;   

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

        marker = new google.maps.Marker({ 
         map: map, 
         position: results[0].geometry.location 
        }); 

        var infowindow = new google.maps.InfoWindow(); 
        infowindow.setContent(address); 
        google.maps.event.addListener(marker, 'click', function() { 
         infowindow.open(map, marker); 
        }); 

        var myLatLng = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());      
        addressesBounds(total_addresses, address_count, myLatLng); 

       } 

      }); 

     } 

    }, 'json'); 

}); 

function addressesBounds(total_addresses, address_count, myLatLng) { 

    markerBounds.push(myLatLng); 

    // make sure you only run this function when all addresses have been geocoded 
    if (total_addresses == address_count) { 
     var latlngbounds = new google.maps.LatLngBounds(); 
     for (var i = 0; i < markerBounds.length; i++) { 
      latlngbounds.extend(markerBounds[i]); 
     } 
     map.setCenter(latlngbounds.getCenter()); 
     map.fitBounds(latlngbounds); 
    } 
} 
+0

並且不可能同時做所有事情? –

+0

@RodrigoMoreno我還沒有重建這個代碼,因此我無法回答這個問題。我相信他們可能在當前和現在都有所改進。 –

2

做它來定義你的邊界在該頂部與其他變量全局範圍內對象,然後與每個結果構造它的最簡單的方式,因爲它的發現(在地理編碼器回調中)。

基本上,你想與回調的數據盡一切需要在回調或回調觸發的功能(如你發現)。但在這種情況下,您不需要單獨的功能。瀏覽器應該存儲所有的操作,只做最後一個操作。

var latLng = new google.Maps.LatLng(
          results[0].geometry.location.lat(), 
          results[0].geometry.location.lng()); 
marker_bounds.push(latLng); 
latlngbounds.extend(latLng); 
map.fitBounds(latlngbounds); 

如果有必要(因爲你的瀏覽器是速度不夠快,做fitBounds每一個地址),你可以跟蹤多少結果實際上已經在另一個變量返回,像你address_count,並測試你是否有所有的結果在做fitBounds之前。也就是說,您的輔助功能可以併入地理編碼回調。

var latLng = new google.Maps.LatLng(
          results[0].geometry.location.lat(), 
          results[0].geometry.location.lng()); 
marker_bounds.push(latLng); 
latlngbounds.extend(latLng); 
address_count++; 
if (address_count == data.addresses.length) map.fitBounds(latlngbounds); 
0

我知道下面是不是嚴格相關,但我一直在這個掙扎了很長一段時間,我認爲這是值得分享。 與呈遞的DirectionsRenderer多個方向的請求後,地圖是通常集中在最後的渲染命令的結果,儘管我發出map.fitBounds發出最後的渲染邊界框的命令包括所有在指引請求之後的結果其實視口。行爲不是確定性的,有時候視口集中在整個地圖上,有時在最後的方向請求結果上。解決的辦法是設置preserveViewport,用於:真正的渲染器,所以顯示方向請求結果後,它永遠不會改變地圖的焦點,所以現在我能夠與fitbounds來改變焦點。

+0

這是一個答案? –

相關問題