Ottieni il nome della città utilizzando la geolocalizzazione


140

Sono riuscito a ottenere la latitudine e la longitudine dell'utente utilizzando la geolocalizzazione basata su HTML.

//Check if browser supports W3C Geolocation API
if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
} 
//Get latitude and longitude;
function successFunction(position) {
    var lat = position.coords.latitude;
    var long = position.coords.longitude;
}

Voglio visualizzare il nome della città, sembra che l'unico modo per ottenerlo sia utilizzare un'API di geolocalizzazione inversa. Ho letto la documentazione di Google per la geolocalizzazione inversa ma non so come ottenere l'output sul mio sito.

Non so come andare usa questo: "http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true"per visualizzare il nome della città sulla pagina.

Come posso raggiungere questo obiettivo?


4
Se non hai intenzione di utilizzare le mappe, sai che questo è contro il TOS di Google, giusto? Punto 10.4 qui developers.google.com/maps/terms Nessun utilizzo di contenuti senza una mappa di Google. A meno che la Documentazione sulle API di Maps non ti consenta espressamente di farlo, non utilizzerai il Contenuto in un'implementazione dell'API di Maps senza una corrispondente mappa di Google. Ad esempio, puoi visualizzare le immagini di Street View senza una corrispondente mappa di Google perché la documentazione delle API di Maps consente espressamente questo uso.
PirateApp,

5
Sì, @PirateApp ha un buon punto. Potrebbero esserci servizi migliori là fuori. Ho già lavorato con SmartyStreets e so che hanno Termini di servizio molto più aperti. Tuttavia, la maggior parte dei servizi non esegue la geocodifica inversa. So che Texas A&M ha un servizio gratuito ma hanno un avviso TOS che non è possibile raccogliere dati su altre persone e hanno già avuto problemi di uptime e accuratezza.
Joseph Hansen,

Risposte:


201

Faresti qualcosa del genere utilizzando l'API di Google.

Si noti che è necessario includere la libreria di google maps affinché funzioni. Google geocoder restituisce molti componenti dell'indirizzo, quindi è necessario fare un'ipotesi su quale sarà la città.

"Administrative_area_level_1" è in genere ciò che stai cercando, ma a volte la località è la città che stai cercando.

Comunque - maggiori dettagli sui tipi di risposta di Google sono disponibili qui e qui .

Di seguito è riportato il codice che dovrebbe fare il trucco:

<!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]) {
         //formatted address
         alert(results[0].formatted_address)
        //find country name
             for (var i=0; i<results[0].address_components.length; i++) {
            for (var b=0;b<results[0].address_components[i].types.length;b++) {

            //there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
                if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
                    //this is the object you are looking for
                    city= results[0].address_components[i];
                    break;
                }
            }
        }
        //city data
        alert(city.short_name + " " + city.long_name)


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

</body> 
</html> 

3
Non vero per l'area di amministrazione livello 1, a volte il nome della città non è presente. - {"long_name" => "San Francisco", "types" => ["amministrative_area_level_2", "politico"], "short_name" => "San Francisco"}, {"long_name" => "California", "tipi "=> [" Administrative_area_level_1 "," politico "]," short_name "=>" CA "}, {" long_name "=>" Stati Uniti "," types "=> [" paese "," politico "]," short_name "=>" US "}
Ming Tsai

5
Per V3, la stringa {'latlng': latlng} dovrebbe essere cambiata in 'location', come in ... geocode ({'location': latlng}). Questo esempio mi ha portato quasi lì, ma la stringa 'latlng' non sembra più essere valida nelle nuove API. Vedi: developers.google.com/maps/documentation/javascript/… per dettagli.
binarygiant

@Michal come possiamo trovare solo il nome del paese o il codice del paese anziché l'indirizzo completo?
giovedì

1
@ajay nel test dell'istruzione if per "paese" e la variabile città ora restituiranno i dati del paese. Se rinominalo country = results [0] .address_components [i] puoi accedere ai dati per country.long_name e country.short_name
Michal

C'è un modo per restringerlo alle città all'interno di una provincia o semplicemente per verificare se la posizione proviene da una provincia specifica e se è l'utente viene reindirizzato a una pagina Web specifica?
Siamo spiacenti,

52

Un altro approccio a questo è utilizzare il mio servizio, http://ipinfo.io , che restituisce la città, la regione e il nome del paese in base all'indirizzo IP corrente dell'utente. Ecco un semplice esempio:

$.get("http://ipinfo.io", function(response) {
    console.log(response.city, response.country);
}, "jsonp");

Ecco un esempio JSFiddle più dettagliato che stampa anche le informazioni di risposta complete, in modo da poter vedere tutti i dettagli disponibili: http://jsfiddle.net/zK5FN/2/


23
Non altrettanto accurato però.
Salman von Abbas,

4
Impossibile rilevare la città e persino trgion dall'IP di un grande fornitore russo: (
Jehy

2
Lol ... questo dà il mio IP di rete interna (192.168 ...)
major-mann

Posso farlo da un browser del dispositivo (palmare)?
Arti

Non sembra affidabile. Sto usando un laptop e un telefono cellulare in questo momento. Le città mostrate in entrambi i dispositivi tramite ipinfo.io sono distanti 530 chilometri!
Ashish Goyal,

52

$.ajax({
  url: "https://geolocation-db.com/jsonp",
  jsonpCallback: "callback",
  dataType: "jsonp",
  success: function(location) {
    $('#country').html(location.country_name);
    $('#state').html(location.state);
    $('#city').html(location.city);
    $('#latitude').html(location.latitude);
    $('#longitude').html(location.longitude);
    $('#ip').html(location.IPv4);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<div>Country: <span id="country"></span></div>
  <div>State: <span id="state"></span></div>
    <div>City: <span id="city"></span></div>
      <div>Latitude: <span id="latitude"></span></div>
        <div>Longitude: <span id="longitude"></span></div>
          <div>IP: <span id="ip"></span></div>

L'uso della geolocalizzazione html5 richiede l'autorizzazione dell'utente. Nel caso in cui non lo desideri, scegli un localizzatore esterno come https://geolocation-db.com IPv6 è supportato. Nessuna limitazione e richieste illimitate consentite.

Esempio

Per un esempio javascript puro, senza usare jQuery, dai un'occhiata a questa risposta.


17

Puoi ottenere il nome della città, il paese, il nome della via e altri geodati utilizzando l'API di geocodifica di Google Maps

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>
    <script type="text/javascript">
        navigator.geolocation.getCurrentPosition(success, error);

        function success(position) {
            console.log(position.coords.latitude)
            console.log(position.coords.longitude)

            var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';

            $.getJSON(GEOCODING).done(function(location) {
                console.log(location)
            })

        }

        function error(err) {
            console.log(err)
        }
    </script>
</body>
</html>

e per visualizzare questi dati sulla pagina usando jQuery

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>

    <p>Country: <span id="country"></span></p>
    <p>State: <span id="state"></span></p>
    <p>City: <span id="city"></span></p>
    <p>Address: <span id="address"></span></p>

    <p>Latitude: <span id="latitude"></span></p>
    <p>Longitude: <span id="longitude"></span></p>

    <script type="text/javascript">
        navigator.geolocation.getCurrentPosition(success, error);

        function success(position) {

            var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';

            $.getJSON(GEOCODING).done(function(location) {
                $('#country').html(location.results[0].address_components[5].long_name);
                $('#state').html(location.results[0].address_components[4].long_name);
                $('#city').html(location.results[0].address_components[2].long_name);
                $('#address').html(location.results[0].formatted_address);
                $('#latitude').html(position.coords.latitude);
                $('#longitude').html(position.coords.longitude);
            })

        }

        function error(err) {
            console.log(err)
        }
    </script>
</body>
</html>

15

Ecco una versione di lavoro aggiornata per me che otterrà City / Town, sembra che alcuni campi vengano modificati nella risposta json. Riferendo le risposte precedenti per queste domande. (Grazie a Michal e un altro riferimento: Link

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) {
      if (results[1]) {
        var arrAddress = results;
        console.log(results);
        $.each(arrAddress, function(i, address_component) {
          if (address_component.types[0] == "locality") {
            console.log("City: " + address_component.address_components[0].long_name);
            itemLocality = address_component.address_components[0].long_name;
          }
        });
      } else {
        alert("No results found");
      }
    } else {
      alert("Geocoder failed due to: " + status);
    }
  });
}

10

geolocator.js può farlo. (Sono l'autore).

Ottenere il nome della città (indirizzo limitato)

geolocator.locateByIP(options, function (err, location) {
    console.log(location.address.city);
});

Ottenere informazioni sull'indirizzo completo

L'esempio seguente proverà innanzitutto l'API di geolocalizzazione HTML5 per ottenere le coordinate esatte. Se fallito o rifiutato, tornerà alla ricerca Geo-IP. Una volta ottenute le coordinate, invertirà il geocodifica delle coordinate in un indirizzo.

var options = {
    enableHighAccuracy: true,
    fallbackToIP: true, // fallback to IP if Geolocation fails or rejected
    addressLookup: true
};
geolocator.locate(options, function (err, location) {
    console.log(location.address.city);
});

Questo utilizza API di Google internamente (per la ricerca di indirizzi). Quindi, prima di questa chiamata, è necessario configurare il geolocator con la chiave dell'API di Google.

geolocator.config({
    language: "en",
    google: {
        version: "3",
        key: "YOUR-GOOGLE-API-KEY"
    }
});

Geolocator supporta la geolocalizzazione (tramite ricerche HTML5 o IP), geocodifica, ricerche di indirizzi (geocodifica inversa), distanza e durata, informazioni sul fuso orario e molte altre funzionalità ...


6

Dopo aver cercato e messo insieme un paio di soluzioni diverse insieme alle mie cose, ho pensato a questa funzione:

function parse_place(place)
{
    var location = [];

    for (var ac = 0; ac < place.address_components.length; ac++)
    {
        var component = place.address_components[ac];

        switch(component.types[0])
        {
            case 'locality':
                location['city'] = component.long_name;
                break;
            case 'administrative_area_level_1':
                location['state'] = component.long_name;
                break;
            case 'country':
                location['country'] = component.long_name;
                break;
        }
    };

    return location;
}

3

Puoi usare https://ip-api.io/ per ottenere il nome della città. Supporta IPv6.

Come bonus consente di verificare se l'indirizzo IP è un nodo tor, proxy pubblico o spammer.

Codice Javascript:

$(document).ready(function () {
        $('#btnGetIpDetail').click(function () {
            if ($('#txtIP').val() == '') {
                alert('IP address is reqired');
                return false;
            }
            $.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
                 function (result) {
                     alert('City Name: ' + result.city)
                     console.log(result);
                 });
        });
    });

Codice HTML

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div>
    <input type="text" id="txtIP" />
    <button id="btnGetIpDetail">Get Location of IP</button>
</div>

Uscita JSON

{
    "ip": "64.30.228.118",
    "country_code": "US",
    "country_name": "United States",
    "region_code": "FL",
    "region_name": "Florida",
    "city": "Fort Lauderdale",
    "zip_code": "33309",
    "time_zone": "America/New_York",
    "latitude": 26.1882,
    "longitude": -80.1711,
    "metro_code": 528,
    "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_suspicious": false
    }
}

2

Come menzionato da @PirateApp nel suo commento, è esplicitamente contrario alle licenze dell'API di Google Maps utilizzare l'API di Maps come desiderato.

Esistono diverse alternative, tra cui il download di un database Geoip e l'interrogazione locale o l'utilizzo di un servizio API di terze parti, come il mio servizio ipdata.co .

ipdata fornisce i dati sullo stato di geolocalizzazione, organizzazione, valuta, fuso orario, codice chiamante, flag e Tor Exit Node da qualsiasi indirizzo IPv4 o IPv6.

Ed è scalabile con 10 endpoint globali ciascuno in grado di gestire> 10.000 richieste al secondo!

Questa risposta utilizza una chiave API "test" che è molto limitata e pensata solo per testare alcune chiamate. Iscriviti alla tua chiave API gratuita e ricevi fino a 1500 richieste al giorno per lo sviluppo.

$.get("https://api.ipdata.co?api-key=test", function(response) {
  $("#ip").html("IP: " + response.ip);
  $("#city").html(response.city + ", " + response.region);
  $("#response").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1><a href="https://ipdata.co">ipdata.co</a> - IP geolocation API</h1>

<div id="ip"></div>
<div id="city"></div>
<pre id="response"></pre>

Il violino; https://jsfiddle.net/ipdata/6wtf0q4g/922/


1

Eccone un altro. Aggiungendo di più alla risposta accettata, forse più completa .. ovviamente switch -case lo farà sembrare elegante.

function parseGeoLocationResults(result) {
    const parsedResult = {}
    const {address_components} = result;

    for (var i = 0; i < address_components.length; i++) {
        for (var b = 0; b < address_components[i].types.length; b++) {
            if (address_components[i].types[b] == "street_number") {
                //this is the object you are looking for
                parsedResult.street_number = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "route") {
                //this is the object you are looking for
                parsedResult.street_name = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_1") {
                //this is the object you are looking for
                parsedResult.sublocality_level_1 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_2") {
                //this is the object you are looking for
                parsedResult.sublocality_level_2 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_3") {
                //this is the object you are looking for
                parsedResult.sublocality_level_3 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "neighborhood") {
                //this is the object you are looking for
                parsedResult.neighborhood = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "locality") {
                //this is the object you are looking for
                parsedResult.city = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "administrative_area_level_1") {
                //this is the object you are looking for
                parsedResult.state = address_components[i].long_name;
                break;
            }

            else if (address_components[i].types[b] == "postal_code") {
                //this is the object you are looking for
                parsedResult.zip = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "country") {
                //this is the object you are looking for
                parsedResult.country = address_components[i].long_name;
                break;
            }
        }
    }
    return parsedResult;
}

0

Ecco una semplice funzione che puoi usare per ottenerla. Ho usato axios per fare la richiesta API, ma puoi usare qualsiasi altra cosa.

async function getCountry(lat, long) {
  const { data: { results } } = await axios.get(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${long}&key=${GOOGLE_API_KEY}`);
  const { address_components } = results[0];

  for (let i = 0; i < address_components.length; i++) {
    const { types, long_name } = address_components[i];

    if (types.indexOf("country") !== -1) return long_name;
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.