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

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

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

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

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

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

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

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

  1. [App] テンプレートから新しい Xcode プロジェクトを作成します。

  2. インターフェースには [SwiftUI] を選択します。

  3. ライフサイクルには [SwiftUI] アプリケーションを選択します。

  4. 言語には [Swift] を選択します。

Swift パッケージを使用した依存関係の追加 MapLibre

Xcode プロジェクトにパッケージ依存関係を追加するには:

  1. [ファイル] > [Swift パッケージ] > [パッケージ依存関係の追加] に移動します。

  2. リポジトリ URL に https://github.com/maplibre/maplibre-gl-native-distribution を入力します。

    注記

    Swift パッケージの詳細については、Apple.com の「アプリへのパッケージ依存関係の追加」を参照してください。

  3. ターミナルに をインストールします CocoaPods。

    sudo gem install cocoapods
  4. アプリケーションのプロジェクトディレクトリに移動し、 CocoaPods パッケージマネージャーを使用して Podfile を初期化します。

    pod init
  5. Podfile を開いて、AWSCore を依存関係として追加します。

    platform :ios, '12.0' target 'Amazon Location Service Demo' do use_frameworks! pod 'AWSCore' end
  6. 依存関係をダウンロードしインストールします。

    pod install --repo-update
  7. が CocoaPods 作成した Xcode ワークスペースを開きます。

    xed .

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

Info.plist に以下のキーと値を追加してアプリケーションを設定します。

キー
AWSRegion us-east-1
IdentityPoolId us-east-1:54 f2ba88-9390-498d-aaa5-0d97fb7ca3bd
MapName ExampleMap

アプリケーションの構築: ContentView レイアウト

マップをレンダリングするには、ContentView.swift を編集します。

  • マップをレンダリングする MapView を追加します。

  • アトリビューションを表示する TextField を追加します。

これにより、マップの初期中心点も設定されます。

import SwiftUI struct ContentView: View { @State private var attribution = "" var body: some View { MapView(attribution: $attribution) .centerCoordinate(.init(latitude: 49.2819, longitude: -123.1187)) .zoomLevel(12) .edgesIgnoringSafeArea(.all) .overlay( TextField("", text: $attribution) .disabled(true) .font(.system(size: 12, weight: .light, design: .default)) .foregroundColor(.black) .background(Color.init(Color.RGBColorSpace.sRGB, white: 0.5, opacity: 0.5)) .cornerRadius(1), alignment: .bottomTrailing) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
注記

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

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

AWSSignatureV4Delegate.swift という名前の Swift ファイルを作成し、AWS リクエストをインターセプトし、署名バージョン 4 を使用して署名するクラスを定義します。マップビューでは、このクラスのインスタンスが URL の書き換えも担当するオフラインストレージデリゲートとして割り当てられます。

import AWSCore import Mapbox class AWSSignatureV4Delegate : NSObject, MGLOfflineStorageDelegate { private let region: AWSRegionType private let identityPoolId: String private let credentialsProvider: AWSCredentialsProvider init(region: AWSRegionType, identityPoolId: String) { self.region = region self.identityPoolId = identityPoolId self.credentialsProvider = AWSCognitoCredentialsProvider(regionType: region, identityPoolId: identityPoolId) super.init() } class func doubleEncode(path: String) -> String? { return path.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)? .addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) } func offlineStorage(_ storage: MGLOfflineStorage, urlForResourceOf kind: MGLResourceKind, with url: URL) -> URL { if url.host?.contains("amazonaws.com") != true { // not an AWS URL return url } // URL-encode spaces, etc. let keyPath = String(url.path.dropFirst()) guard let percentEncodedKeyPath = keyPath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { print("Invalid characters in path '\(keyPath)'; unsafe to sign") return url } let endpoint = AWSEndpoint(region: region, serviceName: "geo", url: url) let requestHeaders: [String: String] = ["host": endpoint!.hostName] // sign the URL let task = AWSSignatureV4Signer .generateQueryStringForSignatureV4( withCredentialProvider: credentialsProvider, httpMethod: .GET, expireDuration: 60, endpoint: endpoint!, // workaround for https://github.com/aws-amplify/aws-sdk-ios/issues/3215 keyPath: AWSSignatureV4Delegate.doubleEncode(path: percentEncodedKeyPath), requestHeaders: requestHeaders, requestParameters: .none, signBody: true) task.waitUntilFinished() if let error = task.error as NSError? { print("Error occurred: \(error)") } if let result = task.result { var urlComponents = URLComponents(url: (result as URL), resolvingAgainstBaseURL: false)! // re-use the original path; workaround for https://github.com/aws-amplify/aws-sdk-ios/issues/3215 urlComponents.path = url.path // have Mapbox GL fetch the signed URL return (urlComponents.url)! } // fall back to an unsigned URL return url } }

アプリケーションの構築:マップビュー

マップビューは、AWSSignatureV4Delegate インスタンスを初期化し、リソースを取得してマップをレンダリングする基盤となる MGLMapView の構成を行います。また、スタイル記述子のソースからにアトリビューション文字列を ContentView に伝達する処理も行います。

以下の struct の定義を含む、MapView.swift という名前の新しい Swift ファイルを作成します。

import SwiftUI import AWSCore import Mapbox struct MapView: UIViewRepresentable { @Binding var attribution: String private var mapView: MGLMapView private var signingDelegate: MGLOfflineStorageDelegate init(attribution: Binding<String>) { let regionName = Bundle.main.object(forInfoDictionaryKey: "AWSRegion") as! String let identityPoolId = Bundle.main.object(forInfoDictionaryKey: "IdentityPoolId") as! String let mapName = Bundle.main.object(forInfoDictionaryKey: "MapName") as! String let region = (regionName as NSString).aws_regionTypeValue() // MGLOfflineStorage doesn't take ownership, so this needs to be a member here signingDelegate = AWSSignatureV4Delegate(region: region, identityPoolId: identityPoolId) // register a delegate that will handle SigV4 signing MGLOfflineStorage.shared.delegate = signingDelegate mapView = MGLMapView( frame: .zero, styleURL: URL(string: "https://maps.geo.\(regionName).amazonaws.com/maps/v0/maps/\(mapName)/style-descriptor")) _attribution = attribution } func makeCoordinator() -> Coordinator { Coordinator($attribution) } class Coordinator: NSObject, MGLMapViewDelegate { var attribution: Binding<String> init(_ attribution: Binding<String>) { self.attribution = attribution } func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) { let source = style.sources.first as? MGLVectorTileSource let attribution = source?.attributionInfos.first self.attribution.wrappedValue = attribution?.title.string ?? "" } } // MARK: - UIViewRepresentable protocol func makeUIView(context: UIViewRepresentableContext<MapView>) -> MGLMapView { mapView.delegate = context.coordinator mapView.logoView.isHidden = true mapView.attributionButton.isHidden = true return mapView } func updateUIView(_ uiView: MGLMapView, context: UIViewRepresentableContext<MapView>) { } // MARK: - MGLMapView proxy func centerCoordinate(_ centerCoordinate: CLLocationCoordinate2D) -> MapView { mapView.centerCoordinate = centerCoordinate return self } func zoomLevel(_ zoomLevel: Double) -> MapView { mapView.zoomLevel = zoomLevel return self } }

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