Flutter

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

マップを表示する

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

マップには、地理データのレイヤーが含まれています。マップには、ベースマップ レイヤーと、オプションで 1 つ以上のデータ レイヤーを追加できます。

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

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

前提条件

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

  1. API キーにアクセスするための ArcGIS 開発者アカウント。アカウントをお持ちでない場合は、サインアップ(無料)してください。アカウントの作成方法は「開発者アカウントの作成」をご覧ください。
  2. 開発環境がシステム要件を満たしており、Flutter の開発環境 が整っていることを確認します。
  3. Flutter 用の IDE。VS Code を推奨しています。

認証の設定

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

API キー認証

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

  1. API キーの作成のチュートリアルを完了し、以下の権限を持つ API キーを作成します。
    • Privileges
      • Location services > Basemaps
  2. API キーのアクセス トークン をコピーし、安全な場所に貼り付けます。これは後のステップで使用します。

開発またはダウンロード

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

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

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

新しい Flutter アプリを作成する

  1. VS Code を開き、Welcome タブで [Open Folder…] を選択します。プロジェクトの場所を選んでください。

  2. [View] > [Terminal] に進みます。

  3. ターミナル ウィンドウで以下のコマンドを使い、display_a_map という新しい Flutter アプリを作成します。 必要なターゲット プラットフォームと 組織名 com.example.app を設定します。

    flutter create -e display_a_map --platforms ios,android --org com.example.app
    

ArcGIS Maps SDK for Flutter を追加する

arcgis_maps パッケージに依存関係を追加します。

  1. VS Code のターミナルで、ディレクトリーを新しいプロジェクトに変更します。
    cd display_a_map
    
  2. 以下のコマンドを実行します。
    dart pub add arcgis_maps
    
  3. 以下のコマンドを実行します。
    flutter pub upgrade
    
  4. 最後に、以下のコマンドを実行します。
    dart run arcgis_maps install
    

プラットフォーム固有の構成

Android

  1. プロジェクトの android/app/build.gradle.kts ファイルを編集して、最小要件を更新します。

    build.gradle.kts

    android {
        namespace = "com.example.app.display_a_map"
        compileSdk = 36 //変更
        ndkVersion = "27.0.12077973" //変更
    
        compileOptions {
            sourceCompatibility = JavaVersion.VERSION_11
            targetCompatibility = JavaVersion.VERSION_11
        }
    
        kotlinOptions {
            jvmTarget = JavaVersion.VERSION_11.toString()
        }
    
        defaultConfig {
            // TODO: 任意のアプリケーション ID を指定します (https://developer.android.com/studio/build/application-id.html).
            applicationId = "com.example.app.display_a_map"
            // アプリケーションの要件に合わせて次の値を更新します。
            // 詳細については https://flutter.dev/to/review-gradle-config を参照してください。
            minSdk = 28 //変更
            targetSdk = flutter.targetSdkVersion
            versionCode = flutter.versionCode
            versionName = flutter.versionName
        }
    
  2. android/app/src/main/AndroidManifest.xml に、オンライン リソースにアクセスするためのパーミッションを追加します。

    AndroidManifest.xml

    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <uses-permission android:name="android.permission.INTERNET" /> <!-- 追加 -->
        <application
            android:label="display_a_map"
            android:name="${applicationName}"
            android:icon="@mipmap/ic_launcher">
    

iOS

  1. ios/Podfile ファイルを編集して iOS 17.0 を最小に設定します。 行のコメントを解除し、バージョン番号を更新します。

    Podfile

    # Uncomment this line to define a global platform for your project
    platform :ios, '17.0'  #変更
    
  2. Runtimecore pod と arcgis_maps_ffi pod を Runner ターゲット セクションに追加します。

    Podfile

    target 'Runner' do
        use_frameworks!
        use_modular_headers!
    
        #変更開始
        pod 'Runtimecore', :podspec => '../arcgis_maps_core/ios/Runtimecore.podspec'
        pod 'arcgis_maps_ffi', :podspec => '../arcgis_maps_core/ios/arcgis_maps_ffi.podspec'
        #変更終了
    
        flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
        target 'RunnerTests' do
            inherit! :search_paths
        end
    end
    
  3. pod update を使用して Pods を設定します。

    cd ios && pod update && cd ..
    

開発者資格情報を設定する

アプリ ユーザーが ArcGIS の位置情報サービスにアクセスできるようにするには、認証の設定 ステップで作成した開発者資格情報を使用して、リソースへのリクエストを認証します。

API キーを設定する

  1. VS Codeで、lib/main.dart を開きます。

  2. arcgis_maps パッケージをインポートします。

    main.dart

    import 'package:flutter/material.dart';
    
    import 'package:arcgis_maps/arcgis_maps.dart'; //追加
    
  3. main() 関数で、ArcGISEnvironment.apiKey の値をアクセス トークンに設定します。

    void main() {
    
         ArcGISEnvironment.apiKey = ''; // アクセス トークンをここに記入します。 //追加
    
        runApp(const MainApp());
    }
    

    このチュートリアルでは便宜上、アクセス トークンをコードに直接格納しています。アクセス トークンをソース コードに格納することはベスト プラクティスではありません。

  4. runApp() 内で MaterialApp をインスタンス化し、名前付き引数 homeMainApp のインスタンスを設定します。

    main.dart

    void main() {
    
    ArcGISEnvironment.apiKey = ''; // アクセス トークンをここに記入します。
    
    ArcGISEnvironment.apiKey = apiKey; //追加
    
    runApp(
        const MaterialApp(home: MainApp()) //変更
        );
    }
    

マップを追加する

地形図ベースマップ レイヤーを含む地図を作成します。 地図は富士山の付近とします。

  1. テンプレート MainApp クラス定義をリファクタリングして、StatefulWidget を拡張します。 StatelessWidget キーワードにマウス カーソルを合わせて右クリックし、[Refactor…] から、[Convert to StatefulWidget] を選択してコードをリファクタリングします。

    ArcGIS Maps SDK for Flutter で作業していると、データの変更に応じて UI を更新するなど、アプリケーションの状態の更新が必要になることがよくあります。 ステートフル ウィジェットを実装することで、アプリはこのような状況に対応できます。 ステートレス ウィジェットの実装を使用して、単に地図を表示することも可能です。Display map サンプルをご確認ください。

    main.dart

    class MainApp extends StatefulWidget { //変更
    
        const MainApp({super.key});
    
        // 変更開始
        @override
        State<MainApp> createState() => _MainAppState();
        // 変更終了
    
    }
    
    //追加開始
    class _MainAppState extends State<MainApp> {
        @override
        Widget build(BuildContext context) {
    
            return const MaterialApp(
                home: Scaffold(
                    body: Center(
                        child: Text('Hello World!'),
                    ),
                ),
            );
    
        }
    }
    //追加終了
    
  2. _MainAppState クラスの build メソッド内で返される MaterialApp ウィジェットを削除します。 このコードは Flutter create テンプレートによって生成されたもので、次項でマップを含むウィジェットを返すコードに置き換えられます。

    main.dart

    class MainApp extends StatefulWidget {
    
        const MainApp({super.key});
    
        @override
        State<MainApp> createState() => _MainAppState();
    
    }
    
    class _MainAppState extends State<MainApp> {
            @override
            Widget build(BuildContext context) {
    
                // 削除開始
                return const MaterialApp(
                    home: Scaffold(
                        body: Center(
                            child: Text('Hello World!'),
                        ),
                    ),
                );
                // 削除終了
    
            }
    }
    
  3. _MainAppState クラスの内部で、最後のクラス メンバー変数 _mapViewController を定義し、ArcGISMapView クラスの createController() を呼び出して ArcGISMapViewController で初期化します。

    ArcGIS マップ ビュー コントローラーは、ArcGISMap で定義された 2 次元 (2D) 地理コンテンツを表示するユーザー インタフェース コントロールです。

    main.dart

    class _MainAppState extends State<MainApp> {
    
        final _mapViewController = ArcGISMapView.createController(); //追加
    
        @override
        Widget build(BuildContext context) {
    
        }
    
    }
    
  4. build メソッド内で ScaffoldColumnExpanded からなるウィジェット ツリーに ArcGISMapView ウィジェットを追加します。 引数名 controllerProvider をクラス メンバー変数 _mapViewController に設定し、onMapViewReady 引数を次に定義する引数と同じ名前の新しいメソッドに設定します。

    Scaffold ウィジェットは基本的なマテリアル デザインのビジュアル レイアウト構造を提供し、Column ウィジェットは子ウィジェットを垂直配列で表示します。ArcGISMapView ウィジェットは、サイズが制限されたウィジェット内でのみ使用できます。 サイズが制限されていない状態で使用すると、アプリケーションは例外をスローします。 たとえば、ArcGISMapViewColumn ウィジェット内で使用すると、サイズが制限されないため、このような例外が発生します。 代わりに、チュートリアルのこのステップで説明するように、ArcGISMapViewExpanded ウィジェットでラップして、適切な境界を提供することができます。

    main.dart

    class _MainAppState extends State<MainApp> {
    
        final _mapViewController = ArcGISMapView.createController();
    
        @override
        Widget build(BuildContext context) {
    
            //追加開始
            return Scaffold(
              body: Column(
                children: [
                  Expanded(
                    child: ArcGISMapView(
                      controllerProvider: () => _mapViewController,
                      onMapViewReady: onMapViewReady,
                    ),
                  ),
                ],
              ),
            );
            //追加終了
    
        }
    
    }
    
  5. _MainAppState 内で、何も返さない新しいメソッド onMapViewReady() を定義します。

    main.dart

    class _MainAppState extends State<MainApp> {
    
        final _mapViewController = ArcGISMapView.createController();
    
        @override
        Widget build(BuildContext context) {
    
            return Scaffold(
                body: Column(
                    children: [
                        Expanded(
                            child: ArcGISMapView(
                                controllerProvider: () => _mapViewController,
                                onMapViewReady: onMapViewReady,
                            ),
                        ),
                    ],
                ),
            );
    
        }
    
        //追加開始
        void onMapViewReady() {
    
        }
        //追加終了
    
    }
    
  6. 新しいメソッド内で、final 変数 map を定義し、ArcGIS Topographic ベースマップ スタイルを持つ ArcGISMap インスタンスに初期化します。

    • basemapStyleParams: BasemapStyleParameters をインスタンス化し、specificLanguage を日本語に変更します。
    • basemap: ArcGIS Topographic ベースマップ スタイルと 生成した basemapStyleParamsBasemap をインスタンス化します。
    • map: basemapArcGISMap をインスタンス化します。

    main.dart

    class _MainAppState extends State<MainApp> {
    
        final _mapViewController = ArcGISMapView.createController();
    
        @override
        Widget build(BuildContext context) {
    
            return Scaffold(
                body: Column(
                    children: [
                        Expanded(
                            child: ArcGISMapView(
                                controllerProvider: () => _mapViewController,
                                onMapViewReady: onMapViewReady,
                            ),
                        ),
                    ],
                ),
            );
    
        }
    
        void onMapViewReady() {
    
            //追加開始
            final basemapStyleParams = BasemapStyleParameters();
            basemapStyleParams.specificLanguage = "ja"; //ベースマップの言語を日本語に設定
    
            final basemap = Basemap.withStyle(BasemapStyle.arcGISTopographic, parameters: basemapStyleParams); //ベースマップに設定を適用
            final map = ArcGISMap.withBasemap(basemap); //設定したベースマップでマップを生成
            //追加終了
    
        }
    
    }
    
  7. ArcGIS マップ ビュー コントローラーの arcGISMap プロパティーを map に設定します。 さらに、setViewpoint() を呼び出して、富士山にズームします。

    main.dart

    class _MainAppState extends State<MainApp> {
    
        final _mapViewController = ArcGISMapView.createController();
    
        @override
        Widget build(BuildContext context) {
    
            return Scaffold(
                body: Column(
                    children: [
                        Expanded(
                            child: ArcGISMapView(
                                controllerProvider: () => _mapViewController,
                                onMapViewReady: onMapViewReady,
                            ),
                        ),
                    ],
                ),
            );
    
        }
    
        void onMapViewReady() {
    
            final basemapStyleParams = BasemapStyleParameters();
            basemapStyleParams.specificLanguage = "ja"; //ベースマップの言語を日本語に設定
    
            final basemap = Basemap.withStyle(BasemapStyle.arcGISTopographic, parameters: basemapStyleParams); //ベースマップに設定を適用
            final map = ArcGISMap.withBasemap(basemap); //設定したベースマップでマップを生成
    
            //追加開始
            _mapViewController.arcGISMap = map;
            _mapViewController.setViewpoint(
                Viewpoint.withLatLongScale(
                    latitude: 35.360626,
                    longitude: 138.727363,
                    scale: 200000.0,
                ),
            );
            //追加終了
    
        }
    
    }
    

アプリを実行する

  1. Android エミュレーター、iOS シミュレーター、または物理的なデバイスが設定され、実行されていることを確認します。
  2. VS Codeで、[Run] > [Run Without Debugging] を選択します。

富士山を中心に、地形図のベースマップ層が表示された地図が表示されます。地図ビューをピンチ、ドラッグ、またはダブルタップして、地図を閲覧してください。


または、以下の手順に従ってチュートリアルの解答をダウンロードすることもできます。

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

  1. こちらをクリックしファイルをダウンロードし、コンピュータ内の任意の場所に解凍してください。
  2. VS Code で、プロジェクトを開いてください。

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

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

アプリ ユーザーが ArcGIS の位置情報サービスにアクセスできるようにするには、認証の設定 ステップで作成した開発者資格情報を使用して、リソースへのリクエストを認証します。

API キーを設定する

  1. VS Codeで、lib/main.dart を開きます。

  2. main() 関数で、ArcGISEnvironment.apiKey の値をアクセス トークンに設定します。

    void main() {
    
         ArcGISEnvironment.apiKey = ''; // アクセス トークンをここに記入します。 //追加
    
        runApp(const MainApp());
    }
    

    このチュートリアルでは便宜上、アクセス トークンをコードに直接格納しています。アクセス トークンをソース コードに格納することはベスト プラクティスではありません。

アプリを実行する

以下の手順に従ってアプリケーションを実行してください。

  1. VS Codeのターミナルで、次のコマンドを実行してください。

    flutter pub upgrade
    
  2. 実行します。

    dart run arcgis_maps install
    
  3. Android エミュレーター、iOS シミュレーター、または物理的なデバイスが設定され、実行されていることを確認します。

  4. VS Codeで、[Run] > [Run Without Debugging] を選択します。

富士山を中心に、地形図のベースマップ層が表示された地図が表示されます。地図ビューをピンチ、ドラッグ、またはダブルタップして、地図を閲覧してください。


アプリの動作が確認できたら ArcGIS の セキュリティーと認証について学びましょう!