С Google API directions
я могу получить всю информацию, чтобы перейти от одного места к другому, и я также могу получить все шаги.
Но я не знаю, есть ли способ получить / вычислить позицию (Lat / Lng) по истечении заданного времени. Предполагая, что для упрощения моя скорость постоянна, я могу ответить на вопрос: где я буду через X минут?
ЗАМЕТКА
Я знаю, что Distance travelled = Time * Speed
но таким образом я знаю, сколько KM я путешествовал. То, что я хочу знать, – это (Lat / Lng) через некоторое время.
рабочий пример с использованием GetPointAtDistance из библиотеки сторонних разработчиков epoly.js от Майка Уильямса, перенесенного на v3
var directionDisplay; var directionsService = new google.maps.DirectionsService(); var map; var polyline = null; function createMarker(latlng, label, html) { // alert("createMarker("+latlng+","+label+","+html+","+color+")"); var contentString = '<b>'+label+'</b><br>'+html; var marker = new google.maps.Marker({ position: latlng, map: map, title: label, zIndex: Math.round(latlng.lat()*-100000)<<5 }); marker.myname = label; // gmarkers.push(marker); google.maps.event.addListener(marker, 'click', function() { infowindow.setContent(contentString); infowindow.open(map,marker); }); return marker; } function initialize() { directionsDisplay = new google.maps.DirectionsRenderer({suppressMarkers:true}); var chicago = new google.maps.LatLng(41.850033, -87.6500523); var myOptions = { zoom: 6, mapTypeId: google.maps.MapTypeId.ROADMAP, center: chicago } map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); polyline = new google.maps.Polyline({ path: [], strokeColor: '#FF0000', strokeWeight: 3 }); directionsDisplay.setMap(map); calcRoute(); } function calcRoute() { var start = document.getElementById("start").value; var end = document.getElementById("end").value; var travelMode = google.maps.DirectionsTravelMode.DRIVING var request = { origin: start, destination: end, travelMode: travelMode }; directionsService.route(request, function(response, status) { if (status == google.maps.DirectionsStatus.OK) { polyline.setPath([]); var bounds = new google.maps.LatLngBounds(); startLocation = new Object(); endLocation = new Object(); directionsDisplay.setDirections(response); var route = response.routes[0]; var summaryPanel = document.getElementById("directions_panel"); summaryPanel.innerHTML = ""; // For each route, display summary information. var path = response.routes[0].overview_path; var legs = response.routes[0].legs; for (i=0;i<legs.length;i++) { if (i == 0) { startLocation.latlng = legs[i].start_location; startLocation.address = legs[i].start_address; // marker = google.maps.Marker({map:map,position: startLocation.latlng}); marker = createMarker(legs[i].start_location,"start",legs[i].start_address,"green"); } endLocation.latlng = legs[i].end_location; endLocation.address = legs[i].end_address; var steps = legs[i].steps; for (j=0;j<steps.length;j++) { var nextSegment = steps[j].path; for (k=0;k<nextSegment.length;k++) { polyline.getPath().push(nextSegment[k]); bounds.extend(nextSegment[k]); } } } polyline.setMap(map); computeTotalDistance(response); } else { alert("directions response "+status); } }); } var totalDist = 0; var totalTime = 0; function computeTotalDistance(result) { totalDist = 0; totalTime = 0; var myroute = result.routes[0]; for (i = 0; i < myroute.legs.length; i++) { totalDist += myroute.legs[i].distance.value; totalTime += myroute.legs[i].duration.value; } totalDist = totalDist / 1000. document.getElementById("total").innerHTML = "total distance is: "+ totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes"; document.getElementById("totalTime").value = (totalTime/60.).toFixed(2); } function putMarkerOnRoute(time) { var distance = (time*60/totalTime) * totalDist*1000; // alert("Time:"+time+" totalTime:"+totalTime+" totalDist:"+totalDist+" dist:"+distance); if (!marker) { marker = createMarker(polyline.GetPointAtDistance(distance),"time: "+time,"marker"); } else { marker.setPosition(polyline.GetPointAtDistance(distance)); marker.setTitle("time:"+time); } }
v3_epoly.js
/*********************************************************************\ * * * epolys.js by Mike Williams * * updated to API v3 by Larry Ross * * * * A Google Maps API Extension * * * * Adds various Methods to google.maps.Polygon and google.maps.Polyline * * * * .GetPointAtDistance() returns a GLatLng at the specified distance * * along the path. * * The distance is specified in metres * * Reurns null if the path is shorter than that * * * * .GetPointsAtDistance() returns an array of GLatLngs at the * * specified interval along the path. * * The distance is specified in metres * * * *********************************************************************** * * * This Javascript is provided by Mike Williams * * Blackpool Community Church Javascript Team * * http://www.blackpoolchurch.org/ * * http://econym.org.uk/gmap/ * * * * This work is licenced under a Creative Commons Licence * * http://creativecommons.org/licenses/by/2.0/uk/ * * * *********************************************************************** * * * Version 1.1 6-Jun-2007 * * Version 1.2 1-Jul-2007 - fix: Bounds was omitting vertex zero * * add: Bearing * * Version 1.3 28-Nov-2008 add: GetPointsAtDistance() * * Version 1.4 12-Jan-2009 fix: GetPointsAtDistance() * * Version 3.0 11-Aug-2010 update to v3 * * * \*********************************************************************/ // === first support methods that don't (yet) exist in v3 google.maps.LatLng.prototype.distanceFrom = function(newLatLng) { var EarthRadiusMeters = 6378137.0; // meters var lat1 = this.lat(); var lon1 = this.lng(); var lat2 = newLatLng.lat(); var lon2 = newLatLng.lng(); var dLat = (lat2-lat1) * Math.PI / 180; var dLon = (lon2-lon1) * Math.PI / 180; var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) * Math.sin(dLon/2) * Math.sin(dLon/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = EarthRadiusMeters * c; return d; } google.maps.LatLng.prototype.latRadians = function() { return this.lat() * Math.PI/180; } google.maps.LatLng.prototype.lngRadians = function() { return this.lng() * Math.PI/180; } // === A method which returns the length of a path in metres === google.maps.Polygon.prototype.Distance = function() { var dist = 0; for (var i=1; i < this.getPath().getLength(); i++) { dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i-1)); } return dist; } // === A method which returns a GLatLng of a point a given distance along the path === // === Returns null if the path is shorter than the specified distance === google.maps.Polygon.prototype.GetPointAtDistance = function(metres) { // some awkward special cases if (metres == 0) return this.getPath().getAt(0); if (metres < 0) return null; if (this.getPath().getLength() < 2) return null; var dist=0; var olddist=0; for (var i=1; (i < this.getPath().getLength() && dist < metres); i++) { olddist = dist; dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i-1)); } if (dist < metres) { return null; } var p1= this.getPath().getAt(i-2); var p2= this.getPath().getAt(i-1); var m = (metres-olddist)/(dist-olddist); return new google.maps.LatLng( p1.lat() + (p2.lat()-p1.lat())*m, p1.lng() + (p2.lng()-p1.lng())*m); } // === A method which returns an array of GLatLngs of points a given interval along the path === google.maps.Polygon.prototype.GetPointsAtDistance = function(metres) { var next = metres; var points = []; // some awkward special cases if (metres <= 0) return points; var dist=0; var olddist=0; for (var i=1; (i < this.getPath().getLength()); i++) { olddist = dist; dist += this.getPath().getAt(i).distanceFrom(this.getPath().getAt(i-1)); while (dist > next) { var p1= this.getPath().getAt(i-1); var p2= this.getPath().getAt(i); var m = (next-olddist)/(dist-olddist); points.push(new google.maps.LatLng( p1.lat() + (p2.lat()-p1.lat())*m, p1.lng() + (p2.lng()-p1.lng())*m)); next += metres; } } return points; } // === Copy all the above functions to GPolyline === google.maps.Polyline.prototype.Distance = google.maps.Polygon.prototype.Distance; google.maps.Polyline.prototype.GetPointAtDistance = google.maps.Polygon.prototype.GetPointAtDistance; google.maps.Polyline.prototype.GetPointsAtDistance = google.maps.Polygon.prototype.GetPointsAtDistance;