JS - Google Maps API - 标记点击方向

时间:2017-02-08 10:51:48

标签: javascript google-maps geolocation

我一直致力于使用Google Maps API创建一个网站,用户可以对用户进行地理定位,并向他们展示附近开放/关闭咖啡馆的位置。

我目前正在尝试集成功能,当用户点击标记时,会向用户提供从当前地理位置到咖啡馆的指示,但我无法让它工作,并且想知道是否有人可以提供有关如何实现此目的的任何指示< / p>

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();
}

here's a link that shows where i'm currently at with this - (为了这个例子的目的,我编辑了地理定位功能,以便重定向到收集咖啡馆的城市)

对此的任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

有两件事阻止了您提供的代码:

  1. 您已将地理定位结果更改为var chch中的静态位置,因此var pos从未设置
  2. 您已将directionsDisplay附加到任何面板。我添加了

    <div id="directionsPanel"></div>
    

    到标记和

    directionsDisplay.setPanel(document.getElementById("directionsPanel"));
    
    <{1>}致电

  3. 后的

    事实证明,除此之外,你的代码已经是正确的,结果只是没有显示在任何地方: <击> https://jsfiddle.net/786zeqc7/4/ (你必须使用滚动条滚动输出窗口,因为地图覆盖了整个框架,在点击标记后查看地图容器下方的方向)看到这个更新的小提琴有一个非常业余的列布局预览用途:https://jsfiddle.net/786zeqc7/5/

    超出问题的一些建议:

    1. 您应该检查.setMap()而不是字符串status === google.maps.DirectionsStatus.OK - 这是非常不可能的,但是当API应该更改该常量的值时,它会破坏您的代码。

    2. 您应该查看并修复控制台中的更多JavaScript错误

    3. 对标记图像使用无协议的网址,使其在https环境中也可以使用

    4. 你在全局范围内有var 'OK'以及函数pos的参数 - 这让我很困惑,当你再次查看这段代码时,它也可能会让你感到困惑在几个月或几年内。