Compartilhar via


Adicionar um pop-up ao mapa

Este artigo mostra como adicionar um pop-up para um ponto em um mapa.

Compreender o código

O código a seguir adiciona um recurso de ponto com as propriedades name e description ao mapa usando uma camada de símbolos. Uma instância da classe Popup é criada, mas não exibida. Os eventos do mouse são adicionados à camada de símbolo para disparar a abertura e o fechamento do pop-up. Quando o símbolo de marcador é focalizado, a propriedade position do pop-up é atualizada com a posição do marcador, e a opção content é atualizada com um HTML que encapsula as propriedades name e description do recurso de ponto que está sendo focalizado. O pop-up é exibido no mapa usando a função open.

//Define an HTML template for a custom popup content laypout.
var popupTemplate = '<div class="customInfobox"><div class="name">{name}</div>{description}</div>';

//Create a data source and add it to the map.
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

dataSource.add(new atlas.data.Feature(new atlas.data.Point([-122.1333, 47.63]), {
  name: 'Microsoft Building 41', 
  description: '15571 NE 31st St, Redmond, WA 98052'
}));

//Create a layer to render point data.
var symbolLayer = new atlas.layer.SymbolLayer(dataSource);

//Add the polygon and line the symbol layer to the map.
map.layers.add(symbolLayer);

//Create a popup but leave it closed so we can update it and display it later.
popup = new atlas.Popup({
  pixelOffset: [0, -18],
  closeButton: false
});

//Add a hover event to the symbol layer.
map.events.add('mouseover', symbolLayer, function (e) {
  //Make sure that the point exists.
  if (e.shapes && e.shapes.length > 0) {
    var content, coordinate;
    var properties = e.shapes[0].getProperties();
    content = popupTemplate.replace(/{name}/g, properties.name).replace(/{description}/g, properties.description);
    coordinate = e.shapes[0].getCoordinates();

    popup.setOptions({
      //Update the content of the popup.
      content: content,

      //Update the popup's position with the symbol's coordinate.
      position: coordinate

    });
    //Open the popup.
    popup.open(map);
  }
});

map.events.add('mouseleave', symbolLayer, function (){
  popup.close();
});

Reutilizar um pop-up com vários pontos

Há casos em que a melhor abordagem é criar um pop-up e reutilizá-lo. Por exemplo, você pode ter um grande número de pontos e deseja mostrar apenas um pop-up de cada vez. Ao reutilizar o pop-up, o número de elementos do DOM criados pelo aplicativo será bastante reduzido, o que poderá fornecer um melhor desempenho. A amostra a seguir cria recursos de três pontos. Se você selecionar qualquer um deles, um pop-up será exibido com o conteúdo desse recurso de ponto.

Para obter uma amostra totalmente funcional que mostra como criar um popup e reutilizá-lo em vez de criar um popup para cada recurso de ponto, consulte Reutilização de Popup com Várias Marcações em Amostras do Azure Mapas. Para obter o código-fonte desse exemplo, consulte Código-fonte da reutilização de pop-ups com Vários Marcadores.

Uma captura de tela do mapa com três marcas azuis.

Personalizar um pop-up

Por padrão, o pop-up tem uma tela de fundo branca, uma seta de ponteiro na parte inferior e um botão de fechar no canto superior direito. A amostra a seguir altera a cor da tela de fundo para preto usando a opção fillColor do pop-up. O botão de fechar é removido definindo a opção CloseButton como false. O conteúdo HTML do pop-up usa preenchimento com dez pixels das bordas do pop-up. O texto fica branco e, portanto, aparece bem na tela de fundo preta.

Para obter uma amostra totalmente funcional que mostra como personalizar a aparência de um pop-up, confira Personalizar um pop-up em Amostras do Azure Mapas. Para obter o código-fonte desse exemplo, consulte Código-fonte de personalização de um pop-up.

Uma captura de tela do mapa com um pop-up personalizado no centro do mapa com a legenda 'Olá mundo'.

Adicionar modelos de pop-up ao mapa

Os modelos de pop-up facilitam a criação de layouts controlados por dados para pop-ups. As seções a seguir demonstram o uso de vários modelos de pop-up para gerar conteúdo formatado usando propriedades de recursos.

Observação

Por padrão, todo o conteúdo renderizado que usa o modelo de pop-up será colocado em área restrita dentro de um iframe como um recurso de segurança. Porém, há limitações:

  • Todos os scripts, formulários, bloqueio de ponteiro e funcionalidade de navegação superior estão desabilitados. Os links podem ser abertos em uma nova guia quando selecionados.
  • Os navegadores mais antigos que não dão suporte ao parâmetro srcdoc em iframes ficarão limitados a renderizar uma pequena quantidade de conteúdo.

Se você confiar nos dados que estão sendo carregados nos pop-ups e possivelmente desejar que os scripts carregados em pop-ups possam acessar seu aplicativo, poderá desabilitar isso definindo a opção sandboxContent de modelos de pop-up como false.

Modelo String

O modelo String substitui espaços reservados pelos valores das propriedades de recurso. As propriedades de recurso não precisam receber um valor do tipo Cadeia de caracteres. Por exemplo, value1 contém um inteiro. Esses valores são passados para a propriedade de conteúdo do popupTemplate.

A opção numberFormat especifica o formato do número a ser exibido. Se numberFormat não for especificado, o código usará o formato de data dos modelos de pop-up. A opção numberFormat formata os números usando a função Number.toLocaleString. Para formatar números grandes, considere usar a opção numberFormat com funções de NumberFormat.format. Por exemplo, o trecho de código a seguir usa maximumFractionDigits para limitar o número de dígitos de fração a dois.

Observação

Há apenas uma maneira para o modelo String renderizar imagens. Primeiro, esse modelo precisa ter uma marca de imagem. O valor transmitido à marca de imagem deve ser uma URL para uma imagem. O modelo String precisa ter isImage definida como true em HyperLinkFormatOptions. A opção isImage especifica que o hiperlink é para uma imagem, e o hiperlink será carregado em uma marca de imagem. Quando o hiperlink for clicado, a imagem será aberta.

var templateOptions = {
  content: 'This template uses a string template with placeholders.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
  numberFormat: {
    maximumFractionDigits: 2
  }
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
    title: 'Template 1 - String template',
    value1: 1.2345678,
    value2: {
        subValue: 'Pizza'
    },
    arrayValue: [3, 4, 5, 6]
});

var popup = new atlas.Popup({
  content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
  position: feature.geometry.coordinates
});

Modelo PropertyInfo

O modelo PropertyInfo exibe as propriedades disponíveis do recurso. A opção label especifica o texto a ser exibido para o usuário. Se label não for especificado, o hiperlink será exibido. E, se o hiperlink for uma imagem, o valor atribuído à marca "alt" será exibido. O dateFormat especifica o formato da data e, se o formato da data não for especificado, a data será renderizada como uma cadeia de caracteres. A opção hyperlinkFormat renderiza links clicáveis. Da mesma forma, a opção email pode ser usada para renderizar endereços de email clicáveis.

Antes que o modelo PropertyInfo exiba as propriedades para o usuário final, ele verifica recursivamente se as propriedades são definidas de fato para esse recurso. Ele também ignora a exibição de propriedades de estilo e título. Por exemplo, ele não exibe color, size, anchor, strokeOpacity e visibility. Assim, quando a verificação do caminho da propriedade for concluída no back-end, o modelo PropertyInfo mostrará o conteúdo em um formato de tabela.

var templateOptions = {
  content: [
    {
        propertyPath: 'createDate',
        label: 'Created Date'
    },
    {
        propertyPath: 'dateNumber',
        label: 'Formatted date from number',
        dateFormat: {
          weekday: 'long',
          year: 'numeric',
          month: 'long',
          day: 'numeric',
          timeZone: 'UTC',
          timeZoneName: 'short'
        }
    },
    {
        propertyPath: 'url',
        label: 'Code samples',
        hideLabel: true,
        hyperlinkFormat: {
          lable: 'Go to code samples!',
          target: '_blank'
        }
    },
    {
        propertyPath: 'email',
        label: 'Email us',
        hideLabel: true,
        hyperlinkFormat: {
          target: '_blank',
          scheme: 'mailto:'
        }
    }
  ]
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
    title: 'Template 2 - PropertyInfo',
    createDate: new Date(),
    dateNumber: 1569880860542,
    url: 'https://samples.azuremaps.com/',
    email: 'info@microsoft.com'
}),

var popup = new atlas.Popup({
  content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
  position: feature.geometry.coordinates
});

Modelos de vários conteúdos

Um recurso também pode exibir conteúdo usando uma combinação do modelo String e do modelo PropertyInfo. Nesse caso, o modelo String renderiza valores de espaços reservados em uma tela de fundo branca. O modelo PropertyInfo renderiza uma imagem de largura inteira dentro de uma tabela. As propriedades nesta amostra são semelhantes às propriedades que explicamos nas amostras anteriores.

var templateOptions = {
  content: [
    'This template has two pieces of content; a string template with placeholders and a array of property info which renders a full width image.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
    [{
      propertyPath: 'imageLink',
      label: 'Image',
      hideImageLabel: true,
      hyperlinkFormat: {
        isImage: true
      }
    }]
  ],
  numberFormat: {
    maximumFractionDigits: 2
  }
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
    title: 'Template 3 - Multiple content template',
    value1: 1.2345678,
    value2: {
    subValue: 'Pizza'
    },
    arrayValue: [3, 4, 5, 6],
    imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg'
});

var popup = new atlas.Popup({
  content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
  position: feature.geometry.coordinates
});

Pontos sem um modelo definido

Quando o modelo de pop-up não estiver definido como String, PropertyInfo ou uma combinação de ambos, ele usará as configurações padrão. Quando title e description são as únicas propriedades atribuídas, o modelo de pop-up mostra uma tela de fundo branca e um botão de fechar no canto superior direito. Em telas pequenas e médias, ele mostra uma seta na parte inferior. As configurações padrão são exibidas dentro de uma tabela para todas as propriedades que não sejam title e description. Mesmo ao fazer fallback para as configurações padrão, o modelo de pop-up ainda poderá ser manipulado programaticamente. Por exemplo, os usuários podem desativar a detecção de hiperlink e as configurações padrão ainda se aplicarão a outras propriedades.

Depois de executar, você pode selecionar os pontos no mapa para ver o pop-up. Há um ponto no mapa para cada um dos seguintes modelos de pop-up: Modelo de cadeia de caracteres, Modelo de PropertyInfo e Modelo de conteúdo múltiplo. Há também três pontos para mostrar como os modelos são renderizados usando as configurações padrão.

function InitMap()
{
  var map = new atlas.Map('myMap', {
      zoom: 2,
      view: "Auto",

    //Add authentication details for connecting to Azure Maps.
      authOptions: {
          authType: 'subscriptionKey',
          subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
      }
  });

  //Wait until the map resources are ready.
  map.events.add('ready', function() {
    //Create a data source and add it to the map.
    var datasource = new atlas.source.DataSource();
    map.sources.add(datasource);

    //Add sample data.
    datasource.add([
      new atlas.data.Feature(new atlas.data.Point([-20, 20]), {
        title: 'No template - title/description',
        description: 'This point doesn\'t have a template defined, fallback to title and description properties.'
      }),

      new atlas.data.Feature(new atlas.data.Point([20, 20]), {
        title: 'No template - property table',
        message: 'This point doesn\'t have a template defined, fallback to title and table of properties.',
        randomValue: 10,
        url: 'https://samples.azuremaps.com/',
        imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg',
        email: 'info@microsoft.com'
      }),

      new atlas.data.Feature(new atlas.data.Point([40, 0]), {
        title: 'No template - hyperlink detection disabled',
        message: 'This point doesn\'t have a template defined, fallback to title and table of properties.',
        randomValue: 10,
        url: 'https://samples.azuremaps.com/',
        email: 'info@microsoft.com',
        popupTemplate: {
          detectHyperlinks: false
        }
      }),

      new atlas.data.Feature(new atlas.data.Point([-20, -20]), {
        title: 'Template 1 - String template',
        value1: 1.2345678,
        value2: {
          subValue: 'Pizza'
        },
        arrayValue: [3, 4, 5, 6],
        popupTemplate: {
          content: 'This template uses a string template with placeholders.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
          numberFormat: {
            maximumFractionDigits: 2
          }
        }
      }),

      new atlas.data.Feature(new atlas.data.Point([20, -20]), {
        title: 'Template 2 - PropertyInfo',
        createDate: new Date(),
        dateNumber: 1569880860542,
        url: 'https://samples.azuremaps.com/',
        email: 'info@microsoft.com',
        popupTemplate: {
          content: [{
            propertyPath: 'createDate',
            label: 'Created Date'
          },
                    {
                      propertyPath: 'dateNumber',
                      label: 'Formatted date from number',
                      dateFormat: {
                        weekday: 'long',
                        year: 'numeric',
                        month: 'long',
                        day: 'numeric',
                        timeZone: 'UTC',
                        timeZoneName: 'short'
                      }
                    },
                    {
                      propertyPath: 'url',
                      label: 'Code samples',
                      hideLabel: true,
                      hyperlinkFormat: {
                        lable: 'Go to code samples!',
                        target: '_blank'
                      }
                    },
                    {
                      propertyPath: 'email',
                      label: 'Email us',
                      hideLabel: true,
                      hyperlinkFormat: {
                        target: '_blank',
                        scheme: 'mailto:'
                      }
                    }
                    ]
        }
      }),

      new atlas.data.Feature(new atlas.data.Point([0, 0]), {
        title: 'Template 3 - Multiple content template',
        value1: 1.2345678,
        value2: {
          subValue: 'Pizza'
        },
        arrayValue: [3, 4, 5, 6],
        imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg',
        popupTemplate: {
          content: [
            'This template has two pieces of content; a string template with placeholders and a array of property info which renders a full width image.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
            [{
              propertyPath: 'imageLink',
              label: 'Image',
              hideImageLabel: true,
              hyperlinkFormat: {
                isImage: true
              }
            }]
          ],
          numberFormat: {
            maximumFractionDigits: 2
          }
        }
      }),
    ]);

    //Create a layer that defines how to render the points on the map.
    var layer = new atlas.layer.BubbleLayer(datasource);
    map.layers.add(layer);

    //Create a popup but leave it closed so we can update it and display it later.
    popup = new atlas.Popup();

    //Add a click event to the layer.
    map.events.add('click', layer, showPopup);
  });

  function showPopup(e) {
    if (e.shapes && e.shapes.length > 0) {
      var properties = e.shapes[0].getProperties();

      popup.setOptions({
        //Update the content of the popup.
        content: atlas.PopupTemplate.applyTemplate(properties, properties.popupTemplate),

        //Update the position of the popup with the pins coordinate.
        position: e.shapes[0].getCoordinates()
      });

      //Open the popup.
      popup.open(map);
    }
  }
}

Uma captura de tela do mapa com seis pontos azuis.

Reutilizar o modelo de pop-up

Assim como a reutilização de pop-up, você pode reutilizar os modelos de pop-up. Essa abordagem é útil quando você deseja mostrar apenas um modelo pop-up por vez, para vários pontos. A reutilização de modelos de pop-up reduz o número de elementos DOM criados pelo aplicativo, melhorando o desempenho dos aplicativos. A amostra a seguir usa o mesmo modelo de pop-up para três pontos. Se você selecionar qualquer um deles, um pop-up será exibido com o conteúdo desse recurso de ponto.

Para obter uma amostra totalmente funcional que mostra como reutilizar um único modelo de pop-up com vários recursos que compartilham um conjunto comum de campos de propriedade, consulte Reutilizar um modelo de pop-up em Amostras do Azure Mapas. Para obter o código-fonte deste exemplo, consulte Reutilizar um código-fonte de modelo pop-up .

Uma captura de tela de um mapa mostrando Seattle com três marcas azuis para demonstrar como reutilizar os modelos de pop-up.

Os pop-ups podem ser abertos, fechados e arrastados. A classe popup fornece eventos para ajudar os desenvolvedores a reagir a esses eventos. A amostra a seguir destaca quais eventos são acionados quando o usuário abre, fecha ou arrasta o pop-up.

Para obter uma amostra totalmente funcional que mostra como adicionar eventos a pop-ups, confira Eventos de pop-up em Amostras do Azure Mapas. Para obter o código-fonte desse exemplo, consulte Código-fonte dos eventos pop-up.

Uma captura de tela de um mapa do mundo com um pop-up no centro e uma lista de eventos no canto superior esquerdo que são destacados quando o usuário abre, fecha ou arrasta o pop-up.

Próximas etapas

Saiba mais sobre as classes e métodos usados neste artigo:

Consulte os seguintes artigos excelentes para obter exemplos de código completo: