Google Map V3--geocode与fitBounds方法的同步操作

google.maps.Geocoder类的geocode方法与google.maps.Map类的fitBounds都是异步方法, 在页面上添加google map的引用就可以使用这些类, 现在的一个问题是我想页面上所有map相关的数据加载完再进步下一步操作该如何实现?

场景

  1. 页面中有一个Select标签, 存放全国各城市的信息,
  2. 一个640px高度和宽度的正方型div, 用来加载地图.
  3. 一个输出按钮

在select标签中选择一个城市后, 用异步方式与服务器会话并取回这个城市所有的苹果专卖店的地址, div中显示被选中的城市并用Marker标出所有的苹果专卖店, 点击输入按钮将适合的zoom level和地图中心点坐标传回服务端生成报表再输出到客户端

 

理想操作

  1. 选择一个城市
  2. div中显示对应的城市并标出所有苹果专卖店
  3. 点击输出按输出一张报表并内嵌一个地图

上面按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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值