如何知道从任何位置的路径经过的百分比?

时间:2016-04-04 06:39:50

标签: google-maps google-maps-api-3

我有一个预先定义的路径(折线)。

_path = new google.maps.Polyline({
    path: path,
    editable: false,
    map: map,
    strokeColor: '#ff0000',
    strokeWeight: 3,
    strokeOpacity: 70 / 100,
    geodesic: true
});

我也有一些实时位置(我通过Ajax请求接收它们)。

// FOREACH new location:
function addMarker(e_location) {
var on_path = google.maps.geometry.poly.isLocationOnEdge(e_location, _path, 0.0007);
var color = (on_path === true) ? '#12cc32' : '#ff1213';


var marker = new google.maps.Marker({
    position: e_location,
    map: map,
    draggable: false,
    animation: google.maps.Animation.DROP,
    icon: {
        path: google.maps.SymbolPath.CIRCLE,
        scale: 3,
        strokeColor: color
    }
});
marker.info = 'some info...';
}

到目前为止,我可以检查新位置是否位于轨道上,但我无法确定该位置从路径的开头经过了多长时间。

我想说我需要知道新位置距路径的距离百分比。

enter image description here

绿色圆圈表示路径上我想知道每个点的百分比的点。

感谢。

4 个答案:

答案 0 :(得分:1)

这里可能有一个解决方案,您可以使用谷歌找到:Find a point in a polyline which is closest to a latlng

我真的不是js中最好的,也不是解决数学问题。问题,但这里是一个简单的解决方案,我用于编辑折线(点击折线并返回最近的点)。在此基础上,您还可以计算如上所述的仪表。

但是,如果您可以提供路径和标记作为汽车的完整工作示例,那么也许有人可以将其更改为您的确切需求。

HTH,Reinhard

function getNearestVertex(poly, pLatLng) {
// test to get nearest point on poly to the pLatLng point
// marker is on poly, so the nearest vertex is the smallest diff between
    var g = google.maps;    
    var minDist = 9999999999;
var minDiff = 9999999999;
var path = poly.getPath();
var count = path.length || 0;

for (var n = 0; n < count - 1; n++) {
    if (n == 0) {
        point = path.getAt(n);
        dist = g.geometry.spherical.computeDistanceBetween(pLatLng, point);
    }
    var pointb = path.getAt(n + 1);
    distb =  g.geometry.spherical.computeDistanceBetween(pLatLng, pointb);
    distp2p = g.geometry.spherical.computeDistanceBetween(point, pointb);
    var pdiff = dist + distb - distp2p;

    //alert(n + " / " +dist +" + " +distb +" - " +distp2p +" = " +pdiff);
    if (pdiff < minDiff) {
        minDiff = pdiff.toFixed(3);
        index = n;
    }
    point = pointb;
    dist = distb;
} //-> end for
//alert(index +":" + minDiff);
return index +":" + minDiff;

} // - &gt; getNearestVertex的结尾

答案 1 :(得分:1)

在这里,您可以有效地解决问题。此代码将使您在路径总长度上的精度为0.1%。

查看检查员中的“时间轴”。如果您觉得应用程序运行缓慢(不应该),您可能希望减少'path_increment'变量。如果你想要更高的精度,只需增加它。

'path_increment = totaldist / 1000'表示我将您的路径分成1000条并寻找与您的标记最接近的路径。

工作示例:http://jsfiddle.net/fcoramos/tjm0kpby/1/

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="https://maps.googleapis.com/maps/api/js" ></script>
<script>
var map,
    myCenter = new google.maps.LatLng(-32.7,-70.7)


function initialize() {
  var mapProp = {
    center:myCenter,
    zoom:9,
    mapTypeId:google.maps.MapTypeId.HYBRID,
    scaleControl:true };

  map=new google.maps.Map(document.getElementById('map'),mapProp);


  var _path = new google.maps.Polyline({            //Here goes your _path
           path: [{lat: -33.0, lng: -71.0},
                  {lat: -32.9, lng: -71.0},
                  {lat: -32.8, lng: -70.9},
                  {lat: -32.7, lng: -70.85},
                  {lat: -32.6, lng: -70.7},
                  {lat: -32.5, lng: -70.5}],
           strokeColor: 'orange',
           strokeWeight: 2,  
           map: map
           });

map.addListener('click', addmarker);

function addmarker(event) {
         var marker = new google.maps.Marker({
            position:  event.latLng,
            map: map,
            draggable: false,
            icon: {
                path: google.maps.SymbolPath.CIRCLE,
                scale: 3,
                strokeColor: 'red'
            }});

         var xmarker = marker.getPosition().lng();
         var ymarker = marker.getPosition().lat();

         var vertex = _path.getPath();

         var totaldist = 0; // In pseudodegrees

         // We calculate the total length of path in order to yield a relevant precision.
         for (var i = 1; i < vertex.length; i++) {  
                    x1 = vertex.getAt(i-1).lng();
                    y1 = vertex.getAt(i-1).lat();

                    x2 = vertex.getAt(i).lng();
                    y2 = vertex.getAt(i).lat();

                    totaldist = totaldist + Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
                    }

          var path_increment = totaldist / 1000;    // This means precision on 0.1% of total path legth. Adjust accordingly. 
          var dist_to_marker = 1000;
          var closest_x;
          var closest_y;
          var closest_percentage;
          var partialdist = 0;

          for (var i = 1; i < vertex.length; i++) {
               x1 = vertex.getAt(i-1).lng();
               y1 = vertex.getAt(i-1).lat();

               x2 = vertex.getAt(i).lng();
               y2 = vertex.getAt(i).lat();

              var intervertex_dist = Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)) ;
              partialdist = partialdist + intervertex_dist;

              var j=0; 
              var accumulated_dist = 0;
              var azimut = Math.atan2((x2-x1),(y2-y1));

              while ( accumulated_dist < intervertex_dist )
                    { 
                      j++;

                      var delta_newx = path_increment * Math.sin(azimut);
                      var delta_newy = path_increment * Math.cos(azimut);

                      var newx = x1 + (delta_newx*j);
                      var newy = y1 + (delta_newy*j);

                      var new_dist_to_marker = Math.sqrt(Math.pow(xmarker-newx,2)+Math.pow(ymarker-newy,2));


                      if (new_dist_to_marker < dist_to_marker) {
                           closest_percentage = ((partialdist - intervertex_dist + ( path_increment * j)) / totaldist ) * 100; 
                           closest_x = newx;
                           closest_y = newy;
                           dist_to_marker = new_dist_to_marker;
                           }
                      accumulated_dist = accumulated_dist + path_increment;
                    }
              }

        var marker = new google.maps.Marker({
            position:  {lat: closest_y, lng: closest_x},
            map: map });

        var infowindow = new google.maps.InfoWindow({ content:Math.round(closest_percentage)+'%'  }); 
        infowindow.open(map,marker);
   }
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map" style="width:500px;height:500px;"></div>
</body>
</html>

答案 2 :(得分:0)

我们在这里有趣的项目。试试这个。

  1. 确定原始“折线总长度”。如何做到这一点已经在thread中得到了回答。然后,您可以将其分配给“original_length”之类的变量。
  2. 由于您使用的是实时,因此您每次都必须更新“折线总长度”。创建另一个变量,如“realtime_length”,它接收更新的长度。
  3. 确定从起点起经过的距离百分比:
  4.   

    function realtimeUpdate(){

    var product = (realtime_length/orginal_length) * 100;
    var distance_elapsed_percent = 100 - product;
    }
    
    1. 现在,为了确保对象(汽车)在“正确路径”的范围内(以避免不必要的结果),您需要学习如何使用containsLocation()。您的应用程序逻辑应确保经过的距离仅在正确的路径/包含位置的范围内有效。
    2. if( carA && carB is inside polygon){
           calculateDistanceElapsed();
      }else{
         print("Car is not on track");
      }
      

      希望伪代码有用:)

答案 3 :(得分:0)

&#34; ...了解汽车在路径上的确切位置的功能。&#34;

嗯,我想你必须计算/得到最近的路径顶点(点)到汽车位置点。然后你可以逐点累加路径km,最后汽车的km指向最近的顶点。

这是一种选择吗?莱因哈德

PS:您可以查看此示例:http://wtp2.appspot.com/cSnapToRouteDemo.html 如果你真的需要,也可以在这里找到最近顶点的计算。 有很多变化和解决方案。