O PlaceListElement é um elemento HTML que renderiza os resultados de uma pesquisa de lugares em uma lista. Há duas maneiras de
configurar o elemento gmp-place-list
:
- Pesquisar por solicitação de texto para configurar o widget a renderizar os resultados da pesquisa de uma Pesquisa de texto do Places.
- Pedido de pesquisa por perto para configurar o widget para renderizar resultados de pesquisa de uma Pesquisa por perto do Places.
Pesquisar por solicitação de texto
O exemplo a seguir renderiza o elemento Lista de lugares em resposta a uma pesquisa de texto do usuário. Quando um resultado é selecionado, uma janela de informações mostrando os detalhes do lugar é exibida. Para adicionar o elemento "Place List" ao mapa, adicione um elemento gmp-place-list
à página HTML, conforme mostrado no snippet abaixo:
<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>
Várias chamadas querySelector
são usadas para selecionar os elementos da página para interação:
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 o usuário clica no botão de pesquisa,
configureFromSearchByTextRequest
é chamado e o elemento "Place List" renderiza
os resultados. Os marcadores são adicionados na função auxiliar addMarkers
. O snippet a seguir
mostra o código para processar eventos de clique:
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); } });
Confira o exemplo de código completo
O exemplo a seguir usa o componente de interface da lista de lugares para mostrar lugares com base em uma pesquisa de texto
usando
configureFromSearchByTextRequest
e adiciona marcadores clicáveis ao mapa para mostrar
detalhes do lugar após a seleção.
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>
Pesquisar solicitação nas proximidades
O exemplo a seguir renderiza o elemento Lista de lugares em resposta a uma pesquisa nas proximidades. Para simplificar, apenas três tipos de lugar são listados:
café, restaurante e estação de recarga de VEs. Quando um resultado é selecionado, uma janela de informações mostrando os detalhes do lugar é exibida. Para adicionar o elemento "Place List" ao mapa, adicione um elemento gmp-place-list
à página HTML, conforme mostrado no snippet abaixo:
<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>
Várias chamadas querySelector
são usadas para selecionar os elementos da página para interação:
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 o usuário clica no botão de pesquisa,
configureFromSearchNearbyRequest
é chamado e o elemento Place List exibe
os resultados. Os marcadores são adicionados na função auxiliar addMarkers
. O snippet a seguir também mostra o código para processar eventos de clique na lista de lugares usando o 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(); }); } });
Confira o exemplo de código completo
O exemplo a seguir usa o componente de interface da lista de lugares para mostrar lugares com base em uma pesquisa de lugares próximos usando
configureFromSearchNearbyRequest
e adiciona marcadores clicáveis ao mapa para mostrar detalhes do lugar ao selecionar.
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>