Aggiungi la ricerca di geocodifica inversa di Amazon Location alla tua applicazione - Servizio di posizione Amazon

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Aggiungi la ricerca di geocodifica inversa di Amazon Location alla tua applicazione

Ora aggiungerai la ricerca con geocodifica inversa all'applicazione, in cui troverai gli elementi in una posizione. Per semplificare l'utilizzo di un'app per Android, effettueremo una ricerca al centro dello schermo. Per trovare una nuova posizione, sposta la mappa nel punto in cui desideri effettuare la ricerca. Posizioneremo un indicatore al centro della mappa per mostrare dove stiamo cercando.

L'aggiunta di una ricerca con geocodifica inversa sarà composta da due parti.

  • Aggiungi un marker al centro dello schermo per mostrare all'utente dove stiamo cercando.

  • Aggiungi una casella di testo per i risultati, quindi cerca cosa si trova nella posizione del marker e mostralo nella casella di testo.

Per aggiungere un marker alla tua applicazione
  1. Salva questa immagine nel tuo progetto nella app/res/drawable cartella come red_marker.png (puoi anche accedere all'immagine da GitHub). In alternativa, puoi creare la tua immagine. Puoi anche usare un file.png con trasparenza per le parti che non vuoi mostrare.

  2. Aggiungi il codice seguente al tuo MapLoadScreenfile.kt.

    // ...other imports import androidx.compose.foundation.Image import androidx.compose.foundation.layout.size import androidx.compose.ui.Alignment import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.amazon.testmapapp.R @Composable fun MapLoadScreen( mapReadyCallback: OnMapReadyCallback, ) { Box( modifier = Modifier .fillMaxWidth() .fillMaxHeight(), ) { MapView(mapReadyCallback) Box( modifier = Modifier .align(Alignment.Center), ) { Image( painter = painterResource(id = R.drawable.red_marker), contentDescription = "marker", modifier = Modifier .size(40.dp) .align(Alignment.Center), ) } } } @Composable fun MapView(mapReadyCallback: OnMapReadyCallback) { AndroidView( factory = { context -> val mapView = org.maplibre.android.maps.MapView(context) mapView.onCreate(null) mapView.getMapAsync(mapReadyCallback) mapView }, ) }
  3. Crea ed esegui la tua app per visualizzare in anteprima la funzionalità.

La tua app ora ha un indicatore sullo schermo. In questo caso, si tratta di un'immagine statica che non si muove. Viene utilizzato per mostrare il centro della visualizzazione della mappa, dove cercheremo. Nella procedura seguente, aggiungeremo la ricerca in quella posizione.

Per aggiungere alla tua app la ricerca con geocodifica inversa in una località
  1. Nella finestra del progetto, apri gradle in un libs.versions.toml file nella vista ad albero. Questo aprirà il libs.versions.toml file per la modifica. Ora aggiungi la versione e i dati delle librerie seguenti nel libs.versions.toml file.

    [versions] ... okhttp = "4.12.0" [libraries] ... com-squareup-okhttp3 = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } [plugins] ...
  2. Dopo aver finito di modificare il libs.versions.toml file, è AndroidStudio necessario risincronizzare il progetto. Nella parte superiore della finestra di libs.versions.toml modifica, AndroidStudio ti chiede di eseguire la sincronizzazione. Seleziona «Sincronizza ora» per sincronizzare il progetto prima di continuare.

  3. Nella finestra del progetto, apri Gradle Scripts nella vista ad albero e seleziona il build.gradle file per il modulo applicativo. Questo aprirà il build.gradle file per la modifica.

  4. Nella parte inferiore del file, nella sezione delle dipendenze, aggiungi la seguente dipendenza.

    dependencies { ... implementation(libs.com.squareup.okhttp3) }
  5. Dopo aver finito di modificare le dipendenze di Gradle, è AndroidStudio necessario risincronizzare il progetto. Nella parte superiore della finestra di build.gradle modifica, ti AndroidStudio chiede di eseguire la sincronizzazione. Seleziona questa opzione SyncNowper sincronizzare il progetto prima di continuare.

  6. Ora nella visualizzazione ad albero aggiungi i dati alla directory delle richieste e crea la classe di ReverseGeocodeRequest.kt dati. Aggiungi il seguente codice alla classe.

    import com.google.gson.annotations.SerializedName data class ReverseGeocodeRequest( @SerializedName("Language") val language: String, @SerializedName("MaxResults") val maxResults: Int, @SerializedName("Position") val position: ListDouble )
  7. Ora nella visualizzazione ad albero aggiungi i dati alla directory delle risposte e crea la classe di ReverseGeocodeResponse.kt dati. Aggiungi il seguente codice al suo interno.

    import com.google.gson.annotations.SerializedName data class ReverseGeocodeResponse( @SerializedName("Results") val results: ListResult ) data class Result( @SerializedName("Place") val place: Place ) data class Place( @SerializedName("Label") val label: String )
  8. Ora, dalla finestra del progetto, apri App, Java, your package name nella visualizzazione ad albero e vai alla cartella ui, all'interno della cartella ui create viewModeldirectory.

  9. All'interno della viewModeldirectory crea MainViewModel.kt il file.

  10. Aggiungi il seguente codice al tuo MainViewModel.kt file.

    import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import com.amazon.testmapapp.data.request.ReverseGeocodeRequest import com.amazon.testmapapp.data.response.ReverseGeocodeResponse import com.google.gson.Gson import java.io.IOException import okhttp3.Call import okhttp3.Callback import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response import org.maplibre.android.geometry.LatLng import org.maplibre.android.maps.MapLibreMap class MainViewModel : ViewModel() { var label by mutableStateOf("") var isLabelAdded: Boolean by mutableStateOf(false) var client = OkHttpClient() var mapLibreMap: MapLibreMap? = null fun reverseGeocode(latLng: LatLng, apiKey: String) { val region = "YOUR_AWS_REGION" val indexName = "YOUR_AWS_PLACE_INDEX" val url = "https://places.geo.${region}.amazonaws.com/places/v0/indexes/${indexName}/search/position?key=${apiKey}" val requestBody = ReverseGeocodeRequest( language = "en", maxResults = 1, position = listOf(latLng.longitude, latLng.latitude) ) val json = Gson().toJson(requestBody) val mediaType = "application/json".toMediaTypeOrNull() val request = Request.Builder() .url(url) .post(json.toRequestBody(mediaType)) .build() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { e.printStackTrace() } override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { val jsonResponse = response.body?.string() val reverseGeocodeResponse = Gson().fromJson(jsonResponse, ReverseGeocodeResponse::class.java) val responseLabel = reverseGeocodeResponse.results.firstOrNull()?.place?.label if (responseLabel != null) { label = responseLabel isLabelAdded = true } } } }) } }
  11. Se non è già aperto, apri il MapLoadScreen.kt file, come nella procedura precedente. Aggiungere il codice seguente. Verrà creata una vista di composizione del testo in cui verranno visualizzati i risultati della ricerca con geocodifica inversa nella posizione.

    // ...other imports import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.sp import com.amazon.testmapapp.ui.viewModel.MainViewModel @Composable fun MapLoadScreen( mapReadyCallback: OnMapReadyCallback, mainViewModel: MainViewModel, ) { Box( modifier = Modifier .fillMaxWidth() .fillMaxHeight(), ) { MapView(mapReadyCallback) Box( modifier = Modifier .align(Alignment.Center), ) { Image( painter = painterResource(id = R.drawable.red_marker), contentDescription = "marker", modifier = Modifier .size(40.dp) .align(Alignment.Center), ) } if (mainViewModel.isLabelAdded) { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Bottom ) { Box( modifier = Modifier .fillMaxWidth() .background(Color.White), ) { Text( text = mainViewModel.label, modifier = Modifier .padding(16.dp) .align(Alignment.Center) .testTag("label") .semantics { contentDescription = "label" }, fontSize = 14.sp, ) } Spacer(modifier = Modifier.height(80.dp)) } } } } @Composable fun MapView(mapReadyCallback: OnMapReadyCallback) { AndroidView( factory = { context -> val mapView = org.maplibre.android.maps.MapView(context) mapView.onCreate(null) mapView.getMapAsync(mapReadyCallback) mapView }, ) }
  12. Nell'app, in java, nella cartella del nome del pacchetto in AndroidStudio, apri il file. MainActivity.kt Modifica il codice come mostrato.

    // ...other imports import androidx.activity.viewModels import com.amazon.testmapapp.ui.viewModel.MainViewModel class MainActivity : ComponentActivity(), OnMapReadyCallback, MapLibreMap.OnCameraMoveStartedListener, MapLibreMap.OnCameraIdleListener { private val mainViewModel: MainViewModel by viewModels() private val region = "YOUR_AWS_REGION" private val mapName = "YOUR_AWS_MAP_NAME" private val apiKey = "YOUR_AWS_API_KEY" override fun onCreate(savedInstanceState: Bundle?) { MapLibre.getInstance(this) super.onCreate(savedInstanceState) setContent { TestMapAppTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { MapLoadScreen(this, mainViewModel) } } } } override fun onMapReady(map: MapLibreMap) { map.setStyle( Style.Builder() .fromUri( "https://maps.geo.$region.amazonaws.com/maps/v0/maps/$mapName/style-descriptor?key=$apiKey" ), ) { map.uiSettings.isAttributionEnabled = true map.uiSettings.isLogoEnabled = false map.uiSettings.attributionGravity = Gravity.BOTTOM or Gravity.END val initialPosition = LatLng(47.6160281982247, -122.32642111977668) map.cameraPosition = CameraPosition.Builder() .target(initialPosition) .zoom(14.0) .build() map.addOnCameraMoveStartedListener(this) map.addOnCameraIdleListener(this) map.cameraPosition.target?.let { latLng -> mainViewModel.reverseGeocode( LatLng( latLng.latitude, latLng.longitude ), apiKey ) } } } override fun onCameraMoveStarted(p0: Int) { mainViewModel.label = "" mainViewModel.isLabelAdded = false } override fun onCameraIdle() { if (!mainViewModel.isLabelAdded) { mainViewModel.mapLibreMap?.cameraPosition?.target?.let { latLng -> mainViewModel.reverseGeocode( LatLng( latLng.latitude, latLng.longitude ), apiKey ) } } } }

    Questo codice funziona con la visualizzazione della mappa. La posizione della telecamera virtuale definisce la visualizzazione della mappa in MapLibre. Lo spostamento della mappa può essere considerato come lo spostamento di quella telecamera virtuale.

    • ViewModel ha una variabile label: questa variabile imposta i dati nella vista di composizione del testo.

    • onMapReadyha una variabile label: Questa variabile imposta i dati nella vista di composizione del testo. ----sep----:Questa funzione viene aggiornata per registrare due nuovi eventi.

    • L'onCameraMoveevento si verifica ogni volta che l'utente sposta la mappa. In generale, quando spostiamo la mappa, vogliamo nascondere la ricerca finché l'utente non ha finito di spostare la mappa.

    • L'onCameraIdleevento si verifica quando l'utente sospende lo spostamento della mappa. Questo evento richiama la nostra funzione di geocodifica inversa per effettuare ricerche al centro della mappa.

    • reverseGeocode(latLng: LatLng, apiKey: String): Questa funzione, chiamata nell'evento onCameraIdle, cerca una posizione al centro della mappa e aggiorna l'etichetta per mostrare i risultati. Utilizza il target della fotocamera, che definisce il centro della mappa (dove la fotocamera sta guardando).

  13. Salva i tuoi file e crea ed esegui l'app per vedere se funziona.

La tua applicazione di avvio rapido con funzionalità di ricerca è completa.