.NET

出典:ArcGIS Maps SDK for .NET - Tutorials - Display a map

マップを表示する

このチュートリアルでは ArcGIS Maps SDK for .NET を使用して、マップとベースマップ レイヤーを表示する方法を紹介します。

マップには、地理データのレイヤーが含まれています。マップには、ベースマップ レイヤーと、オプションで 1 つ以上のデータ レイヤーを追加できます。マップ ビューを使用し、場所とズーム レベルを設定することで、マップの特定の領域を表示できます。

このチュートリアルでは、地形ベースマップ レイヤーを使用して、富士山付近を表示する地図を作成します。

このチュートリアルのトピックの背景情報については、Mapping API and location services guideMaps (2D)ベースマップ を参照してください。

前提条件

このチュートリアルを実施するには、以下が必要です。

  • API キーにアクセスするための開発者アカウントもしくは ArcGIS Online アカウントが必要です。アカウントをお持ちでない場合は、サインアップ (無料)してください。アカウントの作成方法は「開発者アカウントの作成」をご覧ください。
  • 開発環境がシステム要件を満たしていることを確認します。

必要に応じて、ArcGIS Maps SDK for .NET をインストールして、Visual Studio プロジェクト テンプレート (Windows のみ) とオフラインにコピーされた NuGet パッケージを利用することもできます。

認証の設定

このチュートリアルで使用するセキュアな ArcGIS ロケーション サービスにアクセスするには、ArcGIS Location Platform または ArcGIS Online アカウントを使用して、API キー認証またはユーザー認証を実装する必要があります。

このチュートリアルを完了するには、下の切り替えタブから、ご希望の認証タイプ(API キー認証またはユーザー認証)のタブをクリックしてください。

  • ユーザーはサインインする必要がありません。
  • 適切な権限を持つ API キーの認証情報を作成する必要があります。
  • API キーは長期間のアクセス トークンです。
  • サービス使用料は、API キーの所有者/開発者に請求されます。
  • 実装が最も簡単な認証方法です。
  • 新規の ArcGIS 開発者に推奨される方法です。

詳しくは API キー認証をご覧ください。

このチュートリアルで使用するセキュアなリソースにアクセスする権限を持つ、新しい API キーのアクセス トークンを作成します。

  1. API キーの作成のチュートリアルを完了し、以下の権限を持つ API キーを作成します。
    • Privileges
      • Location services > Basemaps
  2. API キーのアクセス トークン をコピーし、安全な場所に貼り付けます。これは後のステップで使用します。
  • ユーザーは、ArcGIS アカウントでサインインする必要があります。
  • ユーザー アカウントには、アプリケーションで使用する ArcGIS サービスにアクセスする権限が必要です。
  • OAuth 認証情報の作成が必要です。
  • アプリケーションには、リダイレクト URL とクライアント ID を使用します。
  • サービスの使用料は、アプリケーションにサインインしたユーザーの組織に請求されます。

詳しくは、ユーザー認証をご覧ください。

このチュートリアルで使用するセキュアなリソースにアクセスするための新しい OAuth 認証情報を作成します。

チュートリアルの後の設定ステップでは、リダイレクト URL が my-app://auth であると仮定します。別の URL を使用する場合は、それに応じてアプリの設定を行ってください。
  1. ユーザー認証用の OAuth 認証情報を作成するチュートリアルを完了し、Client IDRedirect URL を取得してください。

    Client ID は、認証サーバー上でアプリを一意に識別するものです。サーバーが指定された Client ID を持つアプリを見つけられない場合、認証は続行されません。

    Redirect URL(Callback URL とも呼ばれます)は、OAuth ログイン後にシステムが制御をアプリに戻す際、認証サーバーからの応答を識別するために使用されます。Redirect URL は、必ずしもユーザーが移動できる有効なエンドポイントを表すわけではないため、my-app://auth のようなカスタム スキームを使用できます。アプリのコードで使用される Redirect URL が、認証サーバーで設定された Redirect URL と一致していることを確認することが重要です。

  2. ClientIDRedirect URL をコピーして安全な場所に貼り付けます。これらは後のステップで使用します。

このアプリケーションにアクセスするすべてのユーザーには、ベースマップ スタイル サービスにアクセスするためのアカウント権限が必要です。

セキュリティーと認証ガイド : 認証の種類について詳しくは、認証の種類をご覧ください。

開発またはダウンロード

このチュートリアルを完了するには、2 つの選択肢があります。

  1. オプション 1: コードを開発する
  2. オプション 2: 完成したソリューションをダウンロードする

オプション 1: コードを開発する

新しい Visual Studio プロジェクトを作成する

ArcGIS Maps SDK for .NET は、Windows Presentation Framework (WPF)、Windows UI Library (WinUI)、.NET MAUI 向けのアプリをサポートしています。 このチュートリアルの説明は、Visual Studio for Windows を使用して WPF .NET プロジェクトを作成する手順を説明します。

.NET API アプリを開発できるプラットフォームは、開発環境に応じて異なります。例えば、Mac で開発する場合、WPF のプロジェクトは利用できません。詳しくは、システム要件をご覧ください。
  1. Visual Studio を起動し、新しいプロジェクトを作成します。
    • Visual Studio の開始画面で、[新しいプロジェクトの作成] をクリックします。
    • C# 用の [WPF アプリケーション]テンプレートを選択します。テンプレートが表示されていない場合は、[テンプレートの検索]テキスト ボックスに WPF アプリケーション と入力すると、テンプレートを見つけることができます。
    • [次へ] をクリックします。
    • [新しいプロジェクトを構成します] 画面で必要な値を入力します。
      • プロジェクト名: DisplayAMap
      • 場所: 任意のフォルダーを選択
    • [次へ] をクリックします。
      • フレームワークで .NET 8.0 (長期的なサポート) を選択します。
    • [作成] をクリックしてプロジェクトを作成します。

Visual Studio for Windows で開発する場合、ArcGIS Maps SDK for .NET には、サポートされる .NET プラットフォームごとにプロジェクト テンプレート セットが用意されています。これらのテンプレートは、Model-View-ViewModel(MVVM)デザイン パターンに従っています。ArcGIS Maps SDK for .NET Visual Studio Extension をインストールして、テンプレートを Visual Studio に追加します(Windows のみ)。詳細については、インストールとセットアップを参照してください。

このチュートリアルの手順は、WPF for .NET(Visual Studio 2022 以降が必要)を使用してアプリケーションを作成することに特化しています。サポートされている他の .NET プラットフォームでアプリを完成させるには、ArcGIS Maps SDK for .NET プロジェクト テンプレートの 1 つからプロジェクトを作成できます。Visual Studio テンプレートの 1 つから開始する場合、ガイドに記載されているコードとプロジェクトに含まれるコードにいくつかの違いがあることがあります。

API の参照を追加する

ArcGIS Maps SDK for .NET プロジェクト テンプレートの 1 つからプロジェクトを作成した場合、必要な NuGet パッケージが既にプロジェクトに追加されています。
  1. NuGet パッケージをインストールして、API への参照を追加します。

    • ソリューション エクスプローラーで、[参照] を右クリックし、[NuGet パッケージの管理] を選択します。
    • [NuGet パッケージ マネージャー] ウィンドウで、[パッケージ ソース] に nuget.org (右上)が選択されていることを確認します。
    • [参照] タブを選択して、ArcGIS Maps SDK を検索します。
    • 検索結果から、プラットフォームに適したパッケージを選択します。このチュートリアルではEsri.ArcGISRuntime.WPF NuGet パッケージを選択します。
    • [バージョン] にパッケージの「最新の安定版…」が選択されていることを確認します。
    • [インストール] をクリックします。
    • NuGet は、パッケージの依存関係または競合を自動的に解決します。デフォルトでは、[変更のプレビュー] ダイアログが表示されます。 変更を確認し [OK] をクリックしてパッケージのインストールを続行します。
    • [ライセンスへの同意] ダイアログでライセンス条項を確認し、[同意する] をクリックしてパッケージをプロジェクトに追加します。
    • Visual Studio の [出力] ウィンドウで、パッケージが正常にインストールされたことを確認します。ターゲットの Windows バージョンに関するエラーが表示された場合は、次の手順で修正します。
    • [NuGet パッケージ マネージャー] ウィンドウを閉じます。
  2. Visual Studio エラー リストに The 'Esri.ArcGISRuntime.WPF' nuget package cannot be used to target 'net8.0-windows'. Target 'net8.0-windows10.0.19041.0' or later instead. のようなエラーが表示される場合があります。その場合は、次の手順に従って対処してください。

    • ソリューション エクスプローラーで、ツリー ビューのプロジェクト エントリーを右クリックし、[プロジェクト ファイルの編集] を選択します。

    • <TargetFramework> 要素を net8.0-windows10.0.19041.0(またはそれ以上)で更新します。

      <PropertyGroup>
      <OutputType>WinExe</OutputType>
      <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
      <UseWPF>true</UseWPF>
      </PropertyGroup>
    • プロジェクト ファイル (DisplayAMap) を保存して閉じます。

アプリ ロジックを保存するビュー モデルを作成する

このアプリは、以降のすべてのチュートリアルで使用する基盤を構築するためのものです。堅固な設計で構築することをお勧めします。

Model-View-ViewModel (MVVM) デザイン パターンは、ユーザー インターフェイス要素 (および関連するコード) をアプリの基礎となるロジックから分離するアーキテクチャーを提供します。このパターンでは、モデルはアプリで消費されるデータを表し、ビュー はユーザー インターフェイスであり、ビュー モデル にはモデルとビューをバインド (結合) するロジックが含まれます。このようなパターンに必要な追加のフレームワークは、小規模なプロジェクトでは大変な作業に思えるかもしれませんが、プロジェクトの複雑さが増すにつれて、堅固な設計を行うことでコードの保守性と柔軟性が大幅に向上します。

MVVM で設計された ArcGIS アプリでは、通常、マップ ビューがメインのビュー コンポーネントになります。クラスの多くは、モデルの役割を果たします (データをマップ、レイヤー、グラフィックス、フィーチャなどとして表します)。 ビュー モデル コンポーネントには、ArcGIS オブジェクトを操作するためのロジックを追加したり、ビューに表示するためのデータを提供したりするため、記述するコードの多くはここになります。

すべての ArcGIS Maps SDK for .NET プロジェクト テンプレートは、MVVM デザイン パターンを使用しています。
  1. プロジェクトのビュー モデルを定義する新しいクラスを追加します。

    • [プロジェクト] メニュー > [クラスの追加…] をクリックします。
    • 新しいクラスに MapViewModel.cs と名前を付けます。
    • [追加] をクリックして新しいクラスを作成し、プロジェクトに追加します。
    • 新しいクラスが VisualStudio で開きます。
  2. 必要な using ステートメントをビュー モデルに追加します。

    MapViewModel.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    // 追加開始
    using Esri.ArcGISRuntime.Mapping;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using Esri.ArcGISRuntime.Geometry;
    // 追加終了
  3. MapViewModel クラスに INotifyPropertyChanged インターフェイスを実装します。

    このインターフェイスは、ビュー モデルのプロパティが変更されたことをクライアント (ビュー) に通知するために使用される PropertyChanged イベントを定義します。

    MapViewModel.cs
    namespace DisplayAMap
    {
        // 変更前
        // internal class MapViewModel
        // 変更後
        internal class MapViewModel : INotifyPropertyChanged
        {
        }
    }
  4. MapViewModel クラス内に、PropertyChanged イベントを実装するコードを追加します。

    ビュー モデルのプロパティが変更されると、OnPropertyChanged の呼び出しにより、このイベントが発生します。

    MapViewModel.cs
    class MapViewModel : INotifyPropertyChanged
    {
        // 追加開始
        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        // 追加終了
    }
  5. ビュー モデルに Map オブジェクトを公開する Map という新しいプロパティを定義します。 プロパティが設定されると、OnPropertyChanged を呼び出します。

    MapViewModel.cs
        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    
        // 追加開始
        private Map? _map;
        public Map? Map
        {
            get { return _map; }
            set
            {
                _map = value;
                OnPropertyChanged();
            }
        }
        // 追加終了
    }
  6. MapViewModel クラスに SetupMap という関数を追加します。この関数は、新しいマップを作成して Map プロパティを設定します。地図は、セキュアな ArcGIS ベースマップ スタイルの1つを使用し、富士山を中心に表示されます。

    縮尺は、視点を設定する上で欠かせない要素です。縮尺によって、地図をどの程度の拡大率で表示するかが決まります。縮尺とは、地図上の寸法と実世界の寸法の比率のことです。この変換ツールを使って、ズームレベルと縮尺の関係を確かめ、両者の関連性について詳しく学びましょう。

    MapViewModel.cs
        private Map _map;
        public Map Map
        {
            get { return _map; }
            set
            {
                _map = value;
                OnPropertyChanged();
            }
        }
    
        // 追加開始
        private void SetupMap()
        {
            //ベースマップのラベルを日本語で表示します。
            BasemapStyleParameters bsp = new BasemapStyleParameters();
            bsp.SpecificLanguage = System.Globalization.CultureInfo.CreateSpecificCulture("ja");
            Basemap basemap = new Basemap(BasemapStyle.ArcGISTopographic, bsp);
    
            // ベースマップを設定した新しいマップを作成します。
            var map = new Map(basemap);
    
            // 富士山をマップの中心位置として設定する MapPoint を作成します。
            MapPoint mapCenterPoint = new MapPoint(138.727363, 35.360626, SpatialReferences.Wgs84);
            // マップの視点を決める Viewpoint を設定します。
            map.InitialViewpoint = new Viewpoint(mapCenterPoint, 200000.0);
    
            //すべての設定を Map に渡します。
            Map = map;
        }
        // 追加終了
    }
  7. MapViewModel が新規にインスタンス化された際に、SetupMap 関数を呼び出すコンストラクターを追加します。

    MapViewModel newMapVM = new MapViewModel(); のようなコードを書くと、クラス コンストラクターが実行されます。これはクラスが初期化された時に実行する必要があるコードを追加するのに良い場所です。

    MapViewModel.cs
    class MapViewModel : INotifyPropertyChanged
    {
        // 追加開始
        public MapViewModel()
        {
            SetupMap();
        }
        // 追加終了
    
        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

これで MapViewModel が完成しました。

MVVM デザイン パターンを使用する利点は、ビュー モデルのコードを再利用できることです。API はプラットフォーム間でほぼ標準的な API サーフェスを持っているため、1つのアプリ用に作成した ビュー モデル のコードは、通常、サポートされているすべての .NET プラットフォームで動作します。 このビューモデルは、ほとんど、あるいはまったく変更を加えることなく、.NET MAUI アプリや WinUI アプリで使用できます。

開発者認証情報の設定

アプリのユーザーが ArcGIS ロケーション サービスやセキュアなコンテンツにアクセスできるようにするには、認証の設定ステップで作成した開発者認証情報を使用して、リソースへのアクセスを認証します。

  1. ソリューション エクスプローラーで、App.xaml のノードを展開し、App.xaml.cs をダブルクリックして開きます。

  2. App クラスで、OnStartup() 関数のオーバーライドを追加して、ArcGISRuntimeEnvironmentApiKey プロパティを設定します。

    App.xaml.cs
    public partial class App : Application
    {
        // 追加開始
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            // 注: API キーをソース コードに保存することはベスト プラクティスではありません。
            // API キーは、チュートリアルの便宜上、ここで参照されています。
            Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.ApiKey = "API キー";
        }
        // 追加終了
    }
  3. “API キー” は先ほど作成した API キーに置き換えてください。

  4. App.xaml.cs ファイルを保存して閉じます。

ベスト プラクティス: このチュートリアルでは、便宜上、アクセス トークンをコード内に直接格納しています。本番環境では、認証情報をソース コード内に直接格納しないでください。
  1. Microsoft.Web.WebView2 NuGet パッケージを追加します。このパッケージは Microsoft Edge WebView2 コントロールを提供し、これによりネイティブ アプリに Web テクノロジー (HTML、CSS、JavaScript) を組み込むことができます。アプリでは、WebView2 コントロールを使用して、ユーザー認証のためのログイン UI を表示します。

    • ソリューション エクスプローラーで[依存関係]を右クリックし、[NuGet パッケージの管理]を選択します。
    • [NuGet パッケージ マネージャー]ウィンドウで、[パッケージ ソース]が nuget.org(右上)に設定されていることを確認します。
    • [参照]タブを選択し、Microsoft.Web.WebView2 を検索します。
    • 検索結果から、Microsoft.Web.WebView2 NuGet パッケージを選択します。
    • [バージョン] ドロップダウンで、パッケージの[最新の安定版]が選択されていることを確認します。
    • [インストール]をクリックします。
    • [変更のプレビュー]ダイアログで、パッケージの依存関係や競合が確認されます。変更内容を確認し、[適用]をクリックしてパッケージのインストールを続行します。
    • [ライセンス同意]ダイアログでライセンス情報を確認し、[同意する]をクリックしてパッケージをプロジェクトに追加します。
    • Visual Studio の[出力]ウィンドウで、パッケージが正常にインストールされたことを確認します。
    • [NuGet パッケージ マネージャー] ウィンドウを閉じます。
  2. Visual Studio の [プロジェクト] メニューから、[クラスの追加…] を選択します。クラス名を ArcGISLoginPrompt.cs と指定し、[追加] をクリックします。新しいクラスがプロジェクトに追加され、Visual Studio で開きます。

  3. 新しいクラス内のコードをすべて選択して削除してください。

  4. 以下のコードをすべてコピーし、プロジェクト内の ArcGISLoginPrompt.cs クラスに貼り付けてください。

    ArcGISLoginPrompt.cs
    // Copyright 2021 Esri.
    //
    // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
    // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
    // language governing permissions and limitations under the License.
    
    using Esri.ArcGISRuntime.Portal;
    using Esri.ArcGISRuntime.Security;
    using Microsoft.Web.WebView2.Core;
    using Microsoft.Web.WebView2.Wpf;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Threading;
    
    namespace UserAuth
    {
    
        internal static class ArcGISLoginPrompt
        {
            private const string ArcGISOnlineUrl = "https://www.arcgis.com/sharing/rest";
            // Specify the Client ID and Redirect URL to use with OAuth authentication.
            // See the instructions here for creating OAuth app settings:
            // https://developers.arcgis.com/documentation/security-and-authentication/user-authentication/tutorials/           create-oauth-credentials-user-auth/
    
            private const string AppClientId = "YOUR_CLIENT_ID";
            private const string OAuthRedirectUrl = "YOUR_REDIRECT_URL";
    
            public static async Task<bool> EnsureAGOLCredentialAsync()
            {
                bool loggedIn = false;
    
                try
                {
                    // Create the portal, prompting the user to log in if they haven't already.
                    var portal = await ArcGISPortal.CreateAsync(new Uri(ArcGISOnlineUrl), loginRequired: true);
                    // If the user logged in successfully, the portal's User property will be non-null.
                    loggedIn = portal.User != null;
                }
                catch (OperationCanceledException)
                {
                    // OAuth login was canceled, no need to display error to user.
                }
                catch (Exception ex)
                {
                    // Login failure
                    MessageBox.Show("Login failed: " + ex.Message);
                }
    
                return loggedIn;
            }
    
            public static void RegisterOAuthConfig()
            {
                var userConfig = new OAuthUserConfiguration(new Uri(ArcGISOnlineUrl), AppClientId, new Uri(OAuthRedirectUrl));
                AuthenticationManager.Current.OAuthUserConfigurations.Add(userConfig);
                AuthenticationManager.Current.OAuthHandler = new OAuthAuthorize();
            }
    
            #region OAuth handler
    
            // In a desktop (WPF) app, an IOAuthHandler component is used to handle some of the OAuth details. Specifically, it
            //     implements AuthorizeAsync to show the login UI (generated by the server that hosts secure content) in a web control.
            //     When the user logs in successfully, cancels the login, or closes the window without continuing, the IOAuthAuthorizeHandler
            //     is responsible for obtaining the authorization from the server or raising an OperationCanceledException.
            public class OAuthAuthorize : IOAuthHandler
            {
                // Window to contain the OAuth UI.
                private Window? _authWindow;
    
                // Use a TaskCompletionSource to track the completion of the authorization.
                private TaskCompletionSource<IDictionary<string, string>> _tcs;
    
                // URL for the authorization callback result (the redirect URI configured for your application).
                private string _callbackUrl = "";
    
                // URL that handles the OAuth request.
                private string? _authorizeUrl;
    
                // Function to handle authorization requests, takes the URIs for the secured service, the authorization endpoint, and           the redirect URI.
                public Task<IDictionary<string, string>> LoginAsync(OAuthLoginParameters parameters)
                {
                    if (_tcs != null && !_tcs.Task.IsCompleted)
                        throw new Exception("Task in progress");
    
                    _tcs = new TaskCompletionSource<IDictionary<string, string>>();
    
                    // Store the authorization and redirect URLs.
                    _authorizeUrl = parameters.AuthorizeUri.AbsoluteUri;
                    _callbackUrl = parameters.RedirectUri.AbsoluteUri;
    
                    // Call a function to show the login controls, make sure it runs on the UI thread for this app.
                    Dispatcher dispatcher = Application.Current.Dispatcher;
                    if (dispatcher == null || dispatcher.CheckAccess())
                    {
                        AuthorizeOnUIThread(_authorizeUrl);
                    }
                    else
                    {
                        Action authorizeOnUIAction = () => AuthorizeOnUIThread(_authorizeUrl);
                        dispatcher.BeginInvoke(authorizeOnUIAction);
                    }
    
                    // Return the task associated with the TaskCompletionSource.
                    return _tcs.Task;
                }
    
                // Challenge for OAuth credentials on the UI thread.
                private void AuthorizeOnUIThread(string authorizeUri)
                {
                    // Initialize a WebView2 control to display the authorize page.
                    WebView2 webBrowser = new WebView2() { MinWidth = 500, MinHeight = 500 };
    
                    // Handle the navigation event for the browser to check for a response to the redirect URL.
                    webBrowser.NavigationStarting += WebBrowserOnNavigationStarting;
    
                    // Display the web browser in a new window.
                    _authWindow = new Window
                    {
                        Content = webBrowser,
                        SizeToContent = SizeToContent.WidthAndHeight,
                        WindowStartupLocation = WindowStartupLocation.CenterOwner
                    };
    
                    // Set the app's window as the owner of the browser window (if main window closes, so will the browser).
                    if (Application.Current != null && Application.Current.MainWindow != null)
                    {
                        _authWindow.Owner = Application.Current.MainWindow;
                    }
    
                    // Handle window loaded event as the WebView2 control can only be initialized after it is visible in the UI
                    _authWindow.Loaded += async (s, e) =>
                    {
                        await webBrowser.EnsureCoreWebView2Async();
                        webBrowser.CoreWebView2.Navigate(authorizeUri);
                    };
    
                    // Handle the window closed event
                    _authWindow.Closed += OnWindowClosed;
    
                    // Display the window.
                    _authWindow.ShowDialog();
                }
    
                // Handle the browser window closing.
                private void OnWindowClosed(object? sender, EventArgs e)
                {
                    // If the browser window closes, return the focus to the main window.
                    if (_authWindow != null && _authWindow.Owner != null)
                    {
                        _authWindow.Owner.Focus();
                    }
    
                    // If the task wasn't completed, the user must have closed the window without logging in.
                    if (!_tcs.Task.IsCompleted)
                    {
                        // Set the task completion source exception to indicate a canceled operation.
                        _tcs.SetCanceled();
                    }
    
                    _authWindow = null;
                }
    
                // Handle browser navigation
                private void WebBrowserOnNavigationStarting(object? sender, CoreWebView2NavigationStartingEventArgs e)
                {
                    // Check for a response to the callback url.
                    const string portalApprovalMarker = "/oauth2/approval";
    
                    Uri uri = new Uri(e.Uri);
    
                    // If no browser, uri, or an empty url, return.
                    if (sender == null || uri == null || string.IsNullOrEmpty(uri.AbsoluteUri))
                        return;
    
                    // Check for redirect.
                    bool isRedirected = uri.AbsoluteUri.StartsWith(_callbackUrl) ||
                        _callbackUrl.Contains(portalApprovalMarker) && uri.AbsoluteUri.Contains(portalApprovalMarker);
    
                    // Check if browser was redirected to the callback URL. (This indicates succesful authentication.)
                    if (isRedirected)
                    {
                        e.Cancel = true;
    
                        // Call a helper function to decode the response parameters.
                        IDictionary<string, string> authResponse = DecodeParameters(uri);
    
                        // Set the result for the task completion source.
                        _tcs.SetResult(authResponse);
    
                        // Close the window.
                        if (_authWindow != null)
                        {
                            _authWindow.Close();
                        }
                    }
                }
    
                private static IDictionary<string, string> DecodeParameters(Uri uri)
                {
                    // Create a dictionary of key value pairs returned in an OAuth authorization response URI query string.
                    string answer = "";
    
                    // Get the values from the URI fragment or query string.
                    if (!string.IsNullOrEmpty(uri.Fragment))
                    {
                        answer = uri.Fragment.Substring(1);
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(uri.Query))
                        {
                            answer = uri.Query.Substring(1);
                        }
                    }
    
                    // Parse parameters into key / value pairs.
                    Dictionary<string, string> keyValueDictionary = new Dictionary<string, string>();
                    string[] keysAndValues = answer.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string kvString in keysAndValues)
                    {
                        string[] pair = kvString.Split('=');
                        string key = pair[0];
                        string value = string.Empty;
                        if (key.Length > 1)
                        {
                            value = Uri.UnescapeDataString(pair[1]);
                        }
    
                        keyValueDictionary.Add(key, value);
                    }
    
                    // Return the dictionary of string keys/values.
                    return keyValueDictionary;
                }
            }
    
            #endregion OAuth handler
        }
    }
  5. クライアント ID (AppClientId) とリダイレクト URL (OAuthRedirectUri)の値を追加します。これらは、認証の設定ステップで作成したユーザー認証設定です。

    ArcGISLoginPrompt.cs
    internal static class ArcGISLoginPrompt
        {
            private const string ArcGISOnlineUrl = "https://www.arcgis.com/sharing/rest";
            // Specify the Client ID and Redirect URL to use with OAuth authentication.
            // See the instructions here for creating OAuth app settings:
            // https://developers.arcgis.com/documentation/security-and-authentication/user-authentication/tutorials/create-oauth-credentials-user-auth/
    
            // 更新開始
            private const string AppClientId = "YOUR_CLIENT_ID";
            private const string OAuthRedirectUrl = "YOUR_REDIRECT_URL";
            // 更新終了
  6. [ソリューション エクスプローラー] で App.xaml のノードを展開し、App.xaml.cs をダブルクリックして開きます。

  7. App クラスで OnStartup() 関数のオーバーライドを追加して、静的 ArcGISLoginPrompt クラスの SetChallengeHandler() メソッドを呼び出します。

    App.xaml.cs
        public partial class App : Application
        {
    
            // 追加開始
            protected override void OnStartup(StartupEventArgs e)
            {
                base.OnStartup(e);
    
                // Call a function to set up the AuthenticationManager for OAuth.
                UserAuth.ArcGISLoginPrompt.RegisterOAuthConfig();
    
            }
            // 追加終了
    
        }
    }
  8. App.xaml.cs ファイルを保存して閉じます。

ベスト プラクティス: このチュートリアルでは、便宜上、OAuth の認証情報をコード内に直接保存しています。本番環境では、認証情報をソース コード内に直接保存しないでください。

次に、ビュー モデルを使用するビューをプロジェクトに設定します。

マップ ビューを追加する

MapView コントロールは、マップを表示するために使用します。 マップ ビューをプロジェクトの UI に追加し、MapViewModel で定義したマップを使用するように設定します。

  1. MainWindow.xaml を開きます。

  2. 必要な XML 名前空間とリソース宣言を追加します。

    • MainWindow.xaml を開き、XAML ビューに切り替えます。
    • 既存の名前空間の宣言内に、ArcGIS コントロールの esri XML 名前空間を追加します。
    • MapViewModel インスタンスを静的リソースとして定義する XAML を追加します。
    MainWindow.xaml
    <Window x:Class="DisplayAMap.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:DisplayAMap"
            <!--追加開始-->
            xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013"
            <!--追加終了-->
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <!--追加開始-->
        <Window.Resources>
            <local:MapViewModel x:Key="MapViewModel" />
        </Window.Resources>
        <!--追加終了-->
        <Grid>
        </Grid>
  3. MapView コントロールを MainWindow.xaml に追加し、MapViewModel にバインドします。

    • MapView コントロールを定義する XAML を追加します。
    • データ バインディングを使用して、MapViewModel リソースからコントロールの Map プロパティを設定します。
      Visual Studio で、MapView が見つからないというエラーが表示される場合があります。これは、プロジェクトがまだビルドされていないためです。このエラーは、ひとまず無視して構いません。
    MainWindow.xaml
    <Window.Resources>
        <local:MapViewModel x:Key="MapViewModel" />
    </Window.Resources>
    
    <Grid>
    <!--追加開始-->
        <esri:MapView x:Name="MainMapView" Map="{Binding Map, Source={StaticResource MapViewModel}}" />
    <!--追加終了-->
    </Grid>

アプリを実行する

[デバッグ] メニュー > [デバッグの開始] をクリックして (またはキーボードの <F5> キーを押して) アプリを実行します。

富士山を中心に、地形図ベースマップ レイヤーが追加されたマップが表示されます。マップ ビュー上でマウス ホイールをダブルクリック、ドラッグ、およびスクロールして、マップを操作します。

Web マップを表示する

Web マップの作成」のガイドで Web マップを作成している場合は、作成した Web マップも基本的に同じステップで表示できます。

  1. Visual Studio で、マップを表示するのステップで作成したプロジェクトの MapViewModel.cs を開きます。

  2. 必要な using ステートメントを追加します。

    MapViewModel.cs
    using Esri.ArcGISRuntime.Portal;
    using System.Threading.Tasks;
  3. MapViewModel.cs 内の SetupMap 関数を下記のように書き換えます。

    MapViewModel.cs
    private async Task SetupMap()
    {
        // ArcGIS ポータルを作成します。URI を指定しない場合は "www.arcgis.com" を使用します。
        ArcGISPortal portal = await ArcGISPortal.CreateAsync();
    
        // アイテム ID を使用して、Web マップをポータル アイテムとして取得します。
        PortalItem mapItem = await PortalItem.CreateAsync(portal, "Web マップの ID");
    
        // ポータル アイテムからマップを作成します。
        Map map = new Map(mapItem);
    
        // マップを表示するには、マップ ビューにバインドされている MapViewModel.Map プロパティを設定します。
        this.Map = map;
    }

オプション 2: 完成したソリューションをダウンロードする

  1. Download solution をクリックしてください。
  2. マシンの任意の場所にファイルを解凍します。
  3. .sln ファイルを Visual Studio で開きます。

ダウンロードしたソリューションには認証情報が含まれていないため、認証の設定で作成した開発者認証情報を追加する必要があります。

ソリューションに開発者認証情報を設定する

アプリのユーザーが ArcGIS ロケーション サービスやセキュアなコンテンツにアクセスできるようにするには、認証の設定ステップで作成した開発者認証情報を使用して、リソースへのアクセスを認証します。

  1. Visual Studioソリューション エクスプローラーで、App.xaml.cs をクリックしてファイルを開きます。

  2. ArcGISEnvironment.ApiKey プロパティに API キーのアクセス トークンを設定します。

    App.xaml.cs
            protected override void OnStartup(StartupEventArgs e)
            {
                base.OnStartup(e);
    
                // Set the access token for ArcGIS Maps SDK for .NET.
                Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.ApiKey = "YOUR_ACCESS_TOKEN";
    
                // Call a function to set up the AuthenticationManager for OAuth.
                UserAuth.ArcGISLoginPrompt.SetChallengeHandler();
    
            }
  3. ユーザー認証を設定するコードを削除します。

    App.xaml.cs
            protected override void OnStartup(StartupEventArgs e)
            {
                base.OnStartup(e);
    
                // Set the access token for ArcGIS Maps SDK for .NET.
                Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.ApiKey = "YOUR_ACCESS_TOKEN";
    
                // 削除開始
                // Call a function to set up the AuthenticationManager for OAuth.
                UserAuth.ArcGISLoginPrompt.SetChallengeHandler();
                // 削除終了
    
            }
ベスト プラクティス: アクセス トークンは、このチュートリアルの便宜上、コードに直接格納されていますが、本番環境では認証情報をソース コードに直接保存しないでください。
  1. Visual Studio のソリューション エクスプローラーから ArcGISLoginPrompt.cs ファイルを開きます。

  2. クライアント ID (OAuthClientID) とリダイレクト URL (OAuthRedirectUri) の値を設定します。これらは認証の設定で作成したユーザー認証設定です。

    ArcGISLoginPrompt.cs
        internal static class ArcGISLoginPrompt
        {
            private const string ArcGISOnlineUrl = "https://www.arcgis.com/sharing/rest";
            // Specify the Client ID and Redirect URL to use with OAuth authentication.
            // See the instructions here for creating OAuth app settings:
            // https://developers.arcgis.com/documentation/security-and-authentication/user-authentication/tutorials/create-oauth-credentials-user-auth/
    
            private const string AppClientId = "YOUR_CLIENT_ID";
            private const string OAuthRedirectUrl = "YOUR_REDIRECT_URL";
  3. Visual Studioソリューション エクスプローラーApp.xaml.cs をクリックしてファイルを開きます。

  4. API キーのアクセス トークンを設定するコード行を削除します。

    App.xaml.cs
            protected override void OnStartup(StartupEventArgs e)
            {
                base.OnStartup(e);
    
                // 削除開始
                // Set the access token for ArcGIS Maps SDK for .NET.
                Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.ApiKey = "YOUR_ACCESS_TOKEN";
                // 削除終了
    
                // Call a function to set up the AuthenticationManager for OAuth.
                UserAuth.ArcGISLoginPrompt.SetChallengeHandler();
    
            }
ベスト プラクティス: OAuth 認証情報は、このチュートリアルの便宜上、コードに直接格納されていますが、本番環境では認証情報をソース コードに直接保存しないでください。

アプリを実行する

[デバッグ] メニュー > [デバッグの開始] をクリックして (またはキーボードの <F5> キーを押して) アプリを実行します。

カリフォルニア州のサンタモニカ山脈を中心とした地形図ベースマップ レイヤーの地図が表示されます。マップ ビューをダブルクリック、ドラッグ、マウス ホイールをスクロールしてマップを操作します。

次のチュートリアル

これらのチュートリアルでは、追加の API 機能ArcGIS ロケーション サービスおよび ArcGIS ツールの使用方法について説明します。(英語ページ)