Torno a scrivere sul mio blog per trattare un argomento a mio giudizio interessante, anche se un po’ specifico.
Per conto di un cliente mi sto occupando delle API di Google Maps, in particolare l’ultima versione, ossia la V3.
Premetto, per chi non conoscesse l’argomento, che dalla versione 2 c’è stato un grande passo avanti, con ottime nuove funzionalità e tanti metodi che fanno risparmiare un sacco di tempo… D’altronde stiamo parlando di Big G!
Lo script che pubblico in questa pagina serve per rimediare al problema delle limitazioni poste da Google su ogni singola richiesta di calcolo di un percorso. Il cliente in questione deve visualizzare sulla mappa il tragitto tra due punti, passando però per un numero indefinito di punti intermedi.
Per fare questo Google rende disponibili le directions API impostando però il limite di 2500 richieste giornaliere e 8 punti intermedi per richiesta. L’idea è semplice, ottimizzare le richieste includendo al massimo 8 punti intermedi, settando però, dalla seconda richiesta in avanti, il punto di partenza uguale al punto finale della richiesta precedente.
Vediamo il codice javascript:
var map = null; var markers = new Array(); var coordinates = new Array(); var directionsDisplay = new Array(); var directionsService = new google.maps.DirectionsService(); function placeMarker(lat, lng){ var markerPos = new google.maps.LatLng(lat, lng); var marker = new google.maps.Marker({ position: markerPos, map: map, draggable: true, animation: google.maps.Animation.DROP }); markers.push(marker); } function removeRoutes(){ for(var i = 0; i < directionsDisplay.length; i++){ directionsDisplay[i].setMap(null); } directionsDisplay = new Array(); } function drawRoute(begin, end, waypts){ var request = { origin: begin, destination: end, waypoints: waypts, optimizeWaypoints: true, travelMode: google.maps.TravelMode.DRIVING }; directionsService.route(request, function(response, status) { if (status === google.maps.DirectionsStatus.OK) { var dirDisp = new google.maps.DirectionsRenderer({suppressMarkers: true}); dirDisp.setMap(map); dirDisp.setDirections(response); directionsDisplay.push(dirDisp); } }); } function calculateRoutes(){ removeRoutes(); var begin = new google.maps.LatLng(coordinates[0][0], coordinates[0][1]); var end = null; var waypts = new Array(); var wCount = 0; var REQUEST_WAYPOINTS_LIMIT = 8; var i; for(i = 1; i < (coordinates.length-1); i++){ if(wCount === REQUEST_WAYPOINTS_LIMIT){ i++; end = new google.maps.LatLng(coordinates[i][0], coordinates[i][1]); drawRoute(begin, end, waypts); begin = end; wCount = 0; waypts = new Array(); } waypts.push({ location: new google.maps.LatLng(coordinates[i][0], coordinates[i][1]), stopover: true }); wCount++; } if(waypts.length > 0){ end = new google.maps.LatLng(coordinates[coordinates.length-1][0], coordinates[coordinates.length-1][1]); drawRoute(begin, end, waypts); } for(var i = 0; i < coordinates.length; i++){ placeMarker(coordinates[i][0], coordinates[i][1]); } }
Nel codice qui sopra come potete vedere ho un array di coordinate che contiene i vari punti da rappresentare sulla mappa, e il percorso deve essere calcolato partendo dalla prima coordinata presente in array per arrivare all’ultima cella dell’array, passando per tutte le altre.
Ho dato per scontato che la mappa sia già stata inizializzata e che la variabile map contenga l’oggetto google.maps.Map.
Un’ulteriore miglioria già fatta (che tratterò in un futuro articolo) sarà quella di colorare e numerare i marker dinamicamente e di adattare automaticamente lo zoom della mappa ai markers attivi sulla mappa visualizzata.