Google Maps: làm thế nào để lấy quốc gia, tiểu bang / tỉnh / khu vực, thành phố cho một giá trị vĩ độ / kinh độ?


107

Tôi cần danh sách các quốc gia, tiểu bang và thành phố dựa trên tập hợp các giá trị vĩ độ / kinh độ mà tôi có. Tôi cần lưu trữ thông tin này theo cách mà hệ thống phân cấp được bảo toàn và không trùng lặp (ví dụ: "Hoa Kỳ" và "Hoa Kỳ" và "Hợp chủng quốc Hoa Kỳ" là cùng một quốc gia; tôi chỉ muốn một trường hợp của quốc gia này trong cơ sở dữ liệu của mình) .

Điều này có thể làm được với API Google Map không?


Bạn đã nhận được tỉnh?
Deepak Dholiyan

Câu trả lời:


135

Những gì bạn đang tìm kiếm được gọi là mã hóa địa lý ngược . Google cung cấp dịch vụ mã hóa địa lý ngược phía máy chủ thông qua API mã hóa địa lý của Google mà bạn có thể sử dụng cho dự án của mình.

Đây là cách phản hồi cho yêu cầu sau sẽ trông như thế nào:

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

Phản ứng:

{
  "status": "OK",
  "results": [ {
    "types": [ "street_address" ],
    "formatted_address": "275-291 Bedford Ave, Brooklyn, NY 11211, USA",
    "address_components": [ {
      "long_name": "275-291",
      "short_name": "275-291",
      "types": [ "street_number" ]
    }, {
      "long_name": "Bedford Ave",
      "short_name": "Bedford Ave",
      "types": [ "route" ]
    }, {
      "long_name": "New York",
      "short_name": "New York",
      "types": [ "locality", "political" ]
    }, {
      "long_name": "Brooklyn",
      "short_name": "Brooklyn",
      "types": [ "administrative_area_level_3", "political" ]
    }, {
      "long_name": "Kings",
      "short_name": "Kings",
      "types": [ "administrative_area_level_2", "political" ]
    }, {
      "long_name": "New York",
      "short_name": "NY",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "United States",
      "short_name": "US",
      "types": [ "country", "political" ]
    }, {
      "long_name": "11211",
      "short_name": "11211",
      "types": [ "postal_code" ]
    } ],
    "geometry": {
      "location": {
        "lat": 40.7142298,
        "lng": -73.9614669
      },
      "location_type": "RANGE_INTERPOLATED",
      "viewport": {
        "southwest": {
          "lat": 40.7110822,
          "lng": -73.9646145
        },
        "northeast": {
          "lat": 40.7173774,
          "lng": -73.9583193
        }
      }
    }
  },

  ... Additional results[] ...

Bạn cũng có thể chọn nhận phản hồi trong xml thay vì json, bằng cách chỉ cần thay thế json cho xml trong URI yêu cầu:

http://maps.googleapis.com/maps/api/geocode/xml?latlng=40.714224,-73.961452&sensor=false

Theo như tôi biết, Google cũng sẽ trả lại tên tương tự cho các thành phần địa chỉ, đặc biệt là đối với các tên cấp cao như tên quốc gia và tên thành phố. Tuy nhiên, hãy nhớ rằng mặc dù kết quả rất chính xác cho hầu hết các ứng dụng, bạn vẫn có thể tìm thấy lỗi chính tả không thường xuyên hoặc kết quả không rõ ràng.


Cảm ơn! Bộ sưu tập vĩ độ / thời gian tôi có thực sự được liên kết với hồ sơ người dùng trong cơ sở dữ liệu của tôi. Bạn có biết làm cách nào để tôi có thể triển khai tính năng tìm kiếm cho phép người dùng tìm thấy những người dùng khác trong một vị trí cụ thể (ví dụ: tìm tất cả người dùng ở Brooklyn, NY)? Hãy nhớ rằng, tất cả những gì tôi có là vĩ độ / kinh độ.
StackOverflowNewbie

1
@StackOverflowNewbie: Bạn có thể muốn đảo ngược mã hóa địa lý tất cả vĩ độ / kinh độ của mình và điền vào các trường "thành phố", "tiểu bang", "quốc gia" trong cơ sở dữ liệu của mình. Sau đó, chỉ cần thực hiện một bộ lọc trên các trường này trong cơ sở dữ liệu của bạn.
Daniel Vassallo

1
Hoặc bạn có thể sử dụng kiểu dữ liệu không gian như địa lý nếu bạn đang khởi kiện MS Sql 2008 và cần tìm vị trí gần một điểm
GibboK

1
Làm thế nào bạn có thể chắc chắn về số chỉ mục của thành phố và quốc gia trong phản hồi? Nó tiếp tục thay đổi, ví dụ như nếu một số khu vực có diện tích phụ sau đó các phím chỉ số thay đổi
Khan Shahrukh

4
những gì sensor=falselàm gì?
CENT1PEDE

21

Bạn có câu trả lời cơ bản ở đây: Nhận tên thành phố bằng cách sử dụng vị trí địa lý

Nhưng đối với những gì bạn đang tìm kiếm, tôi khuyên bạn nên sử dụng cách này.

Chỉ khi bạn cũng cần management_area_level_1, để lưu trữ những thứ khác nhau cho Paris, Texas, Hoa Kỳ và Paris, Ile-de-France, Pháp và cung cấp dự phòng thủ công:

-

Có một vấn đề theo cách của Michal, đó là nó lấy kết quả đầu tiên, không phải một kết quả cụ thể. Anh ấy sử dụng kết quả [0]. Cách tôi thấy phù hợp (tôi vừa sửa đổi mã của anh ấy) là CHỈ lấy kết quả có kiểu là "địa phương", luôn hiện diện, ngay cả trong dự phòng thủ công cuối cùng trong trường hợp trình duyệt không hỗ trợ định vị địa lý.

Cách của anh ấy: kết quả được tìm nạp khác với việc sử dụng http://maps.googleapis.com/maps/api/geocode/json?address=bucharest&sensor=false so với việc sử dụng http://maps.googleapis.com/maps/api/geocode /json?latlng=44.42514,26.10540&sensor=false (tìm kiếm theo tên / tìm kiếm theo lat & lng)

Theo cách này: kết quả tìm nạp giống nhau.

<!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]) {
        var indice=0;
        for (var j=0; j<results.length; j++)
        {
            if (results[j].types[0]=='locality')
                {
                    indice=j;
                    break;
                }
            }
        alert('The good number is: '+j);
        console.log(results[j]);
        for (var i=0; i<results[j].address_components.length; i++)
            {
                if (results[j].address_components[i].types[0] == "locality") {
                        //this is the object you are looking for City
                        city = results[j].address_components[i];
                    }
                if (results[j].address_components[i].types[0] == "administrative_area_level_1") {
                        //this is the object you are looking for State
                        region = results[j].address_components[i];
                    }
                if (results[j].address_components[i].types[0] == "country") {
                        //this is the object you are looking for
                        country = results[j].address_components[i];
                    }
            }

            //city data
            alert(city.long_name + " || " + region.long_name + " || " + country.short_name)


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

</body> 
</html> 

Điều này tiết kiệm ngày của tôi
Andi AR

4

Tôi đã sử dụng câu hỏi này như một điểm khởi đầu cho giải pháp của riêng tôi. Tôi nghĩ rằng nó là thích hợp để đóng góp mã của tôi trở lại vì nó nhỏ hơn tabacitu của

Sự phụ thuộc:

Mã:

if(geoPosition.init()){  

    var foundLocation = function(city, state, country, lat, lon){
        //do stuff with your location! any of the first 3 args may be null
        console.log(arguments);
    }

    var geocoder = new google.maps.Geocoder(); 
    geoPosition.getCurrentPosition(function(r){
        var findResult = function(results, name){
            var result =  _.find(results, function(obj){
                return obj.types[0] == name && obj.types[1] == "political";
            });
            return result ? result.short_name : null;
        };
        geocoder.geocode({'latLng': new google.maps.LatLng(r.coords.latitude, r.coords.longitude)}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK && results.length) {
                results = results[0].address_components;
                var city = findResult(results, "locality");
                var state = findResult(results, "administrative_area_level_1");
                var country = findResult(results, "country");
                foundLocation(city, state, country, r.coords.latitude, r.coords.longitude);
            } else {
                foundLocation(null, null, null, r.coords.latitude, r.coords.longitude);
            }
        });
    }, { enableHighAccuracy:false, maximumAge: 1000 * 60 * 1 });
}

3

Tôi thấy javascript GeoCoder có một chút lỗi khi tôi đưa nó vào các tệp jsp của mình.

Bạn cũng có thể thử điều này:



    var lat = "43.7667855" ;
    var long = "-79.2157321" ;
    var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng="
       +lat+","+long+"&sensor=false";
    $.get(url).success(function(data) {
       var loc1 = data.results[0];
       var county, city;
         $.each(loc1, function(k1,v1) {
            if (k1 == "address_components") {
               for (var i = 0; i < v1.length; i++) {
                  for (k2 in v1[i]) {
                     if (k2 == "types") {
                        var types = v1[i][k2];
                        if (types[0] =="sublocality_level_1") {
                            county = v1[i].long_name;
                            //alert ("county: " + county);
                        } 
                        if (types[0] =="locality") {
                           city = v1[i].long_name;
                           //alert ("city: " + city);
                       } 
                     }

                  }          

               }

            }

         });
         $('#city').html(city); 
    }); 


Một sửa chữa nhỏ, thay đổi $.get(url).success(function(data)đến $.get(url, function(data)và nó làm việc tốt
Precious Tom

3

Tôi đã viết hàm này trích xuất những gì bạn đang tìm kiếm dựa trên kết quả address_componentstrả về từ API gmaps. Đây là thành phố (ví dụ).

export const getAddressCity = (address, length) => {
  const findType = type => type.types[0] === "locality"
  const location = address.map(obj => obj)
  const rr = location.filter(findType)[0]

  return (
    length === 'short'
      ? rr.short_name
      : rr.long_name
  )
}

Đổi localitythành administrative_area_level_1cho Bang, v.v.

Trong mã js của tôi, tôi đang sử dụng như vậy:

const location =`${getAddressCity(address_components, 'short')}, ${getAddressState(address_components, 'short')}`

Sẽ trở lại: Waltham, MA


0

Chỉ cần thử mã này mã này hoạt động với tôi

var posOptions = {timeout: 10000, enableHighAccuracy: false};
$cordovaGeolocation.getCurrentPosition(posOptions).then(function (position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
 //console.log(lat +"          "+long);
$http.get('https://maps.googleapis.com/maps/api/geocode/json?latlng=' + lat + ',' + long + '&key=your key here').success(function (output) {
//console.log( JSON.stringify(output.results[0]));
//console.log( JSON.stringify(output.results[0].address_components[4].short_name));
var results = output.results;
if (results[0]) {
//console.log("results.length= "+results.length);
//console.log("hi "+JSON.stringify(results[0],null,4));
for (var j = 0; j < results.length; j++){
 //console.log("j= "+j);
//console.log(JSON.stringify(results[j],null,4));
for (var i = 0; i < results[j].address_components.length; i++){
 if(results[j].address_components[i].types[0] == "country") {
 //this is the object you are looking for
  country = results[j].address_components[i];
 }
 }
 }
 console.log(country.long_name);
 console.log(country.short_name);
 } else {
 alert("No results found");
 console.log("No results found");
 }
 });
 }, function (err) {
 });

0

Tôi đã tạo một hàm ánh xạ nhỏ:

private getAddressParts(object): Object {
    let address = {};
    const address_components = object.address_components;
    address_components.forEach(element => {
        address[element.types[0]] = element.short_name;
    });
    return address;
}

Đó là một giải pháp cho Angular 4 nhưng tôi nghĩ bạn sẽ hiểu.

Sử dụng:

geocoder.geocode({ 'location' : latlng }, (results, status) => {
    if (status === google.maps.GeocoderStatus.OK) {
        const address = {
            formatted_address: results[0].formatted_address,
            address_parts: this.getAddressParts(results[0])
        };
        (....)
    }

Bằng cách này, addressđối tượng sẽ giống như sau:

address: {
    address_parts: {
        administrative_area_level_1: "NY",
        administrative_area_level_2: "New York County",
        country: "US",
        locality: "New York",
        neighborhood: "Lower Manhattan",
        political: "Manhattan",
        postal_code: "10038",
        route: "Beekman St",
        street_number: "90",
    },
    formatted_address: "90 Beekman St, New York, NY 10038, USA"
}

Hy vọng nó giúp!


0
 <div id="location"></div>
        <script>
            window.onload = function () {
                var startPos;
                var geoOptions = {
                    maximumAge: 5 * 60 * 1000,
                    timeout: 10 * 1000,
                    enableHighAccuracy: true
                }


                var geoSuccess = function (position) {
                    startPos = position;
                    geocodeLatLng(startPos.coords.latitude, startPos.coords.longitude);

                };
                var geoError = function (error) {
                    console.log('Error occurred. Error code: ' + error.code);
                    // error.code can be:
                    //   0: unknown error
                    //   1: permission denied
                    //   2: position unavailable (error response from location provider)
                    //   3: timed out
                };

                navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
            };
            function geocodeLatLng(lat, lng) {
                var geocoder = new google.maps.Geocoder;
                var latlng = {lat: parseFloat(lat), lng: parseFloat(lng)};
                geocoder.geocode({'location': latlng}, function (results, status) {
                    if (status === 'OK') {
                        console.log(results)
                        if (results[0]) {
                            document.getElementById('location').innerHTML = results[0].formatted_address;
                            var street = "";
                            var city = "";
                            var state = "";
                            var country = "";
                            var zipcode = "";
                            for (var i = 0; i < results.length; i++) {
                                if (results[i].types[0] === "locality") {
                                    city = results[i].address_components[0].long_name;
                                    state = results[i].address_components[2].long_name;

                                }
                                if (results[i].types[0] === "postal_code" && zipcode == "") {
                                    zipcode = results[i].address_components[0].long_name;

                                }
                                if (results[i].types[0] === "country") {
                                    country = results[i].address_components[0].long_name;

                                }
                                if (results[i].types[0] === "route" && street == "") {

                                    for (var j = 0; j < 4; j++) {
                                        if (j == 0) {
                                            street = results[i].address_components[j].long_name;
                                        } else {
                                            street += ", " + results[i].address_components[j].long_name;
                                        }
                                    }

                                }
                                if (results[i].types[0] === "street_address") {
                                    for (var j = 0; j < 4; j++) {
                                        if (j == 0) {
                                            street = results[i].address_components[j].long_name;
                                        } else {
                                            street += ", " + results[i].address_components[j].long_name;
                                        }
                                    }

                                }
                            }
                            if (zipcode == "") {
                                if (typeof results[0].address_components[8] !== 'undefined') {
                                    zipcode = results[0].address_components[8].long_name;
                                }
                            }
                            if (country == "") {
                                if (typeof results[0].address_components[7] !== 'undefined') {
                                    country = results[0].address_components[7].long_name;
                                }
                            }
                            if (state == "") {
                                if (typeof results[0].address_components[6] !== 'undefined') {
                                    state = results[0].address_components[6].long_name;
                                }
                            }
                            if (city == "") {
                                if (typeof results[0].address_components[5] !== 'undefined') {
                                    city = results[0].address_components[5].long_name;
                                }
                            }

                            var address = {
                                "street": street,
                                "city": city,
                                "state": state,
                                "country": country,
                                "zipcode": zipcode,
                            };

                            document.getElementById('location').innerHTML = document.getElementById('location').innerHTML + "<br/>Street : " + address.street + "<br/>City : " + address.city + "<br/>State : " + address.state + "<br/>Country : " + address.country + "<br/>zipcode : " + address.zipcode;
                            console.log(address);
                        } else {
                            window.alert('No results found');
                        }
                    } else {
                        window.alert('Geocoder failed due to: ' + status);
                    }
                });
            }
        </script>

        <script async defer
                src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY">
        </script>

0

@ Szkíta Có một giải pháp tuyệt vời bằng cách tạo một hàm nhận các phần địa chỉ trong một mảng đã đặt tên. Đây là một giải pháp đã biên dịch cho những ai muốn sử dụng JavaScript đơn giản.

Hàm chuyển đổi kết quả thành mảng đã đặt tên:

function getAddressParts(obj) {

    var address = [];

    obj.address_components.forEach( function(el) {
        address[el.types[0]] = el.short_name;
    });

    return address;

} //getAddressParts()

Mã hóa địa lý các giá trị LAT / LNG:

geocoder.geocode( { 'location' : latlng }, function(results, status) {

    if (status == google.maps.GeocoderStatus.OK) {
        var addressParts =  getAddressParts(results[0]);

        // the city
        var city = addressParts.locality;

        // the state
        var state = addressParts.administrative_area_level_1;
    }

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