[英]JS - Google Maps API - Directions on Marker Click
我一直在使用Google Maps API创建一个可以对用户进行地理位置定位的网站,并向他们显示附近的开放式/封闭式咖啡馆所在的位置。
我目前正在尝试集成一些功能,这些功能可以在单击标记时为用户提供从当前地理位置到咖啡馆的指导,但是我很难使它正常工作,并且想知道是否有人可以提供有关如何实现此目标的指导
var service, map, pos, infoWindow, google, directionsService, directionsDisplay;
/* create google map & add styling */
function initMap() {
clicked = null;
directionsService = new google.maps.DirectionsService;
directionsDisplay = new google.maps.DirectionsRenderer({
suppressMarkers: true,
suppressBicyclingLayer: true
});
directionsDisplay.setMap(map);
var styledMapType = new google.maps.StyledMapType([{"featureType": "all", "elementType": "geometry.fill", "stylers": [{"weight": "2.00"}]}, {"featureType": "all", "elementType": "geometry.stroke", "stylers": [{"color": "#9c9c9c"}]}, {"featureType": "all", "elementType": "labels.text", "stylers": [{"visibility": "on"}]}, {"featureType": "administrative.locality", "elementType": "labels.text.fill", "stylers": [{"color": "#ac8d93"}]}, {"featureType": "landscape", "elementType": "all", "stylers": [{"color": "#f2f2f2"}]}, {"featureType": "landscape", "elementType": "geometry.fill", "stylers": [{"color": "#ffffff"}]}, {"featureType": "landscape.man_made", "elementType": "geometry.fill", "stylers": [{"color": "#ffffff"}]}, {"featureType": "poi", "elementType": "all", "stylers": [{"visibility": "off"}]}, {"featureType": "road", "elementType": "all", "stylers": [{"saturation": -100}, {"lightness": 45}]}, {"featureType": "road", "elementType": "geometry.fill", "stylers": [{"color": "#eeeeee"}]}, {"featureType": "road", "elementType": "labels.text.fill", "stylers": [{"color": "#7b7b7b"}]}, {"featureType": "road", "elementType": "labels.text.stroke", "stylers": [{"color": "#ffffff"}]}, {"featureType": "road.highway", "elementType": "all", "stylers": [{"visibility": "simplified"}]}, {"featureType": "road.arterial", "elementType": "labels.icon", "stylers": [{"visibility": "off"}]}, {"featureType": "transit", "elementType": "all", "stylers": [{"visibility": "off"}]}, {"featureType": "water", "elementType": "all", "stylers": [{"color": "#46bcec"}, {"visibility": "on"}]}, {"featureType": "water", "elementType": "geometry.fill", "stylers": [{"color": "#c8d7d4"}]}, {"featureType": "water", "elementType": "labels.text.fill", "stylers": [{"color": "#070707"}]}, {"featureType": "water", "elementType": "labels.text.stroke", "stylers": [{"color": "#ffffff"}]}],
{name: 'Styled Map'});
var chch = {lat: -43.530, lng: 172.646};
map = new google.maps.Map(document.getElementById('map'), {
center: chch,
zoom: 13,
mapTypeControlOptions: {
mapTypeIds: ['roadmap', 'satellite', 'hybrid', 'terrain',
'styled_map']
}
});
map.mapTypes.set('styled_map', styledMapType);
map.setMapTypeId('styled_map');
infoWindow = new google.maps.InfoWindow({map: map});
service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: chch,
openNow: true && false,
radius: 5000,
type: ['cafe']
}, function (results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
});
geolocate();
initAutocomplete();
}
function createMarker(place) {
var marker = new google.maps.Marker({
map: map,
icon: 'img/greenmarker.svg',
position: place.geometry.location
});
var request = {
reference: place.reference
};
service.getDetails(request, function (place, status) {
var open = "";
if (!place.hasOwnProperty('opening_hours')) {
open += "No open times provided";
marker.setIcon('img/greymarker.svg');
} else if (place.opening_hours.open_now === true) {
open += "We are Open";
} else {
open += "We are Closed";
marker.setIcon('img/redmarker.svg');
}
;
if (status === google.maps.places.PlacesServiceStatus.OK) {
var contentStr = '<h5>' + place.name + '</h5><p>' + place.formatted_address;
if (!!place)
contentStr += '<br>' + open;
if (!!place.formatted_phone_number)
contentStr += '<br>' + place.formatted_phone_number;
if (!!place.website)
contentStr += '<br><a target="_blank" href="' + place.website + '">' + place.website + '</a></p>';
} else {
var contentStr = "<h5>No Result, status=" + status + "</h5>";
}
setupInfowindow(marker, infoWindow, contentStr);
});
function setupInfowindow(marker, infoWindow, contentStr) {
marker.addListener('click', function () {
infoWindow.setContent(contentStr);
infoWindow.open(map, this);
});
}
google.maps.event.addListener(marker, 'click', function () {
clicked = marker.getPosition();
calculateAndDisplayRoute(directionsService, directionsDisplay, pos, clicked);
console.log(clicked);
// clicked = {
// lat: this.position.lat(),
// lng: this.position.lng()
// };
});
}
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
new google.maps.Marker({
map: map,
icon: 'img/cross.svg',
position: pos
});
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
map.setCenter(pos);
map.setZoom(14);
}, function () {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function initAutocomplete() {
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
//map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function () {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function () {
var places = searchBox.getPlaces();
if (places.length === 0) {
return;
}
// Clear out the old markers.
markers.forEach(function (marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function (place) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var searched = {
lat: place.geometry.location.lat(),
lng: place.geometry.location.lng()
};
infoWindow.setPosition(searched);
infoWindow.setContent('Location found.');
map.setCenter(searched);
map.setZoom(14);
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: 'img/cross.svg',
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
});
}
function calculateAndDisplayRoute(directionsService, directionsDisplay, pos, clicked) {
directionsService.route({
origin: pos,
destination: clicked,
travelMode: 'BICYCLING'
}, function (response, status) {
if (status === 'OK') {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
//if browser doesn't have geolocation then search box shows
function handleLocationError() {
$(".input__wrapper").show();
}
这是一个链接,显示了我目前所处的位置 -(在本示例中,我编辑了地理位置功能,以便将其重定向到收集咖啡馆的城市)
任何帮助,将不胜感激!
有两件事使您提供的代码无法正常工作:
var chch
的静态位置,因此从未设置过var pos
您没有将directionsDisplay附加到任何面板。 我加了
<div id="directionsPanel"></div>
到标记和
directionsDisplay.setPanel(document.getElementById("directionsPanel"));
在.setMap()
调用之后
事实证明,除此之外,您的代码已经正确,结果只是未在任何地方显示:
https
:
//jsfiddle.net/786zeqc7/4/ (您必须使用滚动条滚动输出窗口,因为地图覆盖了整个框架,请在单击标记后查看地图容器下方的方向)
,以预览的目的查看此更新的小提琴,并提供了相当业余的列布局: https : //jsfiddle.net/786zeqc7/5/
一些超出问题的建议:
您应该检查status === google.maps.DirectionsStatus.OK
而不是字符串'OK'
status === google.maps.DirectionsStatus.OK
这是不太可能的,但是当API应该更改该常量的值时,它将破坏您的代码。
控制台中还会引发一些JavaScript错误,您应该调查并修复
使用无协议的网址作为标记图片,以使其也可在https环境中使用
您拥有全局范围内的var pos
以及函数calculateAndDisplayRoute()
的参数,这使我感到困惑,当您在几个月或几年后再次查看此代码时,也可能使您感到困惑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.