2010-10-25 25 views
88

Necesito una lista de países, estados & ciudades basadas 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) .Google Maps: cómo obtener un país, estado/provincia/región, ciudad con un valor lat/long?

¿Es esto posible con Google Map API?

+0

¿Recibió provincia? –

Respuesta

113

Lo que estás buscando se llama reverse geocoding. Google proporciona un servicio de geocodificación inversa del lado del servidor a través del Google Geocoding API, que usted debería poder usar para su proyecto.

Esto es como una respuesta a la petición siguiente se vería así:

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 regresará el mismo nombre para componentes de dirección, especialmente para los nombres de alto nivel como nombres de países y nombres de 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.

+0

Gracias! Esta colección de lat/long que tengo está realmente asociada con perfiles de usuario en mi base de datos. ¿Sabe cómo puedo implementar una función de búsqueda que permita a los usuarios encontrar otros usuarios dentro de una ubicación específica (por ejemplo, encontrar a todos los usuarios en Brooklyn, NY)? Recuerda, todo lo que tengo son lat/longs. – StackOverflowNewbie

+1

@StackOverflowNewbie: Es posible que desee revertir la geocodificación de todos sus lat/longs, y rellenar los campos "city", "state", "country" en su base de datos. Luego simplemente haga un filtro en estos campos en su base de datos. –

+0

O puede usar el tipo de datos espaciales como geografía si está demandando MS Sql 2008 y necesita encontrar la ubicación cerca de un punto – GibboK

16

usted tiene una respuesta básica aquí: Get city name using geolocation

Pero para lo que está buscando, me gustaría recomendar esta manera. Sólo

si también necesita administrative_area_level_1, para almacenar cosas diferentes para París, Texas, Estados Unidos y París, Ile-de-France, Francia y proporcionar un manual de repliegue:

-

Hay una 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.

Su manera: resultados inverosímiles son diferentes de usar http://maps.googleapis.com/maps/api/geocode/json?address=bucharest&sensor=false que el uso de http://maps.googleapis.com/maps/api/geocode/json?latlng=44.42514,26.10540&sensor=false (buscar por nombre/búsqueda por lat & GNL)

esta manera: mismos resultados inverosímiles.

<!DOCTYPE html> 
<html> 
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>Reverse Geocoding</title> 

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 
    var geocoder; 

    if (navigator.geolocation) { 
    navigator.geolocation.getCurrentPosition(successFunction, errorFunction); 
} 
//Get the latitude and the longitude; 
function successFunction(position) { 
    var lat = position.coords.latitude; 
    var lng = position.coords.longitude; 
    codeLatLng(lat, lng) 
} 

function errorFunction(){ 
    alert("Geocoder failed"); 
} 

    function initialize() { 
    geocoder = new google.maps.Geocoder(); 



    } 

    function codeLatLng(lat, lng) { 

    var latlng = new google.maps.LatLng(lat, lng); 
    geocoder.geocode({'latLng': latlng}, function(results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
     //console.log(results); 
     if (results[1]) { 
     var indice=0; 
     for (var j=0; j<results.length; j++) 
     { 
      if (results[j].types[0]=='locality') 
       { 
        indice=j; 
        break; 
       } 
      } 
     alert('The good number is: '+j); 
     console.log(results[j]); 
     for (var i=0; i<results[j].address_components.length; i++) 
      { 
       if (results[j].address_components[i].types[0] == "locality") { 
         //this is the object you are looking for 
         city = results[j].address_components[i]; 
        } 
       if (results[j].address_components[i].types[0] == "administrative_area_level_1") { 
         //this is the object you are looking for 
         region = results[j].address_components[i]; 
        } 
       if (results[j].address_components[i].types[0] == "country") { 
         //this is the object you are looking for 
         country = results[j].address_components[i]; 
        } 
      } 

      //city data 
      alert(city.long_name + " || " + region.long_name + " || " + country.short_name) 


      } else { 
       alert("No results found"); 
      } 
     //} 
     } else { 
     alert("Geocoder failed due to: " + status); 
     } 
    }); 
    } 
</script> 
</head> 
<body onload="initialize()"> 

</body> 
</html> 
4

He utilizado esta pregunta como punto de partida para mi propia solución.Pensó que era apropiado para aportar mi código atrás desde sus más pequeños que

Dependencias de tabacitu:

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 }); 
} 
2

he encontrado el GEOCODER Javascript de errores, cuando lo incluí en mis archivos JSP.

También puede 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); 
    }); 

0

Solo trata de este código funciona este código 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) { 
}); 
2

escribí esta función que los extractos de lo que busca en base a la address_components regresaron de la API 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 
) 
} 

Cambio locality a administrative_area_level_1 para el Estado, etc.

En mi código JS estoy usando este modo:

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

volveremos: el Waltham, MA

0

He creado una pequeña función del asignador:

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 ya entenderás.

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 manera el objeto 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 que ayude!

0
<div id="location"></div> 
     <script> 
      window.onload = function() { 
       var startPos; 
       var geoOptions = { 
        maximumAge: 5 * 60 * 1000, 
        timeout: 10 * 1000, 
        enableHighAccuracy: true 
       } 


       var geoSuccess = function (position) { 
        startPos = position; 
        geocodeLatLng(startPos.coords.latitude, startPos.coords.longitude); 

       }; 
       var geoError = function (error) { 
        console.log('Error occurred. Error code: ' + error.code); 
        // error.code can be: 
        // 0: unknown error 
        // 1: permission denied 
        // 2: position unavailable (error response from location provider) 
        // 3: timed out 
       }; 

       navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions); 
      }; 
      function geocodeLatLng(lat, lng) { 
       var geocoder = new google.maps.Geocoder; 
       var latlng = {lat: parseFloat(lat), lng: parseFloat(lng)}; 
       geocoder.geocode({'location': latlng}, function (results, status) { 
        if (status === 'OK') { 
         console.log(results) 
         if (results[0]) { 
          document.getElementById('location').innerHTML = results[0].formatted_address; 
          var street = ""; 
          var city = ""; 
          var state = ""; 
          var country = ""; 
          var zipcode = ""; 
          for (var i = 0; i < results.length; i++) { 
           if (results[i].types[0] === "locality") { 
            city = results[i].address_components[0].long_name; 
            state = results[i].address_components[2].long_name; 

           } 
           if (results[i].types[0] === "postal_code" && zipcode == "") { 
            zipcode = results[i].address_components[0].long_name; 

           } 
           if (results[i].types[0] === "country") { 
            country = results[i].address_components[0].long_name; 

           } 
           if (results[i].types[0] === "route" && street == "") { 

            for (var j = 0; j < 4; j++) { 
             if (j == 0) { 
              street = results[i].address_components[j].long_name; 
             } else { 
              street += ", " + results[i].address_components[j].long_name; 
             } 
            } 

           } 
           if (results[i].types[0] === "street_address") { 
            for (var j = 0; j < 4; j++) { 
             if (j == 0) { 
              street = results[i].address_components[j].long_name; 
             } else { 
              street += ", " + results[i].address_components[j].long_name; 
             } 
            } 

           } 
          } 
          if (zipcode == "") { 
           if (typeof results[0].address_components[8] !== 'undefined') { 
            zipcode = results[0].address_components[8].long_name; 
           } 
          } 
          if (country == "") { 
           if (typeof results[0].address_components[7] !== 'undefined') { 
            country = results[0].address_components[7].long_name; 
           } 
          } 
          if (state == "") { 
           if (typeof results[0].address_components[6] !== 'undefined') { 
            state = results[0].address_components[6].long_name; 
           } 
          } 
          if (city == "") { 
           if (typeof results[0].address_components[5] !== 'undefined') { 
            city = results[0].address_components[5].long_name; 
           } 
          } 

          var address = { 
           "street": street, 
           "city": city, 
           "state": state, 
           "country": country, 
           "zipcode": zipcode, 
          }; 

          document.getElementById('location').innerHTML = document.getElementById('location').innerHTML + "<br/>Street : " + address.street + "<br/>City : " + address.city + "<br/>State : " + address.state + "<br/>Country : " + address.country + "<br/>zipcode : " + address.zipcode; 
          console.log(address); 
         } else { 
          window.alert('No results found'); 
         } 
        } else { 
         window.alert('Geocoder failed due to: ' + status); 
        } 
       }); 
      } 
     </script> 

     <script async defer 
       src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"> 
     </script> 
0

@ Szkíta Tenía una gran solución mediante la creación de una función que recibe las partes de la dirección en una matriz llamada. Aquí hay una solución compilada para aquellos que quieran usar JavaScript simple.

Función para convertir los resultados a la matriz denominada:

function getAddressParts(obj) { 

    var address = []; 

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

    return address; 

} //getAddressParts() 

Geocodificar los valores/GNL Latitud:

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; 
    } 

}); 
Cuestiones relacionadas