Odkrywanie miejsc za pomocą elementu PlaceSearchElement

Cel

Dowiedz się, jak zintegrować PlaceSearchElement z Mapami Google, aby ułatwić użytkownikom znajdowanie miejsc za pomocą wyszukiwania w pobliżu lub wyszukiwania tekstowego i zwiększyć ich możliwości odkrywania ciekawych miejsc. Użyj elementu kompaktowego ze szczegółami miejsca, aby podać więcej informacji o miejscach wyświetlanych w aplikacji.

Co to jest PlaceSearchElement?

Komponent PlaceSearchElement jest częścią interfejsu Places UI Kit w Maps JavaScript API. Jest to element HTML, który renderuje wyniki wyszukiwania miejsc bezpośrednio w formacie listy w aplikacji. Ten element upraszcza proces wyświetlania miejsc znalezionych za pomocą wyszukiwania w pobliżu lub wyszukiwania tekstowego, co ułatwia użytkownikom odkrywanie miejsc. Gdy użytkownik wybierze miejsce z listy, możesz wyświetlić jego informacje o miejscu na mapie, często za pomocą okna informacyjnego i elementu informacji o miejscu.

Wizualizacja odkrywania miejsc

Poniższy obraz przedstawia przykład działania PlaceSearchElement. Po lewej stronie wyświetla się lista restauracji (PlaceSearchElement). Po wybraniu restauracji jej szczegóły pojawiają się w oknie informacyjnym na mapie, a mapa jest wyśrodkowana na jej lokalizacji.

obraz

Przypadki użycia związane z odkrywaniem miejsc

Integracja PlaceSearchElement może ulepszyć różne aplikacje w różnych branżach:

  • Podróże i turystyka: umożliwiaj turystom wyszukiwanie atrakcji, hoteli lub konkretnych rodzajów kuchni w danym regionie.
  • Nieruchomości: umożliwiaj potencjalnym kupującym lub najemcom znajdowanie pobliskich szkół, supermarketów lub opcji transportu publicznego.
  • Logistyka i usługi: pomagaj kierowcom w znajdowaniu stacji ładowania EV, stacji benzynowych lub konkretnych punktów serwisowych.

Przepływ pracy rozwiązania: wdrażanie odkrywania miejsc

W tej sekcji dowiesz się, jak zintegrować PlaceSearchElement, aby odkrywać miejsca na mapie. Znajdziesz tu też fragmenty kodu do interakcji z interfejsem Places UI Kit. Dowiedz się, jak zainicjować mapę i wdrożyć wyszukiwanie w pobliżu oraz wyszukiwanie tekstowe. Na koniec użyj elementu Szczegóły miejsca, aby wyświetlić więcej informacji o miejscu, gdy użytkownik kliknie jego pinezkę na mapie.

Wymagania wstępne

Zalecamy zapoznanie się z tymi dokumentami:

Włącz w projekcie Maps JavaScript API i Places UI Kit.

Zanim zaczniesz, sprawdź, czy interfejs Maps JavaScript API został wczytany i czy wymagane biblioteki zostały zaimportowane. W tym dokumencie zakładamy też, że masz praktyczną wiedzę na temat tworzenia stron internetowych, w tym znajomość języków HTML, CSS i JavaScript.

Dodawanie mapy do strony

Najpierw dodaj mapę do strony. Ta mapa będzie używana do wyświetlania wyników PlaceSearchElement jako pinezek, które można wybrać.

Mapę możesz dodać do strony na 2 sposoby:

  1. Użycie komponentu internetowego HTML gmp-map.
  2. za pomocą JavaScript,

Fragmenty kodu na tej stronie zostały wygenerowane za pomocą mapy w JavaScripcie.

Mapa może być wyśrodkowana na lokalizacji, w której użytkownik ma wyszukiwać, np. na hotelu, lub zainicjowana tak, aby prosić użytkownika o podanie bieżącej lokalizacji, na której ma zostać wyśrodkowana. Na potrzeby tego dokumentu będziemy używać stałej lokalizacji do zakotwiczenia wyszukiwania.

Jeśli wizualizujesz miejsca w pobliżu stałej lokalizacji, np. hotelu, umieść na mapie znacznik, który będzie reprezentować to miejsce. Na przykład:

obraz

Mapa jest wyśrodkowana na San Francisco, a niebieska pinezka reprezentuje miejsce, w pobliżu którego szukamy. Kolor pinezki został dostosowany za pomocą PinElement. Element sterujący typem mapy został ukryty w interfejsie.

Skonfiguruj PlaceSearchElement

Teraz skonfiguruj kod HTML i CSS, aby wyświetlać PlaceSearchElement. W tym przykładzie element jest umieszczony nad lewą stroną mapy, ale możesz wypróbować różne układy, aby dopasować je do swojej aplikacji.

PlaceSearchElement używa podejścia deklaratywnego. Zamiast konfigurować go w całości w języku JavaScript, typ wyszukiwania definiujesz bezpośrednio w kodzie HTML, umieszczając element żądania, np. <gmp-place-nearby-search-request>, w głównym komponencie <gmp-place-search>.

W kodzie HTML zainicjuj element <gmp-place-search>. Użyj atrybutu selectable, aby włączyć zdarzenia kliknięcia w wynikach. Wewnątrz dodaj element <gmp-place-nearby-search-request>, aby określić, że ten element będzie używany do wyszukiwania w pobliżu.

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

Aby przeprowadzić wstępne wyszukiwanie i wyświetlić wyniki, użyjemy JavaScriptu, aby uzyskać odwołanie do zagnieżdżonego elementu żądania i ustawić jego właściwości. Zainicjuj obiekt Circle, który będzie używany jako locationRestriction, używając pozycji znacznika z poprzedniego kroku jako punktu środkowego. Następnie ustaw właściwości locationRestriction i includedPrimaryTypes w elemencie żądania, aby uruchomić wyszukiwanie.

Fragment kodu wygląda tak:

// Get references to the Place Search and its nested request element
const placeSearchElement = document.querySelector("gmp-place-search");
const placeSearchRequestElement = document.querySelector("gmp-place-nearby-search-request");

// Define the location restriction for the search
const circleRestriction = new Circle({
    center: marker.position,
    radius: 500
});

// Set the properties on the request element to perform an initial search for restaurants.
placeSearchRequestElement.locationRestriction = circleRestriction;
placeSearchRequestElement.includedPrimaryTypes = ['restaurant'];

Oto przykład, jak może wyglądać aplikacja na tym etapie:

obraz

PlaceSearchElement umożliwia 2 opcje wyszukiwania:

Są to elementy zagnieżdżone w elemencie <gmp-place-search>. Następnie możesz wywoływać wyszukiwania, ustawiając właściwości tego zagnieżdżonego elementu żądania za pomocą JavaScriptu.

W tej sekcji opisujemy, jak wdrożyć obie metody.

obraz

Aby umożliwić użytkownikom wyszukiwanie w pobliżu, musisz najpierw udostępnić im element interfejsu, który pozwoli im wybrać typ miejsca. Wybierz metodę wyboru, która najlepiej sprawdza się w Twojej aplikacji, np. listę rozwijaną z wybranymi typami miejsc.

Zalecamy wybranie podzbioru typów, które są odpowiednie dla Twojego przypadku użycia. Jeśli na przykład tworzysz aplikację, która pokazuje turystom, co znajduje się w pobliżu hotelu, możesz wybrać: bakery, coffee_shop, museum, restaurant i tourist_attraction.

Kod HTML powinien zawierać element <gmp-place-search> z zagnieżdżonym elementem <gmp-place-nearby-search-request>.

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

Następnie utwórz detektor JavaScriptu dla zdarzenia change w selektorze typu miejsca. Ten detektor wywoła funkcję, która aktualizuje właściwości elementu <gmp-place-nearby-search-request>, co automatycznie uruchamia nowe wyszukiwanie i aktualizuje listę.

// Get a reference to the nested request element
const placeSearchRequestElement = document.querySelector('gmp-place-nearby-search-request');

// Function to update the place search based on the selected type
function updatePlaceList() {
    const selectedType = placeTypeSelect.value;
    if (!selectedType) {
        // If no type is selected, don't perform a search.
        // You could optionally hide the list or clear previous results here.
        placeSearchElement.style.display = 'none';
        return;
    }
    placeSearchElement.style.display = 'block';

    // Set properties on the request element to trigger a new search
    placeSearchRequestElement.locationRestriction = searchCircle;
    placeSearchRequestElement.maxResultCount = 8;
    placeSearchRequestElement.includedPrimaryTypes = [selectedType];
}

Ten sam parametr searchCircle z etapu konfiguracji jest używany w przypadku locationRestriction. Właściwość includedPrimaryTypes jest ustawiona na wartość wybraną przez użytkownika. Ustawiono też opcjonalny parametr maxResultCount, aby ograniczyć liczbę wyników.

obraz

Aby włączyć wyszukiwanie tekstu, musisz zmienić konfigurację HTML. Zamiast żądania wyszukiwania w pobliżu zagnieżdżasz element <gmp-place-text-search-request>.

<gmp-place-search selectable>
  <gmp-place-text-search-request>
  </gmp-place-text-search-request>
</gmp-place-search>

Dodaj do interfejsu pole tekstowe i przycisk wyszukiwania. Utwórz detektor JavaScriptu dla zdarzenia click przycisku. Moduł obsługi zdarzeń pobierze dane wejściowe użytkownika i zaktualizuje właściwości elementu <gmp-place-text-search-request>, aby przeprowadzić wyszukiwanie.

// Get a reference to the text search request element
const placeTextSearchRequestElement = document.querySelector('gmp-place-text-search-request');
const textSearchInput = document.getElementById('textSearchInput');
const textSearchButton = document.getElementById('textSearchButton');

textSearchButton.addEventListener('click', performTextSearch);

function performTextSearch() {
    const query = textSearchInput.value.trim();
    if (!query) {
        console.log("Search query is empty.");
        return;
    }
    // Set properties on the request element to trigger a new search
    placeTextSearchRequestElement.textQuery = query;
    placeTextSearchRequestElement.locationBias = map.getBounds();
    placeTextSearchRequestElement.maxResultCount = 8;
}

W tym miejscu ustawiamy właściwość textQuery na podstawie danych wejściowych użytkownika. Udostępniamy też locationBias, który używa bieżących granic mapy. Informuje on interfejs API, że ma preferować wyniki z tego obszaru, ale nie ograniczać się tylko do nich. Opcjonalny parametr maxResultCount ogranicza liczbę zwracanych wyników.

Wyświetlanie pinezek i szczegółów miejsc

Teraz aplikacja może wyszukać miejsce i wypełnić element. W następnym kroku ulepszymy jej funkcjonalność przez:

  • Wyświetlanie pinezek na mapie dla każdego miejsca w pliku PlaceSearchElement.
  • Użytkownik może kliknąć pinezkę lub miejsce w PlaceSearchElement, aby wyświetlić więcej informacji o danym miejscu.

Zasada działania tego kroku jest taka sama niezależnie od tego, czy aplikacja korzysta z wyszukiwania w pobliżu czy z wyszukiwania tekstowego.

Najpierw dodaj do kodu JavaScriptu zmienną globalną, która będzie przechowywać znaczniki miejsc. Dzięki temu będziesz mieć możliwość ich usunięcia, gdy zmieni się wyszukiwanie, oraz obsługi zdarzeń kliknięcia.

let markers = {};

Utwórz funkcję dodawania znaczników do mapy. Ta funkcja będzie wywoływana za każdym razem, gdy zostaną wczytane nowe wyniki wyszukiwania. Będzie ona obejmować:

  • Usuń z mapy wszystkie istniejące znaczniki miejsc.
  • Przejrzyj wyniki z PlaceSearchElement i dodaj znacznik dla każdego z nich.
  • Dostosuj granice mapy, aby wszystkie nowe znaczniki były widoczne.

Aby nasłuchiwać, kiedy wyniki wyszukiwania są dostępne, dodaj detektor zdarzeń gmp-load do elementu <gmp-place-search>. To zdarzenie jest wywoływane po zakończeniu wyszukiwania i wyrenderowaniu wyników.

Dodamy detektor wewnątrz funkcji wyszukiwania (np. updatePlaceList) i użyjemy opcji { once: true }, aby upewnić się, że uruchamia się on tylko w przypadku wyników bieżącego wyszukiwania.

// In your search function, after setting the request properties:
placeSearchElement.addEventListener('gmp-load', addMarkers, { once: true });

Funkcja addMarkers wygląda tak:

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

    if (placeSearchElement.places.length > 0) {
        // Remove existing markers
        for (const m in markers) {
            markers[m].map = null;
        }
        markers = {};

        // Loop through each place from the search results
        // and add a marker for each one.
        for (const place of placeSearchElement.places) {
            const marker = new google.maps.marker.AdvancedMarkerElement({
                map: map,
                position: place.location,
            });

            markers[place.id] = marker;
            bounds.extend(place.location);
            marker.collisionBehavior = google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL;

            // Add a click listener for each marker.
            marker.addListener('gmp-click', (event) => {
                // The main logic for showing details will go here.
            });
        }
        // Position the map to display all markers.
        map.setCenter(bounds.getCenter());
        map.fitBounds(bounds);
    }
}

Po wykonaniu tego kroku aplikacja będzie wyglądać tak jak poniżej i będzie mogła wyświetlać znaczniki dla każdego miejsca zwróconego przez PlaceSearchElement:

obraz

Mamy już znaczniki na mapie. Ostatnim krokiem jest obsługa zdarzeń kliknięcia znacznika i elementu, aby wyświetlić okno informacyjne z informacjami o miejscu dostarczonymi przez element Szczegóły miejsca. W tym przykładzie użyjemy kompaktowego elementu informacji o miejscu.

Dodaj do kodu kod HTML elementu kompaktowego ze szczegółowymi informacjami o miejscu, na przykład:

<gmp-place-details-compact orientation="vertical" style="display: none;">
    <gmp-place-all-content></gmp-place-all-content>
    <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
</gmp-place-details-compact>

Wartość style jest ustawiona na display: none. Nie będzie widoczna, dopóki nie będzie wymagana. Do renderowania całej zawartości elementu przekazywany jest parametr gmp-place-all-content. Aby dowiedzieć się, jak wybrać treści do renderowania, zapoznaj się z dokumentacją dotyczącą kompaktowego elementu ze szczegółowymi informacjami o miejscu.

Utwórz zmienną globalną w JavaScript, aby przechowywać odwołanie do elementu kompaktowego ze szczegółami miejsca, i wypełnij ją w kodzie inicjowania, na przykład:

let placeDetailsElement;
...
placeDetailsElement = document.querySelector('gmp-place-details-compact');

W funkcji addMarkers dodaj detektor zdarzeń gmp-click do każdego znacznika i skonfiguruj kompaktowy element informacji o miejscu, aby wyświetlał informacje o miejscu, przekazując identyfikator miejsca bieżącego znacznika.

Po wykonaniu tej czynności otworzy się okno informacyjne, w którym wyświetli się kompaktowy element z informacjami o miejscu, zakotwiczony na znaczniku.

Na koniec mapa jest ustawiana na widoczny obszar wybranego miejsca, dzięki czemu jest ono widoczne.

async function addMarkers() {
          ...
            marker.addListener('gmp-click', (event) => {
                //Set up Place Details Compact Widget
                placeDetailsElement.style.display = "block";
                // Remove any existing place request element
                const existingPlaceRequest = placeDetailsElement.querySelector('gmp-place-details-place-request');
                if (existingPlaceRequest) {
                    existingPlaceRequest.remove();
                }
                // Create and configure the new place request element
                const placeRequestElement = new google.maps.places.PlaceDetailsPlaceRequestElement({ place: place.id });
                // Prepend the new place request element to the main widget
                placeDetailsElement.prepend(placeRequestElement);
                if (infoWindow.isOpen) {
                    infoWindow.close();
                }
                infoWindow.setOptions({
                    content: placeDetailsElement
                });
                infoWindow.open({
                    anchor: marker,
                    map: map
                });
                // Position the map to show the selected place
                placeDetailsElement.addEventListener('gmp-load', () => {
                    map.fitBounds(place.viewport, { top: 500, left: 400 });
                });
            });
          ...
        });
    }
}

Aby umożliwić użytkownikowi kliknięcie miejsca w komponencie listy miejsc w celu wyświetlenia komponentu kompaktowego ze szczegółami miejsca, dodaj do kodu JavaScript poniższy fragment po wywołaniu configureFromSearchNearbyRequest.

placeSearchElement.addEventListener("gmp-select", ({ place }) => {
    if (markers[place.id]) {
        markers[place.id].click();
    }
});

Po wykonaniu tego kroku aplikacja będzie mogła używać wyszukiwania w pobliżu lub wyszukiwania tekstowego do wypełniania elementu listy miejsc. W wyniku tego na mapie pojawią się pinezki. Kliknięcie pinezki lub miejsca w elemencie listy miejsc spowoduje wyświetlenie okna informacyjnego z informacjami o miejscu, które są dostarczane przez element kompaktowy z informacjami o miejscu.

Aplikacja będzie wyglądać tak:

obraz

Podsumowanie

PlaceSearchElement w połączeniu z kompaktowym elementem informacji o miejscu umożliwia łatwe dodawanie do aplikacji Google Maps Platform rozbudowanych funkcji odkrywania miejsc.

Wypróbuj Places UI Kit już dziś, aby umożliwić użytkownikom znajdowanie i odkrywanie miejsc za pomocą wyszukiwania w pobliżu i wyszukiwania tekstowego oraz wyświetlać szczegółowe informacje o miejscach, co ułatwi im interakcję z przypadkami użycia związanymi z odkrywaniem miejsc.

Współtwórcy

Henrik Valve | inżynier DevX