惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
D
Docker
Blog — PlanetScale
Blog — PlanetScale
罗磊的独立博客
美团技术团队
V
V2EX
Last Week in AI
Last Week in AI
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Microsoft Security Blog
Microsoft Security Blog
Microsoft Azure Blog
Microsoft Azure Blog
人人都是产品经理
人人都是产品经理
M
MIT News - Artificial intelligence
P
Proofpoint News Feed
B
Blog RSS Feed
博客园_首页
B
Blog
博客园 - 叶小钗
I
InfoQ
WordPress大学
WordPress大学
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
About on SuperTechFans
The GitHub Blog
The GitHub Blog
The Register - Security
The Register - Security
MyScale Blog
MyScale Blog
云风的 BLOG
云风的 BLOG
博客园 - 司徒正美
Latest news
Latest news
W
WeLiveSecurity
T
The Exploit Database - CXSecurity.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
aimingoo的专栏
aimingoo的专栏
小众软件
小众软件
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CERT Recently Published Vulnerability Notes
C
CXSECURITY Database RSS Feed - CXSecurity.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
N
News and Events Feed by Topic
S
Secure Thoughts
The Hacker News
The Hacker News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News

博客园 - Terry Sun

Ubuntu安装Java7 SDK Postgres整理 RESTful架构API的设计误区 解决createdb: could not connect to database postgres: FATAL: Peer authentication failed for user &quot;postgres&quot; 如何升级Nginx到最新稳定版 The remote name could not be resolved:&#39;maps.googleapis.com&#39; 的解决办法 关于Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80070005的解决办法 [iOS]黑色状态栏 圆角内容区 No connection could be made because the target machine actively refused it 127.0.0.1:808 的解决办法 ADO.NET Entity Framework--不再查询直接更新数据 安装SSL证书-解决导入证书时的ASN1 bad tag value met错误 解决 The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>) - Terry Sun &lt;转&gt;用HTML判断IE版本 关于Master Page的css和js文件引用问题 ASP.NET Mvc 2.0 - 2. 异步Controller执行流程时序图 [转载]ASP.NET 2.0 中的异步页 ASP.NET Mvc 2.0 - 1. Areas的创建与执行 深入分析 ASP.NET Mvc 1.0 – 4. 使用ModelBinder绑定Action的参数 深入分析 ASP.NET Mvc 1.0 – 3. Controller.Execute(Request)-ActionInvoker.InvokeAction()
Google Map V3--geocode与fitBounds方法的同步操作
Terry Sun · 2012-01-13 · via 博客园 - Terry Sun

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