在路线中以固定时间间隔确定中间纬度/经度

Posted

技术标签:

【中文标题】在路线中以固定时间间隔确定中间纬度/经度【英文标题】:Determine intermediate lat/long at regular time interval in a route 【发布时间】:2016-12-02 01:40:55 【问题描述】:

假设从源到目的地的给定道路路线,我正在尝试确定中间纬度和经度列表。

例如 - 假设我的来源是密苏里州堪萨斯城,目的地是伊利诺伊州芝加哥,途经 US-36 E 和 I-55 N。假设我现在要开始(没有交通延误),我该如何找到这条路线上每隔 1 小时的所有纬度/经度列表?

【问题讨论】:

Calculate the geo position at given time 的可能重复项(您只需多次计算或在计算 1 小时内行驶的距离后使用 GetPointsAtDistance)。 相关问题:Is it possible to specify a route and then get a list of (long,lat) by specifying a percentage of the route? 【参考方案1】:

一种选择是假设一个恒定的旅行速度并使用第三方库epoly.js的GetPointsAtDistance方法

  // parse the distance and duration out of the response from the DirectionsService
  var duration = 0; // seconds
  var distance = 0; // meters
  for (var i = 0; i < response.routes[0].legs.length; i++) 
    duration += response.routes[0].legs[i].duration.value;
    distance += response.routes[0].legs[i].distance.value;
  
  var points = polyline.GetPointsAtDistance(distance / (duration / 60 / 60));

proof of concept fiddle

代码 sn-p:

var polyline;

function initMap() 
  var directionsService = new google.maps.DirectionsService;
  var directionsDisplay = new google.maps.DirectionsRenderer;
  var map = new google.maps.Map(document.getElementById('map'), 
    zoom: 7,
    center: 
      lat: 41.85,
      lng: -87.65
    
  );
  directionsDisplay.setMap(map);
  polyline = new google.maps.Polyline(
    path: [],
    strokeColor: '#0000FF',
    strokeWeight: 3,
    map: map
  );

  var onChangeHandler = function() 
    calculateAndDisplayRoute(directionsService, directionsDisplay, map);
  ;
  document.getElementById('btn').addEventListener('click', onChangeHandler);
  calculateAndDisplayRoute(directionsService, directionsDisplay, map);

google.maps.event.addDomListener(window, 'load', initMap);

function calculateAndDisplayRoute(directionsService, directionsDisplay, map) 
  directionsService.route(
    origin: document.getElementById('start').value,
    destination: document.getElementById('end').value,
    travelMode: 'DRIVING'
  , function(response, status) 
    if (status === 'OK') 
      // directionsDisplay.setDirections(response);
      renderDirections(response, map);
      var duration = 0; // seconds
      var distance = 0; // meters
      for (var i = 0; i < response.routes[0].legs.length; i++) 
        duration += response.routes[0].legs[i].duration.value;
        distance += response.routes[0].legs[i].distance.value;
      
      document.getElementById('info').innerhtml = "total distance=" + (distance / 1000).toFixed(2) + " km<br>total duration=" + (duration / 60 / 60).toFixed(2) + " hours";
      var points = polyline.GetPointsAtDistance(distance / (duration / 60 / 60));
      // verify the result
      var request = 
        waypoints: [],
        travelMode: 'DRIVING'
      ;
      for (var i = 0; i < points.length; i++) 
        var marker = new google.maps.Marker(
          map: map,
          position: points[i],
          title: "" + i
        );
        if (i == 0) 
          request.origin = marker.getPosition();
         else if ((i > 0) && (i < (points.length - 1))) 
          request.waypoints.push(
            location: marker.getPosition(),
            stopover: true
          );
         else 
          request.destination = marker.getPosition();
        
      
      directionsService.route(request, function(response, status) 
        if (status === 'OK') 
          directionsDisplay.setDirections(response);
          directionsDisplay.setPanel(document.getElementById('dirPanel'));
         else 
          window.alert('Directions request failed due to ' + status);
        
      );
    
  );


function renderDirections(response, map) 
    // directionsDisplay.setDirections(response);
    var bounds = new google.maps.LatLngBounds();

    var legs = response.routes[0].legs;
    for (i = 0; i < legs.length; i++) 
      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);
  
  // 
  /*********************************************************************\
   *                                                                     *
   * 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 *
   */
  // === A method which returns an array of GLatLngs of points a given interval along the path ===
google.maps.Polyline.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 += google.maps.geometry.spherical.computeDistanceBetween(this.getPath().getAt(i), 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;
html,
body 
  height: 100%;
  margin: 0;
  padding: 0;

#map 
  height: 100%;

#floating-panel 
  position: absolute;
  top: 50px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: 'Roboto', 'sans-serif';
  line-height: 30px;
  padding-left: 10px;
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="info"></div>
<div id="floating-panel">
  <b>Start: </b>
  <!-- via via US-36 E and I-55 N -->
  <input id="start" value="Kansas City, MO" />
  <br><b>End: </b>
  <input id="end" value="Chicago IL" />
  <br>
  <input id="btn" value="calculate" type="button" />
</div>
<div id="map"></div>
<div id="dirPanel"></div>

【讨论】:

另外这篇文章对我帮助很大。 ***.com/questions/16711350/…

以上是关于在路线中以固定时间间隔确定中间纬度/经度的主要内容,如果未能解决你的问题,请参考以下文章

以 15 分钟的时间间隔在服务器上发送纬度和经度

Strava - 具有纬度、经度和时间的团体路线接近度

如何删除数据帧中的间隔之间的值

在实时纬度和经度之间绘制路线

较小的 MapKit 缩放间隔 iPhone

检查两条路线(以纬度和经度表示)是不是彼此相对