Date le coordinate lat / long, come possiamo scoprire la città / il paese?


141

Ad esempio se abbiamo questo insieme di coordinate

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

Come possiamo scoprire la città / il paese?


2
Probabilmente avrai bisogno di un database di qualche tipo. Proverei io stesso a giocare con l'API di Google Maps ... supporta lat / long.
beatgammit,

Risposte:


96

L' API di geocodifica gratuita di Google fornisce questo servizio tramite un'API REST HTTP. Nota, l'API è limitata per utilizzo e tariffa , ma puoi pagare per un accesso illimitato.

Prova questo link per vedere un esempio dell'output (questo è in json, l'output è disponibile anche in XML)

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


accettandolo perché questo è quello che finisco per :) La risposta di Michael è sicuramente un'ottima opzione!
ming yeow il

5
La geocodifica inversa di Google è consentita solo in combinazione con una mappa di Google. Se vuoi una soluzione che non abbia tali restrizioni (anche se è commerciale e ha solo città degli Stati Uniti), controlla: askgeo.com
James D

mapquest api è un'altra opzione qui in quanto non ha limiti di velocità in alcuni casi e limiti di velocità molto elevati per le varie esigenze di geocodifica.
Tom,

2
gratuito è discutibile, è gratuito solo con determinati limiti.
Petah,

@JamesD: i criteri API indicano che se si visualizzano i dati su una mappa, allora devono essere una Google Map, ma non è necessario visualizzarli su una mappa (o affatto).
user276648

173

Un'altra opzione:

  • Scarica il database delle città da http://download.geonames.org/export/dump/
  • Aggiungi ogni città come lat / long -> City mapping a un indice spaziale come un R-Tree (alcuni DB hanno anche la funzionalità)
  • Usa la ricerca del vicino più vicino per trovare la città più vicina per un dato punto

vantaggi:

  • Non dipende da un server esterno per essere disponibile
  • Molto veloce (esegue facilmente migliaia di ricerche al secondo)

svantaggi:

  • Non aggiornato automaticamente
  • Richiede un codice aggiuntivo se si desidera distinguere il caso in cui la città più vicina si trova a decine di miglia di distanza
  • Può dare strani risultati vicino ai poli e alla linea di data internazionale (anche se non ci sono città in quei luoghi comunque

5
Fornirà anche risultati strani per le città all'interno delle città, ad esempio alcune località di Roma potrebbero restituire "Città del Vaticano", a seconda del lat / lon specificato nel database per ciascuna.
Noel Abrahams,

1
Hanno anche un API REST e sembra abbastanza decente: api.geonames.org/…
jeudyx,

8
Un esempio sarebbe stato prezioso
Hack-R

GeoNames offre anche un servizio web gratuito che è semplicemente fantastico!
Mc

Nel 2020, GeoNames.org sembra praticamente inattivo, qualcuno sa se è ancora attuale? Il problema non è da nessuna parte menzionano le date dell'ultimo aggiornamento sul sito.
joedotnot

45

Hai bisogno geopy

pip install geopy

e poi:

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

print(location.address)

per ottenere maggiori informazioni:

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
Ci sono limiti a questo? Questo sembra essere l'approccio più rapido. Potrebbe esserci qualche motivo per non usare questo approccio all'approccio di @ Michael?
Satys,

1
bene richiede un servizio esterno
maxbachmann

È un ottimo approccio, tuttavia ho solo bisogno delle contee, quindi devo perfezionare l'indirizzo. Vorrei che ci fosse un modo per restituire le contee.
Fatemeh Asgarinejad,

22

Un'alternativa Open Source è Nominatim da Open Street Map. Tutto quello che devi fare è impostare le variabili in un URL e restituire la città / il paese di quella posizione. Si prega di controllare il seguente link per la documentazione ufficiale: Nominatim


3
Si noti che la politica di utilizzo di Nominatim operations.osmfoundation.org/policies/nominatim stabilisce un tasso massimo di una richiesta al secondo, quindi è davvero adatto solo per query ad hoc.
Matthew Wise,

22

Ero alla ricerca di una funzionalità simile e ho visto i dati " http://download.geonames.org/export/dump/ " condivisi sulla risposta precedente (grazie per la condivisione, è una fonte eccellente) e ho implementato un servizio basato sui dati cities1000.txt.

Puoi vederlo funzionare a http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (link non funzionante) Basta cambiare la latitudine e la longitudine per le posizioni.

È distribuito su OpenShift (piattaforma RedHat). La prima chiamata dopo un lungo periodo di inattività può richiedere qualche tempo, ma in genere le prestazioni sono soddisfacenti. Sentiti libero di usare questo servizio come preferisci ...

Inoltre, puoi trovare la fonte del progetto su https://github.com/turgos/Location .


Non funziona correttamente. Se non riesce a ottenere la città, cerca la città nota più vicina. Ecco un esempio: scatter-otl.rhcloud.com/… Dice "Basseterre" invece di "Saint John" ...
smartmouse

1
È corretto. l'algoritmo cerca la città più vicina disponibile nel set di dati. Per il server distribuito sopra, ho usato "cities1000.txt". Ha solo le principali città. Il codice sorgente è disponibile su github.com/turgos/Location . Puoi iniziare con i tuoi dati più dettagliati da " download.geonames.org/export/dump ".
Turgos,

Sembra cities1000.txt sono i dati più dettagliati disponibili. Ho ragione?
smartmouse,

8

Ho usato Geocoder , una buona libreria Python che supporta più provider, tra cui Google, Geonames e OpenStreetMaps, per citarne solo alcuni . Ho provato a utilizzare la libreria GeoPy e spesso ottiene timeout. Sviluppare il tuo codice per GeoNames non è il miglior uso del tuo tempo e potresti finire per ottenere un codice instabile. Geocoder è molto semplice da usare nella mia esperienza e ha una documentazione sufficiente . Di seguito è riportato un codice di esempio per cercare città per latitudine e longitudine o per trovare latitudine / longitudine in base al nome della città.

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

Grazie per averlo condiviso, ma non funziona per tutte le coordinate. Il numero di cifre delle coordinate deve avere una dimensione specifica?
Fatemeh Asgarinejad,

1
Credo di aver scelto correttamente longitudine e latitudine. Ho migliaia di coordinate da cui una coordinata casuale non ha funzionato. Adesso va bene. Ho usato un altro approccio. Grazie per la risposta.
Fatemeh Asgarinejad,

1
Benvenuto. Curioso di sapere quale approccio ha funzionato per te? Se è meglio di geocoder, mi piacerebbe provare anche io!
Hamman Samuel,

1
Ho usato questo: da geopy.geocoders import Nominatim geolocator = Nominatim () location = geolocator.reverse ("41.4721, -72.6311") print (location.address) Fornisce l'intero indirizzo e quindi filtro la contea da esso.
Fatemeh Asgarinejad,

1
Grazie, ho lavorato con un set di dati di grandi dimensioni e nel 2017 l'utilizzo di GeoPy mi ha fatto ottenere molti timeout. Forse 3 anni dopo hanno allentato le loro restrizioni, quindi è bello saperlo!
Hamman Samuel,

5

Ho impiegato circa 30 minuti a cercare un esempio di codice su come eseguire questa operazione in Javascript. Non sono riuscito a trovare una risposta rapida e chiara alla domanda che hai pubblicato. Quindi ... ho fatto il mio. Spero che le persone possano usarlo senza dover scavare nell'API o fissare il codice che non hanno idea di come leggere. Ah se non altro posso fare riferimento a questo post per le mie cose .. Bella domanda e grazie per il forum di discussione!

Questo sta utilizzando l'API di 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

So che questa domanda è davvero vecchia, ma ho lavorato sullo stesso problema e ho trovato un pacchetto estremamente efficiente e conveniente reverse_geocoder, creato da Ajay Thampi. Il codice è disponibile qui . Si basava su un'implementazione parallela di alberi KD che è estremamente efficiente per grandi quantità di punti (mi ci sono voluti pochi secondi per ottenere 100.000 punti.

Si basa su questo database, già evidenziato da @turgos.

Se il tuo compito è trovare rapidamente il paese e la città di un elenco di coordinate, questo è un ottimo strumento.


3

Dipende davvero dalle restrizioni tecnologiche che hai.

Un modo è quello di avere un database spaziale con i contorni dei paesi e delle città che ti interessano. Per contorno intendo che i paesi e le città sono archiviati come poligoni di tipo spaziale. Il tuo set di coordinate può essere convertito nel punto del tipo spaziale e interrogato contro i poligoni per ottenere il nome del paese / città in cui si trova il punto.

Ecco alcuni dei database che supportano il tipo spaziale: SQL server 2008 , MySQL , postGIS - un'estensione di postgreSQL e Oracle .

Se desideri utilizzare un servizio invece di avere il tuo database per questo, puoi utilizzare GeoPlanet di Yahoo . Per l'approccio al servizio potresti voler dare un'occhiata a questa risposta su gis.stackexchange.com , che copre la disponibilità di servizi per risolvere il tuo problema.


1

Puoi utilizzare l'API di geocodifica di Google

Bellow è la funzione php che restituisce Indirizzo, Città, Stato e Paese

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

se desidero solo Administrative_area_level_ 3 o località (se Administrative_area_level_ 3 non disponibile), quale devo modificare? Nuovo per php ..
mese di agosto

1

Loc2country è uno strumento basato su Golang che restituisce il codice ISO alpha-3 del paese per determinate coordinate di posizione (lat / lon). Risponde in microsecondi. Usa un geohash per la mappa del paese.

I dati geohash sono generati usando georaptor .

Usiamo geohash al livello 6 per questo strumento, ovvero scatole di dimensioni 1,2 km x 600 m.



0

Si prega di controllare la risposta qui sotto. Per me funziona

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

Se stai utilizzando l'API Places di Google, ecco come ottenere Paese e città dall'oggetto Place utilizzando 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;
  }
}
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.