2017-08-22 174 views
-1

有一个项目中使用Google Maps API来构建路线。在Google Maps API中生成Google Maps URL

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

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

我观看了文档,分析了Google Maps API和Google地图的查询和答案。所以我没有找到解决方案。

我想澄清是否有可能实现这项任务?

+2

你能否更清楚地解释一下? – TechnoTech

+0

@TechnoTech我认为这个问题很复杂,需要对话。 提问你不明白 – Yaros

+0

我会建议发布你已经试过的代码。这样其他人可能会更好地理解你的问题。 – xomena

回答

2

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

您可以通过以下思路实现这一点:

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

  • 您可以使用Google Maps URLs为Google地图网站或原生应用创建通用跨平台链接。有一个方向模式,您可以指定出发地,目的地和方式点以及相应的地点ID。有关更多详细信息,请参阅文档。

  • 您可以从DirectionsResult中提取地点ID,以获取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

我希望这有助于!

+0

类似的服务非常感谢你,你已经很长一段时间了解我。 是的,我正在寻找这个答案。 – Yaros

+0

乐于帮忙,欢迎来到Stack Overflow。如果此答案解决了您的问题,请将其标记为已接受。 – xomena

+0

原谅我的粗鲁,我想问一个更清晰的问题,但我不能在这里发表评论,因为谷歌地图上的链接非常大,并且超过了允许的字符数。 我该如何再问你一个问题? – Yaros