Google Maps API v3:可以在fitBounds之后设置缩放吗?
我有一套要在embedded式Google地图(API v3)上绘制的点。 我希望边界能容纳所有点,除非缩放级别太低(即缩小得太多)。 我的方法是这样的:
var bounds = new google.maps.LatLngBounds(); // extend bounds with each point gmap.fitBounds(bounds); gmap.setZoom( Math.max(6, gmap.getZoom()) );
这不起作用。 如果直接在fitBounds之后调用,最后一行“gmap.setZoom()”不会更改地图的缩放级别。
有没有办法获得一个界限的缩放级别而不应用到地图? 其他想法来解决这个问题?
编辑 :请参阅下面的Matt Diamond的评论。
得到它了! 尝试这个:
map.fitBounds(bounds); var listener = google.maps.event.addListener(map, "idle", function() { if (map.getZoom() > 16) map.setZoom(16); google.maps.event.removeListener(listener); });
修改您的需求。
我在其中一个应用程序中解决了类似的问题。 你对这个问题的描述有点困惑,但是我认为你有同样的目标。
在我的应用程序,我想绘制一个或多个标记,并确保地图显示他们所有。 问题是,如果我完全依赖fitBounds方法,那么当有一个点时,缩放级别将被最大化 – 这是不好的。
解决方法是在有多个点时使用fitBounds,而只有一个点时使用setCenter + setZoom。
if (pointCount > 1) { map.fitBounds(mapBounds); } else if (pointCount == 1) { map.setCenter(mapBounds.getCenter()); map.setZoom(14); }
我已经多次来到这个页面来获得答案,虽然所有现有的答案都是超级有用的,但他们并没有完全解决我的问题。
google.maps.event.addListenerOnce(googleMap, 'zoom_changed', function() { var oldZoom = googleMap.getZoom(); googleMap.setZoom(oldZoom - 1); //Or whatever });
基本上我发现“zoom_changed”事件阻止了地图的UI从“跳过”,当我等待“空闲”事件时发生。
希望这有助于某人!
我刚刚通过提前设置maxZoom来解决这个问题,然后将其删除。 例如:
map.setOptions({ maxZoom: 15 }); map.fitBounds(bounds); map.setOptions({ maxZoom: null });
如果我没有弄错,我假设你想让所有的点在地图上以尽可能高的缩放级别显示。 我通过将地图的缩放级别初始化为16来完成这个任务(不确定它是否是V3上最高的缩放级别)。
var map = new google.maps.Map(document.getElementById('map_canvas'), { zoom: 16, center: marker_point, mapTypeId: google.maps.MapTypeId.ROADMAP });
之后,我做了界限的东西:
var bounds = new google.maps.LatLngBounds(); // You can have a loop here of all you marker points // Begin loop bounds.extend(marker_point); // End loop map.fitBounds(bounds);
结果:成功!
我用:
gmap.setZoom(24); //this looks a high enough zoom value gmap.fitBounds(bounds); //now the fitBounds should make the zoom value only less
这将根据您的代码使用较小的24位和必要的缩放级别,但它可能会改变缩放比例,并不关心缩小多less。
有同样的问题,需要适应在地图上的许多标记。 这解决了我的情况:
- 声明边界
- 使用koderoid提供的scheme(对于每个标记集
bounds.extend(objLatLng)
) -
在地图完成后执行fitbounds:
google.maps.event.addListenerOnce(map, 'idle', function() { map.fitBounds( bounds ); });
我find了一个解决scheme,在调用fitBounds
之前进行检查,以便您不放大并突然缩小
var bounds = new google.maps.LatLngBounds(); // extend bounds with each point var minLatSpan = 0.001; if (bounds.toSpan().lat() > minLatSpan) { gmap.fitBounds(bounds); } else { gmap.setCenter(bounds.getCenter()); gmap.setZoom(16); }
你将不得不玩弄minLatSpanvariables来获得它想要的位置。 它将根据缩放级别和地图canvas的尺寸而变化。
您也可以使用经度而不是纬度
请试试这个:
map.fitBounds(bounds); // CHANGE ZOOM LEVEL AFTER FITBOUNDS zoomChangeBoundsListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) { if (this.getZoom()){ this.setZoom(15); } }); setTimeout(function(){ google.maps.event.removeListener(zoomChangeBoundsListener) }, 2000);
我使用它来确保缩放级别不超过设定的级别,以便我知道卫星图像将可用。
将侦听器添加到zoom_changed
事件。 这还具有在UI上控制缩放控制的额外好处。
只有在需要的时候才执行setZoom
,所以if
语句优于Math.max
或Math.min
google.maps.event.addListener(map, 'zoom_changed', function() { if ( map.getZoom() > 19 ) { map.setZoom(19); } }); bounds = new google.maps.LatLngBounds( ... your bounds ... ) map.fitBounds(bounds);
为了防止缩小太多:
google.maps.event.addListener(map, 'zoom_changed', function() { if ( map.getZoom() < 6 ) { map.setZoom(6); } }); bounds = new google.maps.LatLngBounds( ... your bounds ... ) map.fitBounds(bounds);
在这个函数中,只需要dynamic添加元数据来存储几何types,因为函数接受任何几何。
“fitGeometries”是扩展地图对象的JSON函数。
“几何”是一个通用的JavaScript数组而不是MVCArray()。
geometry.metadata = { type: "point" }; var geometries = [geometry]; fitGeometries: function (geometries) { // go and determine the latLngBounds... var bounds = new google.maps.LatLngBounds(); for (var i = 0; i < geometries.length; i++) { var geometry = geometries[i]; switch (geometry.metadata.type) { case "point": var point = geometry.getPosition(); bounds.extend(point); break; case "polyline": case "polygon": // Will only get first path var path = geometry.getPath(); for (var j = 0; j < path.getLength(); j++) { var point = path.getAt(j); bounds.extend(point); } break; } } this.getMap().fitBounds(bounds); },
我有同样的问题,我能够解决它使用下面的代码。 这个监听器( google.maps.addListenerOnce()
)事件只会在map.fitBounds()
执行后被触发一次。 所以没有必要
- 跟踪并手动删除侦听器,或
- 等到地图
idle
。
它最初设置适当的缩放级别,并允许用户放大和缩小超过初始缩放级别,因为事件监听器已经过期。 例如,如果仅调用google.maps.addListener()
,则用户将永远无法放大超过所述缩放级别(在这种情况下为4)。 由于我们实现了google.maps.addListenerOnce()
,用户将能够放大到他/她select的任何级别。
map.fitBounds(bounds); var zoom_level_for_one_marker = 4; google.maps.event.addListenerOnce(map, 'bounds_changed', function(event){ if (this.getZoom() >= zoom_level_for_one_marker){ this.setZoom(zoom_level_for_one_marker) } });
这项工作对我来说是API v3,但是设置固定缩放:
var bounds = new google.maps.LatLngBounds(); // extend bounds with each point gmap.setCenter(bounds.getCenter()); gmap.setZoom( 6 );
像我一样,如果你不愿意和听众一起玩,这是一个简单的解决scheme:在地图上添加一个严格按照你的要求工作的方法:
map.fitLmtdBounds = function(bounds, min, max){ if(bounds.isEmpty()) return; if(typeof min == "undefined") min = 5; if(typeof max == "undefined") max = 15; var tMin = this.minZoom, tMax = this.maxZoom; this.setOptions({minZoom:min, maxZoom:max}); this.fitBounds(bounds); this.setOptions({minZoom:tMin, maxZoom:tMax}); }
那么你可以调用map.fitLmtdBounds(bounds)
来代替map.fitBounds(bounds)
来设置在定义的缩放范围下的边界…或map.fitLmtdBounds(bounds,3,5)
来覆盖缩放范围。
我看到许多不正确或太复杂的解决scheme,因此决定发布一个工作,优雅的解决scheme 。
setZoom()
不能正常工作,因为fitBounds()
是asynchronous的,所以不能保证它会立即更新缩放,但是你对setZoom()
调用依赖于它。
您可能会考虑的是在调用fitBounds()
之前设置minZoom
映射选项,然后在完成之后清除它(以便用户仍然可以手动缩放):
var bounds = new google.maps.LatLngBounds(); // ... (extend bounds with all points you want to fit) // Ensure the map does not get too zoomed out when fitting the bounds. gmap.setOptions({minZoom: 6}); // Clear the minZoom only after the map fits the bounds (note that // fitBounds() is asynchronous). The 'idle' event fires when the map // becomes idle after panning or zooming. google.maps.event.addListenerOnce(gmap, 'idle', function() { gmap.setOptions({minZoom: null}); }); gmap.fitBounds(bounds);
另外,如果您还想限制最大缩放maxZoom
,则可以使用与maxZoom
属性相同的技巧。
请参阅MapOptions文档 。
请试试这个。
// Find out what the map's zoom level is zoom = map.getZoom(); if (zoom == 1) { // If the zoom level is that low, means it's looking around the world. // Swap the sw and ne coords viewportBounds = new google.maps.LatLngBounds(results[0].geometry.location, initialLatLng); map.fitBounds(viewportBounds); }
如果这对你有帮助。
祝一切顺利
经过计算的边界,你可以检查左上angular和右下angular之间的距离; 那么您可以通过testing距离来了解缩放级别(如果距离太远,缩放级别将会很低),那么您可以使用setbound方法或setZoom来select它。
我不喜欢提出这个build议,但如果你必须尝试 – 首先打电话
gmap.fitBounds(bounds);
然后创build一个新的线程/ AsyncTask,让它hibernate20-50ms左右,然后调用
gmap.setZoom( Math.max(6, gmap.getZoom()) );
从UI线程(使用处理程序或AsyncTask的onPostExecute
方法)。
我不知道它是否有效,只是一个build议。 除此之外,你必须以某种方式自己计算你的点的缩放级别,检查它是否太低,纠正它,然后调用gmap.setZoom(correctedZoom)
google.maps.event.addListener(marker, 'dblclick', function () { var oldZoom = map.getZoom(); map.setCenter(this.getPosition()); map.setZoom(parseInt(oldZoom) + 1); });
如果“bounds_changed”没有正确触发(有时Google似乎完全不接受坐标),那么请考虑使用“center_changed”。
每当调用fitBounds()时,会触发'center_changed'事件,虽然它会立即运行,而不一定在地图移动之后运行。
在正常情况下,“闲置”仍然是最好的事件监听器,但这可能会帮助一对夫妇用fitBounds()调用遇到奇怪的问题。
请参阅Google地图fitBoundscallback
我所做的只是:
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
它适用于V3 API。