1

有一个项目使用 Google Maps API 来构建路线。

现在我的任务如下:在使用 Google Maps API 创建路线的 Web 应用程序中,通过在地图上移动路线(在 Web 应用程序中)来更改路线并生成您使用的链接之后可以打开谷歌地图(https://www.google.com.ua/maps),考虑到用户在应用程序中的移动,应该在其中显示路线。

换句话说:通过 Google Maps API 生成一个链接,在 Google 地图中显示更改的路线。

我看了文档,分析了谷歌地图 API 和谷歌地图的查询和答案。所以我没有找到解决办法。

我想澄清一下是否有可能实现这个任务?

4

1 回答 1

4

我了解到您希望使用 Google Maps JavaScript API 生成可拖动路线并在 Google Maps 网站中打开相同的路线。一旦用户拖动路径点并更改路线,您想更新网站 URL 并在 Google 地图网站上打开更新的路线。这是对的吗?

您可以使用以下想法来实现这一点:

  • google.maps.DirectionsRenderer可以监听事件directions_changed。每次路线更改时,API 都会触发此事件,因此您可以分析DirectionsResult对象以提取路线生成期间使用的航点。 https://developers.google.com/maps/documentation/javascript/reference#DirectionsRenderer

  • 您可以使用Google 地图 URL为 Google 地图网站或本机应用程序创建通用跨平台链接。有一个方向模式,您可以在其中指定起点、目的地和路点以及相应的地点 ID。有关详细信息,请参阅文档。

  • 您可以从中提取地点 ID DirectionsResult,以获取 Google Maps URL 中所需的相应格式地址,您可以使用 Maps JavaScript API 的 Geocoder 服务。请注意,地理编码器服务是异步的,您可能需要使用 Promise 来实现这部分。

我创建了一个小例子来展示这个想法。请看一下,但请注意,此代码尚未准备好生产,它只是一个概念证明。每次更改路线时,“在 Google 地图中打开”链接都会更新。另请注意,我使用了 Promise,因此此代码仅适用于现代浏览器。

var origin = 'Barcelona, Spain';
var destin = 'Madrid, Spain';
var geocoder;
var hashPlaces = {};

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 6,
    center: {lat: 41.557922, lng: -0.895386},  //Spain.
    gestureHandling: 'greedy'
  });

  var directionsService = new google.maps.DirectionsService;
  var directionsDisplay = new google.maps.DirectionsRenderer({
    draggable: true,
    map: map,
    panel: document.getElementById('right-panel')
  });
  geocoder = new google.maps.Geocoder();

  directionsDisplay.addListener('directions_changed', function() {
    computeTotalDistance(directionsDisplay.getDirections());
    prepareMapLink(directionsDisplay.getDirections());
  });

  displayRoute(origin, destin, directionsService,
      directionsDisplay);
}

function displayRoute(origin, destination, service, display) {
  service.route({
    origin: origin,
    destination: destination,
    waypoints: [{location: 'Lleida, Spain'}, {location: 'Zaragoza, Spain'}],
    travelMode: 'DRIVING',
    avoidTolls: true
  }, function(response, status) {
    if (status === 'OK') {
      display.setDirections(response);
    } else {
      alert('Could not display directions due to: ' + status);
    }
  });
}

function computeTotalDistance(result) {
  var total = 0;
  var myroute = result.routes[0];
  for (var i = 0; i < myroute.legs.length; i++) {
    total += myroute.legs[i].distance.value;
  }
  total = total / 1000;
  document.getElementById('total').innerHTML = total + ' km';
}

function geocodePlaceId (placeId) {
  return new Promise(function(resolve, reject) {
      geocoder.geocode({'placeId': placeId}, function(results, status) {
         if (status === 'OK') {
            var r = Object.create(null);
            r[placeId] = results[0].formatted_address
            resolve(r);
         } else {
            reject('Geocode was not successful for the following reason: ' + status);
         }
      });
  });
}

function prepareMapLink(result) {
  var arrWp = [];
  result.geocoded_waypoints.forEach(function (wp) {
      arrWp.push(wp.place_id);
  });

  var oplaceId = arrWp.shift();
  var dplaceId = arrWp.pop();  

  var arrProm = [];
  arrWp.forEach( function (pId) {
    if (!hashPlaces[pId]) {
      arrProm.push(geocodePlaceId(pId));
    }
  });  

  if (arrProm.length) {
      Promise.all(arrProm).then( function (values) {
          values.forEach(function (val) {
             for (key in val) {
                hashPlaces[key] = val[key];
             }
          });
          constructMapsUrl(oplaceId, dplaceId, arrWp);
      }).catch(reason => { 
          console.log(reason)
      });
  } else {
      constructMapsUrl(oplaceId, dplaceId, arrWp);
  }

}

function constructMapsUrl(originId, destinationId, waypoints) {
    var res = "https://www.google.com/maps/dir/?api=1&";
    res += "origin="+encodeURIComponent(origin)+"&origin_place_id="+originId;
    res += "&destination="+encodeURIComponent(destin)+"&destination_place_id="+destinationId;

    var wpAddr = [];
    waypoints.forEach( function (wp) {
        wpAddr.push(hashPlaces[wp]);
    });

    var waypointsStr = encodeURIComponent(wpAddr.join('|'));
    var waypointsIds = waypoints.join('|');

    res += "&waypoints="+waypointsStr+"&waypoint_place_ids="+waypointsIds+"&travelmode=driving";

    var aElem = document.getElementById("mapLink");
    aElem.setAttribute("href", res);
}
#right-panel {
  font-family: 'Roboto','sans-serif';
  line-height: 30px;
  padding-left: 10px;
}

#right-panel select, #right-panel input {
  font-size: 15px;
}

#right-panel select {
  width: 100%;
}

#right-panel i {
  font-size: 12px;
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map {
  height: 100%;
  float: left;
  width: 63%;
  height: 100%;
}
#right-panel {
  float: right;
  width: 34%;
  height: 100%;
}
.panel {
  height: 100%;
  overflow: auto;
}
<div id="map"></div>
<div id="right-panel">
  <p>Total Distance: <span id="total"></span></p>
  <p><a id="mapLink" href="#" title="Open in Google Maps" target="_blank">Open in Google Maps</a></p>
</div>
<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&callback=initMap"></script>

您也可以在 jsbin 上找到此示例:http://jsbin.com/sazelo/edit?html, output

我希望这有帮助!

于 2017-08-23T18:18:54.820 回答