2010-10-25 23 views
88

Ho bisogno di un elenco di paesi, dichiara & città basate su una raccolta di valori lat/long che ho. Ho bisogno di memorizzare queste informazioni in modo che la gerarchia sia preservata e senza duplicati (ad esempio "USA" e "Stati Uniti" e "Stati Uniti d'America" ​​sono lo stesso paese, nel database voglio solo un'istanza di questo paese) .Google Maps: come ottenere paese, stato/provincia/regione, città con un valore lat/long?

E 'possibile farlo con l'API di Google Maps?

+0

Hai avuto provincia? –

risposta

113

Quello che stai cercando si chiama reverse geocoding. Google fornisce un servizio di geocoding inverso sul lato server tramite lo Google Geocoding API, che dovresti essere in grado di utilizzare per il tuo progetto.

Questa è come una risposta alla seguente richiesta sarà simile:

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

Risposta:

{ 
    "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[] ... 

Si può anche scegliere di ricevere la risposta in XML invece di json, semplicemente sostituendo json per xml nell'URI della richiesta:

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

Per quanto ne so, Google sarà anche restituire lo stesso nome per i componenti di indirizzo, in particolare per i nomi di alto livello come i nomi dei paesi e nomi di città. Tuttavia, tieni presente che mentre i risultati sono molto accurati per la maggior parte delle applicazioni, potresti comunque trovare l'errore di ortografia occasionale o il risultato ambiguo.

+0

Grazie! Questa raccolta di lat/long I è effettivamente associata ai profili utente nel mio database. Sai come posso implementare una funzione di ricerca che consenta agli utenti di trovare altri utenti all'interno di una posizione specificata (ad esempio, trovare tutti gli utenti a Brooklyn, NY)? Ricorda, tutto quello che ho sono lat/long. – StackOverflowNewbie

+1

@StackOverflowNewbie: Si consiglia di invertire la geocodifica tutte le latitudine/longitudine, e compilare "città", "stato", "paese" campi nel database. Quindi fai semplicemente un filtro su questi campi nel tuo database. –

+0

Oppure è possibile utilizzare il tipo di dati spaziali, come la geografia, se hanno fatto causa MS SQL 2008 e la necessità di trovare la posizione in prossimità di un punto di – GibboK

16

È avere una risposta di base qui: Get city name using geolocation

Ma per quello che stai cercando, mi consiglia questo modo. Solo

se avete bisogno anche administrative_area_level_1, per memorizzare le cose diverse per Paris, Texas, Stati Uniti e Parigi, Ile-de-France, Francia e fornire un ripiego manuale:

-

C'è una problema nel modo di Michal, nel senso che prende il primo risultato, non un particolare. Usa i risultati [0]. Il modo in cui ritengo opportuno (ho appena modificato il suo codice) è quello di prendere SOLO il risultato il cui tipo è "località", che è sempre presente, anche in un eventuale ripiego manuale nel caso in cui il browser non supporti la geolocalizzazione.

suo modo: i risultati recuperati sono diversi da utilizzare http://maps.googleapis.com/maps/api/geocode/json?address=bucharest&sensor=false di usare i http://maps.googleapis.com/maps/api/geocode/json?latlng=44.42514,26.10540&sensor=false (ricerca per nome/ricerca per lat & GNL)

questo modo: stessi risultati recuperati.

<!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

Ho usato questa domanda come punto di partenza per la mia soluzione.Ho pensato che fosse opportuno contribuire il mio codice indietro da allora i suoi più piccoli di

Dipendenze di tabacitu:

.210

Codice:

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

ho trovato geocoder javascript un po 'buggy quando ho incluso nel mio file jsp.

Si può anche provare questo:



    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

Basta provare questo codice questo lavoro codice con me

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

ho scritto questa funzione che estrae quello che stai cercando in base alla address_components tornato da l'API gmaps. Questa è la città (per esempio).

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

Change locality al administrative_area_level_1 per lo Stato, ecc

Nel mio codice js sto usando in questo modo:

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

tornerà: Waltham, MA

0

Ho creato un funzione small mapper:

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

È una soluzione per Angular 4 ma penso che avrai un'idea.

Usage:

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]) 
     }; 
     (....) 
    } 

In questo modo l'oggetto address sarà qualcosa di simile:

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

Speranza che aiuta!

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 Aveva un'ottima soluzione creando una funzione che ottiene le parti dell'indirizzo in un array denominato. Ecco una soluzione compilata per coloro che vogliono utilizzare JavaScript semplice.

funzione per convertire i risultati alla matrice denominata:

function getAddressParts(obj) { 

    var address = []; 

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

    return address; 

} //getAddressParts() 

Geocode i valori/GNL Lat:

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

});