PlaceListElement — это элемент HTML, который отображает результаты поиска места в списке. Существует два способа настройки элемента gmp-place-list
:
- Поиск по текстовому запросу , чтобы настроить виджет для отображения результатов поиска из текстового поиска мест.
- Запрос «Поиск поблизости» , позволяющий настроить виджет для отображения результатов поиска по местам поблизости .
Поиск по текстовому запросу
В следующем примере элемент Place List отображается в ответ на текстовый поиск пользователя. Когда результат выбран, для выбранного места отображается информационное окно с подробной информацией о месте. Чтобы добавить элемент Place List на карту, добавьте элемент gmp-place-list
на HTML-страницу, как показано в следующем фрагменте:
<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>
Для выбора элементов страницы для взаимодействия используются несколько вызовов 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');
Когда пользователь нажимает кнопку поиска, вызывается configureFromSearchByTextRequest
, и элемент Place List отображает результаты (маркеры добавляются во вспомогательной функции addMarkers
). В следующем фрагменте показан код для обработки событий кликов:
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); } });
См. полный пример кода
В следующем примере используется компонент пользовательского интерфейса Place List для отображения мест на основе текстового поиска с помощью configureFromSearchByTextRequest
и добавляется на карту интерактивные маркеры для отображения сведений о месте после выбора.
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>
Искать ближайший запрос
В следующем примере элемент Place List отображается в ответ на поиск поблизости. Для простоты указаны только три типа мест: кафе, ресторан и станция зарядки электромобилей. Когда результат выбран, для выбранного места отображается информационное окно с подробной информацией о месте. Чтобы добавить элемент Place List на карту, добавьте элемент gmp-place-list
на HTML-страницу, как показано в следующем фрагменте:
<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>
Для выбора элементов страницы для взаимодействия используются несколько вызовов 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');
Когда пользователь нажимает кнопку поиска, вызывается configureFromSearchNearbyRequest
, и элемент Place List отображает результаты (маркеры добавляются во вспомогательной функции addMarkers
). В следующем фрагменте также показан код для обработки событий кликов в списке мест с использованием события 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(); }); } });
См. полный пример кода
В следующем примере используется компонент пользовательского интерфейса Place List для отображения мест на основе поиска поблизости с помощью configureFromSearchNearbyRequest
и добавляется на карту интерактивные маркеры для отображения сведений о месте после выбора.
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>