Google Map V3--geocode与fitBounds方法的同步操作
google.maps.Geocoder類的geocode方法與google.maps.Map類的fitBounds都是異步方法, 在頁面上添加google map的引用就可以使用這些類, 現在的一個問題是我想頁面上所有map相關的數據加載完再進步下一步操作該如何實現?
場景
在select標簽中選擇一個城市后, 用異步方式與服務器會話并取回這個城市所有的蘋果專賣店的地址, div中顯示被選中的城市并用Marker標出所有的蘋果專賣店, 點擊輸入按鈕將適合的zoom level和地圖中心點坐標傳回服務端生成報表再輸出到客戶端
?
理想操作
上面按1, 2, 3的順序是一個理想化操作, 但實際情況是對地址進行geocode的過程是異步的, 調用的fitBounds方法也是異步的。也就是說當你點擊輸出按鈕時, 地圖并沒有完全設置好,這些蘋果專賣店的Marker可能在地圖上還沒有表示出來,? 而且一個城市的蘋果專賣店都比較分散, 可能不會在地圖中顯示所有的Marker。想解決這個問題就要同步gecode和fitBounds方法. 但是這兩上方法原生就是異步的, 沒有同步方法
?
解決辦法
添加2個int型變量, loadingItems和loadedItems。當添加Marker時將loadingItems的值自增1。調用geocode方法解析地址為LatLng對象,在回調函數中將loadedItems值自增1,并執行mapObj.fitBounds(results[0].geometry.viewport) 方法, fitBounds方法會引發bounds_changed事件. 在bounds_changed事件中, 如果loadingItems和loadedItems相等就證明所有Marker加載完畢, 并執行輸出按鈕的相應邏輯, 代碼如下
var mapObj = new google.maps.Map(document.getElementById(targetContainer), mapOptions);var bounds = new google.maps.LatLngBounds();
bounds.count = 0;
bounds.extendNew = function (latLng) {
this.extend(latLng);
this.count++;
};
function EventBind(target, eventName, func) {
var f = func;
google.maps.event.addListener(target, eventName, function (event) { func(event); });
}
EventBind(mapObj, "bounds_changed", function () {
if (loadingItems == loadedItems) {
if (allLoadedEvent != null) {
loadedItems = -1;
allLoadedEvent();
}
}
});
function AddMarkerWithBlurIcon(strAddress) {
var geocoder1 = new google.maps.Geocoder();
loadingItems++;
geocoder1.geocode({ "address": strAddress }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var markerImage = new google.maps.MarkerImage(
"http://maps.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png",
new google.maps.Size(20, 32),
new google.maps.Point(0, 0),
new google.maps.Point(0, 32)
);
loadedItems++;
mapObj.fitBounds(results[0].geometry.viewport);
bounds.extendNew(results[0].geometry.location);
var markerObj = new google.maps.Marker(
{
map: mapObj,
position: results[0].geometry.location,
icon: markerImage,
draggable: true
});
}
});
}
allLoadedEvent就是輸出按鈕的邏輯,allLoadedEvent在下面的方法中添加進來
function ExecuteWhenMapLoadedAll(action, runNow) {allLoadedEvent = action;
if (runNow == true) mapObj.fitBounds(bounds);
}
在bounds_changed事件中當loadingItems == loadedItems條件成立時就會自動執行allLoadedEvent 。?
另一個問題: 當頁面有多個地圖,? 只有所有地圖的數據全部加載完以后再執行相應的代碼
將上面的代碼封裝為一個名為GoogleMapHelper的函數, 假設有2個地圖,那么
var m1 = new GoogleMapHelper();var m2 = new GoogleMapHelper();
m1.Initialize();
m2..Initialize();
m1.ExecuteWhenMapLoadedAll(
function (){
/*m1的邏輯代碼*/
m2.ExecuteWhenMapLoadedAll(
function (){
/*最終需要執行的代碼*/
__doPostBack(“<%= this.btnReport.ClientID %>", "");
}, true);
}, false);
轉載于:https://www.cnblogs.com/terrysun/archive/2012/01/13/2321346.html
總結
以上是生活随笔為你收集整理的Google Map V3--geocode与fitBounds方法的同步操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Codeforces Global Ro
- 下一篇: 【集训心得】在真哥强迫下不得不写的总结