Google Maps JavaScript API V3 - отображение нескольких маршрутов

Я пытаюсь отобразить несколько маршрутов с помощью API карт Google. Но при попытке использовать более 10 маршрутов я получаю исключение OVER_QUERY_LIMIT.

Используя Google, я узнал, что мне нужно вызвать DirectionsDisplay асинхронно, используя функцию обратного вызова (пока не удалось заставить это работать). И что мне нужно использовать какой-то тайм-аут, потому что вы не можете делать больше 10 запросов в секунду.

Вот что я получил до сих пор.

<!DOCTYPE html>
<html>
<head>
    <title>Display multiple routes</title>
    <meta name = "viewport" content = "initial-scale=1.0">
    <meta charset = "utf-8">


    <script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src = "https://maps.googleapis.com/maps/api/js?v=3.exp&key=ENTER_API_KEY"></script>


    <style>
        /* Always set the map height explicitly to define the size of the div
        * element that contains the map. */
        #map {
            height: 100%;
        }
        /* Optional: Makes the sample page fill the window. */
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>

</head>
<body>

    <div id = "map"></div>

    <script>

        var addresses =
            [
                ['243, Dornacherstrasse', '26, Mattenstrasse'],
                ['48 av general de gaulle, saint louis', 'Gründenstraße 40, Muttenz'],
                ['50 ackerstrasse , Basel', 'holeestrasse 133, Basel'],
                ['71 avenue de Bâle , Saint-Louis ', 'Leonhardstr 6, Basel'],
                ['Ackerstrasse 44, Basel', 'Petersplatz 1, Basel'],
                ['Ackerstrasse 51, Basel', 'Maiengasse 51, Basel '],
                ['Aeussere Baselstr. 255, Riehen', 'zu den drei Linden 80, Basel'],
                ['Aeussere Baselstrasse 309, Riehen', 'Gotthelfplatz 1, Basel'],
                ['Ahornstrasse 20, Basel', 'Viaduktstrasse , Basel'],
                ['Albert Schweitzer Strasse 10, Basel', 'Kohlenberg 17, Basel'],
                ['alemannengasse 17, Basel', 'Centrahlbahnplatz, Basel'],
                ['Alemannengasse 23, Basel', 'Peter Merian-Weg 8, Basel'],
                ['Allmendstrasse 233, Basel', 'Universitätsspital Basel, Basel '],
                ['Allmendstrasse 4, Basel', 'Petersplatz 1, Basel'],
                ['Allschwilerstrasse 106, Basel', 'Centralbahnstrasse 10 , Basel'],
                ['Allschwilerstrasse 116, Basel', 'Spitalstrasse 8, Architektur Institut, Basel '],
                ['Allschwilerstrasse 116, Basel', 'Steinenvorstadt 55, Kino Pathè Küchlin, Basel'],
                ['Allschwilerstrasse 48, Basel', 'Schneidergasse 28, Basel'],
                ['Altrheinweg 52, Basel', 'Vogesenplatz 1, Basel '],
                ['Am Rheinpark 6, Weil am Rhein', 'J. J. Balmer-Str. 3, Basel'],
                ['Am Weiher 15, Binningen', 'Klingelbergstrasse 82, Basel '],
                ['Amerbachstrasse, , Basel', 'Peter Merian-Weg, Basel'],
                ['Amerikanerstrasse 16, Binningen', 'Petersplatz 1, Basel'],
                ['Amselweg 20, Reinach', 'Baselstrasse 33, Münchenstein'],
                ['An der Auhalde 15, Riehen', 'Zu den Dreilinden 95, Basel'],
                ['arnikastr. 22, Riehen', 'marktplatz, Basel'],
                ['Auf der Lyss 14, Basel', 'Grenzstrasse 15, Basel']
            ];

        var directionsDisplay;
        var directionsService = new google.maps.DirectionsService();
        var map;

        function initialize() {
            directionsDisplay = new google.maps.DirectionsRenderer();
            var basel = new google.maps.LatLng(41.850033, -87.6500523);
            var mapOptions = {
                zoom: 7,
                center: basel
            }
            map = new google.maps.Map(document.getElementById('map'), mapOptions);
            directionsDisplay.setMap(map);
        }

        function calcRoute(start, end) {

            var request = {
                origin: start,
                destination: end,
                travelMode: 'BICYCLING'
            };
            directionsService.route(request,
                function(result, status) {
                    if (status == 'OK') {

                        directionsDisplay = new google.maps.DirectionsRenderer({
                            suppressBicyclingLayer: true,
                            suppressMarkers: true
                        });
                        directionsDisplay.setMap(map);
                        directionsDisplay.setDirections(result);
                    }
                });
        }

        initialize();
        addresses.forEach(function (v, i) {
            setTimeout(calcRoute(addresses[i][0], addresses[i][1]), 100);
        });
    </script>
</body>
</html>

Я в курсе, что по SO очень много похожих вопросов. Но ни один из них у меня не работал.

Вопрос должен действительно содержать вопрос. В каком подобном вопросе вы видели, что это реализовано таким образом?

MrUpsidown 12.05.2018 21:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
3 234
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использование модифицированного кода из связанного ответа OVER_QUERY_LIMIT в Google Maps API v3: как мне приостановить / задержать в Javascript, чтобы замедлить его?, который решает ту же проблему с геокодером Google Maps Javascript API v3, обнаруживая статус OVER_QUERY_LIMIT и увеличивая задержку между запросами, когда это происходит.

// delay between directions requests
var delay = 100;

function calcRoute(start, end, next) {
  console.info("calcRoute('" + start + "','" + end + "',next)");
  var request = {
    origin: start,
    destination: end,
    travelMode: 'BICYCLING'
  };
  directionsService.route(request,
    function(result, status) {
      if (status == 'OK') {

        directionsDisplay = new google.maps.DirectionsRenderer({
          suppressBicyclingLayer: true,
          suppressMarkers: true,
          preserveViewport: true // don't zoom to fit the route
        });
        directionsDisplay.setMap(map);
        directionsDisplay.setDirections(result);
        // combine the bounds of the responses
        bounds.union(result.routes[0].bounds);
        // zoom and center the map to show all the routes
        map.fitBounds(bounds);
      }
      // ====== Decode the error status ======
      else {
        console.info("status = " + status + " (start = " + start + ", end = " + end + ")");
        // === if we were sending the requests to fast, try this one again and increase the delay
        if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
          nextAddress--;
          delay += 100;
          document.getElementById('delay').innerHTML = delay;
        } else {
          var reason = "Code " + status;
          var msg = 'start = "' + start + ' end = "' + end + '"" error=' + reason + '(delay=' + delay + 'ms)<br>';
          document.getElementById("messages").innerHTML += msg;
        }
      }
      next();
    });
}

доказательство концепции скрипки

screenshot of resulting map

фрагмент кода:

var addresses = [
  ['243, Dornacherstrasse', '26, Mattenstrasse'],
  ['48 av general de gaulle, saint louis', 'Gründenstraße 40, Muttenz'],
  ['50 ackerstrasse , Basel', 'holeestrasse 133, Basel'],
  ['71 avenue de Bâle , Saint-Louis ', 'Leonhardstr 6, Basel'],
  ['Ackerstrasse 44, Basel', 'Petersplatz 1, Basel'],
  ['Ackerstrasse 51, Basel', 'Maiengasse 51, Basel '],
  ['Aeussere Baselstr. 255, Riehen', 'zu den drei Linden 80, Basel'],
  ['Aeussere Baselstrasse 309, Riehen', 'Gotthelfplatz 1, Basel'],
  ['Ahornstrasse 20, Basel', 'Viaduktstrasse , Basel'],
  ['Albert Schweitzer Strasse 10, Basel', 'Kohlenberg 17, Basel'],
  ['alemannengasse 17, Basel', 'Centrahlbahnplatz, Basel'],
  ['Alemannengasse 23, Basel', 'Peter Merian-Weg 8, Basel'],
  ['Allmendstrasse 233, Basel', 'Universitätsspital Basel, Basel '],
  ['Allmendstrasse 4, Basel', 'Petersplatz 1, Basel'],
  ['Allschwilerstrasse 106, Basel', 'Centralbahnstrasse 10 , Basel'],
  ['Allschwilerstrasse 116, Basel', 'Spitalstrasse 8, Architektur Institut, Basel '],
  ['Allschwilerstrasse 116, Basel', 'Steinenvorstadt 55, Kino Pathè Küchlin, Basel'],
  ['Allschwilerstrasse 48, Basel', 'Schneidergasse 28, Basel'],
  ['Altrheinweg 52, Basel', 'Vogesenplatz 1, Basel '],
  ['Am Rheinpark 6, Weil am Rhein', 'J. J. Balmer-Str. 3, Basel'],
  ['Am Weiher 15, Binningen', 'Klingelbergstrasse 82, Basel '],
  ['Amerbachstrasse, , Basel', 'Peter Merian-Weg, Basel'],
  ['Amerikanerstrasse 16, Binningen', 'Petersplatz 1, Basel'],
  ['Amselweg 20, Reinach', 'Baselstrasse 33, Münchenstein'],
  ['An der Auhalde 15, Riehen', 'Zu den Dreilinden 95, Basel'],
  ['arnikastr. 22, Riehen', 'marktplatz, Basel'],
  ['Auf der Lyss 14, Basel', 'Grenzstrasse 15, Basel']
];

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var bounds;

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();
  var basel = new google.maps.LatLng(41.850033, -87.6500523);
  var mapOptions = {
    zoom: 7,
    center: basel
  }
  map = new google.maps.Map(document.getElementById('map'), mapOptions);
  directionsDisplay.setMap(map);
  bounds = new google.maps.LatLngBounds();
}

// delay between directions requests
var delay = 100;

function calcRoute(start, end, next) {
  console.info("calcRoute('" + start + "','" + end + "',next)");
  var request = {
    origin: start,
    destination: end,
    travelMode: 'BICYCLING'
  };
  directionsService.route(request,
    function(result, status) {
      if (status == 'OK') {

        directionsDisplay = new google.maps.DirectionsRenderer({
          suppressBicyclingLayer: true,
          suppressMarkers: true,
          preserveViewport: true // don't zoom to fit the route
        });
        directionsDisplay.setMap(map);
        directionsDisplay.setDirections(result);
        // combine the bounds of the responses
        bounds.union(result.routes[0].bounds);
        // zoom and center the map to show all the routes
        map.fitBounds(bounds);
      }
      // ====== Decode the error status ======
      else {
        console.info("status = " + status + " (start = " + start + ", end = " + end + ")");
        // === if we were sending the requests to fast, try this one again and increase the delay
        if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
          nextAddress--;
          delay += 100;
          document.getElementById('delay').innerHTML = "delay between requests = " + delay;
        } else {
          var reason = "Code " + status;
          var msg = 'start = "' + start + ' end = "' + end + '"" error=' + reason + '(delay=' + delay + 'ms)<br>';
          document.getElementById("messages").innerHTML += msg;
        }
      }
      next();
    });
}

initialize();
// ======= Global variable to remind us what to do next
var nextAddress = 0;

// ======= Function to call the next Geocode operation when the reply comes back

function theNext() {
  if (nextAddress < addresses.length) {
    console.info('call calcRoute("' + addresses[nextAddress][0] + '","' + addresses[nextAddress][1] + ') delay=' + delay);
    setTimeout('calcRoute("' + addresses[nextAddress][0] + '","' + addresses[nextAddress][1] + '",theNext)', delay);
    nextAddress++;
  } else {
    // We're done. Show map bounds
    map.fitBounds(bounds);
  }
}

// ======= Call that function for the first time =======
theNext();

// This Javascript is based on code provided by the
// Community Church Javascript Team
// https://www.bisphamchurch.org.uk/   
// https://econym.org.uk/gmap/
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id = "delay"></div>
<div id = "map"></div>
<div id = "messages"></div>

Другие вопросы по теме