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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32596050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:30:17  来源:igfitidea点击:

Google Maps API directionsService.route different from Google Maps Directions

javascriptgoogle-mapsgoogle-maps-api-3directions

提问by damianb

I'm using Google Maps JS API to search for nearby places, i.e. restaurants based on my LatLng :

我正在使用 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);

I get the Results Array and want to show directions to the first place from the array :

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

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);
        }
    });

where bars[0]is the array with results from the searchService.nearbySearchquery.

哪里bars[0]是带有searchService.nearbySearch查询结果的数组。

I do get the directions, however the last "dotted leg" seems to be missing even though the pin is placed correctly. When you compare it to the maps.google.com directions there's that dotted leg between the pin and direction route.

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

My API directions : http://damianbilski.com/temp/api_example.png

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

Maps.google.com directions : http://damianbilski.com/temp/online_example.png

Maps.google.com 方向:http://damianbilski.com/temp/online_example.png

Any idea how to get that last dotted leg with directionsService.route. Many thanks for all your help!

知道如何用directionsService.route. 非常感谢您的帮助!

回答by geocodezip

The Google Maps Javascript API v3 directions service won't do that for you (at least at present). You can add a "dotted" polyline from the end of the directions result to the location of the place if you want to.

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

proof of concept fiddle

概念证明小提琴

Driving + Walking Directions

驾车+步行路线

code snippet:

代码片段:

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"></script>
<div id="map_canvas"></div>

回答by damianb

Thanks for your answer @geocodezip, in case someone else needs it :

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

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

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
            });
        }
    });