Obtenir le nom de la ville en utilisant la géolocalisation

140

J'ai réussi à obtenir la latitude et la longitude de l'utilisateur en utilisant la géolocalisation 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;
}

Je veux afficher le nom de la ville, il semble que le seul moyen de l'obtenir soit d'utiliser une API de géolocalisation inversée. J'ai lu la documentation de Google pour la géolocalisation inversée mais je ne sais pas comment obtenir la sortie sur mon site.

Je ne sais pas comment utiliser ceci: "http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true"pour afficher le nom de la ville sur la page.

Comment puis-je atteindre cet objectif?

lisovaccaro
la source
4
Si vous n'utilisez pas de cartes, vous SAVEZ que cela va à l'encontre du TOS de Google, n'est-ce pas? Point 10.4 ici developer.google.com/maps/terms Aucune utilisation de contenu sans carte Google. À moins que la documentation des API Maps ne vous autorise expressément à le faire, vous n'utiliserez pas le contenu dans une implémentation d'API Maps sans une carte Google correspondante. Par exemple, vous pouvez afficher des images Street View sans carte Google correspondante, car la documentation des API Maps autorise expressément cette utilisation.
PirateApp
5
Oui, @PirateApp a un bon point. Il existe peut-être de meilleurs services. J'ai déjà travaillé avec SmartyStreets et je sais qu'ils ont des conditions d'utilisation beaucoup plus ouvertes. Cependant, la plupart des services ne font pas de géocodage inversé. Je sais que Texas A&M a un service gratuit, mais ils ont TOS avertissant que vous ne pouvez pas collecter de données sur d'autres personnes, et ils ont déjà eu des problèmes de disponibilité et de précision.
Joseph Hansen

Réponses:

201

Vous feriez quelque chose comme ça en utilisant l'API Google.

Veuillez noter que vous devez inclure la bibliothèque google maps pour que cela fonctionne. Le géocodeur Google renvoie un grand nombre de composants d'adresse, vous devez donc faire une estimation éclairée de celui qui aura la ville.

"administrative_area_level_1" est généralement ce que vous recherchez, mais parfois la localité est la ville que vous recherchez.

Quoi qu'il en soit - plus de détails sur les types de réponse Google peuvent être trouvés ici et ici .

Voici le code qui devrait faire l'affaire:

<!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> 
Michal
la source
3
Ce n'est pas vrai pour le niveau 1 de la zone d'administration, parfois le nom de la ville n'est pas là. - {"long_name" => "San Francisco", "types" => ["administrative_area_level_2", "Political"], "short_name" => "San Francisco"}, {"long_name" => "Californie", "types "=> [" administrative_area_level_1 "," Political "]," short_name "=>" CA "}, {" long_name "=>" États-Unis "," types "=> [" country "," Political "]," short_name "=>" US "}
Ming Tsai
5
Pour la V3, la chaîne {'latlng': latlng} doit être remplacée par 'location', comme dans ... geocode ({'location': latlng}). Cet exemple m'a presque amené là-bas, mais la chaîne 'latlng' ne semble plus être valide dans les API plus récentes. Voir: developer.google.com/maps/documentation/javascript/… pour plus de détails.
binarygiant
@Michal comment pouvons-nous trouver uniquement le nom du pays ou le code du pays au lieu de l'adresse complète?
ajay
1
@ajay dans le test de l'instruction if pour "country" et la variable city renverra désormais les données du pays. Si le renommer country = results [0] .address_components [i], vous pouvez accéder aux données par country.long_name et country.short_name
Michal
Y a-t-il un moyen de limiter cela aux villes d'une province ou simplement de vérifier si l'emplacement provient d'une province spécifique et si l'utilisateur est redirigé vers une page Web spécifique?
DésoléEh
52

Une autre approche consiste à utiliser mon service, http://ipinfo.io , qui renvoie le nom de la ville, de la région et du pays en fonction de l'adresse IP actuelle de l'utilisateur. Voici un exemple simple:

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

Voici un exemple JSFiddle plus détaillé qui imprime également les informations de réponse complètes, afin que vous puissiez voir tous les détails disponibles: http://jsfiddle.net/zK5FN/2/

Ben Dowling
la source
23
Pas aussi précis cependant.
Salman von Abbas le
4
Impossible de détecter la ville et même la trgion à partir de l'adresse IP d'un gros fournisseur russe: (
Jehy
2
Lol ... cela donne mon réseau interne IP (192.168 ...)
major-mann
Puis-je le faire à partir d'un navigateur d'appareil (portable)?
Arti
Cela ne semble pas fiable. J'utilise actuellement un ordinateur portable et un téléphone portable. Les villes affichées dans les deux appareils via ipinfo.io sont distantes de 530 kilomètres!
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'utilisation de la géolocalisation html5 nécessite l'autorisation de l'utilisateur. Au cas où vous ne le souhaiteriez pas, optez pour un localisateur externe tel que https://geolocation-db.com IPv6 est pris en charge. Aucune restriction et demandes illimitées autorisées.

Exemple

Pour un exemple purement javascript, sans utiliser jQuery, consultez cette réponse.

Kurt Van den Branden
la source
17

Vous pouvez obtenir le nom de la ville, du pays, du nom de la rue et d'autres données géographiques à l'aide de l'API de géocodage de 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>

et d'afficher ces données sur la page en utilisant 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>
Mikhail
la source
15

Voici une version de travail mise à jour pour moi qui obtiendra City / Town.Il semble que certains champs soient modifiés dans la réponse json. Se référant aux réponses précédentes pour ces questions. (Merci à Michal et une autre référence: Lien

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);
    }
  });
}
Pradeep
la source
10

geolocator.js peut le faire. (Je suis l'auteur).

Obtenir le nom de la ville (adresse limitée)

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

Obtenir des informations d'adresse complètes

L'exemple ci-dessous essaiera d'abord l'API de géolocalisation HTML5 pour obtenir les coordonnées exactes. En cas d'échec ou de rejet, il reviendra à la recherche Geo-IP. Une fois qu'il a obtenu les coordonnées, il géocodera les coordonnées en une adresse.

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

Cela utilise les API Google en interne (pour la recherche d'adresse). Donc, avant cet appel, vous devez configurer le géolocalisateur avec votre clé API Google.

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

Geolocator prend en charge la géolocalisation (via HTML5 ou recherches IP), le géocodage, les recherches d'adresses (géocodage inversé), la distance et les durées, les informations de fuseau horaire et bien d'autres fonctionnalités ...

Onur Yıldırım
la source
6

Après avoir cherché et assemblé quelques solutions différentes avec mes propres trucs, j'ai trouvé cette fonction:

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;
}
Jafo
la source
3

Vous pouvez utiliser https://ip-api.io/ pour obtenir le nom de la ville. Il prend en charge IPv6.

En prime, il permet de vérifier si l'adresse IP est un nœud tor, un proxy public ou un spammeur.

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

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

Sortie 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
    }
}
Vindhyachal Kumar
la source
2

Comme @PirateApp l'a mentionné dans son commentaire, il est explicitement contraire à la licence d'API Maps de Google d'utiliser l'API Maps comme vous le souhaitez.

Vous avez un certain nombre d'alternatives, y compris le téléchargement d'une base de données Geoip et l'interrogation localement ou l'utilisation d'un service API tiers, tel que mon service ipdata.co .

ipdata vous donne la géolocalisation, l'organisation, la devise, le fuseau horaire, le code d'appel, l'indicateur et les données d'état du nœud de sortie Tor à partir de n'importe quelle adresse IPv4 ou IPv6.

Et est évolutif avec 10 points de terminaison globaux capables chacun de gérer plus de 10 000 requêtes par seconde!

Cette réponse utilise une clé API «test» qui est très limitée et uniquement destinée à tester quelques appels. Inscrivez-vous à votre propre clé API gratuite et recevez jusqu'à 1500 demandes de développement par jour.

$.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>

Le violon; https://jsfiddle.net/ipdata/6wtf0q4g/922/

Jonathan
la source
1

Voici un autre essai ... Ajouter plus à la réponse acceptée peut-être plus complète .. bien sûr, le boîtier de commutation le rendra élégant.

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;
}
user3124360
la source
0

Voici une fonction simple que vous pouvez utiliser pour l'obtenir. J'ai utilisé axios pour faire la demande d'API, mais vous pouvez utiliser n'importe quoi d'autre.

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;
  }
}
Bande-dessinées Kingsley Kbc
la source