如何实现对道路折线的可拖拽抓取



就像在标题:如何实现折线捕捉到街道时,标记是拖动?我花了很多时间寻找答案,但我已经放弃了。如果没有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);
                }
            });
        }
    });
}

在保持良好性能的同时实现这是一件相当困难的事情,原因将在下面的代码中说明。当你拖动标记时,你需要的是抓拍道路,但这样做有局限性和问题。我将为您提供代码来做到这一点,而不是在道路WHILE拖动,而是在结束标记拖动。请注意,取消下面一行代码的注释可以使它在拖动时按您的要求锁定到道路上,但我不建议这样做,原因如下。请参阅我的代码末尾的注释,并在这里查看操作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>

最新更新