在 Google 地图 API 中生成一个 Google 地图 URL
In Google Maps API generate a Google Maps URL
有一个项目,其中 Google 地图 API 用于构建路线。
现在我的任务如下:在 Web 应用程序内部使用 Google 地图 API 创建路线,通过在地图上移动路线更改路线后(这是在网络应用程序中)并在生成 link 之后,您可以使用它打开 google 地图(https://www.google.com.ua/maps),考虑到用户在应用程序中的移动,应在其中显示路线。
换句话说:通过 Google 地图 API 生成 link 在 Google 地图中显示更改的路线。
我看了文档,分析了 Google 地图 API 和 Google 地图的问题和答案。所以我没有找到解决方案。
我想澄清一下这个任务是否可以实现?
我了解到您想使用 Google 地图 JavaScript API 生成可拖动的路线,并在 Google 地图网站中打开相同的路线。一旦用户拖动航路点并更改路线,您想更新网站 URL 并在 Google 地图网站上打开更新后的路线。正确吗?
您可以使用以下想法来实现:
google.maps.DirectionsRenderer
可以监听directions_changed
事件。每次路由更改 API 都会触发此事件,因此您可以分析 DirectionsResult
对象以提取在路由生成期间使用的 waypoints 。
https://developers.google.com/maps/documentation/javascript/reference#DirectionsRenderer
您可以使用 Google Maps URLs 为 Google 地图网站或本机应用程序创建通用跨平台 link。有一个方向模式,您可以在其中指定起点、目的地和途经点以及相应的地点 ID。详情请参考文档
您可以从 DirectionsResult
中提取地点 ID,以获取 Google 地图中所需的相应格式化地址 URL 您可以使用的地理编码器服务地图 JavaScript API。请注意,地理编码器服务是异步的,您可能需要使用承诺来实现这部分。
我创建了一个小例子来展示这个想法。请看一下,但请注意,此代码尚未准备好投入生产,它只是概念验证。每次更改路线时,link 'Open in Google Maps' 都会更新。另请注意,我使用了 promises,因此此代码仅适用于现代浏览器。
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
希望对您有所帮助!
有一个项目,其中 Google 地图 API 用于构建路线。
现在我的任务如下:在 Web 应用程序内部使用 Google 地图 API 创建路线,通过在地图上移动路线更改路线后(这是在网络应用程序中)并在生成 link 之后,您可以使用它打开 google 地图(https://www.google.com.ua/maps),考虑到用户在应用程序中的移动,应在其中显示路线。
换句话说:通过 Google 地图 API 生成 link 在 Google 地图中显示更改的路线。
我看了文档,分析了 Google 地图 API 和 Google 地图的问题和答案。所以我没有找到解决方案。
我想澄清一下这个任务是否可以实现?
我了解到您想使用 Google 地图 JavaScript API 生成可拖动的路线,并在 Google 地图网站中打开相同的路线。一旦用户拖动航路点并更改路线,您想更新网站 URL 并在 Google 地图网站上打开更新后的路线。正确吗?
您可以使用以下想法来实现:
google.maps.DirectionsRenderer
可以监听directions_changed
事件。每次路由更改 API 都会触发此事件,因此您可以分析DirectionsResult
对象以提取在路由生成期间使用的 waypoints 。 https://developers.google.com/maps/documentation/javascript/reference#DirectionsRenderer您可以使用 Google Maps URLs 为 Google 地图网站或本机应用程序创建通用跨平台 link。有一个方向模式,您可以在其中指定起点、目的地和途经点以及相应的地点 ID。详情请参考文档
您可以从
DirectionsResult
中提取地点 ID,以获取 Google 地图中所需的相应格式化地址 URL 您可以使用的地理编码器服务地图 JavaScript API。请注意,地理编码器服务是异步的,您可能需要使用承诺来实现这部分。
我创建了一个小例子来展示这个想法。请看一下,但请注意,此代码尚未准备好投入生产,它只是概念验证。每次更改路线时,link 'Open in Google Maps' 都会更新。另请注意,我使用了 promises,因此此代码仅适用于现代浏览器。
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
希望对您有所帮助!