З огляду на широкі / довгі координати, як ми можемо дізнатися місто / країну?


141

Наприклад, якщо у нас є цей набір координат

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

Як ми можемо дізнатися місто / країну?


2
Можливо, вам буде потрібна якась база даних. Я б спробував сам пограти з API Google Maps ... він підтримує lat / long.
beatgammit

Відповіді:


96

Безкоштовний API геокодування Google надає цю послугу через HTTP REST API. Зауважте, що API використання та обмеження ставок обмежені , але ви можете платити за необмежений доступ.

Спробуйте це посилання, щоб побачити приклад виводу (це в json, вихід також доступний у XML)

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


прийнявши це, тому що це те, на що я закінчуюсь :) Відповідь Майкла, безумовно, чудовий варіант тхо!
помер

5
Зворотне геокодування Google дозволяється лише в поєднанні з картою Google. Якщо ви хочете отримати рішення, яке не має таких обмежень (хоча воно є комерційним і має лише міста США), перегляньте: askgeo.com
James D

mapquest api - це ще один варіант, оскільки він не має обмежень швидкості в деяких випадках і дуже високих обмежень швидкості для різних потреб геокодування.
Том

2
безкоштовно є дискусійним, воно є вільним лише за певних обмежень.
Пета

@JamesD: Політика API говорить, що якщо ви показуєте дані на карті, то це повинна бути карта Google, але не потрібно відображати їх на карті (або взагалі).
користувач276648

173

Ще один варіант:

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

Переваги:

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

Недоліки:

  • Не оновлюється автоматично
  • Потрібен додатковий код, якщо ви хочете виділити випадок, коли найближче місто знаходиться за десятки миль
  • Може давати дивні результати біля полюсів і міжнародної лінії побачень (хоча міста в цих місцях поки немає

5
Також дасть дивні результати для міст у межах міст, наприклад, певні місця в Римі можуть повернути "Ватикан" - залежно від Lat / lon, вказаних у базі даних для кожного.
Ноель Абрахамс

1
Вони також мають REST api та виглядають досить пристойно: api.geonames.org/…
jeudyx

8
Приклад був би неоціненним
Hack-R

GeoNames також пропонує безкоштовний веб-сервіс, який просто приголомшливий!
mcont

У 2020 році GeoNames.org виглядає досить неактивною, хтось знає, чи він навіть поточний? Проблема ніде не згадується на датах останнього оновлення на сайті.
joedotnot

45

Тобі потрібно 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'}

2
Чи є у цього обмеження? Це здається найшвидшим підходом. Чи може бути якась причина не використовувати це через підхід @ Майкла?
Satys

1
ну для цього потрібен зовнішній сервіс
maxbachmann

Це чудовий підхід, однак мені просто потрібні округи, тому мені потрібно уточнити адресу. Я хотів би, щоб був спосіб, який повернув графства.
Fatemeh Asgarinejad

22

Альтернативою з відкритим кодом є Nominatim з Open Street Map. Все, що вам потрібно зробити, це встановити змінні в URL, і він повертає місто / країну цього місця. Перевірте наступне посилання для офіційної документації: Nominatim


3
Зверніть увагу , що Nominatim політики використання operations.osmfoundation.org/policies/nominatim заявляє максимальну швидкість одного запиту в секунду , так тільки дійсно підходить для спеціальних запитів.
Меттью Мудрий

22

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

Ви можете бачити, як воно працює http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (ламане посилання) Просто змініть широту та довготу для своїх місць.

Він розміщений на OpenShift (RedHat Platform). Перший дзвінок після тривалого простою може зайняти колись, але зазвичай ефективність задовільна. Сміливо користуйтеся цією послугою, як вам подобається ...

Також ви можете знайти джерело проекту за адресою https://github.com/turgos/Location .


Це не працює належним чином. Якщо він не може отримати місто, він шукає найближче відоме місто. Ось приклад: scatter-otl.rhcloud.com/… Там написано "Basseterre" замість "Saint John" ...
smartmouse

1
Це правильно. алгоритм здійснює пошук найближчого міста, доступного в наборі даних. Для вище розгорнутого сервера я використовував "Cities1000.txt". У ньому є лише великі міста. Вихідний код доступний на веб- сайті github.com/turgos/Location . Ви можете розпочати власні дані з більш детальними даними з " download.geonames.org/export/dump ".
турго

Здається, місто1000.txt - це більш детальні доступні дані. Маю рацію?
smartmouse

8

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

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

Дякуємо, що поділилися цим, але це працює не для всіх координат. Чи потрібно число цифр координат бути певним розміром?
Fatemeh Asgarinejad

1
Я вважаю, що правильно вибрав довготу та широту. У мене тисячі координат, з яких не працювала випадкова координата. Зараз це добре. Я використовував інший підхід. Дякую за Вашу відповідь.
Fatemeh Asgarinejad

1
Ласкаво просимо. Цікаво дізнатися, який підхід працював у вас? Якщо це краще, ніж geocoderя хотів би спробувати і сам!
Хамман Самуїл

1
Я використовував це: з geopy.geocoders імпортують Nominatim geolocator = Nominatim () location = geolocator.reverse ("41.4721, -72.6311") print (location.address) Він дає всю адресу, а потім я фільтрую з неї округ.
Fatemeh Asgarinejad

1
Дякую, я працював із великим набором даних і у 2017 році, використовуючи GeoPy, отримав у мене багато тайм-аутів. Можливо, через 3 роки вони зняли свої обмеження, тож це чудово знати!
Хамман Самуїл

5

Я витратив близько 30 хвилин, намагаючись знайти приклад коду, як це зробити в Javascript. Я не зміг швидко знайти чітку відповідь на поставлене вами питання. Отже ... я зробив своє. Сподіваємось, люди можуть використовувати це, не заглиблюючись в API чи дивлячись на код, який вони не мають уявлення, як читати. Ха, якщо ні на що інше, я можу посилатися на цю посаду на свої речі .. Приємне запитання і дякую за форум для обговорення!

Для цього використовується 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

Я знаю, що це питання справді давнє, але я працював над тим же питанням, і знайшов надзвичайно ефективний і зручний пакет reverse_geocoder, побудований Ajay Thampi. Код доступний тут . Він ґрунтувався на паралельній реалізації дерев KD, що є надзвичайно ефективним для великої кількості очок (мені знадобилося кілька секунд, щоб отримати 100 000 балів.

Він заснований на цій базі даних, яку вже підкреслив @turgos.

Якщо ваше завдання - швидко знайти країну та місто зі списком координат, це чудовий інструмент.


3

Це дійсно залежить від того, які технологічні обмеження у вас є.

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

Ось деякі бази даних, які підтримують просторовий тип: SQL сервер 2008 , MySQL , postGIS - розширення postgreSQL та Oracle .

Якщо ви хочете скористатися послугою замість того, щоб мати власну базу даних для цього, ви можете скористатися GeoPlanet Yahoo . Для підходу до сервісу ви можете ознайомитись з цією відповіддю на gis.stackexchange.com , де висвітлюється наявність послуг для вирішення вашої проблеми.


1

Ви можете використовувати API геокодування Google

Bellow - це функція 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;
}

якщо я хочу лише administra_area_level_ 3 або місцевість (якщо адміністративний_area_level_ 3 недоступний), яку я можу змінити? new to php ..
серпня

1

Loc2country - це інструмент на основі Golang, який повертає ISO код альфа-3 для заданих координат місцеположення (lat / lon). Він реагує за мікросекунди. Він використовує геогаш на карті країни.

Дані геохаш генеруються за допомогою геораптора .

Для цього інструменту ми використовуємо геохаш на рівні 6, тобто коробки розміром 1,2 км x 600 м.



0

Перевірте нижченаведену відповідь. Це працює для мене

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

Якщо ви використовуєте API Google Місця на карті, саме так ви можете отримати країну та місто з об’єкта місця за допомогою 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;
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.