Utilisation de Tangram ES pour Android avec Amazon Location Service - Amazon Location Service

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation de Tangram ES pour Android avec Amazon Location Service

Tangram ES est une bibliothèque C++ pour le rendu de cartes 2D et 3D à partir de données vectorielles à l'aide d'OpenGL ES. C'est l'équivalent natif de Tangram.

Les styles Tangram conçus pour fonctionner avec le schéma Tilezen sont largement compatibles avec Amazon Location lorsque vous utilisez des cartes provenant de HERE. Il s'agit des licences suivantes :

  • Bubble Wrap — Un style d'orientation complet avec des icônes utiles pour les points d'intérêt.

  • Cinnabar — Un look classique et incontournable pour les applications cartographiques générales.

  • Refill — Un style de carte minimaliste conçu pour les superpositions de visualisation de données, inspiré du style Toner emblématique de Stamen Design.

  • Tron — Une exploration des transformations d'échelle dans le langage visuel de TRON.

  • Walkabout — Un style axé sur le plein air, parfait pour la randonnée ou les sorties.

Ce guide explique comment intégrer Tangram ES pour Android à Amazon Location en utilisant le style Tangram appelé Cinnabar. Cet exemple est disponible dans le référentiel d'exemples Amazon Location Service sur GitHub.

Bien que les autres styles Tangram soient mieux accompagnés de tuiles matricielles, qui encodent les informations du terrain, cette fonctionnalité n'est pas encore prise en charge par Amazon Location.

Important

Les styles Tangram présentés dans le didacticiel suivant sont uniquement compatibles avec les ressources cartographiques Amazon Location configurées avec ce VectorHereContrast style.

Création de l'application : initialisation

Pour initialiser votre application :

  1. Créez un nouveau projet Android Studio à partir du modèle Empty Activity.

  2. Assurez-vous que Kotlin est sélectionné pour la langue du projet.

  3. Sélectionnez un SDK minimum d'API 16 : Android 4.1 (Jelly Bean) ou version ultérieure.

  4. Ouvrez la structure du projet pour sélectionner le fichier, la structure du projet... , puis choisissez la section Dépendances.

  5. Lorsque cette option est <All Modules>sélectionnée, cliquez sur le bouton + pour ajouter une nouvelle dépendance de bibliothèque.

  6. Ajoutez le SDK AWS Android version 2.19.1 ou ultérieure. Par exemple : com.amazonaws:aws-android-sdk-core:2.19.1

  7. Ajoutez la version 0.13.0 ou ultérieure de Tangram. Par exemple : com.mapzen.tangram:tangram:0.13.0.

    Note

    Rechercher Tangram : com.mapzen.tangram:tangram:0.13.0 générera un message indiquant qu'il est « introuvable », mais si vous cliquez sur OK, vous pourrez l'ajouter.

Création de l'application : Configuration

Pour configurer votre application en fonction de vos ressources et de votre AWS région :

  1. Créer app/src/main/res/values/configuration.xml.

  2. Entrez les noms et les identifiants de vos ressources, ainsi que la AWS région dans laquelle elles ont été créées :

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="identityPoolId">us-east-1:54f2ba88-9390-498d-aaa5-0d97fb7ca3bd</string> <string name="mapName">TangramExampleMap</string> <string name="awsRegion">us-east-1</string> <string name="sceneUrl">https://www.nextzen.org/carto/cinnabar-style/9/cinnabar-style.zip</string> <string name="attribution">© 2020 HERE</string> </resources>

Création de l'application : mise en page des activités

Modifier app/src/main/res/layout/activity_main.xml :

  • Ajoutez unMapView, qui affiche la carte. Cela définira également le point central initial de la carte.

  • Ajoutez unTextView, qui affiche l'attribution.

Cela définira également le point central initial de la carte.

Note

Vous devez indiquer l'attribution d'un mot ou d'un texte pour chaque fournisseur de données que vous utilisez, que ce soit sur votre application ou dans votre documentation. Les chaînes d'attribution sont incluses dans la réponse du descripteur de style sous les source.grabmaptiles.attribution touches sources.esri.attributionsources.here.attribution, et.

Étant donné que Tangram ne demande pas ces ressources et n'est compatible qu'avec les cartes d'HERE, utilisez « © 2020 HERE ». Lorsque vous utilisez les ressources Amazon Location avec des fournisseurs de données, assurez-vous de lire les conditions générales du service.

<?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.mapzen.tangram.MapView android:id="@+id/map" android:layout_height="match_parent" android:layout_width="match_parent" /> <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>

Création de l'application : transformation des demandes

Créez une classe nommée SigV4Interceptor pour intercepter les AWS demandes et signez-les à l'aide de Signature Version 4. Cela sera enregistré auprès du client HTTP utilisé pour récupérer les ressources cartographiques lors de la création de l'activité principale.

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() } } }

Création de l'application : activité principale

L'activité principale est chargée d'initialiser les vues qui seront affichées aux utilisateurs. Cela implique :

  • Instanciation d'un Amazon Cognito. CredentialsProvider

  • Enregistrement de l'intercepteur Signature version 4.

  • Configuration de la carte en la pointant sur un style de carte, en remplaçant les URL des vignettes et en affichant l'attribution appropriée.

MainActivityest également chargé de transférer les événements du cycle de vie vers la vue cartographique.

package aws.location.demo.tangram 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.mapzen.tangram.* import com.mapzen.tangram.networking.DefaultHttpHandler import com.mapzen.tangram.networking.HttpHandler private const val SERVICE_NAME = "geo" class MainActivity : AppCompatActivity(), MapView.MapReadyCallback { private var mapView: MapView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mapView = findViewById(R.id.map) mapView?.getMapAsync(this, getHttpHandler()) findViewById<TextView>(R.id.attributionView).text = getString(R.string.attribution) } override fun onMapReady(mapController: MapController?) { val sceneUpdates = arrayListOf( SceneUpdate( "sources.mapzen.url", "https://maps.geo.${getString(R.string.awsRegion)}.amazonaws.com/maps/v0/maps/${ getString( R.string.mapName ) }/tiles/{z}/{x}/{y}" ) ) mapController?.let { map -> map.updateCameraPosition( CameraUpdateFactory.newLngLatZoom( LngLat(-123.1187, 49.2819), 12F ) ) map.loadSceneFileAsync( getString(R.string.sceneUrl), sceneUpdates ) } } private fun getHttpHandler(): HttpHandler { val builder = DefaultHttpHandler.getClientBuilder() val credentialsProvider = CognitoCachingCredentialsProvider( applicationContext, getString(R.string.identityPoolId), Regions.US_EAST_1 ) return DefaultHttpHandler( builder.addInterceptor( SigV4Interceptor( credentialsProvider, SERVICE_NAME ) ) ) } override fun onResume() { super.onResume() mapView?.onResume() } override fun onPause() { super.onPause() mapView?.onPause() } override fun onLowMemory() { super.onLowMemory() mapView?.onLowMemory() } override fun onDestroy() { super.onDestroy() mapView?.onDestroy() } }

L'exécution de cette application affiche une carte en plein écran dans le style de votre choix. Cet exemple est disponible dans le référentiel d'exemples Amazon Location Service sur GitHub.