Nearby Search

Selecciona la plataforma: Android iOS JavaScript Servicio web
Desarrolladores del Espacio Económico Europeo (EEE)

Nearby Search (nueva) toma uno o más tipos de lugar y devuelve una lista de lugares coincidentes. En el siguiente ejemplo, puedes elegir un tipo de lugar y ver los resultados en un mapa. Haz clic en los marcadores para ver más detalles sobre los lugares.

Nearby Search (nueva) muestra información sobre un conjunto de lugares correspondientes al tipo de lugar que especificas (por ejemplo, restaurant, book_store o bowling_alley. El servicio responde con una lista de lugares que coinciden con los tipos de lugar especificados según el radio de locationRestriction.

Para utilizar Nearby Search (nuevo), debes habilitar "API de Places (nueva)" en tu proyecto de Google Cloud. Consulta Cómo comenzar para obtener información detallada.

Encuentra lugares cercanos

Llama a searchNearby() para obtener una lista de lugares según los tipos de lugar, la ubicación y el radio especificados. Especifica parámetros de búsqueda por medio de una solicitud y, luego, llama a searchNearby(). Los resultados se muestran como una lista de objetos Place que contienen detalles del lugar. El siguiente fragmento muestra un ejemplo de una solicitud y una llamada a searchNearby():

TypeScript

// Get bounds and radius to constrain search.
center = mapElement.center;
let bounds = innerMap.getBounds();
const ne = bounds.getNorthEast();
const sw = bounds.getSouthWest();
const diameter = spherical.computeDistanceBetween(ne, sw);
const radius = Math.min((diameter / 2), 50000); // Radius cannot be more than 50000.

const request = {
    // required parameters
    fields: ['displayName', 'location', 'formattedAddress', 'googleMapsURI'],
    locationRestriction: {
        center,
        radius,
    },
    // optional parameters
    includedPrimaryTypes: [typeSelect.value],
    maxResultCount: 5,
    rankPreference: SearchNearbyRankPreference.POPULARITY,
};

const { places } = await Place.searchNearby(request);

JavaScript

// Get bounds and radius to constrain search.
center = mapElement.center;
let bounds = innerMap.getBounds();
const ne = bounds.getNorthEast();
const sw = bounds.getSouthWest();
const diameter = spherical.computeDistanceBetween(ne, sw);
const radius = Math.min((diameter / 2), 50000); // Radius cannot be more than 50000.
const request = {
    // required parameters
    fields: ['displayName', 'location', 'formattedAddress', 'googleMapsURI'],
    locationRestriction: {
        center,
        radius,
    },
    // optional parameters
    includedPrimaryTypes: [typeSelect.value],
    maxResultCount: 5,
    rankPreference: SearchNearbyRankPreference.POPULARITY,
};
const { places } = await Place.searchNearby(request);
  • Utiliza el parámetro fields (obligatorio) para especificar una lista separada por comas de uno o varios campos de datos.
  • Usa el parámetro locationRestriction (obligatorio) para especificar un radio de hasta 50,000 metros.
  • Usa el parámetro includedPrimaryTypes para especificar uno o varios tipos de lugar para buscar.
  • Usa el parámetro rankPreference para especificar una SearchNearbyRankPreference de POPULARITY o DISTANCE.
  • Consulta la lista completa de parámetros.

Ejemplo

En el siguiente ejemplo, se usa searchNearby() para buscar lugares del tipo seleccionado dentro de los límites del mapa y se propagan marcadores en el mapa para mostrar los resultados.

TypeScript

const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
let innerMap;
const advancedMarkerElement = document.querySelector('gmp-advanced-marker') as google.maps.marker.AdvancedMarkerElement;
let center;
let typeSelect;
let infoWindow;

async function initMap() {
    const { Map, InfoWindow } = await google.maps.importLibrary('maps') as google.maps.MapsLibrary;
    const { LatLng } = await google.maps.importLibrary("core") as google.maps.CoreLibrary;

    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });

    typeSelect = document.querySelector(".type-select");

    typeSelect.addEventListener('change', () => {
        nearbySearch();
    });

    infoWindow = new InfoWindow();

    // Kick off an initial search once map has loaded.
    google.maps.event.addListenerOnce(innerMap, 'idle', () => {
        nearbySearch();
    });
}

async function nearbySearch() {
    const { Place, SearchNearbyRankPreference } = await google.maps.importLibrary('places') as google.maps.PlacesLibrary;
    const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;
    const { spherical } = await google.maps.importLibrary('geometry') as google.maps.GeometryLibrary;
    // Get bounds and radius to constrain search.
    center = mapElement.center;
    let bounds = innerMap.getBounds();
    const ne = bounds.getNorthEast();
    const sw = bounds.getSouthWest();
    const diameter = spherical.computeDistanceBetween(ne, sw);
    const radius = Math.min((diameter / 2), 50000); // Radius cannot be more than 50000.

    const request = {
        // required parameters
        fields: ['displayName', 'location', 'formattedAddress', 'googleMapsURI'],
        locationRestriction: {
            center,
            radius,
        },
        // optional parameters
        includedPrimaryTypes: [typeSelect.value],
        maxResultCount: 5,
        rankPreference: SearchNearbyRankPreference.POPULARITY,
    };

    const { places } = await Place.searchNearby(request);

    if (places.length) {
        const { LatLngBounds } = await google.maps.importLibrary("core") as google.maps.CoreLibrary;
        const bounds = new LatLngBounds();

        // First remove all existing markers.
        for (const marker of mapElement.querySelectorAll('gmp-advanced-marker')) marker.remove();

        // Loop through and get all the results.
        places.forEach(place => {
            if (!place.location) return;
            bounds.extend(place.location);

            const marker = new AdvancedMarkerElement({
                map: innerMap,
                position: place.location,
                title: place.displayName,
            });

            // Build the content of the InfoWindow safely using DOM elements.
            const content = document.createElement('div');
            const address = document.createElement('div');
            address.textContent = place.formattedAddress || '';
            const placeId = document.createElement('div');
            placeId.textContent = place.id;
            content.append(address, placeId);

            if (place.googleMapsURI) {
                const link = document.createElement('a');
                link.href = place.googleMapsURI;
                link.target = '_blank';
                link.textContent = 'View Details on Google Maps';
                content.appendChild(link);
            }

            marker.addListener('gmp-click', () => {
                innerMap.panTo(place.location);
                updateInfoWindow(place.displayName, content, marker);
            });
        });

        innerMap.fitBounds(bounds, 100);

    } else {
        console.log('No results');
    }
}

function updateInfoWindow(title, content, anchor) {
    infoWindow.setContent(content);
    infoWindow.setHeaderContent(title);
    infoWindow.open({
        anchor,
    });
}

initMap();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;
const advancedMarkerElement = document.querySelector('gmp-advanced-marker');
let center;
let typeSelect;
let infoWindow;
async function initMap() {
    const { Map, InfoWindow } = await google.maps.importLibrary('maps');
    const { LatLng } = await google.maps.importLibrary("core");
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });
    typeSelect = document.querySelector(".type-select");
    typeSelect.addEventListener('change', () => {
        nearbySearch();
    });
    infoWindow = new InfoWindow();
    // Kick off an initial search once map has loaded.
    google.maps.event.addListenerOnce(innerMap, 'idle', () => {
        nearbySearch();
    });
}
async function nearbySearch() {
    const { Place, SearchNearbyRankPreference } = await google.maps.importLibrary('places');
    const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
    const { spherical } = await google.maps.importLibrary('geometry');
    // Get bounds and radius to constrain search.
    center = mapElement.center;
    let bounds = innerMap.getBounds();
    const ne = bounds.getNorthEast();
    const sw = bounds.getSouthWest();
    const diameter = spherical.computeDistanceBetween(ne, sw);
    const radius = Math.min((diameter / 2), 50000); // Radius cannot be more than 50000.
    const request = {
        // required parameters
        fields: ['displayName', 'location', 'formattedAddress', 'googleMapsURI'],
        locationRestriction: {
            center,
            radius,
        },
        // optional parameters
        includedPrimaryTypes: [typeSelect.value],
        maxResultCount: 5,
        rankPreference: SearchNearbyRankPreference.POPULARITY,
    };
    const { places } = await Place.searchNearby(request);
    if (places.length) {
        const { LatLngBounds } = await google.maps.importLibrary("core");
        const bounds = new LatLngBounds();
        // First remove all existing markers.
        for (const marker of mapElement.querySelectorAll('gmp-advanced-marker'))
            marker.remove();
        // Loop through and get all the results.
        places.forEach(place => {
            if (!place.location)
                return;
            bounds.extend(place.location);
            const marker = new AdvancedMarkerElement({
                map: innerMap,
                position: place.location,
                title: place.displayName,
            });
            // Build the content of the InfoWindow safely using DOM elements.
            const content = document.createElement('div');
            const address = document.createElement('div');
            address.textContent = place.formattedAddress || '';
            const placeId = document.createElement('div');
            placeId.textContent = place.id;
            content.append(address, placeId);
            if (place.googleMapsURI) {
                const link = document.createElement('a');
                link.href = place.googleMapsURI;
                link.target = '_blank';
                link.textContent = 'View Details on Google Maps';
                content.appendChild(link);
            }
            marker.addListener('gmp-click', () => {
                innerMap.panTo(place.location);
                updateInfoWindow(place.displayName, content, marker);
            });
        });
        innerMap.fitBounds(bounds, 100);
    }
    else {
        console.log('No results');
    }
}
function updateInfoWindow(title, content, anchor) {
    infoWindow.setContent(content);
    infoWindow.setHeaderContent(title);
    infoWindow.open({
        anchor,
    });
}
initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
gmp-map {
  height: 100%;
}

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

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.type-select {
    width: 400px;
    height: 32px;
    border: 1px solid #000;
    border-radius: 10px;
    flex-grow: 1;
    padding: 0 10px;
    margin-left: 10px;
    margin-top: 10px;
  }

HTML

<html>

<head>
  <title>Nearby Search</title>

  <link rel="stylesheet" type="text/css" href="./style.css" />
  <script type="module" src="./index.js"></script>
  <!-- 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: "beta" });</script>
</head>

<body>
  <gmp-map center="45.438646,12.327573" zoom="14" map-id="DEMO_MAP_ID"><!-- Map id is required for Advanced Markers. -->
    <gmp-advanced-marker></gmp-advanced-marker>
    <div id="controls" slot="control-inline-start-block-start">
      <select name="types" class="type-select">
        <option value="cafe" selected>Cafe</option>
        <option value="restaurant">Restaurant</option>
        <option value="museum">Museum</option>
        <option value="monument">Monument</option>
        <option value="park">Park</option>
      </select>
    </div>
  </gmp-map>
</body>

</html>

Prueba la muestra