有没有办法设置最大变焦水平fitBounds()
?我的问题是,当地图仅提供一个位置时,地图将尽可能放大,这实际上使地图脱离了上下文,并使其变得无用。也许我采用了错误的方法?
提前致谢!
Answers:
我喜欢mrt的解决方案(尤其是当您不知道要映射或调整多少个点时),除了它会抛弃标记使其不再位于地图中心之外。我只是简单地将其扩展了一个点,即从经度和经度中也减去了0.01,因此将标记保持在中心。效果很好,谢谢!
// Pan & Zoom map to show all markers
function fitToMarkers(markers) {
var bounds = new google.maps.LatLngBounds();
// Create bounds from markers
for( var index in markers ) {
var latlng = markers[index].getPosition();
bounds.extend(latlng);
}
// Don't zoom in too far on only one marker
if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - 0.01, bounds.getNorthEast().lng() - 0.01);
bounds.extend(extendPoint1);
bounds.extend(extendPoint2);
}
map.fitBounds(bounds);
// Adjusting zoom here doesn't work :/
}
fitBounds()
的方法是因为变焦异步发生:stackoverflow.com/questions/2989858/...
您可以像这样maxZoom
在MapOptions
(api-reference)中设置地图:
var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });
这将使地图在使用时无法进一步放大fitBounds()
,甚至从缩放控件中删除缩放级别。
maxZoom
在适合边界之前进行设置,然后map.setOptions({ maxZoom: undefined })
在idle
通过更改边界触发的事件上再次将其取消设置。这样可以防止放大,缩小的效果,而是在idle
事件中重置缩放。
另一个解决方案是,如果在执行fitBounds()之前检测到边界太小,则扩大边界:
var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like
// ...
if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
var extendPoint = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
bounds.extend(extendPoint);
}
map.fitBounds(bounds);
一旦添加了所有实边界,请添加以下行
var offset = 0.002;
var center = bounds.getCenter();
bounds.extend(new google.maps.LatLng(center.lat() + offset, center.lng() + offset));
bounds.extend(new google.maps.LatLng(center.lat() - offset, center.lng() - offset));
它得到了真实边界的中心,然后向中心再加上两个附加点,一个指向东北,另一个指向西南
有效设置最小缩放,更改偏移值以增加或减小缩放
我阻止地图放大的方法是添加以下代码:
var zoomOverride = map.getZoom();
if(zoomOverride > 15) {
zoomOverride = 15;
}
map.setZoom(zoomOverride);
在此行之后:
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
随意将缩放级别更改为您不希望地图缩放到的级别。
如果您有任何问题或疑问,请在http://icode4you.net/creating-your-own-store-locator-map-how-to-prevent-the-单个标记的缩放过近导致地图放大
我真的很喜欢mrt的解决方案,如果您总是只有一点可以使用,那么它非常适合。但是,我确实发现,如果边界框不是基于一个点,而是这些点非常靠近,则仍然可能导致地图放大得太远。
这是一种方法,首先检查这些点之间是否在定义的距离内,然后如果它们小于最小距离,则将边界扩大该最小距离:
var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like
// ...
var minDistance = 0.002;
var sumA = bounds.getNorthEast().lng() - bounds.getSouthWest().lng();
var sumB = bounds.getNorthEast().lat() - bounds.getSouthWest().lat();
if((sumA < minDistance && sumA > -minDistance)
&& (sumB < minDistance && sumB > -minDistance)){
var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + minDistance, bounds.getNorthEast().lng() + minDistance);
var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - minDistance, bounds.getNorthEast().lng() - minDistance);
bounds.extend(extendPoint1);
bounds.extend(extendPoint2);
}
希望这对某人有帮助!
这样可以直接控制最大允许缩放的边界拟合。
var fitToMarkers = function(map, markers, maxZoom) {
if (typeof maxZoom == 'undefined') maxZoom = 15;
google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
if (this.getZoom() > maxZoom) {
this.setZoom(maxZoom);
}
});
var bounds = new google.maps.LatLngBounds();
for (var m = 0; m < markers.length; m++) {
var marker = markers[m];
var latlng = marker.getPosition();
bounds.extend(latlng);
}
map.fitBounds(bounds);
};
对于我来说,我通过在fitBounds之后创建一个空闲事件来解决它。工作完美。猜猜这是这里最干净的解决方案之一
var locations = [['loc', lat, lng], ['loc', lat, lng]];
.....
for (i = 0; i < locations.length; i++) {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10
});
.... create markers, etc.
}
....
map.fitBounds(bounds);
google.maps.event.addListenerOnce(map, 'idle', function() {
if (locations.length == 1) {
map.setZoom(11);
}
});
我解决了这个问题,因为Google Maps V3是事件驱动的:
您可以告诉API在zoom_changed事件触发时将缩放比例设置回适当的值:
var initial = true
google.maps.event.addListener(map, "zoom_changed", function() {
if (intial == true){
if (map.getZoom() > 11) {
map.setZoom(11);
intial = false;
}
}
});
当最终fitBounds偏移时,我使用初始使地图不会缩放太多负载,如果没有它,用户将无法进行超过11的缩放事件。
我有基于限制边界时最大变焦的解决方案。为我工作(在Win 7-IE 9,FF 13,Chrome 19上测试):
// When fitting bounds:
var bounds = new google.maps.LatLngBounds();
// ...
// extend bounds as you like
// ..
// now set global variable when fitting bounds
window.fittingBounds = true;
map.fitBounds(bounds);
window.fittingBounds = false;
// attach this event listener after map init
google.maps.event.addListener(map, 'zoom_changed', function() {
// set max zoom only when fitting bounds
if (window.fittingBounds && map.getZoom() > 16) {
this.setZoom(16);
}
});
还有..这是另一个。
与MRT和Ryan的想法相同,但
(*)注意:如果该框已经足够大,则将这两个额外的点相加将无效。因此,我们不需要任何进一步的检查。
function calcBounds(markers) {
// bounds that contain all markers
var bounds = new google.maps.LatLngBounds();
// Using an underscore _.each(). Feel free to replace with standard for()
_.each(markers, function(marker) {
bounds.extend(marker.getPosition());
});
// prevent lat/lng distortion at the poles
var lng0 = bounds.getNorthEast().lng();
var lng1 = bounds.getSouthWest().lng();
if (lng0 * lng1 < 0) {
// Take the cos at the equator.
var cos = 1;
}
else {
var cos0 = Math.cos(lng0);
var cos1 = Math.cos(lng1);
// Prevent division by zero if the marker is exactly at the pole.
var cos_safe = Math.max(cos0, cos1, 0.0001);
}
var cos0 = Math.cos(bounds.getNorthEast.lng() * Math.PI / 180);
var cos1 = Math.cos(bounds.getSouthWest.lng() * Math.PI / 180);
// "radius" in either direction.
// 0.0006 seems to be an ok value for a typical city.
// Feel free to make this value a function argument.
var rLat = 0.0006;
var rLng = rLat / cos_safe;
// expand the bounds to a minimum width and height
var center = bounds.getCenter();
var p0 = new google.maps.LatLng(center.lat() - rLat, center.lng() - rLng);
var p1 = new google.maps.LatLng(lat.center() + rLat, center.lng() + rLng);
bounds.extend(p0);
bounds.extend(p1);
return bounds;
}
编辑:考虑到我们有墨卡托投影,我不确定我的比率计算是否正确。我可能会重新编辑。
它已经在这里回答了Google Maps v3:执行分钟。使用fitBounds时的缩放级别可以按预期的方式工作:)所以现在,如果在适合范围之后缩放小于13,则可以设置新的缩放比例
这是我的解决方法,当两个标记非常接近时也可以使用。在两种情况下,有效的最大缩放级别均相同。因此,当有多个标记时,我们不会不必要地缩小图像
这种效果再次确保了最大的缩放,而没有使用maxZoom选项,这可能导致不必要的效果,使用户无法使用缩放控件将其缩放到超过maxZoom级别的水平。
我已经预先计算了maxLat,minLat,maxLng和minLng ...
var minLatSpan = 0.002;
if (maxLat - minLat < minLatSpan) {
// ensures that we do not zoom in too much
var delta = (minLatSpan - (maxLat - minLat)) / 2;
maxLat += delta;
minLat -= delta;
}
map.fitBounds({
east: maxLng,
west: minLng,
north: maxLat,
south: minLat,
});