谷歌地图fitBounds回调

时间:2016-03-03 01:23:11

标签: javascript google-maps google-maps-api-3 fitbounds

我知道如果边界已经改变,则会触发bounds_changed事件,但是我需要知道fitBounds何时完成(当边界已经改变或边界保持不变时)。

谷歌有一些容忍,如果边界变化很小,它实际上不会改变边界/调用bounds_changed。我需要知道这种情况何时发生。

我已经成功完成了超时但看起来很hacky并且当bounds_changed超过100ms触发时可能会出现一些错误。

参见示例:http://jsbin.com/sosurexuke/1/edit?js,console,output

有更好的解决方案吗?

编辑:如果你认为只是检查map.getBounds()是否与你发送的fitBounds()相同,那么你会很失望地知道拟合到边界的结果通常都不是很接近到你发送的范围。我写这个函数认为这可能是可能的

function boundsAreIdentical(bounds1, bounds2) {
        if (!bounds1 || !bounds2) return false;

        var tolerance = 0.00001;
        console.log(bounds1.getNorthEast().lat(), bounds2.getNorthEast().lat());
        console.log(bounds1.getNorthEast().lng(), bounds2.getNorthEast().lng());
        console.log(bounds1.getSouthWest().lat(), bounds2.getSouthWest().lat());
        console.log(bounds1.getSouthWest().lng(), bounds2.getSouthWest().lng());
        if (
            (Math.abs(bounds1.getNorthEast().lat() - bounds2.getNorthEast().lat()) <= tolerance) &&
            (Math.abs(bounds1.getNorthEast().lng() - bounds2.getNorthEast().lng()) <= tolerance) &&
            (Math.abs(bounds1.getSouthWest().lat() - bounds2.getSouthWest().lat()) <= tolerance) &&
            (Math.abs(bounds1.getSouthWest().lng() - bounds2.getSouthWest().lng()) <= tolerance)) {
            return true;
        }
        return false;
    }

2年后编辑:

似乎在谷歌地图(3.32)的最新实验版中,即使边界与当前边界相同,也会触发bounds_changed

我将原始示例更新为版本3.31,但仍显示原始版本。

2 个答案:

答案 0 :(得分:1)

解决此问题第一部分的最简单方法(知道边界何时完成更改)是使用idle event listener

您如何更改边界,请在即将更改之前设置此事件。这样,当边界全部结算时,地图将注册为空闲并且空闲事件将被触发,您可以在其中执行您的测试。为了防止事件堆叠在一起,同时清除它。

你可能不得不用它来捣乱。说到摆弄,这是一个小提琴。在这个小提琴我只是设置警报每次都发生:

https://jsbin.com/kapimov/edit?js,output点击“更改边界”,您会看到它一遍又一遍地发生:)

编辑:要检查fitBounds()失败时是否触发,请在触发fitBounds()之前和之后比较中心。

即使尝试将边界设置为相同的坐标两次,中心也会发生变化并可以进行比较。中心检查似乎发生在边界的实际移动之前,但是在调用该函数时总是会改变。

点击“适合当前界限”按钮两次以查看它的运行情况;第一次'bounds_changed'触发,第二次它没有,但中心仍然正确检查。注释掉fitBounds()函数,看看没有它就不会改变中心。

答案 1 :(得分:0)

如问题编辑所示。如果你可以使用3.32,那就用吧。否则,如果您需要一个在3.32之前工作的解决方案,那么您可以在拟合边界之前简单地将地图平移1个像素。视觉变化不会触发刷新并强制边界始终改变。

演示:http://jsbin.com/bipekaxosa/1/edit?js,console,output

function pan(map, newCenterLatLng, offsetx, offsety, callback) {
    if (!map.getProjection()) {
        if (callback) {
            return setTimeout(pan, 1, map, newCenterLatLng, offsetx, offsety, callback);
        }
        throw new Error("You must wait until map.getProjection() is ready. Try using the callback instead");
    }

    var newCenterLatLngPixels = map.getProjection().fromLatLngToPoint(newCenterLatLng);

    var offset = new google.maps.Point(
        ((typeof (offsetx) == "number" ? offsetx : 0) / Math.pow(2, map.getZoom())) || 0,
        ((typeof (offsety) == "number" ? offsety : 0) / Math.pow(2, map.getZoom())) || 0
    );

    map.setCenter(map.getProjection().fromPointToLatLng(new google.maps.Point(
        newCenterLatLngPixels.x - offset.x,
        newCenterLatLngPixels.y + offset.y
    )));

    if (callback) {
        return callback();
    }
}

function fitBoundsAndCallback(map, bounds, callback) {
    google.maps.event.addListenerOnce(map, "bounds_changed", function() {
        if (callback) {
            callback();
        }
    });

    // Pan the map 1 pixel up so that bounds will always change
    // even in the event you are fitting to the same bounds as before
    // Remove this once the move to gmaps 3.32 as bounds_changed works always
    this.pan(map, map.getCenter(), 0, 1, function(){
      map.fitBounds(bounds);
    });
}