Superposer des images sous forme de vignettes sur une carte

Important

Mise hors service Bing Maps for Enterprise

Les services MapControl et MapControl UWP de l’espace de noms Windows.Services.Maps s’appuient sur Bing Maps. Bing Maps for Enterprise est déconseillé et sera mis hors service, auquel cas mapControl et les services ne recevront plus de données.

Pour plus d’informations, consultez le Centre de développement Bing Maps et la documentation Bing Maps.

Remarque

MapControl et les services de carte nécessitent une clé d’authentification de cartes appelée MapServiceToken. Pour plus d’informations sur l’obtention et la définition d’une clé d’authentification de cartes, voir Demander une clé d’authentification de cartes.

Superposez des images vignette tierces ou personnalisées sur une carte à l’aide de sources vignette. Utilisez des sources vignette pour superposer des informations spécifiques (informations météorologiques, démographiques, sismiques...) ou pour remplacer entièrement la carte par défaut.

Vue d’ensemble de l’image en mosaïque

Les services cartographiques tels que Bing Maps découpent les cartes en vignettes carrées pour une récupération et un affichage rapides. Ces vignettes sont de 256 pixels de 256 pixels de taille et sont pré-restituées à plusieurs niveaux de détail. De nombreux services tiers fournissent également des données basées sur la carte qui sont coupées en vignettes. Utilisez des sources de vignettes pour récupérer des vignettes tierces ou pour créer vos propres vignettes personnalisées et les superposer sur la carte affichée dans MapControl.

Lorsque vous utilisez des sources de vignettes, vous n’avez pas besoin d’écrire du code pour demander ou positionner des vignettes individuelles. MapControl demande des vignettes en fonction de leurs besoins. Chaque requête spécifie les coordonnées X et Y et le niveau de zoom de la vignette individuelle. Vous spécifiez simplement le format de l’URI ou du nom de fichier à utiliser pour récupérer les vignettes dans la propriété UriFormatString . Autrement dit, vous insérez des paramètres remplaçables dans l’URI de base ou le nom de fichier pour indiquer où passer les coordonnées X et Y et le niveau de zoom pour chaque vignette.

Voici un exemple de la propriété UriFormatString d’un HttpMapTileDataSource qui affiche les paramètres remplaçables pour les coordonnées X et Y et le niveau de zoom.

http://www.<web service name>.com/z={zoomlevel}&x={x}&y={y}

(Les coordonnées X et Y représentent l’emplacement de la vignette individuelle dans la carte du monde au niveau de détail spécifié. Le système de numérotation des vignettes commence à partir de {0, 0} dans le coin supérieur gauche de la carte. Par exemple, la vignette à {1, 2} se trouve dans la deuxième colonne de la troisième ligne de la grille des vignettes.)

Pour plus d’informations sur le système de vignettes utilisé par les services de mappage, consultez Le système de vignettes Bing Maps.

Superposition de vignettes à partir d’une source de vignette

Superposition d’images en mosaïques à partir d’une source de vignette sur une carte à l’aide de MapTileDataSource.

  1. Instanciez l’une des trois classes de source de données de vignette qui héritent de MapTileDataSource.

    Configurez UriFormatString à utiliser pour demander les vignettes en insérant des paramètres remplaçables dans l’URI de base ou le nom de fichier.

    L’exemple suivant instancie un HttpMapTileDataSource. Cet exemple spécifie la valeur de l’UriFormatString dans le constructeur de HttpMapTileDataSource.

        HttpMapTileDataSource dataSource = new HttpMapTileDataSource(
          "http://www.<web service name>.com/z={zoomlevel}&x={x}&y={y}");
    
  2. Instanciez et configurez une MapTileSource. Spécifiez mapTileDataSource que vous avez configuré à l’étape précédente en tant que Source de données de MapTileSource.

    L’exemple suivant spécifie la Source de données dans le constructeur de MapTileSource.

        MapTileSource tileSource = new MapTileSource(dataSource);
    

    Vous pouvez restreindre les conditions dans lesquelles les vignettes sont affichées à l’aide des propriétés de MapTileSource.

    • Affichez uniquement les vignettes dans une zone géographique spécifique en fournissant une valeur pour la propriété Bounds .
    • Affichez des vignettes uniquement à certains niveaux de détail en fournissant une valeur pour la propriété ZoomLevelRange.

    Si vous le souhaitez, configurez d’autres propriétés de MapTileSource qui affectent le chargement ou l’affichage des vignettes, telles que Layer, AllowOverstretch, IsRetryEnabled et IsTransparencyEnabled.

  3. Ajoutez MapTileSource à la collection TileSources de MapControl.

         MapControl1.TileSources.Add(tileSource);
    

Superposition de vignettes à partir d’un service web

Superposition d’images en mosaïques récupérées à partir d’un service web à l’aide de HttpMapTileDataSource.

  1. Instanciez un HttpMapTileDataSource.

  2. Spécifiez le format de l’URI attendu par le service web comme valeur de la propriété UriFormatString. Pour créer cette valeur, insérez des paramètres remplaçables dans l’URI de base. Par exemple, dans l’exemple de code suivant, la valeur de l’UriFormatString est la suivante :

    http://www.<web service name>.com/z={zoomlevel}&x={x}&y={y}
    

    Le service web doit prendre en charge un URI qui contient les paramètres remplaçables {x}, {y} et {zoomlevel}. La plupart des services web (par exemple, Nokia, Bing et Google) prennent en charge les URI dans ce format. Si le service web nécessite des arguments supplémentaires qui ne sont pas disponibles avec la propriété UriFormatString , vous devez créer un URI personnalisé. Créez et retournez un URI personnalisé en gérant l’événement UriRequested . Pour plus d’informations, consultez la section Fournir une URI personnalisée plus loin dans cette rubrique.

  3. Ensuite, suivez les étapes restantes décrites précédemment dans la vue d’ensemble de l’image mosaïque.

L’exemple suivant montre comment superposer des vignettes à partir d’un service web fictif sur une carte de Amérique du Nord. La valeur de l’UriFormatString est spécifiée dans le constructeur de HttpMapTileDataSource. Dans cet exemple, les vignettes sont affichées uniquement dans les limites géographiques spécifiées par la propriété Bounds facultative.

private void AddHttpMapTileSource()
{
    // Create the bounding box in which the tiles are displayed.
    // This example represents North America.
    BasicGeoposition northWestCorner =
        new BasicGeoposition() { Latitude = 48.38544, Longitude = -124.667360 };
    BasicGeoposition southEastCorner =
        new BasicGeoposition() { Latitude = 25.26954, Longitude = -80.30182 };
    GeoboundingBox boundingBox = new GeoboundingBox(northWestCorner, southEastCorner);

    // Create an HTTP data source.
    // This example retrieves tiles from a fictitious web service.
    HttpMapTileDataSource dataSource = new HttpMapTileDataSource(
        "http://www.<web service name>.com/z={zoomlevel}&x={x}&y={y}");

    // Optionally, add custom HTTP headers if the web service requires them.
    dataSource.AdditionalRequestHeaders.Add("header name", "header value");

    // Create a tile source and add it to the Map control.
    MapTileSource tileSource = new MapTileSource(dataSource);
    tileSource.Bounds = boundingBox;
    MapControl1.TileSources.Add(tileSource);
}
...
#include <winrt/Windows.Devices.Geolocation.h>
#include <winrt/Windows.UI.Xaml.Controls.Maps.h>
...
void MainPage::AddHttpMapTileSource()
{
    Windows::Devices::Geolocation::BasicGeoposition northWest{ 48.38544, -124.667360 };
    Windows::Devices::Geolocation::BasicGeoposition southEast{ 25.26954, -80.30182 };
    Windows::Devices::Geolocation::GeoboundingBox boundingBox{ northWest, southEast };

    Windows::UI::Xaml::Controls::Maps::HttpMapTileDataSource dataSource{
        L"http://www.<web service name>.com/z={zoomlevel}&x={x}&y={y}" };

    dataSource.AdditionalRequestHeaders().Insert(L"header name", L"header value");

    Windows::UI::Xaml::Controls::Maps::MapTileSource tileSource{ dataSource };
    tileSource.Bounds(boundingBox);

    MapControl1().TileSources().Append(tileSource);
}
...
void MainPage::AddHttpMapTileSource()
{
    BasicGeoposition northWest = { 48.38544, -124.667360 };
    BasicGeoposition southEast = { 25.26954, -80.30182 };
    GeoboundingBox^ boundingBox = ref new GeoboundingBox(northWest, southEast);

    auto dataSource = ref new Windows::UI::Xaml::Controls::Maps::HttpMapTileDataSource(
        "http://www.<web service name>.com/z={zoomlevel}&x={x}&y={y}");

    dataSource->AdditionalRequestHeaders->Insert("header name", "header value");

    auto tileSource = ref new Windows::UI::Xaml::Controls::Maps::MapTileSource(dataSource);
    tileSource->Bounds = boundingBox;

    this->MapControl1->TileSources->Append(tileSource);
}

Superposition de vignettes à partir du stockage local

Superposition d’images en mosaïques stockées en tant que fichiers dans le stockage local à l’aide de LocalMapTileDataSource. En règle générale, vous empaquetez et distribuez ces fichiers avec votre application.

  1. Instanciez un LocalMapTileDataSource.

  2. Spécifiez le format des noms de fichiers comme valeur de la propriété UriFormatString. Pour créer cette valeur, insérez des paramètres remplaçables dans le nom de fichier de base. Par exemple, dans l’exemple de code suivant, la valeur de l’UriFormatString est la suivante :

        Tile_{zoomlevel}_{x}_{y}.png
    

    Si le format des noms de fichiers nécessite des arguments supplémentaires qui ne sont pas disponibles avec la propriété UriFormatString , vous devez créer un URI personnalisé. Créez et retournez un URI personnalisé en gérant l’événement UriRequested . Pour plus d’informations, consultez la section Fournir une URI personnalisée plus loin dans cette rubrique.

  3. Ensuite, suivez les étapes restantes décrites précédemment dans la vue d’ensemble de l’image mosaïque.

Vous pouvez utiliser les protocoles et emplacements suivants pour charger des vignettes à partir du stockage local :

Uri Plus d’informations
ms-appx:/// Pointe vers la racine du dossier d’installation de l’application.
Il s’agit de l’emplacement référencé par la propriété Package.InstalledLocation .
ms-appdata :///local Pointe vers la racine du stockage local de l’application.
Il s’agit de l’emplacement référencé par la propriété ApplicationData.LocalFolder .
ms-appdata :///temp Pointe vers le dossier temporaire de l’application.
Il s’agit de l’emplacement référencé par la propriété ApplicationData.TemporaryFolder .

L’exemple suivant charge les vignettes stockées en tant que fichiers dans le dossier d’installation de l’application à l’aide du ms-appx:/// protocole. La valeur de l’UriFormatString est spécifiée dans le constructeur de LocalMapTileDataSource. Dans cet exemple, les vignettes s’affichent uniquement lorsque le niveau de zoom de la carte se trouve dans la plage spécifiée par la propriété ZoomLevelRange facultative.

void AddLocalMapTileSource()
{
    // Specify the range of zoom levels
    // at which the overlaid tiles are displayed.
    MapZoomLevelRange range;
    range.Min = 11;
    range.Max = 20;

    // Create a local data source.
    LocalMapTileDataSource dataSource = new LocalMapTileDataSource(
        "ms-appx:///TileSourceAssets/Tile_{zoomlevel}_{x}_{y}.png");

    // Create a tile source and add it to the Map control.
    MapTileSource tileSource = new MapTileSource(dataSource);
    tileSource.ZoomLevelRange = range;
    MapControl1.TileSources.Add(tileSource);
}

Fournir un URI personnalisé

Si les paramètres remplaçables disponibles avec la propriété UriFormatString de HttpMapTileDataSource ou uriFormatString de la propriété LocalMapTileDataSource ne suffisent pas pour récupérer vos vignettes, vous devez créer un URI personnalisé. Créez et retournez un URI personnalisé en fournissant un gestionnaire personnalisé pour l’événement UriRequested . L’événement UriRequested est déclenché pour chaque vignette individuelle.

  1. Dans votre gestionnaire personnalisé pour l’événement UriRequested, combinez les arguments personnalisés requis avec les propriétés X, Y et ZoomLevel de MapTileUriRequestedEventArgs pour créer l’URI personnalisé.
  2. Retourne l’URI personnalisé dans la propriété Uri de MapTileUriRequest, qui est contenue dans la propriété Request de MapTileUriRequestedEventArgs.

L’exemple suivant montre comment fournir un URI personnalisé en créant un gestionnaire personnalisé pour l’événement UriRequested . Il montre également comment implémenter le modèle de report si vous devez effectuer quelque chose de manière asynchrone pour créer l’URI personnalisé.

using Windows.UI.Xaml.Controls.Maps;
using System.Threading.Tasks;
...
            var httpTileDataSource = new HttpMapTileDataSource();
            // Attach a handler for the UriRequested event.
            httpTileDataSource.UriRequested += HandleUriRequestAsync;
            MapTileSource httpTileSource = new MapTileSource(httpTileDataSource);
            MapControl1.TileSources.Add(httpTileSource);
...
        // Handle the UriRequested event.
        private async void HandleUriRequestAsync(HttpMapTileDataSource sender,
            MapTileUriRequestedEventArgs args)
        {
            // Get a deferral to do something asynchronously.
            // Omit this line if you don't have to do something asynchronously.
            var deferral = args.Request.GetDeferral();

            // Get the custom Uri.
            var uri = await GetCustomUriAsync(args.X, args.Y, args.ZoomLevel);

            // Specify the Uri in the Uri property of the MapTileUriRequest.
            args.Request.Uri = uri;

            // Notify the app that the custom Uri is ready.
            // Omit this line also if you don't have to do something asynchronously.
            deferral.Complete();
        }

        // Create the custom Uri.
        private async Task<Uri> GetCustomUriAsync(int x, int y, int zoomLevel)
        {
            // Do something asynchronously to create and return the custom Uri.        }
        }

Superposition de vignettes à partir d’une source personnalisée

Superposez des vignettes personnalisées à l’aide de CustomMapTileDataSource. Créez des vignettes par programmation en mémoire à la volée ou écrivez votre propre code pour charger des vignettes existantes à partir d’une autre source.

Pour créer ou charger des vignettes personnalisées, fournissez un gestionnaire personnalisé pour l’événement BitmapRequested . L’événement BitmapRequested est déclenché pour chaque vignette individuelle.

  1. Dans votre gestionnaire personnalisé pour l’événement BitmapRequested, combinez les arguments personnalisés requis avec les propriétés X, Y et ZoomLevel de MapTileBitmapRequestedEventArgs pour créer ou récupérer une vignette personnalisée.
  2. Retourne la vignette personnalisée dans la propriété PixelData de MapTileBitmapRequest, qui est contenue dans la propriété Request de MapTileBitmapRequestedEventArgs. La propriété PixelData est de type IRandomAccessStreamReference.

L’exemple suivant montre comment fournir des vignettes personnalisées en créant un gestionnaire personnalisé pour l’événement BitmapRequested . Cet exemple crée des vignettes rouges identiques partiellement opaques. L’exemple ignore les propriétés X, Y et ZoomLevel de MapTileBitmapRequestedEventArgs. Bien qu’il ne s’agit pas d’un exemple réel, l’exemple montre comment créer des vignettes personnalisées en mémoire à la volée. L’exemple montre également comment implémenter le modèle de report si vous devez effectuer quelque chose de manière asynchrone pour créer les vignettes personnalisées.

using Windows.UI.Xaml.Controls.Maps;
using Windows.Storage.Streams;
using System.Threading.Tasks;
...
        CustomMapTileDataSource customDataSource = new CustomMapTileDataSource();
        // Attach a handler for the BitmapRequested event.
        customDataSource.BitmapRequested += customDataSource_BitmapRequestedAsync;
        customTileSource = new MapTileSource(customDataSource);
        MapControl1.TileSources.Add(customTileSource);
...
        // Handle the BitmapRequested event.
        private async void customDataSource_BitmapRequestedAsync(
            CustomMapTileDataSource sender,
            MapTileBitmapRequestedEventArgs args)
        {
            var deferral = args.Request.GetDeferral();
            args.Request.PixelData = await CreateBitmapAsStreamAsync();
            deferral.Complete();
        }

        // Create the custom tiles.
        // This example creates red tiles that are partially opaque.
        private async Task<RandomAccessStreamReference> CreateBitmapAsStreamAsync()
        {
            int pixelHeight = 256;
            int pixelWidth = 256;
            int bpp = 4;

            byte[] bytes = new byte[pixelHeight * pixelWidth * bpp];

            for (int y = 0; y < pixelHeight; y++)
            {
                for (int x = 0; x < pixelWidth; x++)
                {
                    int pixelIndex = y * pixelWidth + x;
                    int byteIndex = pixelIndex * bpp;

                    // Set the current pixel bytes.
                    bytes[byteIndex] = 0xff;        // Red
                    bytes[byteIndex + 1] = 0x00;    // Green
                    bytes[byteIndex + 2] = 0x00;    // Blue
                    bytes[byteIndex + 3] = 0x80;    // Alpha (0xff = fully opaque)
                }
            }

            // Create RandomAccessStream from byte array.
            InMemoryRandomAccessStream randomAccessStream =
                new InMemoryRandomAccessStream();
            IOutputStream outputStream = randomAccessStream.GetOutputStreamAt(0);
            DataWriter writer = new DataWriter(outputStream);
            writer.WriteBytes(bytes);
            await writer.StoreAsync();
            await writer.FlushAsync();
            return RandomAccessStreamReference.CreateFromStream(randomAccessStream);
        }
...
#include <winrt/Windows.Storage.Streams.h>
...
Windows::Foundation::IAsyncOperation<Windows::Storage::Streams::InMemoryRandomAccessStream> MainPage::CustomRandomAccessStream()
{
    constexpr int pixelHeight{ 256 };
    constexpr int pixelWidth{ 256 };
    constexpr int bpp{ 4 };

    std::array<uint8_t, pixelHeight * pixelWidth * bpp> bytes;

    for (int y = 0; y < pixelHeight; y++)
    {
        for (int x = 0; x < pixelWidth; x++)
        {
            int pixelIndex{ y * pixelWidth + x };
            int byteIndex{ pixelIndex * bpp };

            // Set the current pixel bytes.
            bytes[byteIndex] = (byte)(std::rand() % 256);        // Red
            bytes[byteIndex + 1] = (byte)(std::rand() % 256);    // Green
            bytes[byteIndex + 2] = (byte)(std::rand() % 256);    // Blue
            bytes[byteIndex + 3] = (byte)((std::rand() % 56) + 200);    // Alpha (0xff = fully opaque)
        }
    }

    // Create RandomAccessStream from byte array.
    Windows::Storage::Streams::InMemoryRandomAccessStream randomAccessStream;
    Windows::Storage::Streams::IOutputStream outputStream{ randomAccessStream.GetOutputStreamAt(0) };
    Windows::Storage::Streams::DataWriter writer{ outputStream };
    writer.WriteBytes(bytes);

    co_await writer.StoreAsync();
    co_await writer.FlushAsync();

    co_return randomAccessStream;
}
...
InMemoryRandomAccessStream^ TileSources::CustomRandomAccessStream::get()
{
    int pixelHeight = 256;
    int pixelWidth = 256;
    int bpp = 4;

    Array<byte>^ bytes = ref new Array<byte>(pixelHeight * pixelWidth * bpp);

    for (int y = 0; y < pixelHeight; y++)
    {
        for (int x = 0; x < pixelWidth; x++)
        {
            int pixelIndex = y * pixelWidth + x;
            int byteIndex = pixelIndex * bpp;

            // Set the current pixel bytes.
            bytes[byteIndex] = (byte)(std::rand() % 256);        // Red
            bytes[byteIndex + 1] = (byte)(std::rand() % 256);    // Green
            bytes[byteIndex + 2] = (byte)(std::rand() % 256);    // Blue
            bytes[byteIndex + 3] = (byte)((std::rand() % 56) + 200);    // Alpha (0xff = fully opaque)
        }
    }

    // Create RandomAccessStream from byte array.
    InMemoryRandomAccessStream^ randomAccessStream = ref new InMemoryRandomAccessStream();
    IOutputStream^ outputStream = randomAccessStream->GetOutputStreamAt(0);
    DataWriter^ writer = ref new DataWriter(outputStream);
    writer->WriteBytes(bytes);

    create_task(writer->StoreAsync()).then([writer](unsigned int)
    {
        create_task(writer->FlushAsync());
    });

    return randomAccessStream;
}

Remplacer la carte par défaut

Pour remplacer entièrement la carte par défaut par des vignettes tierces ou personnalisées :