Elemento elenco luoghi

PlaceListElement è un elemento HTML che mostra i risultati di una ricerca di luoghi in un elenco. Esistono due modi per configurare l'elemento gmp-place-list:

Richiesta di ricerca per testo

L'esempio seguente mostra l'elemento elenco di luoghi in risposta a una ricerca di testo da parte dell'utente. Quando viene selezionato un risultato, viene visualizzata una finestra informativa con i dettagli del luogo selezionato. Per aggiungere l'elemento Elenco di luoghi alla mappa, aggiungi un elemento gmp-place-list alla pagina HTML, come mostrato nel seguente snippet:

<gmp-map center="-37.813,144.963" zoom="2" map-id="DEMO_MAP_ID">
  <div class="overlay" slot="control-inline-start-block-start">
    <div class="controls">
      <input type="text" class="query-input" />
      <button class="search-button">Search</button>
    </div>
    <div class="list-container">
      <gmp-place-list selectable></gmp-place-list>
    </div>
  </div>
  <gmp-place-details size="large"></gmp-place-details>
</gmp-map>

Per selezionare gli elementi della pagina per l'interazione vengono utilizzate diverse chiamate querySelector:

const map = document.querySelector('gmp-map');
const placeList = document.querySelector('gmp-place-list');
const queryInput = document.querySelector('.query-input');
const searchButton = document.querySelector('.search-button');
const placeDetails = document.querySelector('gmp-place-details');

Quando l'utente fa clic sul pulsante di ricerca, viene chiamata la funzione configureFromSearchByTextRequest e l'elemento Elenco di luoghi mostra i risultati (i marker vengono aggiunti nella funzione di assistenza addMarkers). Lo snippet di seguito mostra il codice per la gestione degli eventi di clic:

searchButton.addEventListener('click', () => {
  for (marker in markers) {
    markers[marker].map = null;
  }
  markers = {};
  if (queryInput.value) {
    placeList
        .configureFromSearchByTextRequest({
          textQuery: queryInput.value,
          locationBias: map.innerMap.getBounds()
        })
        .then(addMarkers);
  }
});

Visualizza l'esempio di codice completo

L'esempio seguente utilizza il componente dell'interfaccia utente Elenco di luoghi per visualizzare i luoghi in base a una ricerca di testo utilizzando configureFromSearchByTextRequest e aggiunge indicatori cliccabili alla mappa per mostrare i dettagli dei luoghi al momento della selezione.

JavaScript

const map = document.querySelector('gmp-map');
const placeList = document.querySelector('gmp-place-list');
const queryInput = document.querySelector('.query-input');
const searchButton = document.querySelector('.search-button');
const placeDetails = document.querySelector('gmp-place-details');
let markers = {};
let infowindow = {};
async function init() {
    await google.maps.importLibrary('places');
    const {
        InfoWindow
    } = await google.maps.importLibrary('maps');
    infowindow = new InfoWindow();
    // Call geolocation helper function to center map.
    findCurrentLocation();
    map.innerMap.setOptions({
        mapTypeControl: false,
        clickableIcons: false,
    });
    // Handle click on search button.
    searchButton.addEventListener('click', () => {
        for (marker in markers) {
            markers[marker].map = null;
        }
        markers = {};
        if (queryInput.value) {
            placeList
                .configureFromSearchByTextRequest({
                    textQuery: queryInput.value,
                    locationBias: map.innerMap.getBounds()
                })
                .then(addMarkers);
        }
    });
    // Handle the user's selection on the Place List.
    placeList.addEventListener('gmp-placeselect', ({
        place
    }) => {
        markers[place.id].click();
    });
}
// Helper function to add markers.
async function addMarkers() {
    const {
        AdvancedMarkerElement
    } = await google.maps.importLibrary('marker');
    const {
        LatLngBounds
    } = await google.maps.importLibrary('core');
    const bounds = new LatLngBounds();
    if (placeList.places.length > 0) {
        placeList.places.forEach((place) => {
            let marker = new AdvancedMarkerElement({
                map: map.innerMap,
                position: place.location
            });
            marker.metadata = {
                id: place.id
            };
            markers[place.id] = marker;
            bounds.extend(place.location);
            marker.addListener('click', (event) => {
                if (infowindow.isOpen) {
                    infowindow.close();
                }
                placeDetails.configureFromPlace(place);
                placeDetails.style.width = '350px';
                infowindow.setOptions({
                    content: placeDetails
                });
                infowindow.open({
                    anchor: marker,
                    map: map.innerMap
                });
                placeDetails.addEventListener('gmp-load', () => {
                    map.innerMap.fitBounds(
                        place.viewport, {
                            top: placeDetails.offsetHeight || 206,
                            left: 200
                        });
                });
            });
            map.innerMap.setCenter(bounds.getCenter());
            map.innerMap.fitBounds(bounds);
        });
    }
}
// Helper function to center map on current device location.
async function findCurrentLocation() {
    const {
        LatLng
    } = await google.maps.importLibrary('core');
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
            (position) => {
                const pos =
                    new LatLng(position.coords.latitude, position.coords.longitude);
                map.innerMap.panTo(pos);
                map.innerMap.setZoom(16);
            },
            () => {
                console.log('The Geolocation service failed.');
                map.innerMap.setZoom(16);
            },
        );
    } else {
        console.log('Your browser doesn\'t support geolocation');
        map.innerMap.setZoom(16);
    }
}

init();

CSS

html,
body {
    height: 100%;
    margin: 0;
}
body {
    display: flex;
    flex-direction: column;
    font-family: Arial, Helvetica, sans-serif;
}
h1 {
    font-size: 16px;
    text-align: center;
}
gmp-map {
    box-sizing: border-box;
    padding: 0 20px 20px;
}
.overlay {
    margin: 20px;
    width: 400px;
}
.controls {
    display: flex;
    gap: 10px;
    margin-bottom: 10px;
    height: 32px;
}
.search-button {
    background-color: #5491f5;
    color: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    width: 100px;
}
.query-input {
    border: 1px solid #ccc;
    border-radius: 5px;
    flex-grow: 1;
    padding: 10px;
}
.list-container {
    height: 600px;
    overflow: auto;
    border-radius: 10px;
}
gmp-place-list {
    background-color: #fff;
}
gmp-place-details {
    width: 320px;
}

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Place List Text Search with Google Maps</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="style.css">

  </head>
  <body>
    <h1>Place List Text Search with Google Maps</h1>
    <gmp-map center="-37.813,144.963" zoom="2" map-id="DEMO_MAP_ID">
        <div class="overlay" slot="control-inline-start-block-start">
          <div class="controls">
            <input type="text" class="query-input" />
            <button class="search-button">Search</button>
          </div>
          <div class="list-container">
            <gmp-place-list selectable></gmp-place-list>
          </div>
        </div>
        <gmp-place-details size="large"></gmp-place-details>
    </gmp-map>
    <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: "YOUR_API_KEY",
        v: "alpha"
      });
    </script>
  </body>
</html>

Richiesta di ricerca nelle vicinanze

L'esempio seguente mostra l'elemento elenco di luoghi in risposta a una ricerca nelle vicinanze. Per semplicità, sono elencati solo tre tipi di luoghi: bar, ristorante e stazione di ricarica EV. Quando viene selezionato un risultato, viene visualizzata una finestra informativa con i dettagli del luogo selezionato. Per aggiungere l'elemento Elenco di luoghi alla mappa, aggiungi un elemento gmp-place-list alla pagina HTML come mostrato nel seguente snippet:

<gmp-map center="-37.813,144.963" zoom="10" map-id="DEMO_MAP_ID">
<div class="overlay" slot="control-inline-start-block-start">
  <div class="controls">
    <select name="types" class="type-select">
      <option value="">Select a place type</option>
      <option value="cafe">Cafe</option>
      <option value="restaurant">Restaurant</option>
      <option value="electric_vehicle_charging_station">
        EV charging station
      </option>
    </select>
    <button class="search-button">Search</button>
  </div>
  <div class="list-container">
    <gmp-place-list selectable></gmp-place-list>
  </div>
</div>

<gmp-place-details size="large"></gmp-place-details>
</gmp-map>

Per selezionare gli elementi della pagina per l'interazione vengono utilizzate diverse chiamate querySelector:

const map = document.querySelector("gmp-map");
const placeList = document.querySelector('gmp-place-list');
const typeSelect = document.querySelector('.type-select');
const searchButton = document.querySelector('.search-button');
const placeDetails = document.querySelector('gmp-place-details');

Quando l'utente fa clic sul pulsante di ricerca, viene chiamata la funzione configureFromSearchNearbyRequest e l'elemento Elenco di luoghi mostra i risultati (i marker vengono aggiunti nella funzione di assistenza addMarkers). Lo snippet riportato di seguito mostra anche il codice per la gestione degli eventi di clic nell'elenco di luoghi utilizzando l'evento gmp-placeselect:

searchButton.addEventListener('click', () => {
  for (marker in markers) {
    markers[marker].map = null;
  }
  markers = {};
  if (typeSelect.value) {
    placeList
        .configureFromSearchNearbyRequest({
          locationRestriction: getContainingCircle(map.innerMap.getBounds()),
          includedPrimaryTypes: [typeSelect.value],
        })
        .then(addMarkers);
    placeList.addEventListener('gmp-placeselect', ({place}) => {
      markers[place.id].click();
    });
  }
});

Visualizza l'esempio di codice completo

L'esempio seguente utilizza il componente dell'interfaccia utente Elenco di luoghi per visualizzare i luoghi in base a una ricerca nelle vicinanze utilizzando configureFromSearchNearbyRequest e aggiunge indicatori cliccabili alla mappa per mostrare i dettagli dei luoghi al momento della selezione.

JavaScript

const map = document.querySelector("gmp-map");
const placeList = document.querySelector("gmp-place-list");
const typeSelect = document.querySelector(".type-select");
const searchButton = document.querySelector(".search-button");
const placeDetails = document.querySelector("gmp-place-details");
let markers = {};
let infowindow = {};
let mapCenter;

async function init() {
    await google.maps.importLibrary("places");
    const {InfoWindow} = await google.maps.importLibrary("maps");
    const { spherical } = await google.maps.importLibrary("geometry");

    infowindow = new InfoWindow();

    function getContainingCircle(bounds) {
        const diameter = spherical.computeDistanceBetween(
            bounds.getNorthEast(),
            bounds.getSouthWest()
        );
        return { center: bounds.getCenter(), radius: diameter / 2 };
    }

    findCurrentLocation();

    map.innerMap.setOptions({
        mapTypeControl: false,
        clickableIcons: false,
    });

    searchButton.addEventListener("click", () => {
        for(marker in markers){
            markers[marker].map = null;
        }
        markers = {};

        if (typeSelect.value) {
            placeList.configureFromSearchNearbyRequest({
                locationRestriction: getContainingCircle(
                    map.innerMap.getBounds()
                ),
                includedPrimaryTypes: [typeSelect.value],
            }).then(addMarkers);

            placeList.addEventListener("gmp-placeselect", ({ place }) => {
                markers[place.id].click();
            });
        }
    });
}

async function addMarkers(){
    const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
    const { LatLngBounds } = await google.maps.importLibrary("core");

    const bounds = new LatLngBounds();

    if(placeList.places.length > 0){
        placeList.places.forEach((place) => {
            let marker = new AdvancedMarkerElement({
                map: map.innerMap,
                position: place.location
            });

            marker.metadata = {id: place.id};
            markers[place.id] = marker;
            bounds.extend(place.location);
            // pinMarkers.push(marker);

            marker.addListener('click',(event) => {
                if(infowindow.isOpen){
                    infowindow.close();
                }
                placeDetails.configureFromPlace(place);
                placeDetails.style.width = "350px";
                infowindow.setOptions({
                    content: placeDetails
                });
                infowindow.open({
                    anchor: marker,
                    map: map.innerMap
                });
                placeDetails.addEventListener('gmp-load',() => {
                    map.innerMap.fitBounds(place.viewport, {top: placeDetails.offsetHeight || 206, left: 200});
                });

            });
            map.innerMap.setCenter(bounds.getCenter());
            map.innerMap.fitBounds(bounds);
        });
    }
}

async function findCurrentLocation(){
    const { LatLng } = await google.maps.importLibrary("core")
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
          (position) => {
            const pos = new LatLng(position.coords.latitude,position.coords.longitude);
            map.innerMap.panTo(pos);
            map.innerMap.setZoom(14);
          },
          () => {
            console.log('The Geolocation service failed.');
            map.innerMap.setZoom(14);
          },
        );
      } else {
        console.log("Your browser doesn't support geolocation");
        map.innerMap.setZoom(14);
      }

}

init();
  

CSS

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

  body {
      display: flex;
      flex-direction: column;
      font-family: Arial, Helvetica, sans-serif;
  }

  h1 {
      font-size: 16px;
      text-align: center;
  }

  gmp-map {
      box-sizing: border-box;
      padding: 0 20px 20px;
  }

  .overlay {
      margin: 20px;
      width: 400px;
  }

  .controls {
      display: flex;
      gap: 10px;
      margin-bottom: 10px;
      height: 32px;
  }

  .search-button {
      background-color: #5491f5;
      color: #fff;
      border: 1px solid #ccc;
      border-radius: 5px;
      width: 100px;
  }

  .type-select {
      border: 1px solid #ccc;
      border-radius: 5px;
      flex-grow: 1;
      padding: 0 10px;
  }

  .list-container {
      height: 600px;
      overflow: auto;
      border-radius: 10px;
  }

  gmp-place-list {
      background-color: #fff;
  }

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Place List Nearby Search with Google Maps</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <h1>Place List Nearby Search with Google Maps</h1>
    <gmp-map center="-37.813,144.963" zoom="10" map-id="DEMO_MAP_ID">
      <div class="overlay" slot="control-inline-start-block-start">
        <div class="controls">
          <select name="types" class="type-select">
            <option value="">Select a place type</option>
            <option value="cafe">Cafe</option>
            <option value="restaurant">Restaurant</option>
            <option value="electric_vehicle_charging_station">
              EV charging station
            </option>
          </select>
          <button class="search-button">Search</button>
        </div>
        <div class="list-container">
          <gmp-place-list selectable></gmp-place-list>
        </div>
      </div>
      <gmp-place-details size="large"></gmp-place-details>
    </gmp-map>

    <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: "YOUR_API_KEY",
        v: "alpha"
      });
    </script>
  </body>
</html>