如何根据谷歌自动完成中的类型更改图标(pac-icon)图像

问题描述 投票:0回答:3

我正在使用谷歌地图自动完成 api 来列出位置。在预测中,结果显示为带有位置图标的地址详细信息。但我需要根据图标区分位置类型。 (例如,如果位置地址是机场位置,则应分别显示机场图标)。如何实现这个场景..

<script>
    var map;
    var marker;
    var polygon;
    var bounds;
    var myLatLng = { lat: 51.507605, lng: -0.1300052 };
    var directionsService;
    var directionsDisplay
    window.onload = initMap;

    // This example requires the Places library. Include the libraries=places parameter when you first load the API. For example:
    function initMap() {
        map = new google.maps.Map(document.getElementById("map"), {
            center: myLatLng,
            zoom: 13,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            scaleControl: true
        });
        //map.setCenter(center);
        new AutocompleteDirectionsHandler(map);
        bounds = new google.maps.LatLngBounds();
        google.maps.event.addListenerOnce(map, 'tilesloaded', function (evt) {
            bounds = map.getBounds();
        });
        marker = new google.maps.Marker({
            position: center
        });
        polygon = new google.maps.Polygon({
            path: area,
            geodesic: true,
            strokeColor: '#FFd000',
            strokeOpacity: 1.0,
            strokeWeight: 1,
            fillColor: '#FFd000',
            fillOpacity: 0.10
        });
        polygon.setMap(map);

        directionsService = new google.maps.DirectionsService;
        directionsDisplay = new google.maps.DirectionsRenderer;
        directionsDisplay.setMap(map);
        calculateAndDisplayRoute(directionsService, directionsDisplay);
    }

    function calculateAndDisplayRoute(directionsService, directionsDisplay) {
        //alert($('#<%=tbPickupLoc.ClientID%>').val() + ' | ' + $('#<%=tbDropLoc.ClientID%>').val());

        directionsService.route({
            origin: $('#<%=tbPickupLoc.ClientID%>').val(),
            destination: $('#<%=tbDropLoc.ClientID%>').val(),
            travelMode: 'DRIVING'
        }, function (response, status) {
            if (status === 'OK') {
                directionsDisplay.setDirections(response);
            }
        });
    }

    /**
     * @constructor
    */
    function AutocompleteDirectionsHandler(map) {
        this.map = map;
        this.originPlaceId = null;
        this.destinationPlaceId = null;
        this.travelMode = 'DRIVING';
        var originInput = document.getElementById('<%=tbPickupLoc.ClientID %>');
        var destinationInput = document.getElementById('<%=tbDropLoc.ClientID %>');
        this.directionsService = new google.maps.DirectionsService;
        this.directionsDisplay = new google.maps.DirectionsRenderer;
        this.directionsDisplay.setMap(map);

        var options = {
            //rankBy: google.maps.places.RankBy.PROMINENCE,
            componentRestrictions: { country: "GB" }
        };

        var originAutocomplete = new google.maps.places.Autocomplete(
            originInput, options, { placeIdOnly: true });
        var destinationAutocomplete = new google.maps.places.Autocomplete(
            destinationInput, options, { placeIdOnly: true });

        this.setupPlaceChangedListener(originAutocomplete, 'ORIG');
        this.setupPlaceChangedListener(destinationAutocomplete, 'DEST');
    }

    AutocompleteDirectionsHandler.prototype.setupPlaceChangedListener = function (autocomplete, mode) {
        var me = this;
        autocomplete.bindTo('bounds', this.map);
        autocomplete.addListener('place_changed', function () {
            marker.setMap(null);
            var place = autocomplete.getPlace();
            var newBounds = new google.maps.LatLngBounds();
            newBounds = bounds;
            if (!place.place_id) {
                window.alert("Please select an option from the dropdown list.");
                return;
            }
            marker.setPosition(place.geometry.location);
            marker.setMap(map);
            newBounds.extend(place.geometry.location);
            map.fitBounds(newBounds);

            if (mode === 'ORIG') {
                me.originPlaceId = place.place_id;
                $('#<%=hdnPickupLatLong.ClientID%>').val(place.geometry.location);
                if (google.maps.geometry.poly.containsLocation(place.geometry.location, polygon)) {
                    $('#<%=hdnIsPickupOptArea.ClientID%>').val("true");
                }
                else {
                    $('#<%=hdnIsPickupOptArea.ClientID%>').val("false");
                }
            }
            else {
                me.destinationPlaceId = place.place_id;
                $('#<%=hdnDropLatLong.ClientID%>').val(place.geometry.location);

                if (google.maps.geometry.poly.containsLocation(place.geometry.location, polygon)) {
                    $('#<%=hdnIsDropOptArea.ClientID%>').val("true");
                }
                else {
                    $('#<%=hdnIsDropOptArea.ClientID%>').val("false");
                }
            }
            me.route();
        });
    };

    AutocompleteDirectionsHandler.prototype.route = function () {
        $('#<%=hdnMiles.ClientID%>').val("0");
        $('#<%=hdnDuration.ClientID%>').val("0");
        $('#<%=lbMiles.ClientID%>').text("Distance is " + $('#<%=hdnMiles.ClientID%>').val() + " miles and Duration is " + $('#<%=hdnDuration.ClientID%>').val() + " mins");

        /* Place Service */
        var service = new google.maps.places.PlacesService(map);

        if (this.originPlaceId != null) {
            $('#<%=hdnOriginId.ClientID%>').val(this.originPlaceId);
            service.getDetails({
                placeId: this.originPlaceId
            }, function (place, status) {
                if (status === google.maps.places.PlacesServiceStatus.OK) {
                    $('#<%=hdnPickupAddr.ClientID%>').val(place.formatted_address);
                    var _typesArr = place.types;
                    var _type = _typesArr[0];
                    //alert(_type + "-" + place);

                    if (_type == "airport") {
                        $('#<%=hdnPickupType.ClientID%>').val("A");
                        $('#<%=hdnPickupAddr.ClientID%>').val("");
                    }
                    else if (_type == "lodging") {
                        $('#<%=hdnPickupType.ClientID%>').val("H");
                    }
                }
            });
        }

        if (this.destinationPlaceId != null) {
            $('#<%=hdnDestId.ClientID%>').val(this.destinationPlaceId);

            service.getDetails({
                placeId: this.destinationPlaceId
            }, function (place, status) {
                if (status === google.maps.places.PlacesServiceStatus.OK) {
                    $('#<%=hdnDropAddr.ClientID%>').val(place.formatted_address);

                    var _typesArr = place.types;
                    var _type = _typesArr[0];

                    if (_type == "airport") {
                        $('#<%=hdnDropType.ClientID%>').val("A");
                        $('#<%=hdnDropAddr.ClientID%>').val("");
                    }
                    else if (_type == "lodging") {
                        $('#<%=hdnDropType.ClientID%>').val("H");
                    }
                }
            });
        }

        if (!this.originPlaceId || !this.destinationPlaceId) {
            return;
        }

        var me = this;

        /* Direction Service */
        this.directionsService.route({
            origin: { 'placeId': this.originPlaceId },
            destination: { 'placeId': this.destinationPlaceId },
            travelMode: this.travelMode
        }, function (response, status) {
            if (status === 'OK') {
                me.directionsDisplay.setDirections(response);

                var distance = response.routes[0].legs[0].distance.value;
                var distanceinkm = distance / 1000;
                var distanceinmiles = (distanceinkm * 0.621371);
                distanceinmiles = distanceinmiles.toFixed(2);

                var duration = response.routes[0].legs[0].duration.value;
                var dvDistance = "";

                duration = parseFloat(duration / 60).toFixed(2);

                dvDistance += "Distance is " + $('#<%=hdnMiles.ClientID%>').val() + " miles and ";
                dvDistance += "Duration is " + $('#<%=hdnDuration.ClientID%>').val() + " mins";

            } else {
                window.alert('Directions request failed due to ' + status);
            }
        });
    };

    var center = new google.maps.LatLng(51.5123443, -0.09098519999997734);
    var area = [
        { lat: 51.249669, lng: -0.142219 },
        { lat: 51.273731, lng: 0.146172 },
        { lat: 51.421264, lng: 0.261528 },
        { lat: 51.578564, lng: 0.310967 },
        { lat: 51.691076, lng: 0.126946 },
        { lat: 51.704695, lng: -0.169685 },
        { lat: 51.733621, lng: -0.257576 },
        { lat: 51.588804, lng: -0.534981 },
        { lat: 51.361279, lng: -0.548714 },
        { lat: 51.304649, lng: -0.488289 },
        { lat: 51.249669, lng: -0.142219 }
    ];
</script>

Our Result

Expected Result

google-maps google-maps-api-3
3个回答
1
投票

目前,Maps JavaScript API 的自动完成功能不允许为不同类型的预测设置自定义图标。 Google 问题跟踪器中有一个对此的功能请求:

https://issuetracker.google.com/issues/66101726

请随意为此功能请求加注星标以添加您的投票并订阅通知。

同时,如果您想要自定义图标,则必须使用 Maps JavaScript API 的

AutocompleteService
类来实现您自己的自动完成小部件。

您可以在下面的代码片段中看到这个想法

function initService() {
  var displaySuggestions = function(predictions, status) {
    if (status != google.maps.places.PlacesServiceStatus.OK) {
      alert(status);
      return;
    }

    var items = {};
    var ap = [];
    var arrPlaces = [];

    predictions.forEach(function(prediction) {
      arrPlaces.push(prediction.place_id);
      items[prediction.place_id] = {
        icon_url: "https://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",
        description: prediction.description
      };
      if (prediction.types.includes('transit_station')){
        ap.push(getPlaceTypes(prediction.place_id)); 
      }
    });
    
    Promise.all(ap).then( function(values) { 
      values.forEach(function(value){
        if (value.types.includes('bus_station')) {
          items[value.placeId].icon_url = "https://maps.gstatic.com/mapfiles/place_api/icons/bus-71.png";
        } else {
          items[value.placeId].icon_url = "https://maps.gstatic.com/mapfiles/place_api/icons/train-71.png";
        }
      });
      arrPlaces.forEach(function(pId){
        var li = document.createElement('li');
        var icon_url = items[pId].icon_url;
        var icon = document.createElement("IMG");
        icon.src = icon_url;
        icon.width = 24;
        icon.height = 24;
        li.appendChild(icon);
        li.appendChild(document.createTextNode(items[pId].description));
        document.getElementById('results').appendChild(li);
      });
    }).catch(function(err){
      console.log(err);
    });
  };

  var service = new google.maps.places.AutocompleteService();
  service.getQueryPredictions({ input: 'gare montparnasse' }, displaySuggestions);
  var geocoder = new google.maps.Geocoder();

  function getPlaceTypes(placeId) {
    var p = new Promise(function(resolve, reject){
        geocoder.geocode({placeId: placeId}, function(result, status){
          if (status === google.maps.GeocoderStatus.OK) {
              resolve({
                placeId: placeId,
                types: result[0].types
              }); 
          } else {
              reject(status);
          }
        });
    });
    return p;
  }
}  
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#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;
}
<div id="right-panel">
  <p>Query suggestions for 'gare montparnasse':</p>
  <ul id="results"></ul>
</div>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&language=fr&libraries=places&callback=initService" async defer></script>

完整的示例也可以在 jsbin 上找到:http://jsbin.com/dufizuq/edit?html,output

我希望这有帮助!


0
投票

是的!你可以用这个CSS替换它

.pac-icon {
    background-image: url('../img/geo-alt-fill.svg') !important;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: contain !important;
}

-1
投票

这是执行此操作的谷歌文档:https://developers.google.com/maps/documentation/javascript/places-autocomplete#style_autocomplete

.pac-container  {
  border: 0;
  padding: 10px;
  .pac-item {
    @include font-source-sans($font: 'Lato', $size: 13px, $colour: #a3a4ab, $weight : 300, $lh : 18px);
    margin: 0 -10px;
    padding: 0 10px;
    .pac-matched {
      color: #191818;
      font-size: 15px;
    }
    .pac-item-query {
      color: #6d6c6c;
      font-size: 13px;
      font-weight: 400;
    }
    &:first-child {
      border: 0
    }
  }
}


.pac-icon {
  background: url('https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3.png') no-repeat center;
  background-size: 12px;
  margin: 5px 6px 6px 0;
  vertical-align: middle;
}
.pac-item-selected, .pac-item:hover {
  background: rgba(0,0,0,.04);
}
© www.soinside.com 2019 - 2024. All rights reserved.