Google Maps API DirectionsService.route 与 Google Maps Directions 不同

Posted

技术标签:

【中文标题】Google Maps API DirectionsService.route 与 Google Maps Directions 不同【英文标题】:Google Maps API directionsService.route different from Google Maps Directions 【发布时间】:2015-12-12 07:11:03 【问题描述】:

我正在使用 Google Maps JS API 搜索附近的地方,即基于我的 LatLng 的餐馆:

var request = 
        location: myLocation,
        rankBy: google.maps.places.RankBy.DISTANCE,
        types: ['bar', 'cafe', 'food', 'liquor_store', 'lodging', 'meal_delivery', 'meal_takeaway', 'night_club', 'restaurant'],
        keyword: ['bar', 'pub']
    ;
searchService.nearbySearch(request, callback);

我得到了结果数组,并想从数组中显示到第一个位置的方向:

var request = 
        origin: myLocation,
        destination: bars[0].geometry.location,
        travelMode: google.maps.TravelMode.WALKING
;
directionsService.route(request, function (response, status) 
        if (status == google.maps.DirectionsStatus.OK) 
            directionsDisplay.setDirections(response);
            directionsDisplay.setOptions(
                suppressMarkers: true
            );
            var myRoute = response.routes[0].legs[0];
            for (var i = 0; i < myRoute.steps.length; i++) 
                Map.marker(myRoute.steps[i].start_location, myRoute.steps[i].instructions);
            
         else 
            console.log("directionsService : " + status);
        
    );

其中bars[0] 是包含searchService.nearbySearch 查询结果的数组。

我确实得到了方向,但是即使引脚放置正确,最后一个“虚线腿”似乎也不见了。当您将其与 maps.google.com 方向进行比较时,在图钉和方向路线之间会有一条虚线。

我的 API 说明:http://damianbilski.com/temp/api_example.png

Maps.google.com 路线:http://damianbilski.com/temp/online_example.png

知道如何使用directionsService.route 获得最后一条虚线。 非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

Google Maps javascript API v3 路线服务不会为您执行此操作(至少目前是这样)。如果需要,您可以从路线结果的末尾添加一条“虚线”折线到该地点的位置。

proof of concept fiddle

代码 sn-p:

var geocoder;
var map;
var searchService;
var myLocation;
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();

function initialize() 
  var map = new google.maps.Map(
    document.getElementById("map_canvas"), 
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 13,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    );
  myLocation = map.getCenter();
  var marker = new google.maps.Marker(
    position: myLocation,
    map: map
  );
  searchService = new google.maps.places.PlacesService(map);
  directionsDisplay.setMap(map);
  var request = 
    location: myLocation,
    rankBy: google.maps.places.RankBy.DISTANCE,
    types: ['bar', 'cafe', 'food', 'liquor_store', 'lodging', 'meal_delivery', 'meal_takeaway', 'night_club', 'restaurant'],
    keyword: ['bar', 'pub']
  ;
  searchService.nearbySearch(request, function(bars, status) 
    if (status === google.maps.places.PlacesServiceStatus.OK) 
      var barMark = new google.maps.Marker(
        position: bars[0].geometry.location,
        map: map,
        icon: 
          url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png",
          size: new google.maps.Size(7, 7),
          anchor: new google.maps.Point(3.5, 3.5)
        
      );
      var request = 
        origin: myLocation,
        destination: bars[0].geometry.location,
        travelMode: google.maps.TravelMode.WALKING
      ;
      directionsService.route(request, function(response, status) 
        if (status == google.maps.DirectionsStatus.OK) 
          directionsDisplay.setDirections(response);
          directionsDisplay.setOptions(
            suppressMarkers: true,
            preserveViewport: true
          );
          var polyline = getPolyline(response);
          map.setCenter(polyline.getPath().getAt(polyline.getPath().getLength() - 1));
          map.setZoom(19);

          var lineLength = google.maps.geometry.spherical.computeDistanceBetween(bars[0].geometry.location, polyline.getPath().getAt(polyline.getPath().getLength() - 1));
          var lineHeading = google.maps.geometry.spherical.computeHeading(bars[0].geometry.location, polyline.getPath().getAt(polyline.getPath().getLength() - 1));
          var markerO = new google.maps.Marker(
            position: google.maps.geometry.spherical.computeOffset(bars[0].geometry.location, lineLength * 0.1, lineHeading)
          );
          var markerD = new google.maps.Marker(
            position: google.maps.geometry.spherical.computeOffset(bars[0].geometry.location, lineLength * 0.9, lineHeading)
          );

          var markerA = new google.maps.Marker(
            position: google.maps.geometry.spherical.computeOffset(markerO.getPosition(), lineLength / 3, lineHeading - 40)
          );
          var markerB = new google.maps.Marker(
            position: google.maps.geometry.spherical.computeOffset(markerD.getPosition(), lineLength / 3, lineHeading - 140)
          );

          var curvedLine = new GmapsCubicBezier(markerO.getPosition(), markerA.getPosition(), markerB.getPosition(), markerD.getPosition(), 0.01, map);

          var line = new google.maps.Polyline(
            path: [bars[0].geometry.location, polyline.getPath().getAt(polyline.getPath().getLength() - 1)],
            strokeOpacity: 0,
            icons: [
              icon: 
                path: 'M 0,-1 0,1',
                strokeOpacity: 1,
                scale: 4
              ,
              offset: '0',
              repeat: '20px'
            ],
            // map: map
          );
         else 
          console.log("directionsService : " + status);
        
      );
    
  );

google.maps.event.addDomListener(window, "load", initialize);

function getPolyline(result) 
  var polyline = new google.maps.Polyline(
    path: []
  );
  var path = result.routes[0].overview_path;
  var legs = result.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]);
      
    
  
  return polyline;


var GmapsCubicBezier = function(latlong1, latlong2, latlong3, latlong4, resolution, map) 
  var lat1 = latlong1.lat();
  var long1 = latlong1.lng();
  var lat2 = latlong2.lat();
  var long2 = latlong2.lng();
  var lat3 = latlong3.lat();
  var long3 = latlong3.lng();
  var lat4 = latlong4.lat();
  var long4 = latlong4.lng();

  var points = [];

  for (it = 0; it <= 1; it += resolution) 
    points.push(this.getBezier(
      x: lat1,
      y: long1
    , 
      x: lat2,
      y: long2
    , 
      x: lat3,
      y: long3
    , 
      x: lat4,
      y: long4
    , it));
  
  var path = [];
  for (var i = 0; i < points.length - 1; i++) 
    path.push(new google.maps.LatLng(points[i].x, points[i].y));
    path.push(new google.maps.LatLng(points[i + 1].x, points[i + 1].y, false));
  

  var Line = new google.maps.Polyline(
    path: path,
    geodesic: true,
    strokeOpacity: 0.0,
    icons: [
      icon: 
        path: 'M 0,-1 0,1',
        strokeOpacity: 1,
        scale: 4
      ,
      offset: '0',
      repeat: '20px'
    ],
    strokeColor: 'grey'
  );

  Line.setMap(map);

  return Line;
;


GmapsCubicBezier.prototype = 

  B1: function(t) 
    return t * t * t;
  ,
  B2: function(t) 
    return 3 * t * t * (1 - t);
  ,
  B3: function(t) 
    return 3 * t * (1 - t) * (1 - t);
  ,
  B4: function(t) 
    return (1 - t) * (1 - t) * (1 - t);
  ,
  getBezier: function(C1, C2, C3, C4, percent) 
    var pos = ;
    pos.x = C1.x * this.B1(percent) + C2.x * this.B2(percent) + C3.x * this.B3(percent) + C4.x * this.B4(percent);
    pos.y = C1.y * this.B1(percent) + C2.y * this.B2(percent) + C3.y * this.B3(percent) + C4.y * this.B4(percent);
    return pos;
  
;
html,
body,
#map_canvas 
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>

【讨论】:

【参考方案2】:

感谢您的回答@geocodezip,以防其他人需要它:

https://developers.google.com/maps/documentation/javascript/examples/overlay-symbol-dashed

services.directions.set.route(request, function (response, status) 
        if (status == google.maps.DirectionsStatus.OK) 
            services.directions.display.setDirections(response);
            var myRoute = response.routes[0].legs[0];
            var lineSymbol = 
                path: 'M 0,-1 0,1',
                strokeOpacity: 1,
                scale: 4
            ;
            var line = new google.maps.Polyline(
                path: [myRoute.steps[myRoute.steps.length - 1].end_point, to.geometry.location],
                strokeOpacity: 0,
                strokeColor: "#7d7d7d",
                icons: [
                    icon: lineSymbol,
                    offset: '0',
                    repeat: '20px'
                ],
                map: map
            );
        
    );

【讨论】:

以上是关于Google Maps API DirectionsService.route 与 Google Maps Directions 不同的主要内容,如果未能解决你的问题,请参考以下文章

Google Directions API未授权访问iOS

指定航点时,Direction API 仅返回一条路线

Google Maps Place API 和 Google Maps Time Zone API 之间的区别

Android 版 Google Direction API 是免费的吗?

Google Maps API DirectionsService.route 与 Google Maps Directions 不同

无法从Google Direction Service api获得优化路线