我想要做的是使用AJAX和JSON加载一堆地址,找出每个地址的纬度和经度,在地图上放置标记,然后使用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 :(得分:7)
好的,这就是我所学到的。
addressBounds
)并计算地理编码的地址数(address_count
)。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);
}
}
答案 1 :(得分:2)
使用其他变量在 top 的全局范围内定义边界对象的简单方法,然后根据找到的每个结果构建它(在地理编码器回调内)。 / p>
基本上,你想要用回调数据做的一切都需要在回调中或由回调触发的函数(如你所发现的那样)。但在这种情况下,您不需要单独的功能。浏览器应存储所有fitBounds
个操作,并仅执行最后一个操作。
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);
答案 2 :(得分:0)
我知道以下并不是严格相关的,但我已经在这方面苦苦挣扎了一段时间,我认为值得分享。 在使用DirectionsRenderer渲染多个方向请求之后,地图通常集中在最后一个渲染命令的结果上,尽管事实上我在发出最后一个渲染命令后发出了map.fitBounds并带有一个边界框以包含所有方向请求结果视。行为不是确定性的,有时视口集中在整个地图上,有时候是最后一个方向请求结果。解决方案是为渲染器设置preserveViewport:true,因此在显示方向请求结果后它永远不会更改地图的焦点,所以现在我可以使用fitbounds更改焦点。