Google Maps: как получить страну, штат/провинцию/регион, город, учитывая значение lat/long?
Мне нужен список стран, штатов и городов, основанный на коллекции значений lat/long, которые у меня есть. Мне нужно сохранить эту информацию таким образом, чтобы иерархия сохранялась и без дубликатов (например, "США" и "Соединенные Штаты" и "Соединенные Штаты Америки" были одной и той же страной, и я хочу только один экземпляр этой страны в моей базе данных).
Возможно ли это с Google Map API?
Ответы
Ответ 1
То, что вы ищете, называется обратным геокодированием. 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 также будет возвращать одно и то же имя для адресных компонентов, особенно для имен высокого уровня, таких как названия стран и названия городов. Тем не менее, имейте в виду, что, хотя результаты очень точны для большинства приложений, вы все равно можете найти случайную орфографическую ошибку или двусмысленный результат.
Ответ 2
У вас есть основной ответ здесь:
Получить название города с использованием геолокации
Но для чего вы ищите, я бы рекомендовал этот путь.
Только если вам также понадобится 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
(поиск по имени/поиску по 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 = 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
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
Я обнаружил, что JavaScript-код 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);
});
Ответ 5
Я написал эту функцию, которая извлекает то, что вы ищете, на основе 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
Ответ 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
Я создал небольшую функцию mapper:
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"
}
Надеюсь, это поможет!