【问题标题】:Google Maps: how to get country, state/province/region, city given a lat/long value?谷歌地图:如何获得国家、州/省/地区、城市给定的纬度/经度值?
【发布时间】:2011-04-30 03:23:18
【问题描述】:

我需要一个基于我拥有的纬度/经度值集合的国家、州和城市列表。我需要以保留层次结构且不重复的方式存储此信息(例如,“USA”、“United States”和“United States of America”是同一个国家;我只希望我的数据库中有一个该国家的实例) .

这可能与 Google Map API 相关吗?

【问题讨论】:

  • 你有省吗?

标签: google-maps geolocation google-maps-api-3 geocoding


【解决方案1】:

您要查找的内容称为reverse geocoding。 Google 通过Google Geocoding API 提供服务器端反向地理编码服务,您应该可以将其用于您的项目。

以下请求的响应如下所示:

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

回复:

{
  "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[] ...

您还可以选择以 xml 代替 json 接收响应,只需在请求 URI 中将 json 替换为 xml:

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

据我所知,Google 也会为地址组件返回相同的名称,尤其是对于国家名称和城市名称等高级名称。然而,请记住,虽然结果对于大多数应用程序来说都非常准确,但您仍然会发现偶尔的拼写错误或模棱两可的结果。

【讨论】:

  • 谢谢!我拥有的这个纬度/经度集合实际上与我数据库中的用户配置文件相关联。您知道如何实现允许用户在指定位置查找其他用户的搜索功能(例如查找纽约布鲁克林的所有用户)吗?请记住,我所拥有的只是纬度/经度。
  • @StackOverflowNewbie:您可能希望对所有纬度/经度进行反向地理编码,并在数据库中填写“城市”、“州”、“国家”字段。然后只需对数据库中的这些字段进行过滤即可。
  • 或者,如果您使用 MS Sql 2008 并且需要查找某个点附近的位置,您可以使用地理数据类型(如地理)
  • 如何确定响应中城市和国家的索引号?它不断变化,例如,如果某个区域有一个子区域,那么索引键就会改变
  • sensor=false 是做什么的?
【解决方案2】:

你在这里有一个基本的答案: Get city name using geolocation

但是对于你要找的东西,我推荐这种方式。

仅当您还需要管理区域级别 1 时,才能存储美国德克萨斯州巴黎和法国法兰西岛巴黎的不同内容并提供手动后备:

--

Michal 的方式有一个问题,它采用第一个结果,而不是特定的结果。他使用结果[0]。我认为合适的方式(我刚刚修改了他的代码)是只采用类型为“locality”的结果,它始终存在,即使在浏览器不支持地理定位的情况下最终手动回退也是如此。

他的方式:获取的结果与使用不同 http://maps.googleapis.com/maps/api/geocode/json?address=bucharest&sensor=false 比使用 http://maps.googleapis.com/maps/api/geocode/json?latlng=44.42514,26.10540&sensor=false (按名称搜索 / 按 lat&lng 搜索)

这样:获取的结果相同。

<!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> 

【讨论】:

  • 这节省了我的时间
【解决方案3】:

我将此问题作为我自己解决方案的起点。认为回馈我的代码是合适的,因为它比 tabacitu 的要小

依赖关系:

代码:

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

【讨论】:

    【解决方案4】:

    当我将 GeoCoder javascript 包含在我的 jsp 文件中时,我发现它有点错误。

    你也可以试试这个:

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

    【讨论】:

    • 小修小补,把$.get(url).success(function(data)改成$.get(url, function(data)就可以了
    【解决方案5】:

    我编写了这个函数,它根据从 gmaps API 返回的address_components 提取您要查找的内容。这是城市(例如)。

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

    将状态等的 locality 更改为 administrative_area_level_1

    在我的 js 代码中,我是这样使用的:

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

    将返回:Waltham, MA

    【讨论】:

      【解决方案6】:

      试试这段代码,这段代码对我有用

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

      【讨论】:

        【解决方案7】:

        我创建了一个小型映射器函数:

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

        这是 Angular 4 的解决方案,但我想你会明白的。

        用法:

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

        这样address 对象将是这样的:

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

        希望对您有所帮助!

        【讨论】:

          【解决方案8】:
           <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>
          

          【讨论】:

            【解决方案9】:

            @Szkíta 通过创建一个函数来获取命名数组中的地址部分,这是一个很好的解决方案。对于那些想要使用纯 JavaScript 的人来说,这是一个编译好的解决方案。

            将结果转换为命名数组的功能:

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

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

            【讨论】:

              【解决方案10】:

              最好先将google对象转换为javascript可读对象。

              创建如下两个函数并调用它传递谷歌地图返回对象。

              function getShortAddressObject(object) {
                           let address = {};
                           const address_components = object[0].address_components;
                           address_components.forEach(element => {
                               address[element.types[0]] = element.short_name;
                           });
                           return address;
               }
              
               function getLongAddressObject(object) {
                           let address = {};
                           const address_components = object[0].address_components;
                           address_components.forEach(element => {
                               address[element.types[0]] = element.long_name;
                           });
                           return address;
               }
              

              然后用户可以访问如下名称。

              var addressObj = getLongAddressObject(object);
              var country = addressObj.country; //Sri Lanka
              

              所有地址部分如下。

              administrative_area_level_1: "Western Province"
              administrative_area_level_2: "Colombo"
              country: "Sri Lanka"
              locality: "xxxx xxxxx"
              political: "xxxxx"
              route: "xxxxx - xxxxx Road"
              street_number: "No:00000"
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-06-24
                • 2014-06-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-11-05
                相关资源
                最近更新 更多