Melapisi gambar petak peta

Catatan

Layanan MapControl dan peta memerlukan kunci autentikasi peta yang disebut MapServiceToken. Untuk informasi selengkapnya tentang mendapatkan dan mengatur kunci autentikasi peta, lihat Meminta kunci autentikasi peta.

Melapisi gambar ubin pihak ketiga atau kustom di peta dengan menggunakan sumber petak peta. Gunakan sumber petak peta untuk melapisi informasi khusus seperti data cuaca, data populasi, atau data seismik; atau gunakan sumber petak peta untuk menggantikan peta default sepenuhnya.

Tips Untuk mempelajari selengkapnya tentang menggunakan peta di aplikasi Anda, unduh sampel peta Platform Windows Universal (UWP) di Github.

Gambaran umum gambaran umum ubin

Layanan peta seperti Nokia Maps dan Bing Maps memotong peta menjadi petak peta persegi untuk pengambilan dan tampilan cepat. Petak peta ini berukuran 256 piksel dengan ukuran 256 piksel, dan telah dirender sebelumnya pada beberapa tingkat detail. Banyak layanan pihak ketiga juga menyediakan data berbasis peta yang dipotong menjadi petak peta. Gunakan sumber petak peta untuk mengambil petak pihak ketiga, atau untuk membuat petak peta kustom Anda sendiri, dan melapisinya di peta yang ditampilkan di MapControl.

Penting Saat Anda menggunakan sumber petak peta, Anda tidak perlu menulis kode untuk meminta atau memposisikan petak peta individual. MapControl meminta petak peta saat membutuhkannya. Setiap permintaan menentukan koordinat X dan Y dan tingkat zoom untuk petak peta individual. Anda cukup menentukan format Uri atau nama file yang akan digunakan untuk mengambil petak peta di properti UriFormatString . Artinya, Anda menyisipkan parameter yang dapat diganti di Uri dasar atau nama file untuk menunjukkan tempat untuk meneruskan koordinat X dan Y dan tingkat zoom untuk setiap petak peta.

Berikut adalah contoh properti UriFormatString untuk HttpMapTileDataSource yang menunjukkan parameter yang dapat diganti untuk koordinat X dan Y dan tingkat zoom.

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

(Koordinat X dan Y mewakili lokasi petak peta individu dalam peta dunia pada tingkat detail yang ditentukan. Sistem penomoran petak peta dimulai dari {0, 0} di sudut kiri atas peta. Misalnya, petak peta pada {1, 2} berada di kolom kedua dari baris ketiga kisi petak peta.)

Untuk informasi selengkapnya tentang sistem petak peta yang digunakan oleh layanan pemetaan, lihat Bing Maps Tile System.

Petak peta overlay dari sumber petak peta

Overlay gambar petak peta dari sumber petak peta dengan menggunakan MapTileDataSource.

  1. Buat instans salah satu dari tiga kelas sumber data petak peta yang mewarisi dari MapTileDataSource.

    Konfigurasikan UriFormatString untuk digunakan untuk meminta petak dengan menyisipkan parameter yang dapat diganti di Uri dasar atau nama file.

    Contoh berikut membuat instans HttpMapTileDataSource. Contoh ini menentukan nilai UriFormatString di konstruktor HttpMapTileDataSource.

        HttpMapTileDataSource dataSource = new HttpMapTileDataSource(
          "http://www.<web service name>.com/z={zoomlevel}&x={x}&y={y}");
    
  2. Membuat instans dan mengonfigurasi MapTileSource. Tentukan MapTileDataSource yang Anda konfigurasi di langkah sebelumnya sebagai DataSourcedari MapTileSource.

    Contoh berikut menentukan DataSource di konstruktor MapTileSource.

        MapTileSource tileSource = new MapTileSource(dataSource);
    

    Anda dapat membatasi kondisi di mana petak peta ditampilkan dengan menggunakan properti MapTileSource.

    • Tampilkan petak peta hanya dalam area geografis tertentu dengan memberikan nilai untuk properti Batas.
    • Tampilkan petak peta hanya pada tingkat detail tertentu dengan memberikan nilai untuk properti ZoomLevelRange .

    Secara opsional, konfigurasikan properti lain dari MapTileSource yang memengaruhi pemuatan atau tampilan petak peta, seperti Layer, AllowOverstretch, IsRetryEnabled, dan IsTransparencyEnabled.

  3. Tambahkan MapTileSource ke koleksi TileSources dari MapControl.

         MapControl1.TileSources.Add(tileSource);
    

Petak peta overlay dari layanan web

Overlay gambar ubin yang diambil dari layanan web dengan menggunakan HttpMapTileDataSource.

  1. Membuat instans HttpMapTileDataSource.

  2. Tentukan format Uri yang diharapkan layanan web sebagai nilai properti UriFormatString . Untuk membuat nilai ini, sisipkan parameter yang dapat diganti di Uri dasar. Misalnya, dalam sampel kode berikut, nilai UriFormatString adalah:

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

    Layanan web harus mendukung Uri yang berisi parameter {x}, {y}, dan {zoomlevel} yang dapat diganti. Sebagian besar layanan web (misalnya, Nokia, Bing, dan Google) mendukung Uri dalam format ini. Jika layanan web memerlukan argumen tambahan yang tidak tersedia dengan properti UriFormatString , maka Anda harus membuat Uri kustom. Buat dan kembalikan Uri kustom dengan menangani peristiwa UriRequested . Untuk informasi selengkapnya, lihat bagian Menyediakan URI kustom nanti dalam topik ini.

  3. Kemudian, ikuti langkah-langkah yang tersisa yang dijelaskan sebelumnya dalam gambaran umum gambaran umum Petak Peta.

Contoh berikut melapisi petak peta dari layanan web fiktif di peta Amerika Utara. Nilai UriFormatString ditentukan dalam konstruktor HttpMapTileDataSource. Dalam contoh ini, petak peta hanya ditampilkan dalam batas geografis yang ditentukan oleh properti Batas opsional.

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

Petak peta overlay dari penyimpanan lokal

Overlay gambar petak yang disimpan sebagai file di penyimpanan lokal dengan menggunakan LocalMapTileDataSource. Biasanya, Anda mengemas dan mendistribusikan file-file ini dengan aplikasi Anda.

  1. Membuat instans LocalMapTileDataSource.

  2. Tentukan format nama file sebagai nilai properti UriFormatString . Untuk membuat nilai ini, sisipkan parameter yang dapat diganti di nama file dasar. Misalnya, dalam sampel kode berikut, nilai UriFormatString adalah:

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

    Jika format nama file memerlukan argumen tambahan yang tidak tersedia dengan properti UriFormatString , maka Anda harus membuat Uri kustom. Buat dan kembalikan Uri kustom dengan menangani peristiwa UriRequested . Untuk informasi selengkapnya, lihat bagian Menyediakan URI kustom nanti dalam topik ini.

  3. Kemudian, ikuti langkah-langkah yang tersisa yang dijelaskan sebelumnya dalam gambaran umum gambaran umum Petak Peta.

Anda dapat menggunakan protokol dan lokasi berikut untuk memuat petak peta dari penyimpanan lokal:

Uri Info selengkapnya
ms-appx:/// Menunjuk ke akar folder penginstalan aplikasi.
Ini adalah lokasi yang dirujuk oleh properti Package.InstalledLocation .
ms-appdata:///local Menunjuk ke akar penyimpanan lokal aplikasi.
Ini adalah lokasi yang dirujuk oleh properti ApplicationData.LocalFolder .
ms-appdata:///temp Menunjuk ke folder sementara aplikasi.
Ini adalah lokasi yang dirujuk oleh properti ApplicationData.TemporaryFolder .

 

Contoh berikut memuat petak peta yang disimpan sebagai file di folder penginstalan aplikasi dengan menggunakan ms-appx:/// protokol . Nilai untuk UriFormatString ditentukan dalam konstruktor LocalMapTileDataSource. Dalam contoh ini, petak peta hanya ditampilkan saat tingkat zoom peta berada dalam rentang yang ditentukan oleh properti ZoomLevelRange opsional.

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

Menyediakan URI kustom

Jika parameter yang dapat diganti tersedia dengan properti UriFormatString dari HttpMapTileDataSource atau properti UriFormatString dari LocalMapTileDataSource tidak cukup untuk mengambil ubin Anda, maka Anda harus membuat Uri kustom. Buat dan kembalikan Uri kustom dengan menyediakan handler kustom untuk peristiwa UriRequested . Peristiwa UriRequested dinaikkan untuk setiap petak peta individual.

  1. Di handler kustom Anda untuk peristiwa UriRequested, gabungkan argumen kustom yang diperlukan dengan properti X, Y, dan ZoomLevel dari MapTileUriRequestedEventArgs untuk membuat Uri kustom.
  2. Mengembalikan Uri kustom di properti UrimapTileUriRequest, yang terkandung dalam properti PermintaanmapTileUriRequestedEventArgs.

Contoh berikut menunjukkan cara menyediakan Uri kustom dengan membuat handler kustom untuk peristiwa UriRequested . Ini juga menunjukkan cara menerapkan pola penangguhan jika Anda harus melakukan sesuatu secara asinkron untuk membuat Uri kustom.

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

Petak peta overlay dari sumber kustom

Overlay ubin kustom dengan menggunakan CustomMapTileDataSource. Buat petak peta secara terprogram dalam memori dengan cepat, atau tulis kode Anda sendiri untuk memuat petak peta yang ada dari sumber lain.

Untuk membuat atau memuat petak peta kustom, sediakan handler kustom untuk peristiwa BitmapRequested . Peristiwa BitmapRequested dinaikkan untuk setiap petak peta individual.

  1. Di handler kustom Anda untuk peristiwa BitmapRequested, gabungkan argumen kustom yang diperlukan dengan properti X, Y, dan ZoomLevel dari MapTileBitmapRequestedEventArgs untuk membuat atau mengambil ubin kustom.
  2. Mengembalikan petak peta kustom di properti PixelData dari MapTileBitmapRequest, yang terkandung dalam properti PermintaanmapTileBitmapRequestedEventArgs. Properti PixelData berjenis IRandomAccessStreamReference.

Contoh berikut menunjukkan cara menyediakan petak kustom dengan membuat handler kustom untuk peristiwa BitmapRequested . Contoh ini membuat petak peta merah identik yang sebagian buram. Contoh mengabaikan properti X, Y, dan ZoomLevel dari MapTileBitmapRequestedEventArgs. Meskipun ini bukan contoh dunia nyata, contoh menunjukkan bagaimana Anda dapat membuat petak peta kustom dalam memori dengan cepat. Contohnya juga menunjukkan cara mengimplementasikan pola deferral jika Anda harus melakukan sesuatu secara asinkron untuk membuat petak peta kustom.

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

Mengganti peta default

Untuk mengganti peta default sepenuhnya dengan petak pihak ketiga atau kustom: