Enlem / boylam koordinatları göz önüne alındığında, şehri / ülkeyi nasıl bulabiliriz?


Yanıtlar:


96

Ücretsiz Google Geocoding API'sı bu hizmeti bir HTTP REST API'sı aracılığıyla sağlar. Unutmayın, API kullanım ve hız sınırlıdır , ancak sınırsız erişim için ödeme yapabilirsiniz.

Çıktıya bir örnek görmek için bu bağlantıyı deneyin (bu json'da, çıktı XML'de de mevcuttur)

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


Bu kabul çünkü ben sonunda gidiş biri :) Michael cevap kesinlikle harika bir seçenek tho!
ming yeow

5
Google'ın ters coğrafi kodlamasına yalnızca bir Google Haritası ile birlikte izin verilir. Bu tür kısıtlamaları olmayan bir çözüm istiyorsanız (ticari ve sadece ABD şehirleri olmasına rağmen), göz atın
James D

mapquest api, bazı durumlarda hız sınırları ve çeşitli coğrafi kodlama ihtiyaçları için çok yüksek hız sınırları olduğundan başka bir seçenektir.
Tom

2
ücretsiz tartışmalıdır, sadece belirli sınırlar altında ücretsizdir.
Petah

@JamesD: API politikaları , verileri bir harita üzerinde görüntülerseniz, bunun bir Google Haritası olması gerektiğini, ancak bir haritada (veya hiç) göstermeniz gerekmediğini belirtir.
user276648 13:19

173

Başka seçenek:

  • Şehirler veritabanını http://download.geonames.org/export/dump/ adresinden indirin.
  • Her şehri R / Tree gibi uzamsal bir dizine enlem / boylam -> Şehir eşlemesi olarak ekleyin (bazı DB'ler de işlevselliğe sahiptir)
  • Herhangi bir noktaya en yakın şehri bulmak için en yakın komşu aramayı kullanın

Avantajları:

  • Kullanılabilecek harici bir sunucuya bağlı değil
  • Çok hızlı (saniyede binlerce arama kolayca yapılabilir)

Dezavantajları:

  • Otomatik olarak güncel değil
  • En yakın şehrin onlarca mil uzakta olduğu durumu ayırt etmek istiyorsanız ekstra kod gerektirir
  • Kutupların ve uluslararası tarih çizgisinin yakınında garip sonuçlar verebilir (yine de bu yerlerde herhangi bir şehir olmasa da)

5
Ayrıca şehirler içindeki şehirler için garip sonuçlar verecektir, örneğin Roma'daki bazı yerler "Vatikan" döndürebilir - her biri için veritabanında belirtilen lat / lon bağlı olarak.
Noel Abrahams

1
Ayrıca bir REST api var ve oldukça iyi görünüyor: api.geonames.org/…
jeudyx

8
Bir örnek paha biçilmezdi
Hack-R

GeoNames ayrıca sadece harika bir ücretsiz web hizmeti sunuyor!
mcont

2020'de GeoNames.org oldukça aktif değil, hatta güncel olup olmadığını bilen var mı? Sorun hiçbir yerde sitede son güncelleme tarihlerinden bahsetmiyorlar.
joedotnot

45

İhtiyacın var geopy

pip install geopy

ve sonra:

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

print(location.address)

daha fazla bilgi almak için:

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
Bunun herhangi bir sınırı var mı? Bu en hızlı yaklaşım gibi görünüyor. Bunu @ Michael'ın yaklaşımında kullanmamak için herhangi bir sebep olabilir mi?
Satys

1
iyi bir dış servis gerektirir
maxbachmann

Harika bir yaklaşım, ancak ilçelere ihtiyacım var, bu yüzden adresi düzeltmem gerekiyor. İlçeleri geri getiren bir yol olsaydı.
Fatemeh Asgarinejad

22

Açık Kaynak alternatifi, Açık Sokak Haritası'ndan Nominatim'dir. Tek yapmanız gereken bir URL'deki değişkenleri ayarlamak ve o yerin şehrini / ülkesini döndürmektir. Resmi belgeler için lütfen aşağıdaki bağlantıyı kontrol edin: Nominatim


3
Nominatim kullanım politikası işlemleri.osmfoundation.org/ policies/nominatim , saniyede en fazla bir istek oranını belirtir, bu nedenle yalnızca geçici sorgular için gerçekten uygundur.
Matthew Wise

22

Benzer bir işlev arıyordum ve verileri gördüm " http://download.geonames.org/export/dump/ " önceki yanıtta paylaşıldığını (paylaştığınız için teşekkür ederim, mükemmel bir kaynak) ve bir hizmet tabanlı şehirler1000.txt verilerinde.

Şurada çalıştığını görebilirsiniz: http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (bozuk bağlantı) Konumlarınızın enlem ve boylamını değiştirmeniz yeterlidir.

OpenShift (RedHat Platformu) üzerine dağıtılır. Uzun bir bekleme süresinden sonraki ilk çağrı bir süre alabilir, ancak genellikle performans tatmin edicidir. Bu hizmeti istediğiniz gibi kullanmaktan çekinmeyin ...

Ayrıca, proje kaynağını https://github.com/turgos/Location adresinde bulabilirsiniz .


Düzgün çalışmıyor. Şehri alamazsa, bilinen en yakın şehri arar. İşte bir örnek: scatter-otl.rhcloud.com/… "Saint John" yerine "Basseterre" yazıyor ...
smartmouse

1
Bu doğru. algoritma, veri kümesinde bulunan en yakın şehri arar. Yukarıda konuşlandırılan sunucu için "Cities1000.txt" kullandım. Sadece büyük şehirleri var. Kaynak kodu github.com/turgos/Location adresinde bulabilirsiniz . " Download.geonames.org/export/dump " adresinden daha ayrıntılı verilerle kendiniz başlayabilirsiniz .
turgos

Cities1000.txt, daha ayrıntılı verilerdir. Haklı mıyım?
smartmouse

8

Ben kullandım Geocoder , Google, Geonames ve openstreetmap destekleri dahil çoklu sağlayıcıları, bu iyi bir Python kütüphanesi sadece bir kaçı . GeoPy kütüphanesini kullanmayı denedim ve çoğu zaman zaman aşımı oluyor. GeoNames için kendi kodunuzu geliştirmek zamanınızı en iyi şekilde kullanmak değildir ve sonuçta kararsız kodlar alabilirsiniz. Geocoder benim deneyimimde kullanımı çok basit ve yeterince iyi belgelere sahip . Aşağıda, şehri enlem ve boylam ile aramak veya şehir adına göre enlem / boylam bulmak için bazı örnek kodlar verilmiştir.

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

Bunu paylaştığınız için teşekkürler, ancak tüm koordinatlar için çalışmaz. Koordinatların basamak sayısının belirli bir boyutta olması gerekiyor mu?
Fatemeh Asgarinejad

1
Boylam ve enlemi doğru seçtiğime inanıyorum. Rastgele bir koordinatın çalışmadığı binlerce koordinatım var. Şimdi iyi. Başka bir yaklaşım kullandım. Yanıtınız için teşekkürler.
Fatemeh Asgarinejad

1
Hoşgeldiniz. Sizin için hangi yaklaşımın işe yaradığını bilmek ister misiniz? Eğer daha iyiyse geocoder, ben de denemek istiyorum!
Hamman Samuel

1
Bunu kullandım: geopy.geocoders from Nominatim'den geolocator = Nominatim () location = geolocator.reverse ("41.4721, -72.6311") print (location.address) Tüm adresi verir ve sonra ilçeyi ondan filtrelerim.
Fatemeh Asgarinejad

1
Teşekkürler, büyük bir veri kümesiyle çalıştım ve 2017'de GeoPy kullanarak bana birçok zaman aşımı oldu. Belki 3 yıl sonra kısıtlamalarını rahatlattılar, bu yüzden bilmek harika!
Hamman Samuel

5

Javascript bunu yapmak için nasıl bir kod örneği bulmaya çalışırken yaklaşık 30 dakika geçirdi. Gönderdiğiniz soruya hızlı ve net bir cevap bulamadım. Yani ... kendim yaptım. Umarım insanlar bunu API'ye girmeye veya koda bakmaya gerek kalmadan okuyabilirler. Ha başka bir şey varsa ben kendi şeyler için bu yazı referans olabilir .. Güzel soru ve tartışma forumu için teşekkürler!

Bu, Google API'sını kullanıyor.

<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

Bu sorunun gerçekten eski olduğunu biliyorum, ama aynı konuda çalışıyorum ve reverse_geocoderAjay Thampi tarafından inşa edilen son derece verimli ve kullanışlı bir paket buldum . Kod burada mevcuttur . Büyük miktarda puan için son derece verimli olan KD ağaçlarının paralel bir uygulamasına dayanmaktadır (100.000 puan elde etmek birkaç saniye sürdü.

@Turgos tarafından vurgulanan bu veritabanını temel alır .

Göreviniz bir koordinat listesinin ülkesini ve şehrini hızlı bir şekilde bulmaksa, bu harika bir araçtır.


3

Gerçekten hangi teknoloji kısıtlamalarına sahip olduğunuza bağlıdır.

Bunun bir yolu, ilgilendiğiniz ülkelerin ve şehirlerin ana hatlarıyla bir mekansal veri tabanına sahip olmaktır. Koordinat kümeniz, uzamsal tür noktasına dönüştürülebilir ve noktanın bulunduğu ülke / şehir adını almak için çokgenlere göre sorgulanabilir.

Uzamsal türü destekleyen bazı veritabanları şunlardır: SQL Server 2008 , MySQL , postGIS - postgreSQL ve Oracle'ın bir uzantısı .

Bunun için kendi veritabanına sahip olmak yerine bir hizmet kullanmak isterseniz Yahoo'nun GeoPlanet'ini kullanabilirsiniz . Hizmet yaklaşımı için, sorununuzu çözmek için hizmetlerin kullanılabilirliğini kapsayan gis.stackexchange.com adresindeki bu yanıtı kontrol etmek isteyebilirsiniz .


1

Google Geocoding API'sını kullanabilirsiniz

Körük Adres, Şehir, Eyalet ve Ülke döndüren php işlevidir

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

yalnızca administrative_area_level_ 3 veya yerellik istiyorsanız (administrative_area_level_ 3 mevcut değilse) hangisini değiştirmeliyim? php için yeni ..
Ağustos

1

Loc2country , verilen konum koordinatları (lat / lon) için ISO alfa-3 ülke kodunu döndüren Golang tabanlı bir araçtır. Mikrosaniye cinsinden yanıt verir. Ülke haritasına bir geohash kullanır.

Geohash verileri georaptor kullanılarak üretilir .

Bu araç için seviye 6'da geohash kullanıyoruz, yani 1.2km x 600m boyutlarında kutular.



0

Lütfen aşağıdaki cevabı kontrol edin. Benim için çalışıyor

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

Google'ın Rehber API'sini kullanıyorsanız, Javascript'i kullanarak yer nesnesinden ülke ve şehri şu şekilde alabilirsiniz:

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;
  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.