[英]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.