Với tọa độ lat / long, làm thế nào chúng ta có thể tìm ra thành phố / quốc gia?


141

Ví dụ: nếu chúng ta có các bộ tọa độ này

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

Làm thế nào chúng ta có thể tìm ra thành phố / quốc gia?


2
Bạn có thể sẽ cần một cơ sở dữ liệu của một số loại. Tôi đã thử tự chơi với API Google Maps ... nó hỗ trợ lat / long.
beatgammit

Câu trả lời:


96

API mã hóa địa lý miễn phí của Google cung cấp dịch vụ này thông qua API HTTP REST. Lưu ý, API là mức sử dụng và tỷ lệ giới hạn , nhưng bạn có thể trả tiền để truy cập không giới hạn.

Hãy thử liên kết này để xem ví dụ về đầu ra (cái này ở dạng json, đầu ra cũng có sẵn trong XML)

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


chấp nhận điều này bởi vì đây là câu trả lời cuối cùng của tôi :) Câu trả lời của Michael chắc chắn là một lựa chọn tuyệt vời tho!
ming yeow

5
Mã hóa địa lý đảo ngược của Google chỉ được phép kết hợp với Google Map. Nếu bạn muốn một giải pháp không có những hạn chế như vậy (mặc dù đó là thương mại và chỉ có các thành phố của Hoa Kỳ), hãy xem: Askgeo.com
James D

mapquest api là một lựa chọn khác ở đây vì nó không có giới hạn tốc độ trong một số trường hợp và giới hạn tốc độ rất cao cho các nhu cầu mã hóa địa lý khác nhau.
Tom

2
miễn phí là tranh cãi, nó chỉ miễn phí trong một số giới hạn nhất định.
Petah

@JamesD: chính sách API nêu rõ rằng nếu bạn hiển thị dữ liệu trên bản đồ thì đó phải là Google Map, nhưng bạn không phải hiển thị nó trên bản đồ (hoặc hoàn toàn).
dùng276648

173

Một lựa chọn khác:

  • Tải xuống cơ sở dữ liệu thành phố từ http://doad.geonames.org/export/dump/
  • Thêm mỗi thành phố dưới dạng lat / long -> Ánh xạ thành phố vào một chỉ mục không gian như R-Tree (một số DB cũng có chức năng)
  • Sử dụng tìm kiếm hàng xóm gần nhất để tìm thành phố gần nhất cho bất kỳ điểm nào

Ưu điểm:

  • Không phụ thuộc vào một máy chủ bên ngoài có sẵn
  • Rất nhanh (dễ dàng thực hiện hàng ngàn lượt tra cứu mỗi giây)

Nhược điểm:

  • Không tự động cập nhật
  • Yêu cầu thêm mã nếu bạn muốn phân biệt các trường hợp thành phố gần nhất là hàng chục dặm
  • Có thể cho kết quả kỳ lạ gần các cực và dòng ngày quốc tế (mặc dù không có thành phố nào ở những nơi đó

5
Cũng sẽ đưa ra kết quả kỳ lạ cho các thành phố trong các thành phố, ví dụ: một số địa điểm nhất định ở Rome có thể trả về "Thành phố Vatican" - tùy thuộc vào lat / lon được chỉ định trong cơ sở dữ liệu cho từng thành phố.
Noel Áp-ra-ham

1
Họ cũng có một api REST và trông khá đẹp: api.geonames.org/ Kẻ
jeudyx 21/07/2015

8
Một ví dụ sẽ là vô giá
Hack-R

GeoNames cũng cung cấp một dịch vụ web miễn phí đơn giản là tuyệt vời!
mcont 7/12/2016

Vào năm 2020, GeoNames.org có vẻ không hoạt động nhiều, có ai biết liệu nó có còn hiện tại không? Vấn đề là không nơi nào họ đề cập đến ngày cập nhật cuối cùng trên trang web.
joedotnot

45

Bạn cần geopy

pip install geopy

và sau đó:

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

print(location.address)

để biết thêm thông tin:

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
Có bất kỳ giới hạn cho cái này? Đây dường như là cách tiếp cận nhanh nhất. Có thể có bất kỳ lý do để không sử dụng điều này trên phương pháp của @ Michael?
Satys

1
tốt, nó đòi hỏi một dịch vụ bên ngoài
maxbachmann

Đó là một cách tiếp cận tuyệt vời, tuy nhiên tôi chỉ cần các quận, vì vậy tôi cần tinh chỉnh địa chỉ. Tôi ước có một cách trả lại các quận.
FHReh Asgarinejad

22

Một thay thế nguồn mở là Nominatim từ Bản đồ đường phố mở. Tất cả bạn phải làm là đặt các biến trong một URL và nó trả về thành phố / quốc gia của vị trí đó. Vui lòng kiểm tra liên kết sau để biết tài liệu chính thức: Nominatim


3
Lưu ý rằng các hoạt động chính sách sử dụng Nominatim.osmfoundation.org/polaho/nominatim nêu tỷ lệ tối đa một yêu cầu mỗi giây vì vậy chỉ thực sự phù hợp cho các truy vấn đặc biệt.
Matthew Wise

22

Tôi đã tìm kiếm một chức năng tương tự và tôi thấy dữ liệu " http://doad.geonames.org/export/dump/ " được chia sẻ trên trả lời trước đó (cảm ơn bạn đã chia sẻ, đây là một nguồn tuyệt vời) và đã triển khai một dịch vụ dựa trên trên dữ liệu city1000.txt.

Bạn có thể thấy nó chạy ở http://scatter-otl.rhcloud.com/location?lat=36&long=-78.9 (liên kết bị hỏng) Chỉ cần thay đổi vĩ độ và kinh độ cho các vị trí của bạn.

Nó được triển khai trên OpenShift (Nền tảng RedHat). Cuộc gọi đầu tiên sau một thời gian nhàn rỗi đôi khi có thể mất thời gian, nhưng thường thì hiệu suất là thỏa đáng. Hãy sử dụng dịch vụ này như bạn muốn ...

Ngoài ra, bạn có thể tìm thấy nguồn dự án tại https://github.com/turgos/Location .


Nó không hoạt động đúng. Nếu nó không thể có được thành phố, nó sẽ tìm kiếm một thành phố được biết đến gần nhất. Dưới đây là một ví dụ: scatter-otl.rhcloud.com/ Từ Nó nói "Basseterre" thay vì "Saint John" ...
smartmouse

1
Đúng rồi. thuật toán tìm kiếm thành phố gần nhất có sẵn trong bộ dữ liệu. Đối với máy chủ được triển khai ở trên, tôi đã sử dụng "thành phố1000.txt". Nó chỉ có các thành phố lớn. Mã nguồn có sẵn tại github.com/turgos/Location . Bạn có thể bắt đầu với dữ liệu chi tiết hơn từ " download.geonames.org/export/dump ".
turgos

Dường như thành phố1000.txt là dữ liệu chi tiết hơn có sẵn. Tôi có đúng không
smartmouse

8

Tôi đã sử dụng Geocoder , một thư viện Python tốt hỗ trợ nhiều nhà cung cấp, bao gồm Google, Geonames và OpenStreetMaps, chỉ đề cập đến một vài . Tôi đã thử sử dụng thư viện GeoPy và nó thường bị hết thời gian. Phát triển mã riêng của bạn cho GeoNames không phải là cách sử dụng tốt nhất thời gian của bạn và cuối cùng bạn có thể nhận được mã không ổn định. Geocoder rất đơn giản để sử dụng theo kinh nghiệm của tôi và có tài liệu đủ tốt . Dưới đây là một số mã mẫu để tìm kiếm thành phố theo vĩ độ và kinh độ hoặc tìm vĩ độ / kinh độ theo tên thành phố.

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

Cảm ơn đã chia sẻ điều này nhưng nó không hoạt động cho tất cả các tọa độ. Số chữ số của tọa độ có cần phải có kích thước cụ thể không?
FHReh Asgarinejad

1
Tôi tin rằng tôi đã chọn kinh độ và vĩ độ chính xác. Tôi có hàng ngàn tọa độ mà tọa độ ngẫu nhiên không hoạt động. Bây giờ thì ổn rồi. Tôi đã sử dụng một phương pháp khác. Cám ơn phản hồi của bạn.
FHReh Asgarinejad

1
Chào mừng bạn Tò mò muốn biết phương pháp nào hiệu quả với bạn? Nếu nó tốt hơn geocoder, tôi cũng muốn thử nó!
Hamman Samuel

1
Tôi đã sử dụng:
FHReh Asgarinejad

1
Cảm ơn, tôi đã làm việc với một bộ dữ liệu lớn và năm 2017, sử dụng GeoPy đã cho tôi nhiều thời gian chờ. Có lẽ 3 năm sau họ đã nới lỏng những hạn chế của mình, vì vậy thật tuyệt khi biết điều đó!
Hamman Samuel

5

Tôi đã dành khoảng 30 phút để cố gắng tìm một ví dụ mã về cách thực hiện điều này trong Javascript. Tôi không thể tìm thấy câu trả lời rõ ràng nhanh chóng cho câu hỏi bạn đã đăng. Vì vậy, ... tôi đã làm cho riêng mình. Hy vọng mọi người có thể sử dụng điều này mà không cần phải đi sâu vào API hoặc nhìn chằm chằm vào mã mà họ không biết cách đọc. Ha nếu không có gì khác tôi có thể tham khảo bài đăng này cho công cụ của riêng tôi .. Câu hỏi hay và cảm ơn cho diễn đàn thảo luận!

Điều này đang sử dụng 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: '/' }); 
                }
        });
    }
}

5

Tôi biết câu hỏi này thực sự cũ, nhưng tôi đã làm việc với cùng một vấn đề và tôi tìm thấy một gói cực kỳ hiệu quả và tiện lợi reverse_geocoder, được xây dựng bởi Ajay Thampi. Mã có sẵn ở đây . Nó dựa trên việc triển khai song song các cây KD cực kỳ hiệu quả với số lượng điểm lớn (tôi mất vài giây để có được 100.000 điểm.

Nó dựa trên cơ sở dữ liệu này , đã được đánh dấu bởi @turgos.

Nếu nhiệm vụ của bạn là nhanh chóng tìm ra quốc gia và thành phố của một danh sách tọa độ thì đây là một công cụ tuyệt vời.


3

Nó thực sự phụ thuộc vào những hạn chế công nghệ bạn có.

Một cách là có một cơ sở dữ liệu không gian với phác thảo về các quốc gia và thành phố mà bạn quan tâm. Theo phác thảo tôi có nghĩa là các quốc gia và thành phố được lưu trữ dưới dạng đa giác loại không gian. Tập hợp tọa độ của bạn có thể được chuyển đổi thành điểm loại không gian và truy vấn đa giác để lấy tên quốc gia / thành phố nơi đặt điểm.

Dưới đây là một số cơ sở dữ liệu hỗ trợ loại không gian: SQL server 2008 , MySQL , postGIS - một phần mở rộng của postgreQuery và Oracle .

Nếu bạn muốn sử dụng một dịch vụ thay vì có cơ sở dữ liệu của riêng bạn, bạn có thể sử dụng GeoPlanet của Yahoo . Đối với phương pháp dịch vụ, bạn có thể muốn xem câu trả lời này trên gis.stackexchange.com , bao gồm sự sẵn có của các dịch vụ để giải quyết vấn đề của bạn.


1

Bạn có thể sử dụng Google Geocoding API

Bellow là hàm php trả về Địa chỉ, Thành phố, Bang và Quốc gia

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

nếu tôi chỉ muốn hành chính_area_level_ 3 hoặc địa phương (nếu hành chính_area_level_ 3 không có sẵn), tôi nên sửa đổi cái nào? mới sử dụng php ..
ngày

1

Loc2country là một công cụ dựa trên Golang trả về mã quốc gia ISO alpha-3 cho tọa độ vị trí đã cho (lat / lon). Nó phản hồi trong vài giây. Nó sử dụng một geohash để bản đồ quốc gia.

Dữ liệu geohash được tạo bằng georaptor .

Chúng tôi sử dụng geohash ở cấp 6 cho công cụ này, tức là các hộp có kích thước 1,2km x 600m.



0

Vui lòng kiểm tra câu trả lời dưới đây. Nó làm việc cho tôi

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

Nếu bạn đang sử dụng API Địa điểm của Google, đây là cách bạn có thể lấy quốc gia và thành phố từ đối tượng địa điểm bằng 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;
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.