將適用於 iOS 的 Tangram ES 與 Amazon Location Service 搭配使用 - Amazon Location Service

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

將適用於 iOS 的 Tangram ES 與 Amazon Location Service 搭配使用

Tangram ES 是 C++ 程式庫,用於使用 OpenGL ES 從向量資料轉譯 2D 和 3D 映射。這是 Tangram 的原生複本。

使用來自 的映射時,為搭配 Tilezen 結構描述使用而建置的 Tangram 樣式在很大程度上與 Amazon Location 相容HERE。其中包含:

  • Bubble Wrap – 功能完整的尋路樣式,具有適用於興趣點的實用圖示

  • Cinnabar – 一般映射應用程式的經典外觀和首選

  • 補充 – 專為資料視覺化重疊所設計的極簡地圖樣式,其靈感來自 Stamen Design 的精實碳粉樣式

  • Tron – 探索 視覺化語言的規模轉換 TRON

  • Walkabout – 專注於戶外的樣式,非常適合健行或外出

本指南說明如何使用名為 Cinnabar 的 Tangram 樣式,將適用於 iOS 的 Tangram ES 與 Amazon Location 整合。此範例可作為 Amazon Location Service 範例儲存庫的一部分GitHub

雖然其他 Tangram 樣式最好搭配編碼地形資訊的光柵圖磚,但 Amazon Location 尚不支援此功能。

重要

下列教學課程中的 Tangram 樣式僅與以 VectorHereContrast樣式設定的 Amazon Location Map 資源相容。

建置應用程式:初始化

若要初始化應用程式:

  1. 應用程式範本建立新的 Xcode 專案。

  2. 為其介面選取 SwiftUI

  3. 為其生命週期選取 SwiftUI 應用程式。

  4. 選取 Swift 做為其語言。

建置應用程式:新增相依性

若要新增相依性,您可以使用相依性管理員,例如CocoaPods

  1. 在終端機中,安裝 CocoaPods:

    sudo gem install cocoapods
  2. 導覽至應用程式的專案目錄,並使用套件管理員初始化 Podfile CocoaPods:

    pod init
  3. 開啟 Podfile 以新增 AWSCoreTangram-es做為相依性:

    platform :ios, '12.0' target 'Amazon Location Service Demo' do use_frameworks! pod 'AWSCore' pod 'Tangram-es' end
  4. 下載並安裝相依性:

    pod install --repo-update
  5. 開啟 CocoaPods 建立的 Xcode 工作區:

    xed .

建置應用程式:組態

將下列金鑰和值新增至 Info.plist,以設定應用程式並停用遙測:

金鑰
AWSRegion us-east-1
IdentityPoolId us-east-1:54f2ba88-9390-498d-aaa5-0d97fb7ca3bd
MapName ExampleMap
場景URL https://www.nextzen.org/carto/cinnabar-style/9/cinnabar-style.zip

建置應用程式: ContentView 配置

若要轉譯映射,請編輯 ContentView.swift

  • 新增MapView轉譯映射的 。

  • 新增顯示屬性TextField的 。

這也會設定地圖的初始中心點。

注意

您必須為應用程式或文件上使用的每個資料提供者提供文字標記或文字屬性。屬性字串包含在 sources.esri.attributionsources.here.attributionsource.grabmaptiles.attribution金鑰下的樣式描述符回應中。將 Amazon Location 資源與資料提供者 搭配使用時,請務必閱讀服務條款與條件

import SwiftUI import TangramMap struct ContentView: View { var body: some View { MapView() .cameraPosition(TGCameraPosition( center: CLLocationCoordinate2DMake(49.2819, -123.1187), zoom: 10, bearing: 0, pitch: 0)) .edgesIgnoringSafeArea(.all) .overlay( Text("© 2020 HERE") .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() } }

建置應用程式:請求轉換

建立名為 的新 Swift 檔案,AWSSignatureV4URLHandler.swift其中包含下列類別定義,以攔截 AWS 請求並使用 Signature 第 4 版簽署請求。這將在 Tangram 中註冊為URL處理常式MapView

import AWSCore import TangramMap class AWSSignatureV4URLHandler: TGDefaultURLHandler { 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() } override func downloadRequestAsync(_ url: URL, completionHandler: @escaping TGDownloadCompletionHandler) -> UInt { if url.host?.contains("amazonaws.com") != true { // not an AWS URL return super.downloadRequestAsync(url, completionHandler: completionHandler) } // URL-encode spaces, etc. let keyPath = String(url.path.dropFirst()) guard let keyPathSafe = keyPath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) else { print("Invalid characters in path '\(keyPath)'; unsafe to sign") return super.downloadRequestAsync(url, completionHandler: completionHandler) } // sign the URL let endpoint = AWSEndpoint(region: region, serviceName: "geo", url: url) let requestHeaders: [String: String] = ["host": endpoint!.hostName] let task = AWSSignatureV4Signer .generateQueryStringForSignatureV4( withCredentialProvider: credentialsProvider, httpMethod: .GET, expireDuration: 60, endpoint: endpoint!, keyPath: keyPathSafe, requestHeaders: requestHeaders, requestParameters: .none, signBody: true) task.waitUntilFinished() if let error = task.error as NSError? { print("Error occurred: \(error)") } if let result = task.result { // have Tangram fetch the signed URL return super.downloadRequestAsync(result as URL, completionHandler: completionHandler) } // fall back to an unsigned URL return super.downloadRequestAsync(url, completionHandler: completionHandler) } }

建置應用程式:地圖檢視

地圖檢視會負責初始化 執行個體AWSSignatureV4Delegate並設定基礎 MGLMapView,這會擷取資源並呈現地圖。它也會處理將屬性字串從樣式描述符的來源傳播回 ContentView

建立名為 的新 Swift 檔案,MapView.swift其中包含下列struct定義:

import AWSCore import TangramMap import SwiftUI struct MapView: UIViewRepresentable { private let mapView: TGMapView init() { 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 sceneURL = URL(string: Bundle.main.object(forInfoDictionaryKey: "SceneURL") as! String)! let region = (regionName as NSString).aws_regionTypeValue() // rewrite tile URLs to point at AWS resources let sceneUpdates = [ TGSceneUpdate(path: "sources.mapzen.url", value: "https://maps.geo.\(regionName).amazonaws.com/maps/v0/maps/\(mapName)/tiles/{z}/{x}/{y}")] // instantiate a TGURLHandler that will sign AWS requests let urlHandler = AWSSignatureV4URLHandler(region: region, identityPoolId: identityPoolId) // instantiate the map view and attach the URL handler mapView = TGMapView(frame: .zero, urlHandler: urlHandler) // load the map style and apply scene updates (properties modified at runtime) mapView.loadScene(from: sceneURL, with: sceneUpdates) } func cameraPosition(_ cameraPosition: TGCameraPosition) -> MapView { mapView.cameraPosition = cameraPosition return self } // MARK: - UIViewRepresentable protocol func makeUIView(context: Context) -> TGMapView { return mapView } func updateUIView(_ uiView: TGMapView, context: Context) { } }

執行此應用程式會以您選擇的樣式顯示全螢幕地圖。此範例可作為 Amazon Location Service 範例儲存庫的一部分GitHub