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, co zwiększy ich możliwości odkrywania ciekawych miejsc. Użyj kompaktowego elementu szczegółów miejsca, aby podać więcej informacji o miejscach wyświetlanych w aplikacji.

Co to jest PlaceSearchElement?

PlaceSearchElement jest częścią 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 wyświetlanie miejsc znalezionych za pomocą wyszukiwania w pobliżu lub wyszukiwania tekstowego, zapewniając użytkownikom płynne odkrywanie miejsc. Gdy użytkownik wybierze miejsce z listy, możesz wyświetlić jego szczegóły na mapie, często za pomocą okna informacyjnego i elementu informacji o miejscu.

Wizualizacja odkrywania miejsc

Na ilustracji poniżej widać przykład działania PlaceSearchElement. Po lewej stronie wyświetlana jest 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 odkrywania miejsc

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

  • Turystyka: umożliwia turystom wyszukiwanie atrakcji, hoteli lub określonych rodzajów kuchni w danym obszarze.
  • Nieruchomości: umożliwia potencjalnym kupującym lub najemcom znajdowanie szkół, supermarketów lub opcji transportu publicznego w pobliżu.
  • Logistyka i usługi: pomaga kierowcom w znajdowaniu stacji ładowania pojazdów elektrycznych, stacji benzynowych lub określonych centrów serwisowych.

Przebieg rozwiązania: implementowanie odkrywania miejsc

W tej sekcji dowiesz się, jak zintegrować PlaceSearchElement, aby odkrywać miejsca na mapie. Znajdziesz tu też fragmenty kodu do interakcji z Places UI Kit. Dowiedz się, jak zainicjować mapę i zaimplementować wyszukiwanie w pobliżu oraz wyszukiwanie tekstowe. Na koniec użyj elementu szczegółów 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 Maps JavaScript API i Places UI Kit w swoim projekcie.

Zanim zaczniesz, sprawdź, czy masz wczytany Maps JavaScript API i zaimportowane wymagane biblioteki. Ten dokument zakłada też praktyczną znajomość tworzenia stron internetowych, w tym HTML, CSS i JavaScript.

Dodawanie mapy do strony

Pierwszym krokiem jest dodanie mapy do strony. Ta mapa będzie używana do wyświetlania wyników PlaceSearchElement jako pinezek, które można wybrać.

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

  1. Za pomocą komponentu internetowego HTML gmp-map web component.
  2. Za pomocą JavaScript.

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

Mapę można wyśrodkować na lokalizacji, w której użytkownik ma wyszukiwać, np. na hotelu, lub zainicjować tak, aby prosiła o bieżącą lokalizację użytkownika w celu wyśrodkowania mapy. Na potrzeby tego dokumentu będziemy używać stałej lokalizacji jako punktu odniesienia do wyszukiwania.

Jeśli wizualizujesz miejsca w pobliżu stałej lokalizacji, np. hotelu, umieść na mapie znacznik reprezentujący to miejsce. Na przykład:

obraz

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

Konfigurowanie PlaceSearchElement

Teraz skonfiguruj HTML i CSS, aby wyświetlać PlaceSearchElement. W tym przykładzie element jest umieszczony po lewej stronie 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 JavaScript, typ wyszukiwania definiujesz bezpośrednio w HTML, zagnieżdżają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 niego dodaj <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ć odniesienie do zagnieżdżonego elementu żądania i ustawić jego właściwości. Zainicjuj okrąg, 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 tego, jak aplikacja może wyglądać na tym etapie:

obraz

PlaceSearchElement umożliwia 2 opcje wyszukiwania:

  • <gmp-place-nearby-search-request> – renderuje wyniki wyszukiwania z wyszukiwania w pobliżu w Miejscach, używając typów miejsc.
  • <gmp-place-text-search-request> – renderuje wyniki wyszukiwania z wyszukiwania tekstowego w Miejscach, używając dowolnego tekstu, np. „Sushi w San Francisco”.

Są to zagnieżdżone elementy wewnątrz <gmp-place-search>. Następnie uruchamiasz wyszukiwanie, ustawiając właściwości tego zagnieżdżonego elementu żądania za pomocą JavaScriptu.

W tej sekcji opisujemy implementację obu metod.

obraz

Aby umożliwić użytkownikom wyszukiwanie w pobliżu, musisz najpierw mieć element interfejsu, w którym mogą wybrać typ miejsca. Wybierz metodę wyboru, która najlepiej pasuje do Twojej aplikacji, np. listę rozwijaną wypełnioną wybranymi typami miejsc.

Zalecamy wybranie podzbioru typów, które są istotne w Twoim przypadku użycia. Jeśli na przykład tworzysz aplikację, która ma pokazywać 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 w nim 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 odbiornik JavaScript dla zdarzenia change w selektorze typu miejsca. Ten odbiornik 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 searchCircle z kroku konfiguracji jest używany jako locationRestriction. Właściwość includedPrimaryTypes jest ustawiona na wartość wybraną przez użytkownika. Możesz też ustawić opcjonalną właściwość maxResultCount, aby ograniczyć liczbę wyników.

obraz

Aby włączyć wyszukiwanie tekstowe, 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 odbiornik JavaScript dla zdarzenia click przycisku. Moduł obsługi zdarzenia 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 przypadku ustawiamy właściwość textQuery na dane wejściowe użytkownika. Podajemy też locationBias za pomocą bieżących granic mapy, co informuje interfejs API, aby preferował wyniki w tym obszarze, ale nie ograniczał ich ściśle. Opcjonalna właściwość maxResultCount ogranicza liczbę zwracanych wyników.

Wyświetlanie pinezek i szczegółów miejsc

Teraz aplikacja może przeprowadzać wyszukiwanie miejsc i wypełniać element. W następnym kroku rozszerzymy jego funkcjonalność, wykonując te czynności:

  • Wyświetlanie pinezek na mapie dla każdego miejsca wypełnionego w PlaceSearchElement.
  • Umożliwianie użytkownikowi kliknięcia pinezki lub miejsca w PlaceSearchElement, aby wyświetlić więcej informacji o danym miejscu.

Zasada tego kroku jest taka sama niezależnie od tego, czy aplikacja używa wyszukiwania w pobliżu, czy wyszukiwania tekstowego.

Najpierw dodaj do kodu JavaScript zmienną globalną, w której będą przechowywane znaczniki miejsc. Umożliwi to usunięcie ich po zmianie wyszukiwania i obsługę 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 wykonywać te czynności:

  • Usuwanie z mapy wszystkich dotychczasowych znaczników miejsc.
  • Przechodzenie przez wyniki z PlaceSearchElement i dodawanie znacznika dla każdego z nich.
  • Dostosowywanie granic 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 odbiornik wewnątrz naszej funkcji wyszukiwania (np. updatePlaceList) i użyjemy opcji { once: true }, aby mieć pewność, że będzie on wywoływany 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

Teraz, gdy mamy znaczniki na mapie, ostatnim krokiem jest obsługa zdarzeń kliknięcia znacznika i elementu, aby wyświetlić okno informacyjne ze informacjami o miejscu, które są udostępniane przez element informacji o miejscu. W tym przykładzie użyjemy kompaktowego elementu informacji o miejscu.

Dodaj do kodu HTML kompaktowy element informacji o miejscu, np.:

<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>

Właściwość style jest ustawiona na display: none; element nie będzie widoczny, dopóki nie będzie potrzebny. Aby wyrenderować całą zawartość elementu, przekazujemy gmp-place-all-content. Aby wybrać, które treści mają być renderowane, zapoznaj się z dokumentacją kompaktowego elementu informacji o miejscu.

Utwórz w JavaScript zmienną globalną, która będzie przechowywać odniesienie do kompaktowego elementu informacji o miejscu, i wypełnij ją w kodzie inicjującym, np.:

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

W funkcji addMarkers dodaj odbiornik zdarzeń gmp-click do każdego znacznika i skonfiguruj kompaktowy element szczegółów miejsca, aby wyświetlał szczegóły miejsca, przekazując identyfikator miejsca bieżącego znacznika.

Gdy to zrobisz, otworzy się okno informacyjne, w którym będzie wyświetlany kompaktowy element informacji o miejscu, zakotwiczony na znaczniku.

Na koniec mapa zostanie ustawiona w widocznym obszarze wybranego miejsca.

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 elemencie listy miejsc i wyświetlenie kompaktowego elementu szczegółów miejsca, dodaj do kodu JavaScript po wywołaniu configureFromSearchNearbyRequest ten kod:

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. Wyniki tego działania będą wyświetlać pinezki na mapie, a kliknięcie pinezki lub miejsca w elemencie listy miejsc spowoduje wyświetlenie okna informacyjnego ze szczegółami miejsca, które są udostępniane przez kompaktowy element szczegółów miejsca.

Aplikacja będzie wyglądać tak:

obraz

Podsumowanie

PlaceSearchElement w połączeniu z kompaktowym elementem informacji o miejscu to uproszczony sposób na dodanie do aplikacji Google Maps Platform zaawansowanych 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świetlanie szczegółowych informacji o miejscach, co zwiększy ich interakcję z przypadkami użycia odkrywania miejsc.

Współtwórcy

Henrik Valve | Inżynier DevX