我需要一份国家/地区和州名单基于我所拥有的纬度/经度值集合的城市。我需要以保持层次结构并且没有重复的方式存储此信息(例如“USA”和“United States”和“United States of America”是同一个国家;我只想在我的数据库中有一个这个国家的实例)
这可能与Google Map API有关吗?
答案 0 :(得分:128)
您要找的是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还会为地址组件返回相同的名称,尤其是对于国家/地区名称和城市名称等高级名称。不过,请记住,虽然结果对于大多数应用程序来说非常准确,但您仍然可以发现偶尔的拼写错误或模糊结果。
答案 1 :(得分:21)
你有一个基本答案: Get city name using geolocation
但是对于你要找的东西,我会推荐这种方式。
只有你还需要administrative_area_level_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>
答案 2 :(得分:4)
我用这个问题作为我自己解决方案的起点。认为将代码贡献回来是合适的,因为它比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 });
}
答案 3 :(得分:3)
当我把它包含在我的jsp文件中时,我发现GeoCoder javascript有点儿错误。
你也可以试试这个:
orphanRemoval
答案 4 :(得分:3)
我编写了这个函数,根据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
答案 5 :(得分: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) {
});
答案 6 :(得分: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"
}
希望它有所帮助!
答案 7 :(得分:0)
var array = [{ "BITFLYER": { "BTC": { "jpy": {} }, "ETH": { "BTC": {} }, "bch": { "BTC": {} }, "future": { "BTCJPY19JAN2018": {}, "BTCJPY26JAN2018": {} } } }, { "BITSTAMP": { "BTC": { "JPY": {} }, "ETH": { "BTC": {} }, "bch": { "BTC": {} } } } ];
array = JSON.parse(JSON.stringify(array).toUpperCase()).map( object => {
var result = object;
for (key of Object.keys(object)) {
if (typeof key === "string" && object.hasOwnProperty(key)) {
result = {};
result[key.toLowerCase()] = object[key];
}
}
return result;
});
console.log(array);
答案 8 :(得分: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 / 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;
}
});
答案 9 :(得分:0)
最好先将google对象转换为javascript可读对象。
创建如下两个函数,并通过Google Map返回对象调用它。
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"