La geocodificación inversa es un proceso utilizado para convertir coordenadas (latitud y longitud) en direcciones legibles por humanos. Esto no es exactamente lo contrario de Geocodificación. En Geocodificación, el Lugar está asociado a un nombre y coordenadas fijas. Estas coordenadas son de naturaleza doble. Un cambio insignificante en estas coordenadas aún puede referirse al mismo lugar, pero nunca obtendremos el nombre del lugar ya que está asociado solo con esas coordenadas fijas. Por lo tanto, definitivamente obtendremos la dirección completa en la geocodificación inversa, pero el nombre del lugar no está garantizado. A través de este artículo, le mostraremos un ejemplo de cómo realizar una geocodificación inversa en Android. Pero antes de continuar, consulte los siguientes artículos:
- Google Cloud Platform: creación de cuentas y proyectos de Google Cloud Console
- Generación de claves API para usar cualquier API de Google
- ¿Cómo ocultar la API y las claves secretas en Android Studio?
- ¿Cómo implementar la barra de autocompletado de lugares de Google en Android?
- ¿Cómo implementar la función de botón de ubicación actual en Google Maps en Android?
Estructura del proyecto
Para la codificación geográfica inversa, necesitaremos la latitud y la longitud en el tipo de datos Doble. Así que implementaremos un mapa de Google y consideraremos su centro como nuestra latitud y longitud principal. Podemos obtener fácilmente las coordenadas del centro usando la posición de la cámara (consulte el código principal). Siempre que se arrastre el Mapa, el centro cambiará y provocará un cambio en la latitud y la longitud. Una vez que el Mapa está inactivo, es decir, deja de arrastrarse o moverse, el algoritmo de geocodificación inversa considerará las coordenadas del centro y las procesará para obtener una dirección completa. Esto se publicará instantáneamente en una vista de texto. Esto confirmará que la geocodificación inversa funciona bien en el código. Siga los pasos a continuación para crear este proyecto.
¿Qué vamos a construir en este artículo?
Paso 1: crea un nuevo proyecto en Android Studio
Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Demostramos la aplicación en Kotlin, así que asegúrese de seleccionar Kotlin como idioma principal al crear un nuevo proyecto.
Paso 2: Obtenga y oculte la clave API
- Nuestra aplicación utiliza la API de lugares de Google, por lo que necesitamos obtener la clave de la API de lugares de Google. Para obtener una clave de API, consulte Generación de claves de API para usar cualquier API de Google .
- Ocultar una clave API es esencial y para hacerlo, consulte ¿Cómo ocultar API y claves secretas en Android Studio? .
Paso 3: Agrega estas dependencias
Esta dependencia será necesaria para la geocodificación inversa.
Kotlin
dependencies { implementation 'com.google.android.libraries.places:places:2.4.0' }
Paso 4: agregar un fragmento de mapa, un marcador de ubicación personalizado y una vista de texto en el archivo de diseño (actividad_principal.xml)
XML
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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"> <!--Map Fragment--> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/map" tools:context=".MapsActivity" android:name="com.google.android.gms.maps.SupportMapFragment" /> <!--This layout overlays the Map Fragment which matches parent width and height--> <!--We want to display our TextView over the Map with good aesthetics--> <LinearLayout android:layout_margin="20sp" android:id="@+id/ll1" android:layout_width="match_parent" android:layout_height="100sp" android:background="@drawable/shape" android:layout_alignBottom="@id/map" android:orientation="horizontal"> <!--TextView for displaying Lat and Lng along with Address--> <TextView android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10sp" /> </LinearLayout> <!--This is only for reference to the center of the screen, can be any element--> <!--We have set fixed this element at the parent center, which is the actual centre of the screen--> <Button android:id="@+id/centerReferencePoint" android:layout_width="0sp" android:layout_height="0sp" android:layout_centerInParent="true"/> <!--This image is the Marker--> <ImageView android:id="@+id/marker" android:layout_width="30sp" android:layout_height="40sp" android:src="@drawable/marker" android:layout_centerInParent="true" android:layout_above="@id/centerReferencePoint" /> </RelativeLayout>
Marcador:
Descargamos esta imagen en formato PNG de Internet. No tiene color de fondo y puede denominarse imagen transparente. Una vez descargado, puede copiarlo directamente desde donde esté almacenado, abrir Android Studio y pegarlo en la carpeta dibujable presente en la carpeta res. Mientras hacía esto, lo renombramos como «marcador» que puede encontrar en los atributos de ImageView en el archivo activity_main.xml .
Archivo Shape.xml (Fondo del diseño lineal en activity_main.xml)
Hemos establecido un fondo blanco y un radio de esquina con algún valor. Esto es para que el diseño se vea mejor.
XML
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#ffffff" > </solid> <corners android:radius="11dp" > </corners> </shape>
Vista previa de activity_main.xml:
Paso 5: Trabajando en el backend (MainActivity.kt)
Tomamos las coordenadas del lugar presente en el centro de la pantalla y las convertimos en direcciones de texto. Una vez que se arrastra la pantalla, las coordenadas del centro cambian y la dirección cambia respectivamente. Los cambios tienen lugar una vez que la pantalla está inactiva y no está en movimiento y es por eso que implementamos nuestro algoritmo de codificación geográfica inversa en setOnCamera Idle Listener. El siguiente código es bastante fácil de entender. Hemos proporcionado algunos comentarios para ayudarlo a comprender mejor.
Kotlin
package org.geeksforgeeks.reversegeocoding import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.location.Address import android.location.Geocoder import android.os.Bundle import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.GoogleMap.OnCameraIdleListener import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.LatLng import com.google.android.libraries.places.api.Places import java.io.IOException import java.util.* class MainActivity : AppCompatActivity(), OnMapReadyCallback { private lateinit var mMap: GoogleMap override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Fetching API_KEY which we wrapped val ai: ApplicationInfo = applicationContext.packageManager.getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA) val value = ai.metaData["com.google.android.geo.API_KEY"] val apiKey = value.toString() // Initializing the Places API // with the help of our API_KEY if (!Places.isInitialized()) { Places.initialize(applicationContext, apiKey) } // Initializing map val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) } override fun onMapReady(p0: GoogleMap) { mMap = p0 // These are GeeksforGeeks Noida Office Coordinates. val india = LatLng(28.5021359, 77.4054901) mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(india,17F)) mMap.setOnCameraIdleListener { val lat = mMap.cameraPosition.target.latitude val lng = mMap.cameraPosition.target.longitude val addressTV = findViewById<TextView>(R.id.tv) // Initializing Geocoder val mGeocoder = Geocoder(applicationContext, Locale.getDefault()) var addressString= "" // Reverse-Geocoding starts try { val addressList: List<Address> = mGeocoder.getFromLocation(lat, lng, 1) // use your lat, long value here if (addressList != null && addressList.isNotEmpty()) { val address = addressList[0] val sb = StringBuilder() for (i in 0 until address.maxAddressLineIndex) { sb.append(address.getAddressLine(i)).append("\n") } // Various Parameters of an Address are appended // to generate a complete Address if (address.premises != null) sb.append(address.premises).append(", ") sb.append(address.subAdminArea).append("\n") sb.append(address.locality).append(", ") sb.append(address.adminArea).append(", ") sb.append(address.countryName).append(", ") sb.append(address.postalCode) // StringBuilder sb is converted into a string // and this value is assigned to the // initially declared addressString string. addressString = sb.toString() } } catch (e: IOException) { Toast.makeText(applicationContext,"Unable connect to Geocoder",Toast.LENGTH_LONG).show() } // Finally, the address string is posted in the textView with LatLng. addressTV.text = "Lat: $lat \nLng: $lng \nAddress: $addressString" } } }
Producción:
Observe, la dirección cambia con un cambio en los valores de latitud y longitud. Los valores de latitud y longitud cambian cuando el usuario arrastra la pantalla, ya que el centro sigue cambiando.
Publicación traducida automáticamente
Artículo escrito por aashaypawar y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA