Карти Google: як отримати країну, штат / провінцію / регіон, місто, отримане значення lat / long?


107

Мені потрібен список країн, штатів та міст на основі колекції Lat / long значень, які я маю. Мені потрібно зберігати цю інформацію таким чином, щоб ієрархія зберігалася і без дублікатів (наприклад, "США" та "Сполучені Штати" та "Сполучені Штати Америки" - одна і та ж країна; я хочу лише один екземпляр цієї країни у своїй базі даних) .

Чи можливо це зробити з API Google Map?


Ви отримали провінцію?
Діпак Доліян

Відповіді:


135

Те, що ви шукаєте, називається зворотним геокодуванням . Google надає сервер зворотного геокодування з боку сервера через API геокодування Google , який ви повинні мати можливість використовувати для свого проекту.

Ось як виглядатиме відповідь на такий запит:

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, просто замінивши json на xml у URI запиту:

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

Наскільки мені відомо, Google також поверне те саме ім’я для адресних компонентів, особливо для імен високого рівня, таких як назви країн та назви міст. Проте майте на увазі, що, хоча результати для більшості застосунків дуже точні, ви все ще можете виявити випадкові орфографічні помилки або неоднозначний результат.


Дякую! Ця колекція lat / long у мене фактично пов'язана з профілями користувачів у моїй базі даних. Чи знаєте ви, як я можу реалізувати функцію пошуку, яка дозволить користувачам знаходити інших користувачів у визначеному місці (наприклад, знайти всіх користувачів у Брукліні, Нью-Йорк)? Пам'ятайте, все, що я маю, - це лат / довго.
StackOverflowNewbie

1
@StackOverflowNewbie: Ви можете скасувати геокодування всіх ваших лат / довголінь і заповнити поля "місто", "держава", "країна" у вашій базі даних. Потім просто зробіть фільтр за цими полями у вашій базі даних.
Даніель Вассалло

1
Або ви можете використовувати просторовий тип даних, наприклад географічний, якщо ви
подаєте

1
Як ви можете бути впевнені в індексній кількості міста та країни у відповіді? Це змінюється, наприклад, якщо в якійсь області є піддіапазон, то змінюються індексні клавіші
Хан Шахрух,

4
що робить sensor=false?
CENT1PEDE

21

Тут ви маєте основну відповідь: Отримайте назву міста за допомогою геолокації

Але для того, що ви шукаєте, я рекомендував би такий спосіб.

Тільки якщо вам також потрібен administrator_area_level_1, щоб зберігати різні речі для Парижа, Техасу, США та Парижа, Іль-де-Франс, Франція та надавати вручну резервну копію:

-

У Міхала є проблема, що вона бере перший результат, а не конкретний. Він використовує результати [0]. Те, як я вважаю за потрібне (я щойно змінив його код), - це ТОЛЬКО взяти результат, тип якого - "локальність", який завжди присутній, навіть у можливій ручній резерві, якщо браузер не підтримує геолокацію.

Його спосіб: отримані результати відрізняються від використання 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 (пошук за іменем / пошук за лат & 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> 

Це рятує мій день
Andi AR

4

Я використав це питання як вихідну точку для власного рішення. Думав, що доречно внести свій код назад, оскільки його менше, ніж табациту

Залежності:

Код:

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

Я знайшов jacode GeoCoder трохи баггі, коли включив його у свої 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)і це добре працює
Precious Том

3

Я написав цю функцію, яка витягує те, що ви шукаєте, на основі address_componentsповернутого з API gmaps. Це місто (наприклад).

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


0

Просто спробуйте цей код, цей код працює зі мною

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

Я створив невелику функцію картографування:

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

Сподіваюся, це допомагає!


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 Мав чудове рішення, створивши функцію, яка отримує частини адреси у названому масиві. Ось складене рішення для тих, хто хоче використовувати звичайний JavaScript.

Функція для перетворення результатів у названий масив:

function getAddressParts(obj) {

    var address = [];

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

    return address;

} //getAddressParts()

Геокодування значень LAT / СПГ:

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

});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.