0

我正在创建一个函数来接受一个点数组并将它们作为一条路线显示在地图上。

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 个),因此很难重复调用该函数,因为地图只会冻结以等待先前的请求完成。有没有办法阻止谷歌地图渲染路线,或者在等待再次调用时停止回调函数本身?

4

1 回答 1

0

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

我已修改__RenderRoute()为:

  • 构建一个复合路线对象,包含所有方向Service.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);
    });
    ...
}
  • 请参阅代码中的注释。
  • 未经测试,因此可能需要调试。
  • 如果它不起作用,也许它会给你一些想法。
于 2013-04-25T02:09:42.250 回答