3

就像标题中一样:当标记拖动时,如何实现折线捕捉到街道?我花了很多时间寻求答案,但我已经放弃了。如果可以不使用 DirectionsRenderer,我只想使用 DirectionsService。下面是我清理过的代码版本,其中捕捉工作不是针对每个,而是仅针对最后一个标记和路径没有清理。帮助将不胜感激。

我在jsfiddle和这里​​的代码:

var map,
path = [],
    markers = [],
    directionsService = new google.maps.DirectionsService(),
    poly;

function addMarker(p) {
    var marker = new google.maps.Marker({
        position: p,
        map: map,
        draggable: true
    });
    markers.push(marker);

    google.maps.event.addListener(marker, "drag", function () {
        var request = {
            origin: path[path.length - 1],
            destination: marker.getPosition(),
            travelMode: google.maps.DirectionsTravelMode.DRIVING
        };
        directionsService.route(request, function (response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                marker.setPosition(response.routes[0].legs[0].end_location);
                path = path.concat(response.routes[0].overview_path);
                poly.setPath(path);
            }
        });
    });
}

function initialize() {
    var myOptions = {
        zoom: 17,
        center: new google.maps.LatLng(40.7143528, -74.00597310000001),
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        draggableCursor: "crosshair"
    }

    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

    google.maps.event.addListener(map, 'click', function (event) {

        if (path.length == 0) {
            path.push(event.latLng);
            poly = new google.maps.Polyline({
                map: map
            });
            poly.setPath(path);
            addMarker(event.latLng);
        } else {
            var request = {
                origin: path[path.length - 1],
                destination: event.latLng,
                travelMode: google.maps.DirectionsTravelMode.DRIVING
            };
            directionsService.route(request, function (response, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                    addMarker(response.routes[0].legs[0].end_location);

                    path = path.concat(response.routes[0].overview_path);
                    poly.setPath(path);
                }
            });
        }
    });
}
4

1 回答 1

3

由于下面我的代码中所述的原因,在保持良好性能的同时实现这是一件相当困难的事情。在拖动标记时捕捉道路是您的要求,但这样做存在限制和问题。我将为您提供代码来执行此操作,而不是在拖动时捕捉到道路,而是在标记拖动的结束处。请注意,取消注释下面的一行代码可以使其在您请求拖动时捕捉到道路,但我建议不要这样做,原因如下所述。请在此处查看我的代码末尾的评论,并在此处查看实际操作http://jsfiddle.net/VvR5k/1/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Some Title</title>
</head>
<body>
<p>Click on map to place markers, drag markers to change route</p>
<p>Please view comment block towards end of javascript code!</p>
<p><button type="button" onclick="resetMarkers();">Reset Markers</button></p>
<div id="map_canvas" style="width:800px; height:600px;">
</div>
<script src="http://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script type="text/javascript">

function init() {
    var markers = [],
        segments = [],
        myOptions = {
            zoom: 12,
            center: new google.maps.LatLng(34.0504, -118.2444),
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            disableDoubleClickZoom: true,
            draggableCursor: "crosshair"
        },
        alphas = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''),
        alphaIdx = 0,
        map = new google.maps.Map(document.getElementById("map_canvas"), myOptions),
        service = new google.maps.DirectionsService(),
        poly = new google.maps.Polyline({
            map: map,
            strokeColor: '#00FFFF',
            strokeOpacity: 0.6,
            strokeWeight: 5
    });
    window.resetMarkers = function () {
        for (var i = 0; i < markers.length; i++) {
            markers[i].setMap(null);
        }
        alphaIdx = 0;
        segments = [];
        markers = [];
        poly.setPath([]);
    };
    function getSegmentsPath() {
        var a, i,
            len = segments.length,
            arr = [];
        for (i = 0; i < len; i++) {
            a = segments[i];
            if (a && a.routes) {
                arr = arr.concat(a.routes[0].overview_path);
            }
        }
        return arr;
    }

    function addSegment(start, end, segIdx) {
        service.route(
            {
                origin: start,
                destination: end,
                travelMode: google.maps.DirectionsTravelMode.DRIVING
            },
            function (result, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                    //store the entire result, as we may at some time want
                    //other data from it, such as the actual directions
                    segments[segIdx] = result;
                    poly.setPath(getSegmentsPath());
                }
            }
        );
    }
    google.maps.event.addListener(map, "click", function (e) {
        //limiting the number of markers added to no more than 26, as if we have
        //that many we have used up all our alphabetical characters for the icons
        if (alphaIdx > 25) {
            return;
        }
        var evtPos = e.latLng,
            c = alphas[alphaIdx++],
            marker = new google.maps.Marker({
                map: map,
                position: evtPos,
                draggable: true,
                icon: 'http://www.google.com/mapfiles/marker'+ c +'.png'
        });
        marker.segmentIndex = markers.length - 1;
        marker.iconChar = c;//just storing this for good measure, may want at some time
        function updateSegments() {
            var start, end, inserts, i,
                idx = this.segmentIndex,
                segLen = segments.length, //segLen will always be 1 shorter than markers.length
                myPos = this.getPosition();
            if (segLen === 0) { //nothing to do, this is the only marker
                return;
            }
            if (idx == -1) { //this is the first marker
                start = [myPos];
                end = [markers[1].getPosition()];
                inserts = [0];
            } else if (idx == segLen - 1) { //this is the last marker
                start = [markers[markers.length - 2].getPosition()];
                end = [myPos];
                inserts = [idx];
            } else {//there are markers both behind and ahead of this one in the 'markers' array
                start = [markers[idx].getPosition(), myPos];
                end = [myPos, markers[idx + 2].getPosition()];
                inserts = [idx, idx + 1];
            }
            for (i = 0; i < start.length; i++) {
                addSegment(start[i], end[i], inserts[i]);
            }
        }
        /**********************************************************************
        Note that the line below which sets an event listener for the markers
        'drag' event and which is commented out (uncomment it to test,
        but I do not recommend using it in reality) causes us to constantly
        poll google for DirectionsResult objects and may perform poorly at times
        while a marker is being dragged, as the application must wait for a
        directions request to be sent and received from google many many many
        times while the marker is dragged. For these reasons, I personally would
        only use the dragend event listener. Additionally, using the below line can
        very quickly run you up against google maps api services usage limit of
        2500 directions requests per day, as while a marker is being dragged it
        could cause hundreds and hundreds of directions requests to be made! Not good!
        see about usage limits: https://developers.google.com/maps/documentation/directions/#Limits
        ***********************************************************************/
        //google.maps.event.addListener(marker, 'drag', updateSegments);
        google.maps.event.addListener(marker, 'dragend', updateSegments);
        markers.push(marker);
        if (markers.length > 1) {
            addSegment(markers[markers.length - 2].getPosition(), evtPos, marker.segmentIndex);
        }
    });
}
init();

</script>
</body>
</html>
于 2013-05-12T12:33:45.297 回答