驾驶距离区域 [英] Driving distance area

查看:111
本文介绍了驾驶距离区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法通过Google Maps API确定给定中心点的给定驾驶时间内的边界多边形?

没有,有没有办法计算驾驶时间函数的倒数 - 也就是说,不是需要多少分钟才​​能从A点到B点,这是一种问题,在特定的几分钟内我能从A点到B点多远?当然,我可以找到点之间的时间并假设幼稚的缩放比例,但如果速度限制在路线的大部分区域内变化很大,那么这可能会失败。

解决方案




  • 程式码片段:

      var map; var container; var zoom = 9; var centerPoint = new google.maps.LatLng(35.149534,-90.04898); var dirService = new google.maps.DirectionsService(); var centerMarker; var circleMarkers = Array(); var circlePoints = Array(); var drivePolyPoints = Array(); var searchPolygon,drivePolygon; var distToDrive = 30; // milesvar pointInterval = 30; var searchPoints = []; var polyline; var polylines = []; var redIcon8 =https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png\";function initialize(){map = new google.maps.Map(document.getElementById(map_canvas),{center:centerPoint,zoom:9,mapTypeId:google.maps.MapTypeId.ROADMAP}); google.maps.event.addListener(map,click,mapClick);} google.maps.event.addDomListener(window,load,initialize);函数mapClick(evt){// map.clearOverlays(); circleMarkers = Array(); if(!centerMarker){centerMarker = new google.maps.Marker({position:evt.latLng,map:map}); } else {centerMarker.setMap(null); centerMarker.setPosition(evt.latLng); } centerMarker.setMap(map); searchPoints = getCirclePoints(evt.latLng,distToDrive); drivePolyPoints = Array(); getDirections();} function getCirclePoints(center,radius){var bounds = new google.maps.LatLngBounds(); var circlePoints = Array(); var searchPoints = Array(); (数学){var rLat =(radius / 3963.189)*(180 / PI); // miles var rLng = rLat / cos(center.lat()*(PI / 180)); for(var a = 0; a< 361; a ++){var aRad = a *(PI / 180); var x = center.lng()+(rLng * cos(aRad)); var y = center.lat()+(rLat * sin(aRad)); var point = new google.maps.LatLng(parseFloat(y),parseFloat(x),true); bounds.extend(点); circlePoints.push(点); if(a%pointInterval == 0){searchPoints.push(point); }}} searchPolygon = new google.maps.Polygon({paths:circlePoints,strokeColor:'#0000ff',strokeWeight:1,strokeOpacity:1,fillColor:'#0000ff',fillOpacity:0.2}); searchPolygon.setMap(地图); map.fitBounds(边界);返回searchPoints;} function getDirections(){if(!searchPoints.length){return; } var to = searchPoints.shift(); var request = {origin:centerMarker.getPosition(),destination:to,travelMode:google.maps.TravelMode.DRIVING}; dirService.route(request,function(result,status){if(status == google.maps.DirectionsStatus.OK){var distance = parseInt(result.routes [0] .legs [0] .distance.value / 1609) ; var duration = parseFloat(result.routes [0] .legs [0] .duration.value / 3600).toFixed(2); var path = result.routes [0] .overview_path; var legs = result.routes [0 ] .legs; if(polyline&& polyline.setPath){polyline.setPath([]);} else {polyline = new google.maps.Polyline({path:[],// map:map,strokeColor: #FF0000,strokeOpacity:1});} for(i = 0; i  

      html,body,#map_canvas {height:100%;宽度:100%; margin:0px; < a href =#/>   

     onclick =clearOverlays();>清除< / a>& nbsp; |& nbsp;< a href =#onclick =pointInterval = 30; clearOverlays();> interval 30 )< / a>& nbsp; |& nbsp;< a href =#onclick =pointInterval = 20; clearOverlays();>间隔20< / a>& nbsp; |&  < script src =https://maps.googleapis.com/maps/api/js?libraries=geometry>< / script>< div id =map_canvas>< / div>  


    Is there a way, via the Google Maps API, to determine the bounding polygon within a given driving time of a given central point?

    Failing that, is there a way to calculate the inverse of the driving time function -- that is, instead of "how many minutes does it take to get from point A to point B", a way to ask "how far will I get from point A to point B in a certain number of minutes?" Of course I could just find the time between points and assume naive scaling, but that could be way off if the speed limits vary widely over significant portions of the route.

    解决方案

    code snippet:

    var map;
    var container;
    var zoom = 9;
    var centerPoint = new google.maps.LatLng(35.149534, -90.04898);
    var dirService = new google.maps.DirectionsService();
    var centerMarker;
    var circleMarkers = Array();
    var circlePoints = Array();
    var drivePolyPoints = Array();
    var searchPolygon, drivePolygon;
    var distToDrive = 30; // miles
    var pointInterval = 30;
    var searchPoints = [];
    var polyline;
    var polylines = [];
    var redIcon8 = "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png";
    
    function initialize() {
      map = new google.maps.Map(
        document.getElementById("map_canvas"), {
          center: centerPoint,
          zoom: 9,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
      google.maps.event.addListener(map, "click", mapClick);
    }
    google.maps.event.addDomListener(window, "load", initialize);
    
    function mapClick(evt) {
      // map.clearOverlays();
      circleMarkers = Array();
      if (!centerMarker) {
        centerMarker = new google.maps.Marker({
          position: evt.latLng,
          map: map
        });
      } else {
        centerMarker.setMap(null);
        centerMarker.setPosition(evt.latLng);
      }
      centerMarker.setMap(map);
      searchPoints = getCirclePoints(evt.latLng, distToDrive);
      drivePolyPoints = Array();
      getDirections();
    }
    
    function getCirclePoints(center, radius) {
      var bounds = new google.maps.LatLngBounds();
      var circlePoints = Array();
      var searchPoints = Array();
      with(Math) {
        var rLat = (radius / 3963.189) * (180 / PI); // miles
        var rLng = rLat / cos(center.lat() * (PI / 180));
        for (var a = 0; a < 361; a++) {
          var aRad = a * (PI / 180);
          var x = center.lng() + (rLng * cos(aRad));
          var y = center.lat() + (rLat * sin(aRad));
          var point = new google.maps.LatLng(parseFloat(y), parseFloat(x), true);
          bounds.extend(point);
          circlePoints.push(point);
          if (a % pointInterval == 0) {
            searchPoints.push(point);
          }
        }
      }
      searchPolygon = new google.maps.Polygon({
        paths: circlePoints,
        strokeColor: '#0000ff',
        strokeWeight: 1,
        strokeOpacity: 1,
        fillColor: '#0000ff',
        fillOpacity: 0.2
      });
      searchPolygon.setMap(map);
      map.fitBounds(bounds);
      return searchPoints;
    }
    
    function getDirections() {
      if (!searchPoints.length) {
        return;
      }
      var to = searchPoints.shift();
      var request = {
        origin: centerMarker.getPosition(),
        destination: to,
        travelMode: google.maps.TravelMode.DRIVING
      };
      dirService.route(request, function(result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
          var distance = parseInt(result.routes[0].legs[0].distance.value / 1609);
          var duration = parseFloat(result.routes[0].legs[0].duration.value / 3600).toFixed(2);
          var path = result.routes[0].overview_path;
          var legs = result.routes[0].legs;
          if (polyline && polyline.setPath) {
            polyline.setPath([]);
          } else {
            polyline = new google.maps.Polyline({
              path: [],
              // map: map,
              strokeColor: "#FF0000",
              strokeOpacity: 1
            });
          }
          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);
          shortenAndShow(polyline);
          getDirections();
        } else {
          console.log("Directions request failed, status=" + status + " [from:" + request.origin + " to:" + request.destination + "]");
          getDirections();
        }
      });
    }
    
    function shortenAndShow(polyline) {
      var distToDriveM = distToDrive * 1609;
      var dist = 0;
      var cutoffIndex = 0;
      var copyPoints = Array();
      for (var n = 0; n < polyline.getPath().getLength() - 1; n++) {
        dist += google.maps.geometry.spherical.computeDistanceBetween(polyline.getPath().getAt(n), polyline.getPath().getAt(n + 1));
        //GLog.write(dist + ' - ' + distToDriveM);
        if (dist < distToDriveM) {
          copyPoints.push(polyline.getPath().getAt(n));
        } else {
          break;
        }
      }
      var lastPoint = copyPoints[copyPoints.length - 1];
      var newLine = new google.maps.Polyline({
        path: copyPoints,
        strokeColor: '#ff0000',
        strokeWeight: 2,
        strokeOpacity: 1
      });
      newLine.setMap(map);
      polylines.push(newLine);
      drivePolyPoints.push(lastPoint);
      addBorderMarker(lastPoint, dist)
      if (drivePolyPoints.length > 3) {
        if (drivePolygon) {
          drivePolygon.setMap(null);
        }
        drivePolygon = new google.maps.Polygon({
          paths: drivePolyPoints,
          strokeColor: '#00ff00',
          strokeWeight: 1,
          strokeOpacity: 1,
          fillColor: '#00ff00',
          fillOpacity: 0.4
        });
        drivePolygon.setMap(map);
      }
    }
    
    function addBorderMarker(pt, d) {
      var str = pt.lat().toFixed(6) + ',' + pt.lng().toFixed(6) + ' - Driving Distance: ' + (d / 1609).toFixed(2) + ' miles';
      var marker = new google.maps.Marker({
        position: pt,
        icon: redIcon8,
        title: str
      });
      circleMarkers.push(marker);
      marker.setMap(map);
    }
    
    function clearOverlays() {
      for (var i = 0; i < circleMarkers.length; i++) {
        circleMarkers[i].setMap(null);
      }
      circleMarkers = [];
      for (var i = 0; i < circlePoints.length; i++) {
        circlePoints[i].setMap(null);
      }
      circlePoints = [];
      for (var i = 0; i < polylines.length; i++) {
        polylines[i].setMap(null);
      }
      polylines = [];
      if (searchPolygon && searchPolygon.setMap) searchPolygon.setMap(null);
      if (drivePolygon && drivePolygon.setMap) drivePolygon.setMap(null);
      if (centerMarker && centerMarker.setMap) centerMarker.setMap(null);
    }

    html,
    body,
    #map_canvas {
      height: 100%;
      width: 100%;
      margin: 0px;
      padding: 0px
    }

    <a href="#" onclick="clearOverlays();">Clear</a>&nbsp;|&nbsp;
    <a href="#" onclick="pointInterval=30;clearOverlays();">interval 30 (default)</a>&nbsp;|&nbsp;
    <a href="#" onclick="pointInterval=20;clearOverlays();">interval 20</a>&nbsp;|&nbsp;
    
    <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
    <div id="map_canvas"></div>

    这篇关于驾驶距离区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆