如何从渲染方向停止谷歌地图?

时间:2013-04-23 19:55:29

标签: javascript jquery google-maps

我正在创建一个接受点数组的函数,并将它们作为单一路径显示在地图上。

function __RenderRoute(map, points, lineColor, DrawResult, i, callback, waitTime) {
    var tmpPoints = points.slice(i, i + 9);
    if (tmpPoints.length > 1) {
        var request = {
            origin: tmpPoints.shift().location,
            destination: tmpPoints.pop().location,
            waypoints: tmpPoints,
            travelMode: google.maps.TravelMode.DRIVING
        };
    }
    var directionsService = new google.maps.DirectionsService();
    directionsService.route(request, function (result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            var directionsDisplay = new google.maps.DirectionsRenderer({
                draggable: false,
                markerOptions: {
                    visible: false
                },
                polylineOptions: {
                    clickable: true,
                    strokeColor: lineColor,
                    strokeOpacity: .6,
                    strokeWeight: 6,
                    zIndex: 5
                },
                preserveViewport: true
            });
            directionsDisplay.setMap(map);
            directionsDisplay.setDirections(result);
            DrawResult.directionDisplays.push(directionsDisplay);
        } else {
            console.log(status);
            console.log("Wait " + waitTime + " miliseconds.");
            setTimeout(function () { __RenderRoute(map, points, lineColor, DrawResult, i, callback, waitTime * 2) }, waitTime);
            return;
        }
        DrawResult.directionResults.push(result);
        if (i + 9 < points.length) {
            __RenderRoute(map, points, lineColor, DrawResult, i + 8, callback, 350);
        } else {
            if (callback != null) {
                callback();
            }
            DrawResult.completed = true;
        }
    });
}

但是,由于我的数组总是包含大量的点(通常超过100),因此很难重复调用该函数,因为映射只会冻结以等待先前的请求完成。反正有没有停止谷歌地图渲染路线,或者在你再次呼叫它时等待回调本身的功能?

1 个答案:

答案 0 :(得分:0)

不太确定谷歌是否会允许他们的8个航路点的限制被如此简单地克服,但现在就去了。

我修改了__RenderRoute()以查看:

  • 构建一个复合路径对象,包含所有DirectionsService.route段的数据,这样......可以为整个路径调用一次
  • 返回一个Promise,它在所有递归完成时解析,或者被一个有意义的错误消息拒绝。

主要功能__RenderRoute()

function __RenderRoute(points, i, waitTime, dfrd, errorObj) {//<<<<< Now called with a reduced number of parameters
    dfrd = dfrd || $.Deferred();
    errorObj = errorObj || {
        count: 0,
        threshold: 5//adjust as necessary
    };
    var tmpPoints = points.slice(i, i + 9);
    if (tmpPoints.length < 2) {
        if (i == 0) {//top level call
            dfrd.reject("Not enough points");
            return dfrd.promise();
        }
        else { return; }
    }
    var request = {
        origin: tmpPoints.shift().location,
        destination: tmpPoints.pop().location,
        waypoints: tmpPoints,
        travelMode: google.maps.TravelMode.DRIVING
    };
    var route = new RouteResult();//Custom object that allows successive directionsService.route results to be componded into a single route.
    var directionsService = new google.maps.DirectionsService();
    directionsService.route(request, function (result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            route.add(result);//Hopefully magic happens here.
            if(i + 9 < points.length) {
                __RenderRoute(points, i+8, 350, dfrd, errorObj);
            } else {
                dfrd.resolve(route);//<<<<< Resolve the jQuery Deferred object
            }
        } else {
            console.log("google.maps.DirectionsService status = " + status);
            if(++errorObj.count < errorObj.threshold) {
                console.log("Wait " + waitTime + " miliseconds.");
                setTimeout(function() {
                    __RenderRoute(points, i, waitTime*2, dfrd, errorObj);
                }, waitTime);
            }
            else {
                dfrd.reject('Error threshold (' + errorObj.threshold + ') exceeded'); //Reject the jQuery Deferred object
            }
        }
    });
    return dfrd;
}

在合适的范围内定义directionsDisplay

//I think a DirectionsRenderer is reusable. If so `directionsDisplay` needs to be constructed only once as below. If not, then move this block inside foo().
var directionsDisplay = new google.maps.DirectionsRenderer({
    draggable: false,
    markerOptions: {
        visible: false
    },
    polylineOptions: {
        clickable: true,
        strokeColor: '#99F',//adjust as desired
        strokeOpacity: .6,
        strokeWeight: 6,
        zIndex: 5
    },
    preserveViewport: true
});
directionsDisplay.setMap(map);//Assumed to be defined elsewhere

在合适的范围内定义RouteResult()

/*
 * RouteResult is a utility class that will (hopefully)
 * allow several routes to be compounded into one.
 * Based on information here :
 * - https://developers.google.com/maps/documentation/javascript/directions
 * -
 * This is experimental and untested.
 */
function RouteResult() {
    var r = {
        legs: [],
        waypoint_order: [],
        overview_path: [],
        copyrights: [],
        warnings: [],
        bounds : new google.maps.LatLngBounds()//initially empty LatLngBounds obj
    };
    this.add = function (result) {
        r.legs = r.legs.concat(result.legs);
        r.waypoint_order = r.waypoint_order.concat(result.waypoint_order);
        r.overview_path = r.overview_path.concat(result.overview_path);
        r.copyrights = r.copyrights.concat(result.copyrights);
        r.warnings = r.warnings.concat(result.warnings);

        r.bounds = r.bounds.union(result.bounds);//???
        //or possibly just
        //r.bounds.union(result.bounds);//???
    };
    this.get = function() { return r; };
}

然后,拨打__RenderRoute(),如下所示:

//foo() is an assumed function from which __RenderRoute() is called.
function foo() {
    ...
    //__RenderRoute returns a Promise, allowing `.done()` and `.fail()` to be chained.
    __RenderRoute(points, 0, 350).done(function(route) {
        directionsDisplay.setDirections(route.get());//route is a custom object. .get() returns the actuual route. 
        //You can safely call __RenderRoute() again here, eg. with `setTimeout(foo, delay)`.
    }).fail(function(errMessage) {
        console.log(errMessage);
    });
    ...
}
  • 请参阅代码中的评论。
  • 未经测试,因此可能需要进行调试。
  • 如果它不起作用,也许它会给你一些想法。