Compartir a través de


Adición de un elemento emergente al mapa

En este artículo se muestra cómo agregar un elemento emergente a un punto de un mapa.

Comprendiendo el código

El código siguiente agrega una característica de punto con las propiedades name y description al mapa mediante una capa de símbolo. Se crea una instancia de la clase popup pero no se muestra. Los eventos del mouse se agregan a la capa de símbolos para desencadenar la apertura y el cierre del elemento emergente. Cuando el mouse se mantiene sobre el símbolo del marcador, la propiedad position del elemento emergente se actualiza con la posición del marcador y la opción content se actualiza con el código HTML que contiene las propiedades name y description de la característica de puntos que se está activando. Después, se muestra el elemento emergente en el mapa mediante su función 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 un elemento emergente con varios puntos

Hay casos en los que el mejor enfoque es crear un elemento emergente y reutilizarlo. Por ejemplo, puede tener una gran cantidad de puntos y desear mostrar solo un elemento emergente cada vez. Al reutilizar el elemento emergente, el número de elementos DOM creados por la aplicación se reduce tanto que puede proporcionar un mejor rendimiento. En el ejemplo siguiente se crean tres características de punto. Si selecciona cualquiera de ellas, se muestra un menú emergente con el contenido de esa característica de punto.

Para obtener un ejemplo totalmente funcional que muestre cómo crear un elemento emergente y reutilizarlo en lugar de crear un elemento emergente para cada característica de punto, consulte Reutilizar elementos emergentes con varios pins en Ejemplos de Azure Maps. Para obtener el código fuente de este ejemplo, consulte el código fuente de Reutilización de un elemento emergente con varias chinchetas.

Captura de pantalla del mapa con tres marcas azules.

Personalización de un elemento emergente

De forma predeterminada, el elemento emergente tiene un fondo blanco, una flecha de puntero en la parte inferior y un botón de cierre en la esquina superior derecha. En el ejemplo siguiente se cambia el color de fondo a negro mediante la opción fillColor del elemento emergente. El botón de cierre se quita al establecer la opción CloseButton en false. El contenido HTML del elemento emergente utiliza un relleno de 10 píxeles desde los bordes del elemento emergente. El texto aparece en color blanco para que pueda verse claramente sobre el fondo negro.

Para obtener un ejemplo totalmente funcional que muestre cómo personalizar la apariencia de un elemento emergente, consulte Personalizar un elemento emergente en Ejemplos de Azure Maps. Para obtener el código fuente de este ejemplo, consulte el código fuente de Personalizar un elemento emergente.

Captura de pantalla de mapa con un elemento emergente personalizado en el centro del mapa con la leyenda

Incorporación de plantillas emergentes al mapa

Las plantillas emergentes facilitan la creación de diseños basados en datos para los elementos emergentes. En las secciones siguientes, se muestra el uso de varias plantillas emergentes para generar contenido con formato mediante las propiedades de las características.

Nota

De forma predeterminada, todo el contenido representado en la plantilla emergente estará en un espacio aislado dentro de un iframe como característica de seguridad, Sin embargo, existen limitaciones:

  • Todos los scripts, los formularios y las funcionalidades de bloqueo de puntero y de navegación superior están deshabilitados. Al seleccionar los vínculos, se pueden abrir en una pestaña nueva.
  • Los exploradores más antiguos que no admitan el parámetro srcdoc en iframes se limitarán a representar una pequeña cantidad de contenido.

Si confía en los datos que se van a cargar en los elementos emergentes y, potencialmente, quiere que estos scripts cargados en los elementos emergentes puedan acceder a su aplicación, puede deshabilitarlo estableciendo la opción sandboxContent de las plantillas emergentes en false.

Plantilla de cadena

La plantilla de cadena reemplaza los marcadores de posición por los valores de las propiedades de la característica. No es necesario asignar un valor de tipo String a las propiedades de la característica. Por ejemplo, value1 contiene un entero. A continuación, estos valores se pasan a la propiedad Content de popupTemplate.

La opción numberFormat especifica el formato del número que se va a mostrar. Si no se especifica el numberFormat, el código utilizará el formato de fecha de las plantillas emergentes. La opción numberFormat da formato a los números mediante la función Number.toLocaleString. Para dar formato a números grandes, considere la posibilidad de usar la opción numberFormat con funciones de NumberFormat.Format. Por ejemplo, el siguiente fragmento de código usa maximumFractionDigits para limitar el número de dígitos de fracción a dos.

Nota

Solo hay una manera en la que la plantilla de cadena puede representar imágenes. En primer lugar, la plantilla de cadena debe tener una etiqueta de imagen. El valor que se pasa a la etiqueta de imagen debe ser una dirección URL a una imagen. A continuación, la plantilla de cadena debe tener isImage establecida en true en HyperLinkFormatOptions. La opción isImage especifica que el hipervínculo es para una imagen y el hipervínculo se cargará en una etiqueta de imagen. Cuando se haga clic en el hipervínculo, se abrirá la imagen.

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

Plantilla PropertyInfo

La plantilla PropertyInfo muestra las propiedades disponibles de la característica. La opción label especifica el texto que se va a mostrar al usuario. Si no se especifica label, se muestra el hipervínculo. Y, si el hipervínculo es una imagen, se muestra el valor asignado a la etiqueta "Alt". dateFormat especifica el formato de la fecha. Si no se especifica, la fecha se representa como una cadena. La opción hyperlinkFormat representa los vínculos en los que se pueden hacer clic; de forma similar, se puede usar la opción email para representar direcciones de correo electrónico en las que se puede hacer clic.

Antes de que la plantilla PropertyInfo muestre las propiedades al usuario final, comprueba de forma recursiva que las propiedades se definen realmente para esa característica. También se omite la visualización de las propiedades de estilo y título. Por ejemplo, no muestra color, size, anchor, strokeOpacity y visibility. Por lo tanto, una vez completada la comprobación de la ruta de acceso de la propiedad en el back-end, la plantilla PropertyInfo muestra el contenido en un formato de tabla.

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

Varias plantillas de contenido

Una característica también puede mostrar contenido mediante una combinación de la plantilla String y la plantilla PropertyInfo. En este caso, la plantilla String representa los valores de los marcadores de posición en un fondo blanco. Y la plantilla PropertyInfo representa una imagen de ancho completo dentro de una tabla. Las propiedades de este ejemplo son similares a las que se explican en los ejemplos 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
});

Puntos sin una plantilla definida

Cuando la plantilla Popup no se define como una plantilla String, una plantilla PropertyInfo o una combinación de ambas, utiliza la configuración predeterminada. Cuando las propiedades title y description son las únicas asignadas, la plantilla emergente muestra un fondo blanco y un botón de cerrar en la esquina superior derecha. Y, en pantallas pequeñas y medianas, muestra una flecha en la parte inferior. La configuración predeterminada se muestra dentro de una tabla para todas las propiedades distintas de title y description. Incluso cuando se revierte a la configuración predeterminada, la plantilla emergente todavía se puede manipular mediante programación. Por ejemplo, los usuarios pueden desactivar la detección de hipervínculos y la configuración predeterminada se seguirá aplicando a otras propiedades.

Una vez en ejecución, puede seleccionar los puntos del mapa para ver el elemento emergente. Hay un punto en el mapa para cada una de las siguientes plantillas emergentes: plantilla String, plantilla PropertyInfo y plantilla de contenido Multiple. También hay tres puntos para mostrar cómo se representan las plantillas mediante la configuración predeterminada.

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

Captura de pantalla del mapa con seis puntos azules.

Reutilización de la plantilla emergente

De forma similar a como se reutiliza una ventana emergente, puede volver a usar las plantillas emergentes. Este enfoque es útil cuando solo desea mostrar una plantilla emergente cada vez, para varios puntos. La reutilización de plantillas emergentes reduce el número de elementos DOM creados por la aplicación, lo que mejora el rendimiento de las aplicaciones. En el ejemplo siguiente se usa la misma plantilla emergente para tres puntos. Si selecciona cualquiera de ellas, se muestra un menú emergente con el contenido de esa característica de punto.

Para ver un ejemplo totalmente funcional que muestra cómo reutilizar una única plantilla de elemento emergente con varias características que comparten un conjunto común de campos de propiedades, consulte Reutilizar una plantilla de elemento emergente en Ejemplos de Azure Maps. Para obtener el código fuente de este ejemplo, consulte el código fuente de Reutilización de una plantilla de elemento emergente.

Captura de pantalla de un mapa de Seattle con tres marcas azules para demostrar cómo reutilizar las plantillas de elementos emergentes.

Los elementos emergentes se pueden abrir, cerrar y arrastrar. La clase del elemento emergente proporciona eventos que ayudan a los desarrolladores a reaccionar ante estos eventos. En el ejemplo siguiente, aparecen resaltados los eventos que se activan cuando un usuario abre, cierra o arrastra el elemento emergente.

Para obtener un ejemplo totalmente funcional que muestra cómo agregar eventos a elementos emergentes, consulte Eventos emergentes en Ejemplos de Azure Maps. Para obtener el código fuente de este ejemplo, consulte el código fuente de Eventos emergentes.

Captura de pantalla de un mapa del mundo con un elemento emergente en el centro y una lista de eventos en la parte superior izquierda que se resaltan cuando el usuario abre, cierra o arrastra el elemento emergente.

Pasos siguientes

Más información sobre las clases y los métodos utilizados en este artículo:

Consulte los siguientes artículos para obtener ejemplos de código completo: