Маршрут на карте Google: единый источник с несколькими пунктами назначения

#google-maps #google-maps-api-3 #google-maps-markers

#google-карты #google-maps-api-3 #google-карты-маркеры

Вопрос:

Есть ли какой-либо способ или функции в Google map, которые позволяют вам иметь единый источник с несколькими направлениями?

например

 A --> B
A --> C
A --> D
  

РЕДАКТИРОВАТЬ: (для запутанного демона)

например

     --> B          
 A |--> C
    --> D
  

До сих пор я делал это, используя путевые точки:

 A --> B --> A --> C --> A --> D
  

Но проблема с этим решением заключается в том, что каждый пункт назначения возвращается к источнику.(От B до A, от C до A)

Я хочу, чтобы исходное сообщение «только для пунктов назначения» не показывало маршруты пункта назначения, возвращающиеся к источнику, просто чтобы перейти к следующему пункту назначения, как в первом примере.

Спасибо.

Обновление: я нашел это (матрица расстояний), но проблема с матрицей расстояний заключается в том, что она не возвращает подробную информацию о маршруте, такую как DirectionsService, что мне нужно.

Комментарии:

1. неясно, чего конкретно вы пытаетесь достичь. Визуализировать маршруты? Что-то вычислить? Показать направления?

Ответ №1:

Я не думаю, что возможно получить несколько направлений, отображаемых одновременно. Я создал что-то вроде этого, где я показывал только одно направление за раз, но когда пользователь нажимал на разные пункты назначения в таблице, я каждый раз обновлял направления.

 <!DOCTYPE html>
<html>
<head>
<title>Driving directions between markers</title>

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?libraries=geometry"></script>

<script>
    var directionsService = new google.maps.DirectionsService();
    var directionsDisplay;
    var arrLatLon = [];
    var homeLatlng;
    var destinationID;

    function initialize() {
        homeLatlng = new google.maps.LatLng(54.42838,-2.9623);

        var myOptions = {
            zoom: 10,
            center: homeLatlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

        var infowindow = new google.maps.InfoWindow({
            content: ''
        });

        directionsDisplay = new google.maps.DirectionsRenderer({
            draggable: true,
            map: map, 
            markerOptions: {
                draggable: true
            },
            panel: document.getElementById("directionsPanel"),
            infoWindow: infowindow
        });

        arrLatLon[1] = new google.maps.LatLng(54.60039,-3.13632);
        arrLatLon[2] = new google.maps.LatLng(54.36897,-3.07561);
        arrLatLon[3] = new google.maps.LatLng(54.5003526,-3.0844116);
        arrLatLon[4] = new google.maps.LatLng(54.57723,-2.79748);

        google.maps.event.addListener(directionsDisplay, 'directions_changed', function() {
            computeTotalDistance(directionsDisplay.directions);
        });

        // only seems possible to display 1 directions at a time?
        calcRoute(1);
    }

    function calcRoute(id) {
        var selectedMode = document.getElementById("mode").value;
        var selectedUnits = document.getElementById("units").value;

        if(typeof(id) != "undefined"){
            destinationID = id;
        }

        var request = {
            origin:homeLatlng,
            destination:arrLatLon[destinationID],
            travelMode: google.maps.DirectionsTravelMode[selectedMode],
            unitSystem: google.maps.UnitSystem[selectedUnits]
        };

        directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                directionsDisplay.setDirections(response);
            }
        });
    }

    function computeTotalDistance(result) {
        var total = 0;
        var myroute = result.routes[0];
        for (var i = 0; i < myroute.legs.length; i  ) {
            total  = myroute.legs[i].distance.value;
        }
        total = total / 1000;

        var selectedUnits = document.getElementById("units").value;

        if (selectedUnits == "IMPERIAL") {
            document.getElementById("total").innerHTML = (Math.round((total* 0.6214)*100)/100)   " miles";
        } else {
            document.getElementById("total").innerHTML = total   " kilometres";
        }
    }

    google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
    <div id="map_canvas" style="float:left;width:70%;height:60%"></div>

    <div id="directionsPanel" style="float:right;width:30%;height:60%"></div>

    <p>Total Distance: <span id="total"></span></p>

    <h2>Use the map below to see destinations near Ambleside</h2>
    <h3>More destinations near Ambleside</h3>

    <table id="tableNeighbours" border="1">
        <tr>
            <th>Destination</th>
            <th colspan="2">Distance from Ambleside</th>
        </tr>

            <tr>
                <td><a href="#" onclick="calcRoute(1); return false;">Keswick</a></td>

                <td>22.2 kilometres</td>
                <td>13.8 miles</td>
            </tr>

            <tr>
                <td><a href="#" onclick="calcRoute(2); return false;">Coniston</a></td>
                <td> 9.9 kilometres</td>

                <td> 6.2 miles</td>
            </tr>

            <tr>
                <td><a href="#" onclick="calcRoute(3); return false;">Lake District</a></td>
                <td>11.3 kilometres</td>
                <td> 7.0 miles</td>

            </tr>

            <tr>
                <td><a href="#" onclick="calcRoute(4); return false;">Cumbria</a></td>
                <td>19.7 kilometres</td>
                <td>12.2 miles</td>
            </tr>

    </table>

    <div>
        <strong>Mode of Travel: </strong>
        <select id="mode" onchange="calcRoute()">
          <option value="DRIVING" selected="selected">Driving</option>
          <option value="WALKING">Walking</option>
        </select>
    </div>

    <div>
        <strong>Measurement units: </strong>
        <select id="units" onchange="calcRoute()">
          <option value="IMPERIAL" selected="selected">Miles</option>
          <option value="METRIC ">Kilometres</option>
        </select>
    </div>
</body>
</html>
  

Комментарии:

1. Привет, Дункан, спасибо, это на самом деле то, что я тоже сделал за это время. 🙂 Но все же, мой клиент видит несколько пунктов назначения только на одном дисплее, поэтому я все еще скрещиваю пальцы.

2. В качестве альтернативы вы можете попробовать создать маршруты в виде полилинии, хотя это потребует дополнительной предварительной работы и может не сработать, если ваш пользователь может изменить пункты назначения в любое удобное для него место, а не выбирать из фиксированного списка.

Ответ №2:

Я думаю, это должно быть возможно. Я не уверен, что это правильный путь, но для меня сработал следующий способ

 location=[
        { b.lat: <lat of b> , b.lng: <lng of b> },
        { c.lat: <lat of c> , c.lng: <lng of c> },
        { d.lat: <lat of d> , d.lng: <lng of d> },
    ]
    location.forEach(function(value){
        var directionsService = new google.maps.DirectionsService();
        var directionsDisplay = new google.maps.DirectionsRenderer();
        directionsDisplay.setMap(map);
        var request = {
            origin: new google.maps.LatLng(<lat of a>, <lng of a>),
            destination: new google.maps.LatLng(value.lat,value.lng),
            travelMode: "DRIVING",
        };
        directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                directionsDisplay.setDirections(response);  
            }
        });
    });
  

Примечание: я заметил, что объявление DirectionsService и directionsDisplay вместе с directionsDisplay.setMap(map) при перемещении за пределы цикла рендеринга не работает, но в конечном итоге rater перезаписывает существующий рендеринг. Таким образом, будет виден только один.