Nhận tên thành phố bằng cách sử dụng vị trí địa lý


140

Tôi đã quản lý để có được vĩ độ và kinh độ của người dùng bằng cách sử dụng định vị địa lý dựa trên HTML.

//Check if browser supports W3C Geolocation API
if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
} 
//Get latitude and longitude;
function successFunction(position) {
    var lat = position.coords.latitude;
    var long = position.coords.longitude;
}

Tôi muốn hiển thị tên thành phố, có vẻ như cách duy nhất để có được nó là sử dụng API định vị địa lý ngược. Tôi đã đọc tài liệu của Google về định vị địa lý ngược nhưng tôi không biết làm thế nào để có được đầu ra trên trang web của mình.

Tôi không biết cách sử dụng cái này: "http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true"để hiển thị tên thành phố trên trang.

Làm thế nào tôi có thể đạt được điều này?


4
Nếu bạn sẽ không sử dụng bản đồ, bạn CÓ BIẾT rằng điều này trái với ĐKDV của Google không? Điểm 10,4 tại đây developers.google.com/maps/terms Không sử dụng Nội dung mà không có bản đồ Google. Trừ khi Tài liệu API của Bản đồ cho phép bạn làm như vậy, bạn sẽ không sử dụng Nội dung trong Triển khai API của Bản đồ mà không có bản đồ Google tương ứng. Ví dụ: bạn có thể hiển thị hình ảnh Chế độ xem phố mà không có bản đồ Google tương ứng vì Tài liệu API của Bản đồ cho phép sử dụng rõ ràng.
PirateApp

5
Vâng, @PirateApp có một điểm tốt. Có thể có dịch vụ tốt hơn ra khỏi đó. Tôi đã làm việc với SmartyStreets trước đây và tôi biết họ có Điều khoản dịch vụ cởi mở hơn nhiều. Tuy nhiên, hầu hết các dịch vụ không thực hiện mã hóa địa lý ngược. Tôi biết Texas A & M có dịch vụ miễn phí nhưng họ có cảnh báo ĐKDV rằng bạn không thể thu thập dữ liệu về người khác và họ đã gặp vấn đề về thời gian và độ chính xác trước đó.
Joseph Hansen

Câu trả lời:


201

Bạn sẽ làm một cái gì đó như thế bằng Google API.

Xin lưu ý rằng bạn phải bao gồm thư viện google maps để làm việc này. Trình mã hóa địa lý của Google trả về rất nhiều thành phần địa chỉ, do đó bạn phải đưa ra dự đoán có giáo dục về việc ai sẽ có thành phố.

"hành chính_area_level_1" thường là những gì bạn đang tìm kiếm nhưng đôi khi địa phương là thành phố bạn đang theo đuổi.

Dù sao đi nữa - chi tiết hơn về các loại phản hồi của google có thể được tìm thấy ở đâyđây .

Dưới đây là mã nên thực hiện thủ thuật:

<!DOCTYPE html> 
<html> 
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>Reverse Geocoding</title> 

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 
  var geocoder;

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
} 
//Get the latitude and the longitude;
function successFunction(position) {
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
    codeLatLng(lat, lng)
}

function errorFunction(){
    alert("Geocoder failed");
}

  function initialize() {
    geocoder = new google.maps.Geocoder();



  }

  function codeLatLng(lat, lng) {

    var latlng = new google.maps.LatLng(lat, lng);
    geocoder.geocode({'latLng': latlng}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
      console.log(results)
        if (results[1]) {
         //formatted address
         alert(results[0].formatted_address)
        //find country name
             for (var i=0; i<results[0].address_components.length; i++) {
            for (var b=0;b<results[0].address_components[i].types.length;b++) {

            //there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
                if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
                    //this is the object you are looking for
                    city= results[0].address_components[i];
                    break;
                }
            }
        }
        //city data
        alert(city.short_name + " " + city.long_name)


        } else {
          alert("No results found");
        }
      } else {
        alert("Geocoder failed due to: " + status);
      }
    });
  }
</script> 
</head> 
<body onload="initialize()"> 

</body> 
</html> 

3
Không đúng với khu vực quản trị cấp 1, đôi khi tên thành phố không có ở đó. - {"long_name" => "San Francisco", "loại" => ["hành chính_area_level_2", "chính trị"], "short_name" => "San Francisco"}, {"long_name" => "California", "loại "=> [" hành chính_area_level_1 "," chính trị "]," short_name "=>" CA "}, {" long_name "=>" Hoa Kỳ "," loại "=> [" quốc gia "," chính trị "]," short_name "=>" US "}
Ming Tsai

5
Đối với V3, chuỗi {'latlng': latlng} nên được thay đổi thành 'location', như trong ... mã địa lý ({'location': latlng}). Ví dụ này đã cho tôi gần như ở đó, nhưng chuỗi 'latlng' dường như không còn hợp lệ trong apis mới hơn. Xem: developers.google.com/maps/documentation/javascript/ trên để biết chi tiết.
nhị phân

@Michal làm thế nào chúng ta chỉ có thể tìm thấy tên quốc gia hoặc mã quốc gia thay vì địa chỉ đầy đủ?
Ajay

1
@ajay trong kiểm tra câu lệnh if cho "quốc gia" và biến thành phố sẽ trả về dữ liệu quốc gia. Nếu đặt tên lại là country = results [0] .address_components [i] bạn có thể truy cập dữ liệu theo country.long_name và country.short_name
Michal

Có cách nào để thu hẹp điều này xuống các thành phố trong một tỉnh hay chỉ để kiểm tra xem vị trí đó có phải từ tỉnh cụ thể không và liệu người dùng có được chuyển hướng đến một trang web cụ thể không?
Xin lỗiEh

52

Một cách tiếp cận khác là sử dụng dịch vụ của tôi, http://ipinfo.io , trả về tên thành phố, vùng và quốc gia dựa trên địa chỉ IP hiện tại của người dùng. Đây là một ví dụ đơn giản:

$.get("http://ipinfo.io", function(response) {
    console.log(response.city, response.country);
}, "jsonp");

Dưới đây là một ví dụ JSFiddle chi tiết hơn cũng in ra thông tin phản hồi đầy đủ, vì vậy bạn có thể thấy tất cả các chi tiết có sẵn: http://jsfiddle.net/zK5FN/2/


23
Mặc dù không chính xác.
Salman von Abbas

4
Không thể phát hiện thành phố và thậm chí cả trgion từ IP của một nhà cung cấp lớn của Nga: (
Jehy

2
Lol ... điều này mang lại cho ip mạng nội bộ của tôi (192.168 ...)
chính-mann

Tôi có thể làm điều đó từ một trình duyệt thiết bị (cầm tay) không?
Arti

Có vẻ không đáng tin cậy. Tôi đang sử dụng máy tính xách tay và điện thoại di động ngay bây giờ. Các thành phố được hiển thị trong cả hai thiết bị thông qua ipinfo.io cách nhau 530 km!
Ashish Goyalty

52

$.ajax({
  url: "https://geolocation-db.com/jsonp",
  jsonpCallback: "callback",
  dataType: "jsonp",
  success: function(location) {
    $('#country').html(location.country_name);
    $('#state').html(location.state);
    $('#city').html(location.city);
    $('#latitude').html(location.latitude);
    $('#longitude').html(location.longitude);
    $('#ip').html(location.IPv4);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<div>Country: <span id="country"></span></div>
  <div>State: <span id="state"></span></div>
    <div>City: <span id="city"></span></div>
      <div>Latitude: <span id="latitude"></span></div>
        <div>Longitude: <span id="longitude"></span></div>
          <div>IP: <span id="ip"></span></div>

Sử dụng định vị địa lý html5 cần có sự cho phép của người dùng. Trong trường hợp bạn không muốn điều này, hãy tìm một công cụ định vị bên ngoài như https://geolocation-db.com IPv6 được hỗ trợ. Không có giới hạn và yêu cầu không giới hạn cho phép.

Thí dụ

Đối với một ví dụ javascript thuần túy, không sử dụng jQuery, hãy xem câu trả lời này .


17

Bạn có thể lấy tên của thành phố, quốc gia, tên đường phố và các geodata khác bằng API mã hóa địa lý của Google Maps

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>
    <script type="text/javascript">
        navigator.geolocation.getCurrentPosition(success, error);

        function success(position) {
            console.log(position.coords.latitude)
            console.log(position.coords.longitude)

            var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';

            $.getJSON(GEOCODING).done(function(location) {
                console.log(location)
            })

        }

        function error(err) {
            console.log(err)
        }
    </script>
</body>
</html>

và để hiển thị dữ liệu này trên trang bằng jQuery

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>

    <p>Country: <span id="country"></span></p>
    <p>State: <span id="state"></span></p>
    <p>City: <span id="city"></span></p>
    <p>Address: <span id="address"></span></p>

    <p>Latitude: <span id="latitude"></span></p>
    <p>Longitude: <span id="longitude"></span></p>

    <script type="text/javascript">
        navigator.geolocation.getCurrentPosition(success, error);

        function success(position) {

            var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';

            $.getJSON(GEOCODING).done(function(location) {
                $('#country').html(location.results[0].address_components[5].long_name);
                $('#state').html(location.results[0].address_components[4].long_name);
                $('#city').html(location.results[0].address_components[2].long_name);
                $('#address').html(location.results[0].formatted_address);
                $('#latitude').html(position.coords.latitude);
                $('#longitude').html(position.coords.longitude);
            })

        }

        function error(err) {
            console.log(err)
        }
    </script>
</body>
</html>

15

Đây là phiên bản làm việc được cập nhật cho tôi sẽ nhận được Thành phố / Thị trấn, Có vẻ như một số trường được sửa đổi trong phản hồi json. Giới thiệu câu trả lời trước cho câu hỏi này. (Cảm ơn Michal và thêm một tài liệu tham khảo: Liên kết

var geocoder;

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
// Get the latitude and the longitude;
function successFunction(position) {
  var lat = position.coords.latitude;
  var lng = position.coords.longitude;
  codeLatLng(lat, lng);
}

function errorFunction() {
  alert("Geocoder failed");
}

function initialize() {
  geocoder = new google.maps.Geocoder();

}

function codeLatLng(lat, lng) {
  var latlng = new google.maps.LatLng(lat, lng);
  geocoder.geocode({latLng: latlng}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      if (results[1]) {
        var arrAddress = results;
        console.log(results);
        $.each(arrAddress, function(i, address_component) {
          if (address_component.types[0] == "locality") {
            console.log("City: " + address_component.address_components[0].long_name);
            itemLocality = address_component.address_components[0].long_name;
          }
        });
      } else {
        alert("No results found");
      }
    } else {
      alert("Geocoder failed due to: " + status);
    }
  });
}

10

geolocator.js có thể làm điều đó. (Tôi là tác giả).

Lấy tên thành phố (địa chỉ giới hạn)

geolocator.locateByIP(options, function (err, location) {
    console.log(location.address.city);
});

Lấy thông tin địa chỉ đầy đủ

Ví dụ bên dưới trước tiên sẽ thử API vị trí địa lý HTML5 để có được tọa độ chính xác. Nếu thất bại hoặc bị từ chối, nó sẽ chuyển sang tra cứu Geo-IP. Khi nó nhận được tọa độ, nó sẽ đảo ngược mã hóa tọa độ thành một địa chỉ.

var options = {
    enableHighAccuracy: true,
    fallbackToIP: true, // fallback to IP if Geolocation fails or rejected
    addressLookup: true
};
geolocator.locate(options, function (err, location) {
    console.log(location.address.city);
});

Điều này sử dụng Google API bên trong (để tra cứu địa chỉ). Vì vậy, trước cuộc gọi này, bạn nên định cấu hình trình định vị địa lý bằng khóa Google API của mình.

geolocator.config({
    language: "en",
    google: {
        version: "3",
        key: "YOUR-GOOGLE-API-KEY"
    }
});

Geolocator hỗ trợ vị trí địa lý (thông qua tìm kiếm HTML5 hoặc IP), mã hóa địa lý, tra cứu địa chỉ (mã hóa địa lý ngược), khoảng cách và thời lượng, thông tin múi giờ và nhiều tính năng khác ...


6

Sau khi tìm kiếm và ghép một vài giải pháp khác nhau cùng với công cụ của riêng tôi, tôi đã tìm ra chức năng này:

function parse_place(place)
{
    var location = [];

    for (var ac = 0; ac < place.address_components.length; ac++)
    {
        var component = place.address_components[ac];

        switch(component.types[0])
        {
            case 'locality':
                location['city'] = component.long_name;
                break;
            case 'administrative_area_level_1':
                location['state'] = component.long_name;
                break;
            case 'country':
                location['country'] = component.long_name;
                break;
        }
    };

    return location;
}

3

Bạn có thể sử dụng https://ip-api.io/ để lấy Tên thành phố. Nó hỗ trợ IPv6.

Là một phần thưởng, nó cho phép kiểm tra xem địa chỉ IP là nút tor, proxy công cộng hay spammer.

Mã Javascript:

$(document).ready(function () {
        $('#btnGetIpDetail').click(function () {
            if ($('#txtIP').val() == '') {
                alert('IP address is reqired');
                return false;
            }
            $.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
                 function (result) {
                     alert('City Name: ' + result.city)
                     console.log(result);
                 });
        });
    });

Mã HTML

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div>
    <input type="text" id="txtIP" />
    <button id="btnGetIpDetail">Get Location of IP</button>
</div>

Đầu ra JSON

{
    "ip": "64.30.228.118",
    "country_code": "US",
    "country_name": "United States",
    "region_code": "FL",
    "region_name": "Florida",
    "city": "Fort Lauderdale",
    "zip_code": "33309",
    "time_zone": "America/New_York",
    "latitude": 26.1882,
    "longitude": -80.1711,
    "metro_code": 528,
    "suspicious_factors": {
        "is_proxy": false,
        "is_tor_node": false,
        "is_spam": false,
        "is_suspicious": false
    }
}

2

Như @PirateApp đã đề cập trong nhận xét của mình, rõ ràng nó chống lại Cấp phép API của Maps Maps để sử dụng API Maps như bạn dự định.

Bạn có một số lựa chọn thay thế, bao gồm tải xuống cơ sở dữ liệu Geoip và truy vấn nó cục bộ hoặc sử dụng dịch vụ API của bên thứ ba, chẳng hạn như dịch vụ ipdata.co của tôi .

ipdata cung cấp cho bạn vị trí địa lý, tổ chức, tiền tệ, múi giờ, mã gọi, cờ và dữ liệu trạng thái Tor Thoát Node từ bất kỳ địa chỉ IPv4 hoặc IPv6.

Và có thể mở rộng với 10 điểm cuối toàn cầu, mỗi điểm có thể xử lý> 10.000 yêu cầu mỗi giây!

Câu trả lời này sử dụng Khóa API 'kiểm tra' rất hạn chế và chỉ có nghĩa là để thử nghiệm một vài cuộc gọi. Đăng ký Khóa API miễn phí của riêng bạn và nhận tới 1500 yêu cầu hàng ngày để phát triển.

$.get("https://api.ipdata.co?api-key=test", function(response) {
  $("#ip").html("IP: " + response.ip);
  $("#city").html(response.city + ", " + response.region);
  $("#response").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1><a href="https://ipdata.co">ipdata.co</a> - IP geolocation API</h1>

<div id="ip"></div>
<div id="city"></div>
<pre id="response"></pre>

Câu đố; https://jsfiddle.net/ipdata/6wtf0q4g/922/


1

Đây là một hướng đi khác .. Thêm nhiều hơn vào câu trả lời được chấp nhận có thể toàn diện hơn .. tất nhiên khóa chuyển đổi sẽ làm cho nó trông thanh lịch.

function parseGeoLocationResults(result) {
    const parsedResult = {}
    const {address_components} = result;

    for (var i = 0; i < address_components.length; i++) {
        for (var b = 0; b < address_components[i].types.length; b++) {
            if (address_components[i].types[b] == "street_number") {
                //this is the object you are looking for
                parsedResult.street_number = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "route") {
                //this is the object you are looking for
                parsedResult.street_name = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_1") {
                //this is the object you are looking for
                parsedResult.sublocality_level_1 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_2") {
                //this is the object you are looking for
                parsedResult.sublocality_level_2 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "sublocality_level_3") {
                //this is the object you are looking for
                parsedResult.sublocality_level_3 = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "neighborhood") {
                //this is the object you are looking for
                parsedResult.neighborhood = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "locality") {
                //this is the object you are looking for
                parsedResult.city = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "administrative_area_level_1") {
                //this is the object you are looking for
                parsedResult.state = address_components[i].long_name;
                break;
            }

            else if (address_components[i].types[b] == "postal_code") {
                //this is the object you are looking for
                parsedResult.zip = address_components[i].long_name;
                break;
            }
            else if (address_components[i].types[b] == "country") {
                //this is the object you are looking for
                parsedResult.country = address_components[i].long_name;
                break;
            }
        }
    }
    return parsedResult;
}

0

Đây là một chức năng dễ dàng bạn có thể sử dụng để có được nó. Tôi đã sử dụng các axios để thực hiện yêu cầu API, nhưng bạn có thể sử dụng bất cứ thứ gì khác.

async function getCountry(lat, long) {
  const { data: { results } } = await axios.get(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${long}&key=${GOOGLE_API_KEY}`);
  const { address_components } = results[0];

  for (let i = 0; i < address_components.length; i++) {
    const { types, long_name } = address_components[i];

    if (types.indexOf("country") !== -1) return long_name;
  }
}
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.