我想在嵌入式 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()”不会更改地图的缩放级别。

有没有办法获得边界的缩放级别而不将其应用于地图?还有其他想法来解决这个问题吗?

有帮助吗?

解决方案

修改:请参见下面马特·戴蒙的意见

明白了!尝试这样:

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个较小的和必要的缩放级别,根据你的代码,但它可能是反正改变变焦,不会在乎你有多少缩小。

我遇到了同样的问题,并且能够使用以下代码解决它。这位听众(google.maps.addListenerOnce()) 事件只会在之后被触发一次 map.fitBounds() 被执行。所以,没有必要

  1. 跟踪并手动删除侦听器,或者
  2. 等到地图出现 idle.

它最初设置适当的缩放级别,并允许用户放大和缩小超过初始缩放级别,因为事件侦听器已过期。例如,如果仅 google.maps.addListener() 被调用,然后用户将 绝不 能够放大超过指定的缩放级别(在本例中为 4)。自从我们实施 google.maps.addListenerOnce(), ,用户将能够缩放到他/她选择的任何级别。

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

遇到同样的问题,需要在地图上放置许多标记。这解决了我的情况:

  1. 声明边界
  2. 使用koderoid提供的方案(对于每个标记集 bounds.extend(objLatLng))
  3. 地图完成后执行 fitbounds:

    google.maps.event.addListenerOnce(map, 'idle', function() { 
        map.fitBounds( bounds );
    });
    

我已经找到了一个解决方案,它检查调用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);
}

您将不得不玩的minLatSpan变量位得到它,你想要的。它会根据两个缩放级别和地图画布的尺寸。

您也可以使用经度纬度,而不是

请试试这个:

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

我看到了许多不正确或过于复杂的解决方案,因此决定发布的工作,优雅的解决方案

如您所愿setZoom()不工作的原因是fitBounds()是异步的,所以它不保证它会立即更新缩放,但你要setZoom()呼叫依赖于这一点。

但您可能考虑的是设置呼叫minZoomfitBounds()地图选项,然后将它完成后(使用户仍然可以手动缩小,如果他们愿意的话)将其清除:

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财产适用同样的伎俩。

请参阅的MapOptions文档

我用这个来确保缩放级别,这样我知道卫星图像将提供不超过设定的水平。

将侦听器添加到zoom_changed事件。 这具有控制在UI上也将变焦控制的附加益处。

如果需要

仅执行setZoom,所以一个if语句优选Math.maxMath.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);

在此功能时,需要动态元数据添加到仅存储,因为该函数接受任何几何几何类型。

“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);
},

这工作对我有API V3而是设置固定变焦:

var bounds = new google.maps.LatLngBounds();
// extend bounds with each point

gmap.setCenter(bounds.getCenter()); 
gmap.setZoom( 6 );

我一样,如果你是不是愿意跟听众打,这是一个简单的解决方案,我想出了: 添加在地图上的一个方法,根据您的要求像这样的作品严格:

    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) 以覆盖变焦范围..

请试试这个。

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

如果这将帮助你。

所有的最佳

boundries的计算之后可以检查左上角和右下角之间的距离;然后就可以通过测试距离(如果距离太远缩放水平将是低)理解的变焦水平,那么可以选择使用wheter方法setbound或setZoom ..

我不喜欢建议它,但如果你的必须的尝试 - 首次调用

gmap.fitBounds(bounds);

然后创建新的线程/的AsyncTask,有它睡20-50ms左右,然后调用

gmap.setZoom( Math.max(6, gmap.getZoom()) );

从UI线程(使用的处理程序或用于所述的AsyncTask方法onPostExecute)。

我不知道,如果它的工作原理,只是一个建议。除此之外,你必须以某种方式从你的观点你自己计算的缩放级别,检查它是否过低,纠正它,然后只需调用gmap.setZoom(correctedZoom)

如果“的bounds_changed”是不正确射击(有时谷歌似乎并不完全接受坐标),那么可以考虑使用“center_changed的”代替。

在“center_changed的”事件触发每次fitBounds()被调用时,虽然它的地图已经移动之后立即和不运行一定。

在正常情况下,“空闲”仍然是最好的事件监听器,但是这可能会帮助运行与他们fitBounds奇怪的问题了几个人()调用。

请参阅谷歌地图fitBounds回调

要与其他解决方案附和 - 我发现,“监听bounds_changed事件,然后设置新的缩放”的做法并没有为我工作可靠。我想,我有时打电话fitBounds地图已经完全初始化之前,并且初始化是造成这会使用监听器,前fitBounds改变了边界和缩放级别的bounds_changed事件。我结束了这段代码,这似乎是迄今为止工作:

// If there's only one marker, or if the markers are all super close together,
// `fitBounds` can zoom in too far. We want to limit the maximum zoom it can
// use.
//
// `fitBounds` is asynchronous, so we need to wait until the bounds have
// changed before we know what the new zoom is, using an event handler.
//
// Sometimes this handler gets triggered by a different event, before
// `fitBounds` takes effect; that particularly seems to happen if the map
// hasn't been fully initialized yet. So we don't immediately remove the
// listener; instead, we wait until the 'idle' event, and remove it then.
//
// But 'idle' might happen before 'bounds_changed', so we can't set up the
// removal handler immediately. Set it up in the first event handler.

var removeListener = null;
var listener = google.maps.event.addListener(map, 'bounds_changed', () => {
  console.log(map.getZoom());
  if (map.getZoom() > 15) {
    map.setZoom(15);
  }

  if (!removeListener) {
    removeListener = google.maps.event.addListenerOnce(map, 'idle', () => {
      console.log('remove');
      google.maps.event.removeListener(listener);
    });
  }
});

有关我的最简单的解决方案是这样的:

map.fitBounds(bounds);

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);
google.maps.event.addListener(marker, 'dblclick', function () {
    var oldZoom = map.getZoom(); 
    map.setCenter(this.getPosition());
    map.setZoom(parseInt(oldZoom) + 1);
});

我所做的是:

map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

和它的工作原理上V3 API。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top