Elemento básico de Place Autocomplete

El widget de BasicPlaceAutocompleteElement crea un campo de entrada de texto, proporciona predicciones de lugares en una lista de selección de la IU y muestra un ID de lugar para el lugar seleccionado.

A diferencia de PlaceAutocompleteElement, el elemento básico simplificado de Place Autocomplete borra el campo de entrada cuando un usuario selecciona una predicción de lugar y también devuelve un objeto Place que contiene solo el ID de lugar, en lugar de un objeto PlacePrediction. Usa este ID de lugar con un elemento de Places UI Kit Details para obtener detalles adicionales del lugar.

Requisitos previos

Para usar el elemento Basic Place Autocomplete, debes habilitar "Places UI Kit" en tu proyecto de Google Cloud. Consulta Cómo comenzar para obtener información detallada.

Agrega un elemento de Basic Place Autocomplete

El elemento Basic Place Autocomplete crea un campo de entrada de texto, proporciona predicciones de lugares en una lista de selección de la IU y muestra un ID de lugar en respuesta a una selección del usuario con el evento gmp-select. En esta sección, se muestra cómo agregar un elemento de Autocomplete básico a una página web o un mapa.

Cómo agregar un elemento de Autocomplete básico a una página web

Para agregar el elemento BasicAutocomplete a una página web, crea un nuevo google.maps.places.BasicPlaceAutocompleteElement y agrégalo a la página como se muestra en el siguiente ejemplo:

  // Request needed libraries.
const {BasicPlaceAutocompleteElement} = await google.maps.importLibrary('places');
// Create the input HTML element, and append it.
const placeAutocomplete = new BasicPlaceAutocompleteElement();
document.body.appendChild(placeAutocomplete);

Cómo agregar un elemento de Autocomplete básico a un mapa

Para agregar un elemento de Autocomplete básico a un mapa, crea una nueva instancia de BasicPlaceAutocompleteElement, agrégala a un div y envíala al mapa como un control personalizado, tal como se muestra en el siguiente ejemplo:

  const placeAutocomplete = new google.maps.places.BasicPlaceAutocompleteElement();
  placeAutocomplete.id = 'place-autocomplete-input';
  placeAutocomplete.locationBias = center;
  const card = document.getElementById('place-autocomplete-card');
  card.appendChild(placeAutocomplete);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

Cómo restringir las predicciones de Autocomplete

De forma predeterminada, Basic Place Autocomplete presenta todos los tipos de lugares, personalizados según la ubicación del usuario. Configura BasicPlaceAutocompleteElementOptions para presentar predicciones más relevantes restringiendo o sesgando los resultados.

La restricción de resultados hace que el elemento Basic Autocomplete ignore cualquier resultado que esté fuera del área de restricción. Una práctica común es restringir los resultados a los límites del mapa. La personalización de resultados hace que el elemento BasicAutocomplete muestre resultados dentro del área especificada, pero algunas coincidencias pueden estar fuera de esa área.

Si no proporcionas límites ni un viewport de mapa, la API intentará detectar la ubicación del usuario a partir de su dirección IP y personalizará los resultados en función de esa ubicación. Establece límites siempre que sea posible. De lo contrario, los distintos usuarios podrían recibir predicciones diferentes. Además, para mejorar las predicciones en general, es importante proporcionar un viewport razonable, como el que estableces cuando realizas desplazamientos laterales o utilizas el zoom en el mapa, o un viewport definido por el desarrollador según la ubicación y el radio del dispositivo. Cuando no hay un radio disponible, se considera que 5 km es un valor predeterminado razonable para el elemento Basic Place Autocomplete. No establezcas un viewport con un radio de cero (un solo punto), un viewport de pocos metros de ancho (menos de 100 m) ni uno que abarque todo el mundo.

Cómo restringir la búsqueda de lugares por país

Si deseas restringir la búsqueda de lugares a uno o más países específicos, usa la propiedad includedRegionCodes para especificar los códigos de país como se muestra en el siguiente fragmento:

const pac = new google.maps.places.BasicPlaceAutocompleteElement({
  includedRegionCodes: ['us', 'au'],
});

Cómo restringir la búsqueda de lugares a los límites del mapa

Para restringir la búsqueda de lugares a los límites de un mapa, usa la propiedad locationRestrictions para agregar los límites, como se muestra en el siguiente fragmento:

const pac = new google.maps.places.BasicPlaceAutocompleteElement({
  locationRestriction: map.getBounds(),
});

Cuando restrinjas la búsqueda a los límites del mapa, asegúrate de agregar un objeto de escucha para actualizar los límites cuando estos cambien:

map.addListener('bounds_changed', () => {
  autocomplete.locationRestriction = map.getBounds();
});

Para quitar la propiedad locationRestriction, configúrala como null.

Cómo personalizar los resultados de la búsqueda de lugares

Personaliza los resultados de la búsqueda a un área circular usando la propiedad locationBias y pasando un radio, como se muestra aquí:

const autocomplete = new google.maps.places.BasicPlaceAutocompleteElement({
  locationBias: {radius: 100, center: {lat: 50.064192, lng: -130.605469}},
});

Para quitar la propiedad locationBias, configúrala como null.

Cómo restringir los resultados de la búsqueda de lugares a determinados tipos

Si deseas restringir los resultados de la búsqueda de lugares a determinados tipos de lugares, utiliza la propiedad includedPrimaryTypes y especifica uno o más tipos, como se muestra a continuación:

const autocomplete = new google.maps.places.BasicPlaceAutocompleteElement({
  includedPrimaryTypes: ['establishment'],
});

Para obtener una lista completa de los tipos admitidos, consulta las tablas A y B de tipos de lugares.

Cómo obtener detalles de un lugar

Para obtener el ID del lugar seleccionado, agrega un objeto de escucha gmp-select a PlaceAutocompleteElement, como se muestra en el siguiente ejemplo:

// Add the gmp-select listener, and display the results.
  placeAutocomplete.addEventListener('gmp-select', async ({ place }) => {
      await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });
      selectedPlaceTitle.textContent = 'Selected Place:';
      selectedPlaceInfo.textContent = JSON.stringify(place.toJSON(), /* replacer */ null, /* space */ 2);
  });
  

En el ejemplo anterior, el objeto de escucha de eventos devuelve un objeto de la clase Place. Llama a place.fetchFields() para obtener los campos de datos de Place Details que necesita tu aplicación.

El objeto de escucha del siguiente ejemplo solicita información sobre un lugar y la muestra en un mapa.

  // Add the gmp-placeselect listener, and display the results on the map.
  //@ts-ignore
  placeAutocomplete.addEventListener('gmp-select', async ({ place }) => {
      await place.fetchFields({ fields: ['displayName', 'formattedAddress', 'location'] });
      // If the place has a geometry, then present it on a map.
      if (place.viewport) {
          map.fitBounds(place.viewport);
      }
      else {
          map.setCenter(place.location);
          map.setZoom(17);
      }
      let content = '<div id="infowindow-content">' +
          '<span id="place-displayname" class="title">' + place.displayName + '</span><br />' +
          '<span id="place-address">' + place.formattedAddress + '</span>' +
          '</div>';
      updateInfoWindow(content, place.location);
      marker.position = place.location;
  });
  

En este ejemplo, se muestra cómo agregar un elemento de Autocomplete básico a un mapa de Google Maps.

JavaScript

const mapContainer = document.getElementById("map-container");
const autocompleteElement = document.querySelector('gmp-basic-place-autocomplete');
const detailsElement = document.querySelector('gmp-place-details-compact');
const mapElement = document.querySelector('gmp-map');
const advancedMarkerElement = document.querySelector('gmp-advanced-marker');
let center = { lat: 40.749933, lng: -73.98633 }; // New York City
async function initMap() {
    //@ts-ignore
    const { BasicPlaceAutocompleteElement, PlaceDetailsElement } = await google.maps.importLibrary('places');
    //@ts-ignore
    const { AdvancedMarkerElement } = await google.maps.importLibrary('marker');
    //@ts-ignore
    const { LatLngBounds } = await google.maps.importLibrary('core');
    // Set the initial map location and autocomplete location bias
    mapElement.center = center;
    autocompleteElement.locationBias = center;
    // Get the underlying google.maps.Map object to add listeners
    const map = mapElement.innerMap;
    // Add the listener tochange locationBias to locationRestriction when the map moves
    map.addListener('bounds_changed', () => {
        autocompleteElement.locationBias = null;
        autocompleteElement.locationRestriction = map.getBounds();
        console.log("bias changed to restriction");
    });
    // Add the listener to update the Place Request element when the user selects a prediction
    autocompleteElement.addEventListener('gmp-select', async (event) => {
        const placeDetailsRequest = document.querySelector('gmp-place-details-place-request');
        placeDetailsRequest.place = event.place.id;
    });
    // Add the listener to update the marker when the Details element loads
    detailsElement.addEventListener('gmp-load', async () => {
        const location = detailsElement.place.location;
        detailsElement.style.display = "block";
        advancedMarkerElement.position = location;
        advancedMarkerElement.content = detailsElement;
        if (detailsElement.place.viewport) {
            map.fitBounds(detailsElement.place.viewport);
        }
        else {
            map.setCenter(location);
            map.setZoom(17);
        }
    });
}
initMap();

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map-container {
  display: flex;
  flex-direction: row;
  height: 100%;
}

#gmp-map {
  height: 100%;
}

gmp-basic-place-autocomplete {
  position: absolute;
  height: 50px;
  top: 10px;
  left: 10px;
  z-index: 1;
  box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.2); 
  color-scheme: light;
  border-radius: 10px;
}

gmp-place-details-compact {
  width: 360px;
  max-height: 300px;
  border: none;
  padding: 0;
  margin: 0;
  position: absolute;
  transform: translate(calc(-180px), calc(-215px)); 
  box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.2); 
  color-scheme: light;
}

/* This creates the pointer attached to the bottom of the element. */
gmp-place-details-compact::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 16px solid transparent;
  border-right: 16px solid transparent;
  border-top: 20px solid var(--gmp-mat-color-surface, light-dark(white, black));
}

HTML

<html>
  <head>
    <title>Place Autocomplete map</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
   <div id="map-container">
      <gmp-basic-place-autocomplete></gmp-basic-place-autocomplete>
      <gmp-place-details-compact orientation="horizontal">
        <gmp-place-details-place-request></gmp-place-details-place-request>
        <gmp-place-all-content></gmp-place-all-content>
      </gmp-place-details-compact>
      <gmp-map zoom="14" map-id="DEMO_MAP_ID">
         <gmp-advanced-marker></gmp-advanced-marker> 
      </gmp-map>
    </div>

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
  </body>
</html>

Prueba la muestra