Google Maps: cómo obtener un país, estado / provincia / región, ciudad con un valor lat / long?

Necesito una lista de países, estados y ciudades basada en una colección de valores lat / long que tengo. Necesito almacenar esta información de manera que la jerarquía se preserve y sin duplicados (por ejemplo, “EE. UU.” Y “Estados Unidos” y “Estados Unidos de América” ​​son el mismo país; solo quiero una instancia de este país en mi base de datos) .

¿Es esto posible con Google Map API?

Lo que estás buscando se llama geoencoding inversa . Google proporciona un servicio de geoencoding inversa del lado del servidor a través de la API de geoencoding de Google , que usted debería poder utilizar para su proyecto.

Así es como se vería una respuesta a la siguiente solicitud:

http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=false

Respuesta:

{ "status": "OK", "results": [ { "types": [ "street_address" ], "formatted_address": "275-291 Bedford Ave, Brooklyn, NY 11211, USA", "address_components": [ { "long_name": "275-291", "short_name": "275-291", "types": [ "street_number" ] }, { "long_name": "Bedford Ave", "short_name": "Bedford Ave", "types": [ "route" ] }, { "long_name": "New York", "short_name": "New York", "types": [ "locality", "political" ] }, { "long_name": "Brooklyn", "short_name": "Brooklyn", "types": [ "administrative_area_level_3", "political" ] }, { "long_name": "Kings", "short_name": "Kings", "types": [ "administrative_area_level_2", "political" ] }, { "long_name": "New York", "short_name": "NY", "types": [ "administrative_area_level_1", "political" ] }, { "long_name": "United States", "short_name": "US", "types": [ "country", "political" ] }, { "long_name": "11211", "short_name": "11211", "types": [ "postal_code" ] } ], "geometry": { "location": { "lat": 40.7142298, "lng": -73.9614669 }, "location_type": "RANGE_INTERPOLATED", "viewport": { "southwest": { "lat": 40.7110822, "lng": -73.9646145 }, "northeast": { "lat": 40.7173774, "lng": -73.9583193 } } } }, ... Additional results[] ... 

También puede optar por recibir la respuesta en xml en lugar de json, simplemente sustituyendo json por xml en el URI de solicitud:

http://maps.googleapis.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=false

Por lo que yo sé, Google también devolverá el mismo nombre para los componentes de la dirección, especialmente para nombres de alto nivel como nombres de países y ciudades. Sin embargo, tenga en cuenta que, si bien los resultados son muy precisos para la mayoría de las aplicaciones, aún puede encontrar errores ortográficos ocasionales o resultados ambiguos.

Usted tiene una respuesta básica aquí: Obtener el nombre de la ciudad utilizando la geolocalización

Pero para lo que estás buscando, lo recomendaría de esta manera.

Solo si también necesita administrative_area_level_1, para almacenar cosas diferentes para París, Texas, EE. UU. Y París, Ile-de-France, Francia y proporcione un respaldo manual:

Hay un problema en el camino de Michal, en el sentido de que toma el primer resultado, no uno en particular. Él usa resultados [0]. La forma que mejor me parece (acabo de modificar su código) es tomar SOLAMENTE el resultado cuyo tipo es “localidad”, que siempre está presente, incluso en una eventual recuperación manual en caso de que el navegador no admita la geolocalización.

A su manera: los resultados obtenidos son diferentes del uso de http://maps.googleapis.com/maps/api/geocode/json?address=bucharest&sensor=false que del uso de http://maps.googleapis.com/maps/api/geocode /json?latlng=44.42514,26.10540&sensor=false (buscando por nombre / buscando por lat & lng)

De esta manera: los mismos resultados obtenidos.

      Reverse Geocoding       

Utilicé esta pregunta como punto de partida para mi propia solución. Pensé que era apropiado contribuir con mi código ya que es más pequeño que el tabacitu

Dependencias:

Código:

 if(geoPosition.init()){ var foundLocation = function(city, state, country, lat, lon){ //do stuff with your location! any of the first 3 args may be null console.log(arguments); } var geocoder = new google.maps.Geocoder(); geoPosition.getCurrentPosition(function(r){ var findResult = function(results, name){ var result = _.find(results, function(obj){ return obj.types[0] == name && obj.types[1] == "political"; }); return result ? result.short_name : null; }; geocoder.geocode({'latLng': new google.maps.LatLng(r.coords.latitude, r.coords.longitude)}, function(results, status) { if (status == google.maps.GeocoderStatus.OK && results.length) { results = results[0].address_components; var city = findResult(results, "locality"); var state = findResult(results, "administrative_area_level_1"); var country = findResult(results, "country"); foundLocation(city, state, country, r.coords.latitude, r.coords.longitude); } else { foundLocation(null, null, null, r.coords.latitude, r.coords.longitude); } }); }, { enableHighAccuracy:false, maximumAge: 1000 * 60 * 1 }); } 

El JavaScript de GeoCoder me pareció un poco problemático cuando lo incluí en mis archivos jsp.

También puedes probar esto:

 var lat = "43.7667855" ; var long = "-79.2157321" ; var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" +lat+","+long+"&sensor=false"; $.get(url).success(function(data) { var loc1 = data.results[0]; var county, city; $.each(loc1, function(k1,v1) { if (k1 == "address_components") { for (var i = 0; i < v1.length; i++) { for (k2 in v1[i]) { if (k2 == "types") { var types = v1[i][k2]; if (types[0] =="sublocality_level_1") { county = v1[i].long_name; //alert ("county: " + county); } if (types[0] =="locality") { city = v1[i].long_name; //alert ("city: " + city); } } } } } }); $('#city').html(city); }); 

Escribí esta función que extrae lo que estás buscando en función de los address_components devueltos por la API de gmaps. Esta es la ciudad (por ejemplo).

 export const getAddressCity = (address, length) => { const findType = type => type.types[0] === "locality" const location = address.map(obj => obj) const rr = location.filter(findType)[0] return ( length === 'short' ? rr.short_name : rr.long_name ) } 

Cambiar la locality a administrative_area_level_1 para el estado, etc.

En mi código js estoy usando así:

 const location =`${getAddressCity(address_components, 'short')}, ${getAddressState(address_components, 'short')}` 

Regresará: Waltham, MA

Solo prueba este código, este código funciona conmigo

 var posOptions = {timeout: 10000, enableHighAccuracy: false}; $cordovaGeolocation.getCurrentPosition(posOptions).then(function (position) { var lat = position.coords.latitude; var long = position.coords.longitude; //console.log(lat +" "+long); $http.get('https://maps.googleapis.com/maps/api/geocode/json?latlng=' + lat + ',' + long + '&key=your key here').success(function (output) { //console.log( JSON.stringify(output.results[0])); //console.log( JSON.stringify(output.results[0].address_components[4].short_name)); var results = output.results; if (results[0]) { //console.log("results.length= "+results.length); //console.log("hi "+JSON.stringify(results[0],null,4)); for (var j = 0; j < results.length; j++){ //console.log("j= "+j); //console.log(JSON.stringify(results[j],null,4)); for (var i = 0; i < results[j].address_components.length; i++){ if(results[j].address_components[i].types[0] == "country") { //this is the object you are looking for country = results[j].address_components[i]; } } } console.log(country.long_name); console.log(country.short_name); } else { alert("No results found"); console.log("No results found"); } }); }, function (err) { }); 

Creé una pequeña función de mapeador:

 private getAddressParts(object): Object { let address = {}; const address_components = object.address_components; address_components.forEach(element => { address[element.types[0]] = element.short_name; }); return address; } 

Es una solución para Angular 4, pero creo que tendrás la idea.

Uso:

 geocoder.geocode({ 'location' : latlng }, (results, status) => { if (status === google.maps.GeocoderStatus.OK) { const address = { formatted_address: results[0].formatted_address, address_parts: this.getAddressParts(results[0]) }; (....) } 

De esta forma, el objeto de address será algo como esto:

 address: { address_parts: { administrative_area_level_1: "NY", administrative_area_level_2: "New York County", country: "US", locality: "New York", neighborhood: "Lower Manhattan", political: "Manhattan", postal_code: "10038", route: "Beekman St", street_number: "90", }, formatted_address: "90 Beekman St, New York, NY 10038, USA" } 

¡Espero eso ayude!

  

@ Szkíta Tuvo una gran solución al crear una función que obtiene las partes de la dirección en una matriz con nombre. Aquí hay una solución comstackda para aquellos que quieran usar JavaScript simple.

Función para convertir resultados a la matriz nombrada:

 function getAddressParts(obj) { var address = []; obj.address_components.forEach( function(el) { address[el.types[0]] = el.short_name; }); return address; } //getAddressParts() 

Geocodificar los valores LAT / LNG:

 geocoder.geocode( { 'location' : latlng }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { var addressParts = getAddressParts(results[0]); // the city var city = addressParts.locality; // the state var state = addressParts.administrative_area_level_1; } });