2014-08-29 55 views
0

随着Google API directions我可以获取所有信息从一个地方到另一个地方,我也可以得到所有的步骤。计算给定时间的地理位置

但我不知道是否有一种方法来检索/计算给定时间后的位置(Lat/Lng)。假设,为了简化,我的速度是不变的,我有办法回答这个问题:我将在X分钟内在哪里?

注意

我知道Distance travelled = Time * Speed但这种方式,我知道我有多少公里行驶。我想知道的是经过一段时间后的(Lat/Lng)。

+0

时间=距离/速度如果这就是你在问什么。 – Matthew 2014-08-29 07:21:50

+0

@Mthethew如果我在一条完美的直线道路上旅行,那将起作用。 – Hpatoio 2014-08-29 07:27:37

+0

@Hpatoio你说你假设速度是恒定的,不管路上的曲线如何,你仍然可以从这个答案中得到正确的时间,因为距离不会对常规数字产生无动于衷的影响(这可以应用于该公式)。 – Matthew 2014-08-29 07:32:14

回答

0

working example使用GetPointAtDistance从epoly.js third party library from Mike Williams移植到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;