如何阻止谷歌地图渲染方向

How to stop google maps from rendering direction?

本文关键字:方向 谷歌地图 何阻止      更新时间:2023-09-26

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

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

不太确定谷歌是否会允许这么简单地克服8个路点的限制,但这里是。

我修改了__RenderRoute(),目的是:

  • 构建一个包含所有directionsService数据的复合路由对象。路由段,这样…
  • 返回一个承诺,该承诺在所有递归完成时被解决,或者被拒绝并带有有意义的错误消息。

主要功能__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);
    });
    ...
}
  • 见代码注释
  • 未测试,所以可能需要调试。
  • 如果它不工作,也许它会给你一些想法。