Compte tenu des coordonnées lat / long, comment pouvons-nous trouver la ville / le pays?


141

Par exemple si nous avons ces ensembles de coordonnées

"latitude": 48.858844300000001,
"longitude": 2.2943506,

Comment connaître la ville / le pays?


2
Vous aurez probablement besoin d'une base de données quelconque. J'essaierais de jouer moi-même avec l'API Google Maps ... elle prend en charge lat / long.
beatgammit

Réponses:


96

L' API gratuite Google Geocoding fournit ce service via une API HTTP REST. Remarque, l' utilisation de l'API est limitée , mais vous pouvez payer pour un accès illimité.

Essayez ce lien pour voir un exemple de la sortie (c'est en json, la sortie est également disponible en XML)

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


accepter cela parce que c'est celui que je finis par chercher :) La réponse de Michael est certainement une excellente option tho!
ming yeow

5
Le géocodage inversé de Google n'est autorisé qu'en conjonction avec une carte Google. Si vous voulez une solution qui n'a pas de telles restrictions (bien qu'elle soit commerciale et ne contienne
James D

mapquest api est une autre option ici car il n'a pas de limites de taux dans certains cas et des limites de taux très élevées pour divers besoins de géocodage.
Tom

2
libre est discutable, il n'est gratuit que sous certaines limites.
Petah

@JamesD: les politiques de l' API stipulent que si vous affichez les données sur une carte, il doit s'agir d'une carte Google, mais vous n'avez pas à l'afficher sur une carte (ou pas du tout).
user276648

173

Une autre option:

  • Téléchargez la base de données des villes sur http://download.geonames.org/export/dump/
  • Ajouter chaque ville en tant que lat / long -> Cartographie de la ville à un index spatial tel qu'un R-Tree (certaines bases de données ont également la fonctionnalité)
  • Utilisez la recherche du voisin le plus proche pour trouver la ville la plus proche pour un point donné

Avantages:

  • Ne dépend pas d'un serveur externe pour être disponible
  • Très rapide (effectue facilement des milliers de recherches par seconde)

Désavantages:

  • Pas automatiquement à jour
  • Nécessite un code supplémentaire si vous voulez distinguer le cas où la ville la plus proche est à des dizaines de kilomètres
  • Peut donner des résultats étranges près des pôles et de la ligne de date internationale (bien qu'il n'y ait pas de villes dans ces endroits de toute façon

5
Donnera également des résultats étranges pour les villes dans les villes, par exemple, certains endroits à Rome peuvent renvoyer «Cité du Vatican» - en fonction de la latitude / longitude spécifiée dans la base de données pour chacun.
Noel Abrahams

1
Ils ont également une API REST et ont l'air assez décent: api.geonames.org
...

8
Un exemple aurait été inestimable
Hack-R

GeoNames propose également un service Web gratuit qui est tout simplement génial!
mcont

En 2020, GeoNames.org semble quasiment inactif, est-ce que quelqu'un sait s'il est encore actuel? Le problème est nulle part ils ne mentionnent les dates de dernière mise à jour sur le site.
joedotnot le

45

Vous avez besoin geopy

pip install geopy

puis:

from geopy.geocoders import Nominatim
geolocator = Nominatim()
location = geolocator.reverse("48.8588443, 2.2943506")

print(location.address)

pour obtenir plus d'informations:

print (location.raw)

{'place_id': '24066644', 'osm_id': '2387784956', 'lat': '41.442115', 'lon': '-8.2939909', 'boundingbox': ['41.442015', '41.442215', '-8.2940909', '-8.2938909'], 'address': {'country': 'Portugal', 'suburb': 'Oliveira do Castelo', 'house_number': '99', 'city_district': 'Oliveira do Castelo', 'country_code': 'pt', 'city': 'Oliveira, São Paio e São Sebastião', 'state': 'Norte', 'state_district': 'Ave', 'pedestrian': 'Rua Doutor Avelino Germano', 'postcode': '4800-443', 'county': 'Guimarães'}, 'osm_type': 'node', 'display_name': '99, Rua Doutor Avelino Germano, Oliveira do Castelo, Oliveira, São Paio e São Sebastião, Guimarães, Braga, Ave, Norte, 4800-443, Portugal', 'licence': 'Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'}

2
Y a-t-il des limites à celui-ci? Cela semble être l'approche la plus rapide. Pourrait-il y avoir une raison de ne pas utiliser cela par rapport à l'approche de @ Michael?
Satys

1
Eh

C'est une excellente approche, mais j'ai juste besoin des comtés, donc j'ai besoin d'affiner l'adresse. Je souhaite qu'il y ait un moyen qui a rendu les comtés.
Fatemeh Asgarinejad le

22

Une alternative Open Source est Nominatim d'Open Street Map. Tout ce que vous avez à faire est de définir les variables dans une URL et elle renvoie la ville / le pays de cet emplacement. Veuillez consulter le lien suivant pour la documentation officielle: Nominatim


3
Notez que la politique d'utilisation de Nominatim operations.osmfoundation.org/policies/nominatim indique un taux maximum d'une demande par seconde et n'est donc vraiment appropriée que pour les requêtes ad hoc.
Matthew Wise

22

Je cherchais une fonctionnalité similaire et j'ai vu les données " http://download.geonames.org/export/dump/ " partagées sur la réponse précédente (merci pour le partage, c'est une excellente source), et implémenté un service basé sur les données cities1000.txt.

Vous pouvez le voir fonctionner à http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (lien cassé) Modifiez simplement la latitude et la longitude de vos emplacements.

Il est déployé sur OpenShift (RedHat Platform). Le premier appel après une longue période d'inactivité peut prendre un certain temps, mais les performances sont généralement satisfaisantes. N'hésitez pas à utiliser ce service comme vous le souhaitez ...

Vous pouvez également trouver la source du projet à l' adresse https://github.com/turgos/Location .


Cela ne fonctionne pas correctement. S'il ne parvient pas à trouver la ville, il recherche la ville connue la plus proche. Voici un exemple: scatter-otl.rhcloud.com / ... Il dit "Basseterre" au lieu de "Saint John" ...
smartmouse

1
C'est correct. l'algorithme recherche la ville la plus proche disponible dans l'ensemble de données. Pour le serveur déployé ci-dessus, j'ai utilisé "cities1000.txt". Il n'a que les grandes villes. Le code source est disponible sur github.com/turgos/Location . Vous pouvez créer le vôtre avec des données plus détaillées à partir de " download.geonames.org/export/dump ".
turgos

Il semble que les villes1000.txt soient les données les plus détaillées disponibles. Ai-je raison?
smartmouse

8

J'ai utilisé Geocoder , une bonne bibliothèque Python qui prend en charge plusieurs fournisseurs, dont Google, Geonames et OpenStreetMaps, pour n'en citer que quelques-uns . J'ai essayé d'utiliser la bibliothèque GeoPy, et il y a souvent des délais d'attente. Développer votre propre code pour GeoNames n'est pas la meilleure utilisation de votre temps et vous risquez de finir par obtenir un code instable. Geocoder est très simple à utiliser d'après mon expérience et dispose d'une documentation suffisamment bonne . Vous trouverez ci-dessous un exemple de code pour rechercher une ville par latitude et longitude, ou pour rechercher une latitude / longitude par nom de ville.

import geocoder

g = geocoder.osm([53.5343609, -113.5065084], method='reverse')
print g.json['city'] # Prints Edmonton

g = geocoder.osm('Edmonton, Canada')
print g.json['lat'], g.json['lng'] # Prints 53.5343609, -113.5065084

Merci de partager cela, mais cela ne fonctionne pas pour toutes les coordonnées. Le nombre de chiffres des coordonnées doit-il être d'une taille spécifique?
Fatemeh Asgarinejad le

1
Je crois avoir choisi correctement la longitude et la latitude. J'ai des milliers de coordonnées à partir desquelles une coordonnée aléatoire ne fonctionnait pas. Ça va maintenant. J'ai utilisé une autre approche. Merci pour votre réponse.
Fatemeh Asgarinejad le

1
Bienvenue. Curieux de savoir quelle approche a fonctionné pour vous? Si c'est mieux que geocoder, j'aimerais essayer moi aussi!
Hamman Samuel le

1
J'ai utilisé ceci: de geopy.geocoders import Nominatim geolocator = Nominatim () location = geolocator.reverse ("41.4721, -72.6311") print (location.address) Il donne l'adresse complète et ensuite je filtre le comté à partir de celui-ci.
Fatemeh Asgarinejad le

1
Merci, j'ai travaillé avec un grand ensemble de données et en 2017, l'utilisation de GeoPy m'a donné de nombreux délais. Peut-être que 3 ans plus tard, ils ont assoupli leurs restrictions, donc c'est bon à savoir!
Hamman Samuel le

5

J'ai passé environ 30 minutes à essayer de trouver un exemple de code expliquant comment faire cela en Javascript. Je n'ai pas trouvé de réponse claire et rapide à la question que vous avez posée. Alors ... j'ai fait le mien. Espérons que les gens puissent l'utiliser sans avoir à fouiller dans l'API ou à regarder du code qu'ils n'ont aucune idée de comment lire. Ha si rien d'autre je peux référencer ce post pour mes propres trucs .. Belle question et merci pour le forum de discussion!

Ceci utilise l'API Google.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=<YOURGOOGLEKEY>&sensor=false&v=3&libraries=geometry"></script>

.

//CHECK IF BROWSER HAS HTML5 GEO LOCATION
if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function (position) {

        //GET USER CURRENT LOCATION
        var locCurrent = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

        //CHECK IF THE USERS GEOLOCATION IS IN AUSTRALIA
        var geocoder = new google.maps.Geocoder();
            geocoder.geocode({ 'latLng': locCurrent }, function (results, status) {
                var locItemCount = results.length;
                var locCountryNameCount = locItemCount - 1;
                var locCountryName = results[locCountryNameCount].formatted_address;

                if (locCountryName == "Australia") {
                    //SET COOKIE FOR GIVING
                    jQuery.cookie('locCountry', locCountryName, { expires: 30, path: '/' }); 
                }
        });
    }
}

5

Je sais que cette question est vraiment ancienne, mais j'ai travaillé sur le même problème et j'ai trouvé un package extrêmement efficace et pratique reverse_geocoder, construit par Ajay Thampi. Le code est disponible ici . Il est basé sur une implémentation parallélisée d'arbres KD qui est extrêmement efficace pour de grandes quantités de points (il m'a fallu quelques secondes pour obtenir 100 000 points.

Il est basé sur cette base de données, déjà mise en évidence par @turgos.

Si votre tâche est de trouver rapidement le pays et la ville d'une liste de coordonnées, c'est un excellent outil.


3

Cela dépend vraiment des restrictions technologiques dont vous disposez.

Une façon est d'avoir une base de données spatiale avec le contour des pays et des villes qui vous intéressent. Par plan, je veux dire que les pays et les villes sont stockés sous forme de polygone de type spatial. Votre ensemble de coordonnées peut être converti en point de type spatial et interrogé sur les polygones pour obtenir le nom du pays / de la ville où se trouve le point.

Voici quelques-unes des bases de données qui prennent en charge le type spatial: SQL Server 2008 , MySQL , postGIS - une extension de postgreSQL et d' Oracle .

Si vous souhaitez utiliser un service au lieu d'avoir votre propre base de données pour cela, vous pouvez utiliser GeoPlanet de Yahoo . Pour l'approche de service, vous voudrez peut-être consulter cette réponse sur gis.stackexchange.com , qui couvre la disponibilité des services pour résoudre votre problème.


1

Vous pouvez utiliser l'API Google Geocoding

Ci-dessous est la fonction php qui renvoie l'adresse, la ville, l'état et le pays

public function get_location($latitude='', $longitude='')
{
    $geolocation = $latitude.','.$longitude;
    $request = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.$geolocation.'&sensor=false'; 
    $file_contents = file_get_contents($request);
    $json_decode = json_decode($file_contents);
    if(isset($json_decode->results[0])) {
        $response = array();
        foreach($json_decode->results[0]->address_components as $addressComponet) {
            if(in_array('political', $addressComponet->types)) {
                    $response[] = $addressComponet->long_name; 
            }
        }

        if(isset($response[0])){ $first  =  $response[0];  } else { $first  = 'null'; }
        if(isset($response[1])){ $second =  $response[1];  } else { $second = 'null'; } 
        if(isset($response[2])){ $third  =  $response[2];  } else { $third  = 'null'; }
        if(isset($response[3])){ $fourth =  $response[3];  } else { $fourth = 'null'; }
        if(isset($response[4])){ $fifth  =  $response[4];  } else { $fifth  = 'null'; }


        $loc['address']=''; $loc['city']=''; $loc['state']=''; $loc['country']='';
        if( $first != 'null' && $second != 'null' && $third != 'null' && $fourth != 'null' && $fifth != 'null' ) {
            $loc['address'] = $first;
            $loc['city'] = $second;
            $loc['state'] = $fourth;
            $loc['country'] = $fifth;
        }
        else if ( $first != 'null' && $second != 'null' && $third != 'null' && $fourth != 'null' && $fifth == 'null'  ) {
            $loc['address'] = $first;
            $loc['city'] = $second;
            $loc['state'] = $third;
            $loc['country'] = $fourth;
        }
        else if ( $first != 'null' && $second != 'null' && $third != 'null' && $fourth == 'null' && $fifth == 'null' ) {
            $loc['city'] = $first;
            $loc['state'] = $second;
            $loc['country'] = $third;
        }
        else if ( $first != 'null' && $second != 'null' && $third == 'null' && $fourth == 'null' && $fifth == 'null'  ) {
            $loc['state'] = $first;
            $loc['country'] = $second;
        }
        else if ( $first != 'null' && $second == 'null' && $third == 'null' && $fourth == 'null' && $fifth == 'null'  ) {
            $loc['country'] = $first;
        }
      }
      return $loc;
}

si je veux seulement administrative_area_level_ 3 ou locality (si administrative_area_level_ 3 n'est pas disponible), lequel dois-je modifier? nouveau sur php ..
août

1

Loc2country est un outil basé sur Golang qui renvoie le code de pays ISO alpha-3 pour des coordonnées de localisation données (lat / lon). Il répond en quelques microsecondes. Il utilise un geohash pour la carte du pays.

Les données geohash sont générées à l'aide d'un géoraptor .

Nous utilisons geohash au niveau 6 pour cet outil, c'est-à-dire des boîtes de 1,2 km x 600 m.



0

Veuillez vérifier la réponse ci-dessous. Ça marche pour moi

if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position){

        initialize(position.coords.latitude,position.coords.longitude);
    }); 
}

function initialize(lat,lng) {
    //directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
    //directionsService = new google.maps.DirectionsService();
    var latlng = new google.maps.LatLng(lat, lng);

    //alert(latlng);
    getLocation(latlng);
}

function getLocation(latlng){

    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({'latLng': latlng}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (results[0]) {
                    var loc = getCountry(results);
                    alert("location is::"+loc);
                }
            }
        });

}

function getCountry(results)
{
    for (var i = 0; i < results[0].address_components.length; i++)
    {
        var shortname = results[0].address_components[i].short_name;
        var longname = results[0].address_components[i].long_name;
        var type = results[0].address_components[i].types;
        if (type.indexOf("country") != -1)
        {
            if (!isNullOrWhitespace(shortname))
            {
                return shortname;
            }
            else
            {
                return longname;
            }
        }
    }

}

function isNullOrWhitespace(text) {
    if (text == null) {
        return true;
    }
    return text.replace(/\s/gi, '').length < 1;
}

0

Si vous utilisez l'API Google Places, voici comment obtenir le pays et la ville à partir de l'objet de lieu à l'aide de Javascript:

function getCityAndCountry(location) {
  var components = {};
  for(var i = 0; i < location.address_components.length; i++) {
    components[location.address_components[i].types[0]] = location.address_components[i].long_name;
  }

  if(!components['country']) {
    console.warn('Couldn\'t extract country');
    return false;
  }

  if(components['locality']) {
    return [components['locality'], components['country']];
  } else if(components['administrative_area_level_1']) {
    return [components['administrative_area_level_1'], components['country']];
  } else {
    console.warn('Couldn\'t extract city');
    return false;
  }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.