Criar um localizador de lojas interativo com o Kit de Interface do Places

Objetivo

Este documento explica as principais etapas para desenvolver um aplicativo interativo de localizador de lojas usando a Plataforma Google Maps, especificamente a API Maps JavaScript e o kit de interface do Places: elemento de detalhes do lugar. Você vai aprender a criar um mapa que mostra locais de lojas, atualiza dinamicamente uma lista de lojas visíveis e mostra informações detalhadas sobre cada loja.

Pré-requisitos

Recomendamos que você conheça os seguintes recursos:

Ative a API Maps JavaScript e o Kit de interface do usuário do Places no seu projeto.

Verifique se você carregou a API Maps JavaScript e importou as bibliotecas necessárias para os marcadores avançados e o Kit de interface do Places antes de começar. Este documento também pressupõe conhecimento prático de desenvolvimento da Web, incluindo HTML, CSS e JavaScript.

Configuração inicial

A primeira etapa é adicionar um mapa à página. Esse mapa será usado para mostrar pinos relacionados aos locais das suas lojas.

Há duas maneiras de adicionar um mapa a uma página:

  1. Como usar um componente Web HTML gmp-map
  2. Usando JavaScript

Escolha o método mais adequado para seu caso de uso. As duas maneiras de implementar o mapa vão funcionar com este guia.

Demonstração

Esta demonstração mostra um exemplo do localizador de lojas em ação, exibindo os locais dos escritórios do Google na Bay Area. O elemento "Place Details" é mostrado para cada local, junto com alguns exemplos de atributos.

Carregar e mostrar locais das lojas

Nesta seção, vamos carregar e mostrar os dados da sua loja no mapa. Este guia pressupõe que você tenha um repositório de informações sobre suas lojas atuais para extrair. Os dados da loja podem vir de várias fontes, como o banco de dados. Para este exemplo, vamos supor um arquivo JSON local (stores.json) com uma matriz de objetos de loja, cada um representando um local de loja. Cada objeto precisa conter pelo menos um name, location (com lat e lng) e um place_id.

Há várias maneiras de recuperar os IDs de lugar das suas lojas, se você ainda não tiver. Consulte a documentação do ID de lugar para mais informações.

Um exemplo de entrada de detalhes da loja no arquivo stores.json pode ser parecido com este. Há campos para nome, local (lat/lng) e ID do lugar. Há um objeto para armazenar o horário de funcionamento da loja (truncado). Há também dois valores booleanos para descrever os recursos personalizados do local da loja.

{
  "name": "Example Store Alpha",
  "location": { "lat": 51.51, "lng": -0.12 },
  "place_id": "YOUR_STORE_PLACE_ID",
  "opening_hours": { "Monday": "09:00 - 17:00", "...": "..." },
  "new_store_design": true,
  "indoor_seating": false
}

No código JavaScript, extraia os dados dos locais das lojas e mostre um alfinete no mapa para cada um deles.

Confira um exemplo de como fazer isso. Essa função recebe um objeto que contém os detalhes das lojas e cria um marcador com base na localização de cada uma delas.

function displayInitialMarkers(storeLocations) {
    if (!AdvancedMarkerElement || !LatLng || !mapElement) return;
    storeLocations.forEach(store => {
        if (store.location) {
            const marker = new AdvancedMarkerElement({
                position: new LatLng(store.location.lat, store.location.lng),
                title: store.name
            });
            mapElement.appendChild(marker);
        }
    });
}

Depois de carregar suas lojas e mostrar no mapa os alfinetes que representam os locais delas, crie uma barra lateral usando HTML e CSS para mostrar detalhes sobre as lojas individuais.

Confira um exemplo de como o localizador de lojas pode ficar nessa fase:

imagem

Detectar mudanças na janela de visualização do mapa

Para otimizar o desempenho e a experiência do usuário, atualize seu aplicativo para mostrar marcadores e detalhes na barra lateral somente quando os locais correspondentes estiverem na área visível do mapa (janela de visualização). Isso envolve detectar mudanças na viewport do mapa, cancelar esses eventos e redesenhar apenas os marcadores necessários.

Anexe um listener de eventos ao evento inativo do mapa. Esse evento é acionado após a conclusão de qualquer operação de panorâmica ou zoom, fornecendo uma viewport estável para seus cálculos.

map.addListener('idle', debounce(updateMarkersInView, 300));

O snippet de código acima detecta o evento idle e chama uma função debounce. O uso de uma função de debounce garante que a lógica de atualização do marcador seja executada somente depois que o usuário parar de interagir com o mapa por um curto período, melhorando a performance.

function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        const context = this;
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}

O código acima é um exemplo de função de debounce. Ele usa uma função e um argumento de atraso, que pode ser transmitido no listener ocioso. Um atraso de 300 ms é suficiente para aguardar o mapa parar de se mover, sem adicionar um atraso perceptível à interface. Quando esse tempo limite expirar, a função transmitida será chamada, neste caso, updateMarkersInView.

A função updateMarkersInView precisa realizar as seguintes ações:

Limpar todos os marcadores do mapa

Confira se o local da loja está dentro dos limites atuais do mapa, por exemplo:

if (map.getBounds().contains(storeLatLng)) {
  // logic
}

Na instrução "if" acima, escreva um código para mostrar os marcadores e armazenar detalhes na barra lateral, se o local da loja estiver na área de visualização do mapa.

Mostrar detalhes completos do lugar usando o elemento Place Details

Nesta fase, o aplicativo mostra todos os locais da loja, e os usuários podem filtrá-los com base na visualização do mapa. Para melhorar isso, detalhes avançados sobre cada loja, como fotos, avaliações e informações de acessibilidade, são adicionados usando o elemento Place Details. Este exemplo usa especificamente o elemento compacto de detalhes do lugar.

Cada local da loja na sua fonte de dados precisa ter um ID de lugar correspondente. Esse ID identifica de forma exclusiva o local no Google Maps e é essencial para buscar os detalhes dele. Normalmente, você adquire esses IDs de lugar com antecedência e os armazena em cada um dos seus registros de loja.

Integrar o elemento compacto de detalhes do lugar no aplicativo

Quando uma loja é determinada como estando dentro da visualização atual do mapa e é renderizada na barra lateral, é possível criar e inserir dinamicamente um elemento compacto de detalhes do lugar.

Para a loja atual em processamento, extraia o ID do lugar dos seus dados. O ID de lugar é usado para controlar qual lugar o elemento vai mostrar.

Em JavaScript, crie dinamicamente uma instância de PlaceDetailsCompactElement. Uma nova PlaceDetailsPlaceRequestElement também é criada, o ID do lugar é transmitido a ela e é anexado ao PlaceDetailsCompactElement. Por fim, use PlaceContentConfigElement para configurar o conteúdo que o elemento vai mostrar.

A função a seguir pressupõe que as bibliotecas necessárias do Place UI Kit sejam importadas e estejam disponíveis no escopo em que essa função é chamada, e que storeData transmitido para a função contenha place_id.

Essa função vai retornar o elemento, e o código de chamada será responsável por anexá-lo ao DOM.

function createPlaceDetailsCompactElement(storeData) {
    // Create the main details component
    const detailsCompact = new PlaceDetailsCompactElement();
    detailsCompact.setAttribute('orientation', 'vertical'); // Or 'horizontal'

    // Specify the Place ID
    const placeRequest = new PlaceDetailsPlaceRequestElement();
    placeRequest.place = storeData.place_id;
    detailsCompact.appendChild(placeRequest);

    // Configure which content elements to display
    const contentConfig = new PlaceContentConfigElement();
    // For this example, we'll render media, rating, accessibility, and attribution:
    contentConfig.appendChild(new PlaceMediaElement({ lightboxPreferred: true }));
    contentConfig.appendChild(new PlaceRatingElement());
    contentConfig.appendChild(new PlaceAccessibleEntranceIconElement());
    // Configure attribution
    const placeAttribution = new PlaceAttributionElement();
    placeAttribution.setAttribute('light-scheme-color', 'gray');
    placeAttribution.setAttribute('dark-scheme-color', 'gray');
    contentConfig.appendChild(placeAttribution);
    detailsCompact.appendChild(contentConfig);
    // Return the element
    return detailsCompact;
}

No exemplo de código acima, o elemento está configurado para mostrar as fotos do lugar, a classificação da avaliação e as informações de acessibilidade. Isso pode ser personalizado adicionando ou removendo outros elementos de conteúdo disponíveis. Consulte a documentação de PlaceContentConfigElement para conferir todas as opções disponíveis.

O elemento compacto de detalhes do lugar oferece suporte a estilos usando propriedades personalizadas do CSS. Isso permite que você personalize a aparência (cores, fontes etc.) para que corresponda ao design do aplicativo. Aplique essas propriedades personalizadas no arquivo CSS. Consulte a documentação de referência de PlaceDetailsCompactElement para conferir as propriedades CSS com suporte.

Confira um exemplo de como seu aplicativo pode ficar nessa fase:

imagem

Melhorar o localizador de lojas

Você criou uma base sólida para seu aplicativo de localizador de lojas. Agora, considere várias maneiras de ampliar a funcionalidade e criar uma experiência ainda mais rica e focada no usuário.

Adicionar preenchimento automático

Melhore a forma como os usuários encontram áreas para pesquisar lojas integrando uma entrada de pesquisa com o Place Autocomplete. Quando os usuários digitam um endereço, bairro ou ponto de interesse e selecionam uma sugestão, programe o mapa para centralizar automaticamente esse local, acionando uma atualização das lojas próximas. Para fazer isso, adicione um campo de entrada e anexe a funcionalidade do Place Autocomplete a ele. Ao selecionar uma sugestão, o mapa pode ser centralizado nesse ponto. Não se esqueça de configurar o modelo para enviesar ou restringir os resultados à sua área operacional.

Detectar local

Ofereça relevância imediata, especialmente para usuários de dispositivos móveis, implementando funcionalidades para detectar a localização geográfica atual. Depois de receber a permissão do navegador para detectar a localização, centralize automaticamente o mapa na posição e mostre as lojas mais próximas. Os usuários valorizam muito esse recurso Perto de mim ao procurar opções imediatas. Adicione um botão ou uma solicitação inicial para solicitar o acesso à localização.

Mostrar distância e rotas

Depois que um usuário identifica uma loja de interesse, melhore significativamente a jornada integrando a API Routes. Para cada loja listada, calcule e mostre a distância do local atual do usuário ou do local pesquisado. Além disso, forneça um botão ou link que use a API Routes para gerar uma rota do local do usuário até a loja selecionada. Em seguida, você pode mostrar esse trajeto no seu mapa ou vincular ao Google Maps para navegação, criando uma transição perfeita entre encontrar uma loja e chegar até ela.

Ao implementar essas extensões, você pode usar mais recursos da Plataforma Google Maps para criar um localizador de lojas mais abrangente e conveniente que atenda diretamente às necessidades comuns dos usuários.

Conclusão

Este guia demonstrou as principais etapas para criar um localizador de lojas interativo. Você aprendeu a mostrar seus próprios locais de lojas em um mapa usando a API Maps JavaScript, a atualizar dinamicamente as lojas visíveis com base nas mudanças da viewport e, mais importante, a mostrar seus próprios dados de lojas de acordo com o Kit de interface do Places. Ao usar as informações atuais da loja, incluindo os IDs de lugar, com o elemento Place Details, você pode apresentar detalhes ricos e padronizados para cada um dos seus locais, criando uma base sólida para um localizador de lojas fácil de usar.

Teste a API Maps JavaScript e o Kit de interface do Places para oferecer ferramentas poderosas baseadas em componentes para desenvolver rapidamente aplicativos sofisticados baseados em localização. Ao combinar esses recursos, você pode criar experiências envolventes e informativas para seus usuários.

Colaboradores

Henrik Valve | Engenheiro do DevX