Amazon Location Service での Android 用 MapLibre ネイティブ SDK の使用 - Amazon Location Service

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Amazon Location Service での Android 用 MapLibre ネイティブ SDK の使用

MapLibre ネイティブ SDK を使用して、Android アプリケーションにインタラクティブマップを埋め込みます。

Android 用 MapLibre ネイティブ SDK は Mapbox Native に基づくライブラリであり、Amazon Location Service Maps API が提供するスタイルやタイルと互換性があります。 MapLibre Native SDK for Android を統合して、インタラクティブマップビューをスケーラブルでカスタマイズ可能なベクトルマップに Android アプリケーションに埋め込むことができます。

このチュートリアルでは、Android 用 MapLibre ネイティブ SDK を Amazon Location と統合する方法について説明します。このチュートリアルのサンプルアプリケーションは、 の Amazon Location Service サンプルリポジトリの一部として利用できますGitHub

アプリケーションの構築:初期化

アプリケーションを初期化するには:

  1. [空のアクティビティ] テンプレートから新しい Android Studio プロジェクトを作成します。

  2. プロジェクト言語に [Kotlin] が選択されていることを確認します。

  3. [Minimum SDK of API 14: Android 4.0 (Ice Cream Sandwich)] 以降を選択してください。

  4. [プロジェクト構造]を開き、[ファイル] > [プロジェクト構造...] に移動します。[依存関係] セクションを選択します。

  5. [<All Modules>] を選択したら、[+] ボタンを選択して[新しいライブラリ依存関係]を追加します。

  6. [AWS Android SDK] バージョンは、2.20.0 以降を追加します。例:com.amazonaws:aws-android-sdk-core:2.20.0

  7. MapLibre Android バージョン 9.4.0 以降のネイティブ SDK を追加します。例:org.maplibre.gl:android-sdk:9.4.0

  8. build.gradle ファイルのプロジェクトレベルで、次の Maven リポジトリを追加して Android のパッケージにアクセスします MapLibre。

    allprojects { repositories { // Retain your existing repositories google() jcenter() // Declare the repositories for MapLibre mavenCentral() } }

アプリケーションの構築:設定

アプリケーションにリソースと AWS リージョンをを設定するには:

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="identityPoolId">us-east-1:54f2ba88-9390-498d-aaa5-0d97fb7ca3bd</string> <string name="mapName">ExampleMap</string> <string name="awsRegion">us-east-1</string> </resources>

アプリケーションの構築:アクティビティレイアウト

app/src/main/res/layout/activity_main.xml を編集します。

  • マップをレンダリングする MapView を追加します。これにより、マップの初期中心点も設定されます。

  • アトリビューションを表示する TextView を追加してください。

<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.mapbox.mapboxsdk.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" app:mapbox_cameraTargetLat="49.2819" app:mapbox_cameraTargetLng="-123.1187" app:mapbox_cameraZoom="12" app:mapbox_uiAttribution="false" app:mapbox_uiLogo="false" /> <TextView android:id="@+id/attributionView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#80808080" android:padding="5sp" android:textColor="@android:color/black" android:textSize="10sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" tools:ignore="SmallSp" /> </androidx.constraintlayout.widget.ConstraintLayout>
注記

使用する各データプロバイダーのワードマークまたはテキストアトリビューションを、アプリケーションまたはドキュメントに記載する必要があります。アトリビューション文字列は、スタイル記述子のレスポンスのsources.esri.attributionsources.here.attributionsource.grabmaptiles.attribution キーに含まれています。Amazon Location リソースをデータプロバイダーと併用する場合は、サービスの利用規約を必ずお読みください。

アプリケーションの構築:リクエスト変換

AWS リクエストをインターセプトし、署名バージョン 4 を使用して署名する SigV4Interceptor という名前のクラスを作成します。この情報は、メインアクティビティの作成時にマップリソースの取得に使用される HTTP クライアントに登録されます。

package aws.location.demo.okhttp import com.amazonaws.DefaultRequest import com.amazonaws.auth.AWS4Signer import com.amazonaws.auth.AWSCredentialsProvider import com.amazonaws.http.HttpMethodName import com.amazonaws.util.IOUtils import okhttp3.HttpUrl import okhttp3.Interceptor import okhttp3.Request import okhttp3.Response import okio.Buffer import java.io.ByteArrayInputStream import java.net.URI class SigV4Interceptor( private val credentialsProvider: AWSCredentialsProvider, private val serviceName: String ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() if (originalRequest.url().host().contains("amazonaws.com")) { val signer = if (originalRequest.url().encodedPath().contains("@")) { // the presence of "@" indicates that it doesn't need to be double URL-encoded AWS4Signer(false) } else { AWS4Signer() } val awsRequest = toAWSRequest(originalRequest, serviceName) signer.setServiceName(serviceName) signer.sign(awsRequest, credentialsProvider.credentials) return chain.proceed(toSignedOkHttpRequest(awsRequest, originalRequest)) } return chain.proceed(originalRequest) } companion object { fun toAWSRequest(request: Request, serviceName: String): DefaultRequest<Any> { // clone the request (AWS-style) so that it can be populated with credentials val dr = DefaultRequest<Any>(serviceName) // copy request info dr.httpMethod = HttpMethodName.valueOf(request.method()) with(request.url()) { dr.resourcePath = uri().path dr.endpoint = URI.create("${scheme()}://${host()}") // copy parameters for (p in queryParameterNames()) { if (p != "") { dr.addParameter(p, queryParameter(p)) } } } // copy headers for (h in request.headers().names()) { dr.addHeader(h, request.header(h)) } // copy the request body val bodyBytes = request.body()?.let { body -> val buffer = Buffer() body.writeTo(buffer) IOUtils.toByteArray(buffer.inputStream()) } dr.content = ByteArrayInputStream(bodyBytes ?: ByteArray(0)) return dr } fun toSignedOkHttpRequest( awsRequest: DefaultRequest<Any>, originalRequest: Request ): Request { // copy signed request back into an OkHttp Request val builder = Request.Builder() // copy headers from the signed request for ((k, v) in awsRequest.headers) { builder.addHeader(k, v) } // start building an HttpUrl val urlBuilder = HttpUrl.Builder() .host(awsRequest.endpoint.host) .scheme(awsRequest.endpoint.scheme) .encodedPath(awsRequest.resourcePath) // copy parameters from the signed request for ((k, v) in awsRequest.parameters) { urlBuilder.addQueryParameter(k, v) } return builder.url(urlBuilder.build()) .method(originalRequest.method(), originalRequest.body()) .build() } } }

アプリケーションの構築:メインアクティビティ

メインアクティビティは、ユーザーに表示されるビューを初期化します。これには以下が含まれます。

  • Amazon Cognito CredentialsProvider をインスタンス化します。

  • 署名バージョン 4をインターセプターとして登録します。

  • マップスタイル記述子を指定してマップを設定し、適切なアトリビューションを表示します。

また、MainActivity には、ライフサイクルイベントをマップビューに転送して、呼び出してもアクティブなビューポートを維持できるようにする役割もあります。

package aws.location.demo.maplibre import android.os.Bundle import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import aws.location.demo.okhttp.SigV4Interceptor import com.amazonaws.auth.CognitoCachingCredentialsProvider import com.amazonaws.regions.Regions import com.mapbox.mapboxsdk.Mapbox import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.Style import com.mapbox.mapboxsdk.module.http.HttpRequestUtil import okhttp3.OkHttpClient private const val SERVICE_NAME = "geo" class MainActivity : AppCompatActivity() { private var mapView: MapView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // configuration val identityPoolId = getString(R.string.identityPoolId) val region = getString(R.string.awsRegion) val mapName = getString(R.string.mapName) // Credential initialization val credentialProvider = CognitoCachingCredentialsProvider( applicationContext, identityPoolId, Regions.fromName(identityPoolId.split(":").first()) ) // initialize MapLibre Mapbox.getInstance(this, null) HttpRequestUtil.setOkHttpClient( OkHttpClient.Builder() .addInterceptor(SigV4Interceptor(credentialProvider, SERVICE_NAME)) .build() ) // initialize the view setContentView(R.layout.activity_main) // initialize the map view mapView = findViewById(R.id.mapView) mapView?.onCreate(savedInstanceState) mapView?.getMapAsync { map -> map.setStyle( Style.Builder() .fromUri("https://maps.geo.${region}.amazonaws.com/maps/v0/maps/${mapName}/style-descriptor") ) { style -> findViewById<TextView>(R.id.attributionView).text = style.sources.first()?.attribution } } } override fun onStart() { super.onStart() mapView?.onStart() } override fun onResume() { super.onResume() mapView?.onResume() } override fun onPause() { super.onPause() mapView?.onPause() } override fun onStop() { super.onStop() mapView?.onStop() } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) mapView?.onSaveInstanceState(outState) } override fun onLowMemory() { super.onLowMemory() mapView?.onLowMemory() } override fun onDestroy() { super.onDestroy() mapView?.onDestroy() } }

このアプリケーションを実行すると、選択したスタイルで全画面マップが表示されます。このサンプルは、 の Amazon Location Service サンプルリポジトリの一部として入手できますGitHub