Учитывая координаты широты / долготы, как мы можем узнать город / страну? - PullRequest
127 голосов
/ 28 мая 2011

Например, если у нас есть этот набор координат

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

Как мы можем узнать город / страну?

Ответы [ 13 ]

160 голосов
/ 15 июня 2011

Другой вариант:

  • Скачать базу данных городов из http://download.geonames.org/export/dump/
  • Добавление каждого города в виде широты / долготы -> Отображение города в пространственный индекс, такой как R-Tree (некоторые БД также имеют функциональность)
  • Используйте поиск ближайших соседей, чтобы найти ближайший город для любой заданной точки

Преимущества:

  • Не зависит от доступности внешнего сервера
  • Очень быстро (легко выполняет тысячи поисков в секунду)

Недостатки:

  • Не обновляется автоматически
  • Требуется дополнительный код, если вы хотите различить случай, когда ближайший город находится на расстоянии десятков миль
  • Может дать странные результаты вблизи полюсов и международной линии дат (хотя в любом случае в этих местах нет городов
91 голосов
/ 15 июня 2011

Бесплатный Google Geocoding API предоставляет эту услугу через HTTP REST API.Обратите внимание, что API использование и скорость ограничена , но вы можете платить за неограниченный доступ.

Попробуйте эту ссылку, чтобы увидеть пример вывода (это в json, вывод также доступенв XML)

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

34 голосов
/ 13 января 2016

Вам нужно geopy

pip install geopy

, а затем:

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

print(location.address)

для получения дополнительной информации:

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'}
20 голосов
/ 03 января 2016

Альтернативой с открытым исходным кодом является Nominatim из Open Street Map.Все, что вам нужно сделать, это установить переменные в URL, и он возвращает город / страну этого местоположения.Пожалуйста, проверьте следующую ссылку для официальной документации: Номинатим

20 голосов
/ 10 июня 2015

Я искал похожую функциональность и увидел данные "http://download.geonames.org/export/dump/", которые были предоставлены в предыдущем ответе (спасибо за обмен, это отличный источник), и реализовал сервис на основе данных towns1000.txt .

Вы можете видеть, что это работает на http://scatter -otl.rhcloud.com / location? Lat = 36 & long = -78,9 (неработающая ссылка) Просто измените широту и долготу для вашего местоположения.

Он развернут в OpenShift (платформа RedHat). Первый звонок после длительного простоя может занять некоторое время, но обычно производительность удовлетворительная. Не стесняйтесь использовать эту услугу, как вам нравится ...

Кроме того, вы можете найти источник проекта на https://github.com/turgos/Location.

5 голосов
/ 08 марта 2017

Я использовал Geocoder , хорошую библиотеку Python, которая поддерживает несколько провайдеров, включая Google, Geonames и OpenStreetMaps, чтобы упомянуть лишь несколько . Я пытался использовать библиотеку GeoPy, и она часто получает таймауты. Разработка собственного кода для GeoNames - не лучшее использование вашего времени, и вы можете получить нестабильный код. По моему опыту, Geocoder очень прост в использовании и имеет достаточно документацию . Ниже приведен пример кода для поиска города по широте и долготе или по поиску широты / долготы по названию города.

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
5 голосов
/ 21 января 2014

Я потратил около 30 минут, пытаясь найти пример кода, как это сделать в Javascript.Я не смог найти быстрый четкий ответ на вопрос, который вы разместили.Итак ... Я сделал свой собственный.Надеемся, что люди могут использовать это без необходимости копаться в API или смотреть на код, который они не знают, как читать.Ха, если ничего другого, я могу сослаться на этот пост для моего собственного материала .. Хороший вопрос и спасибо за форум обсуждения!

Это использует Google API.

<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: '/' }); 
                }
        });
    }
}
3 голосов
/ 15 июня 2011

Это действительно зависит от того, какие у вас технологические ограничения.

Одним из способов является создание пространственной базы данных с описанием стран и городов, которые вас интересуют. Под схемой я подразумеваю, что страны и города хранятся в виде полигона пространственного типа.Ваш набор координат может быть преобразован в точку пространственного типа и сопоставлен с полигонами, чтобы получить название страны / города, где расположена точка.

Вот некоторые базы данных, которые поддерживают пространственный тип: SQL Server 2008 , MySQL , postGIS - расширение postgreSQL и Oracle .

Если вы хотите использовать службу вместо собственной базы данных для этого, вы можете использовать Yahoo GeoPlanet .Для сервисного подхода вы можете проверить этот ответ на gis.stackexchange.com , который охватывает доступность услуг для решения вашей проблемы.

2 голосов
/ 25 октября 2017

Я знаю, что этот вопрос действительно старый, но я работал над той же проблемой, и я нашел чрезвычайно эффективный и удобный пакет reverse_geocoder, созданный Ajay Thampi. Код доступен здесь . Он основан на параллельной реализации K-D деревьев, которая чрезвычайно эффективна для большого количества очков (мне потребовалось несколько секунд, чтобы получить 100 000 очков.

Он основан на этой базе данных, уже выделенной @ turgos.

Если ваша задача - быстро найти страну и город по списку координат, это отличный инструмент.

1 голос
/ 05 декабря 2015

Вы можете использовать Google Geocoding API

Ниже - функция php, которая возвращает адрес, город, штат и страну

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