Découverte de lieux avec PlaceSearchElement

Objectif

Découvrez comment intégrer l'élément PlaceSearchElement à Google Maps pour aider les utilisateurs à trouver des lieux à l'aide de la recherche à proximité ou de la recherche textuelle, et ainsi améliorer leur capacité à explorer des points d'intérêt. Utilisez l'élément Place Details Compact pour fournir plus d'informations sur les lieux affichés dans votre application.

Qu'est-ce que l'élément PlaceSearchElement ?

L'élément PlaceSearchElement fait partie du Kit UI pour Places dans l'API Maps JavaScript. Il s'agit d'un élément HTML qui affiche les résultats d'une recherche de lieu directement dans un format de liste au sein de votre application. Cet élément simplifie le processus d'affichage des lieux trouvés à l'aide d'une recherche à proximité ou d'une recherche textuelle, offrant ainsi une expérience utilisateur fluide pour la découverte de lieux. Lorsqu'un utilisateur sélectionne un lieu dans la liste, vous pouvez afficher ses détails sur la carte, souvent à l'aide d'une fenêtre d'informations et de l'élément Place Details.

Visualiser la découverte de lieux

L'image suivante montre un exemple de l'élément PlaceSearchElement en action. À gauche, une liste de restaurants s'affiche (l'élément PlaceSearchElement). Lorsqu'un restaurant est sélectionné, ses détails apparaissent dans une fenêtre d'informations sur la carte, et la carte se centre sur son emplacement.

image

Cas d'utilisation pour la découverte de lieux

L'intégration de l'élément PlaceSearchElement peut améliorer diverses applications dans différents secteurs :

  • Voyages et tourisme : permet aux touristes de rechercher des attractions, des hôtels ou des types de cuisine spécifiques dans une zone.
  • Immobilier : permet aux acheteurs ou locataires potentiels de trouver des écoles, des supermarchés ou des options de transport en commun à proximité.
  • Logistique et services : aide les conducteurs à trouver des bornes de recharge pour véhicules électriques, des stations-service ou des centres de services spécifiques.

Workflow de la solution : implémenter la découverte de lieux

Cette section vous explique comment intégrer l'élément PlaceSearchElement pour découvrir des lieux sur une carte, et inclut des extraits de code pour interagir avec le Kit UI pour Places. Découvrez comment initialiser la carte et implémenter la recherche à proximité et la recherche textuelle. Enfin, utilisez l'élément Place Details pour afficher plus d'informations sur un lieu lorsqu'un utilisateur clique sur son repère sur la carte.

Prérequis

Il est recommandé de vous familiariser avec la documentation suivante :

  • PlaceSearchElement : permet d'exposer des lieux à l'aide de la recherche à proximité ou de la recherche textuelle.
  • Élément Place Details : permet d'afficher les détails d'un lieu individuel.
  • API Maps JavaScript : permet d'afficher une carte sur votre page et d'importer le Kit UI pour Places.

Activez l'API Maps JavaScript et le Kit UI pour Places sur votre projet.

Avant de commencer, vérifiez que vous avez chargé l'API Maps JavaScript et importé les bibliothèques requises. Ce document suppose également une connaissance pratique du développement Web, y compris HTML, CSS et JavaScript.

Ajouter une carte à la page

La première étape consiste à ajouter une carte à votre page. Cette carte sera utilisée pour afficher les résultats de l'élément PlaceSearchElement sous forme de repères sélectionnables.

Vous pouvez ajouter une carte à une page de deux manières :

  1. À l'aide d'un gmp-map composant Web HTML.
  2. À l'aide de JavaScript.

Les extraits de code de cette page ont été générés à l'aide d'une carte JavaScript.

La carte peut être centrée sur un lieu autour duquel vous souhaitez que l'utilisateur effectue une recherche, comme un hôtel, ou initialisée pour demander la position actuelle de l'utilisateur afin de centrer la carte. Pour les besoins de ce document, nous utiliserons un lieu fixe pour ancrer la recherche.

Si vous visualisez des lieux à proximité d'un lieu fixe, tel qu'un hôtel, placez un repère sur la carte pour représenter ce lieu. Exemple :

image

La carte est centrée sur San Francisco, avec un repère bleu représentant le lieu que nous recherchons à proximité. La couleur du repère a été personnalisée à l'aide de PinElement. Le contrôle du type de carte a été masqué dans l'interface utilisateur.

Configurer l'élément PlaceSearchElement

Configurez maintenant le code HTML et CSS pour afficher l'élément PlaceSearchElement. Dans cet exemple, l'élément est flottant sur le côté gauche de la carte, mais vous pouvez essayer différentes mises en page pour l'adapter à votre application.

L'élément PlaceSearchElement utilise une approche déclarative. Au lieu de le configurer entièrement en JavaScript, vous définissez le type de recherche directement dans votre code HTML en imbriquant un élément de requête, tel que <gmp-place-nearby-search-request>, dans le composant <gmp-place-search> principal.

Dans votre code HTML, initialisez un élément <gmp-place-search>. Utilisez l'attribut selectable pour activer les événements de clic sur les résultats. À l'intérieur, ajoutez un <gmp-place-nearby-search-request> pour spécifier que cet élément sera utilisé pour la recherche à proximité.

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

Pour effectuer une recherche initiale et afficher les résultats, nous allons utiliser JavaScript pour obtenir une référence à l'élément de requête imbriqué et définir ses propriétés. Initialisez un cercle à utiliser comme locationRestriction, en utilisant la position du repère de l'étape précédente comme point central. Ensuite, définissez les propriétés locationRestriction et includedPrimaryTypes sur l'élément de requête pour déclencher la recherche.

Voici l'extrait de code correspondant :

// 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'];

Voici un exemple de l'apparence de l'application à ce stade :

image

L'élément PlaceSearchElement propose deux options de recherche :

Il s'agit d'éléments imbriqués dans <gmp-place-search>. Vous déclenchez ensuite des recherches en définissant des propriétés sur cet élément de requête imbriqué à l'aide de JavaScript.

Cette section décrit l'implémentation des deux méthodes.

image

Pour permettre aux utilisateurs d'effectuer une recherche à proximité, vous avez d'abord besoin d'un élément d'interface utilisateur pour qu'ils puissent sélectionner un type de lieu. Choisissez la méthode de sélection qui convient le mieux à votre application, par exemple une liste déroulante contenant une sélection de types de lieux.

Il est recommandé de choisir un sous-ensemble de types pertinents pour votre cas d'utilisation. Par exemple, si vous développez une application pour montrer aux touristes ce qui se trouve à proximité d'un hôtel, vous pouvez choisir : bakery, coffee_shop, museum, restaurant et tourist_attraction.

Votre code HTML doit contenir l'élément <gmp-place-search> avec un <gmp-place-nearby-search-request> imbriqué à l'intérieur.

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

Ensuite, créez un écouteur JavaScript pour l'événement change sur votre sélecteur de type de lieu. Cet écouteur appellera une fonction qui met à jour les propriétés de l' <gmp-place-nearby-search-request> élément, ce qui déclenche automatiquement une nouvelle recherche et met à jour la liste.

// 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];
}

Le même searchCircle que celui de l'étape de configuration est utilisé pour locationRestriction. La propriété includedPrimaryTypes est définie sur la valeur de la sélection de l'utilisateur. Un élément maxResultCount facultatif est également défini pour limiter le nombre de résultats.

image

Pour activer la recherche textuelle, votre configuration HTML doit être modifiée. Au lieu de la requête de recherche à proximité, vous imbriquez un élément <gmp-place-text-search-request>.

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

Ajoutez une entrée de texte et un bouton de recherche à votre interface utilisateur. Créez un écouteur JavaScript pour l'événement click du bouton. Le gestionnaire d'événements prendra l'entrée de l'utilisateur et mettra à jour les propriétés de l'élément <gmp-place-text-search-request> pour effectuer la recherche.

// 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;
}

Ici, nous définissons la propriété textQuery avec l'entrée de l'utilisateur. Nous fournissons également un élément locationBias à l'aide des limites actuelles de la carte, ce qui indique à l'API de privilégier les résultats dans cette zone sans les limiter strictement. Un élément maxResultCount facultatif limite le nombre de résultats renvoyés.

Afficher les repères et les détails des lieux

L'application peut désormais effectuer une recherche de lieu et remplir l'élément. À l'étape suivante, nous allons améliorer ses fonctionnalités en procédant comme suit :

  • Afficher des repères sur la carte pour chaque lieu renseigné dans l'élément PlaceSearchElement.
  • Permettre à un utilisateur de cliquer sur un repère ou sur le lieu dans l'élément PlaceSearchElement pour afficher plus d'informations sur ce lieu particulier.

Le principe de cette étape est le même, que l'application utilise une recherche à proximité ou une recherche textuelle.

Tout d'abord, ajoutez une variable globale à votre code JavaScript pour stocker les repères de lieu. Cela vous permettra de les supprimer lorsque la recherche change et de gérer les événements de clic.

let markers = {};

Créez une fonction pour ajouter des repères à la carte. Cette fonction sera appelée chaque fois que de nouveaux résultats de recherche seront chargés. Elle effectuera les actions suivantes :

  • Supprimer tous les repères de lieu existants de la carte.
  • Parcourir les résultats de l'élément PlaceSearchElement et ajouter un repère pour chacun d'eux.
  • Ajuster les limites de la carte afin que tous les nouveaux repères soient visibles.

Pour écouter le moment où les résultats de recherche sont disponibles, ajoutez un gmp-load écouteur d'événements à l'élément <gmp-place-search>. Cet événement se déclenche une fois la recherche terminée et les résultats affichés.

Nous allons ajouter l'écouteur dans notre fonction de recherche (par exemple, updatePlaceList) et utiliser l'option { once: true } pour nous assurer qu'il ne se déclenche que pour les résultats de la recherche actuelle.

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

La fonction addMarkers se présente comme suit :

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);
    }
}

Une fois cette étape terminée, l'application se présentera comme suit, avec la possibilité d'afficher des repères pour chaque lieu renvoyé par l'élément PlaceSearchElement :

image

Maintenant que nous avons des repères sur la carte, la dernière étape consiste à gérer les événements de clic sur les repères et les éléments pour afficher une fenêtre d'informations contenant les détails du lieu, fournis par l' élément Place Details. Dans cet exemple, nous allons utiliser l'élément Place Details Compact.

Ajoutez le code HTML de l'élément Place Details Compact à votre code, par exemple :

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

Le style est défini sur display: none ; il ne sera visible que lorsque cela sera nécessaire. gmp-place-all-content est transmis pour afficher tout le contenu de l'élément. Pour choisir le contenu à afficher, consultez la documentation de l'élément Place Details Compact .

Créez une variable globale en JavaScript pour contenir une référence à l'élément Place Details Compact, et remplissez-la dans votre code d'initialisation, par exemple :

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

Dans la fonction addMarkers, ajoutez un écouteur d'événements gmp-click à chaque repère, et configurez l'élément Place Details Compact pour afficher les détails du lieu en transmettant l'ID de lieu du repère actuel.

Une fois cette opération effectuée, une fenêtre d'informations s'ouvre pour afficher l'élément Place Details Compact, ancré sur le repère.

Enfin, la carte est positionnée sur la fenêtre d'affichage du lieu sélectionné, ce qui la rend visible.

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 });
                });
            });
          ...
        });
    }
}

Pour permettre à l'utilisateur de cliquer sur un lieu dans l'élément Place List pour afficher l'élément Place Details Compact, ajoutez le code suivant au code JavaScript après l'appel à configureFromSearchNearbyRequest.

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

Une fois cette étape terminée, l'application pourra utiliser une recherche à proximité ou une recherche textuelle pour remplir l'élément Place List. Les résultats afficheront des repères sur la carte, et en cliquant sur un repère ou sur un lieu dans l'élément Place List, une fenêtre d'informations s'affichera avec les détails du lieu, fournis par l'élément Place Details Compact.

L'application se présentera comme suit :

image

Conclusion

L'élément PlaceSearchElement combiné à l'élément Place Details Compact offre un moyen simplifié d'ajouter des fonctionnalités de découverte de lieux enrichies à vos applications Google Maps Platform.

Essayez Kit UI pour Places dès aujourd'hui pour permettre à vos utilisateurs de trouver et d'explorer des lieux à l'aide de recherches à proximité et textuelles, et d'afficher des détails de lieu enrichis, ce qui améliorera leur interaction avec vos cas d'utilisation de découverte de lieux.

Contributeurs

Henrik Valve | DevX Ingénieur