Javascript 使用地理位置获取城市名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6797569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get city name using geolocation
提问by lisovaccaro
I managed to get the user's latitude and longitude using HTML-based geolocation.
我设法使用基于 HTML 的地理定位来获取用户的纬度和经度。
//Check if browser supports W3C Geolocation API
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
//Get latitude and longitude;
function successFunction(position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
}
I want to display the city name, it seems the only way to get it is to use a reverse geolocation API. I read Google's documentation for reverse geolocation but I don't know how to get the output on my site.
我想显示城市名称,似乎获得它的唯一方法是使用反向地理定位 API。我阅读了 Google 的反向地理定位文档,但我不知道如何在我的网站上获取输出。
I don't know how to go use this: "http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true"
to display the city name on the page.
我不知道如何使用这个:"http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true"
在页面上显示城市名称。
How can I achieve this?
我怎样才能做到这一点?
回答by Michal
You would do something like that using Google API.
您可以使用 Google API 做类似的事情。
Please note you must include the google maps library for this to work. Google geocoder returns a lot of address components so you must make an educated guess as to which one will have the city.
请注意,您必须包含谷歌地图库才能使其正常工作。Google 地理编码器会返回许多地址组件,因此您必须对哪个将拥有该城市进行有根据的猜测。
"administrative_area_level_1"is usually what you are looking for but sometimes locality is the city you are after.
“administrative_area_level_1”通常是您正在寻找的,但有时locality 是您所追求的城市。
Anyhow - more details on google response types can be found hereand here.
无论如何 - 可以在此处和此处找到有关 google 响应类型的更多详细信息。
Below is the code that should do the trick:
以下是应该可以解决问题的代码:
<!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]) {
//formatted address
alert(results[0].formatted_address)
//find country name
for (var i=0; i<results[0].address_components.length; i++) {
for (var b=0;b<results[0].address_components[i].types.length;b++) {
//there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
//this is the object you are looking for
city= results[0].address_components[i];
break;
}
}
}
//city data
alert(city.short_name + " " + city.long_name)
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
</script>
</head>
<body onload="initialize()">
</body>
</html>
回答by Ben Dowling
Another approach to this is to use my service, http://ipinfo.io, which returns the city, region and country name based on the user's current IP address. Here's a simple example:
另一种方法是使用我的服务http://ipinfo.io,它根据用户当前的 IP 地址返回城市、地区和国家/地区名称。这是一个简单的例子:
$.get("http://ipinfo.io", function(response) {
console.log(response.city, response.country);
}, "jsonp");
Here's a more detailed JSFiddle example that also prints out the full response information, so you can see all of the available details: http://jsfiddle.net/zK5FN/2/
这是一个更详细的 JSFiddle 示例,它也打印出完整的响应信息,因此您可以查看所有可用的详细信息:http: //jsfiddle.net/zK5FN/2/
回答by Kurt Van den Branden
$.ajax({
url: "https://geolocation-db.com/jsonp",
jsonpCallback: "callback",
dataType: "jsonp",
success: function(location) {
$('#country').html(location.country_name);
$('#state').html(location.state);
$('#city').html(location.city);
$('#latitude').html(location.latitude);
$('#longitude').html(location.longitude);
$('#ip').html(location.IPv4);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div>Country: <span id="country"></span></div>
<div>State: <span id="state"></span></div>
<div>City: <span id="city"></span></div>
<div>Latitude: <span id="latitude"></span></div>
<div>Longitude: <span id="longitude"></span></div>
<div>IP: <span id="ip"></span></div>
Using html5 geolocation requires user permission. In case you don't want this, go for an external locator like https://geolocation-db.comIPv6 is supported. No restrictions and unlimited requests allowed.
使用 html5 地理定位需要用户许可。如果您不想要这个,请使用像https://geolocation-db.com这样的外部定位器支持 IPv6。没有限制和无限制的请求。
Example
例子
For a pure javascript example, without using jQuery, check out thisanswer.
对于不使用 jQuery 的纯 javascript 示例,请查看此答案。
回答by Mikhail
You can get the name of the city, country, street name and other geodata using the Google Maps Geocoding API
您可以使用 Google Maps Geocoding API 获取城市名称、国家名称、街道名称和其他地理数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>
<script type="text/javascript">
navigator.geolocation.getCurrentPosition(success, error);
function success(position) {
console.log(position.coords.latitude)
console.log(position.coords.longitude)
var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';
$.getJSON(GEOCODING).done(function(location) {
console.log(location)
})
}
function error(err) {
console.log(err)
}
</script>
</body>
</html>
and to display this data on the page using jQuery
并使用 jQuery 在页面上显示此数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.js"></script>
</head>
<body>
<p>Country: <span id="country"></span></p>
<p>State: <span id="state"></span></p>
<p>City: <span id="city"></span></p>
<p>Address: <span id="address"></span></p>
<p>Latitude: <span id="latitude"></span></p>
<p>Longitude: <span id="longitude"></span></p>
<script type="text/javascript">
navigator.geolocation.getCurrentPosition(success, error);
function success(position) {
var GEOCODING = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' + position.coords.latitude + '%2C' + position.coords.longitude + '&language=en';
$.getJSON(GEOCODING).done(function(location) {
$('#country').html(location.results[0].address_components[5].long_name);
$('#state').html(location.results[0].address_components[4].long_name);
$('#city').html(location.results[0].address_components[2].long_name);
$('#address').html(location.results[0].formatted_address);
$('#latitude').html(position.coords.latitude);
$('#longitude').html(position.coords.longitude);
})
}
function error(err) {
console.log(err)
}
</script>
</body>
</html>
回答by Pradeep
Here is updated working version for me which will get City/Town, It looks like some fields are modified in the json response. Referring previous answers for this questions. ( Thanks to Michal & one more reference : Link
这是我更新的工作版本,它将获得城市/城镇,看起来有些字段在 json 响应中被修改了。参考以前对这个问题的回答。(感谢 Michal 和另外一个参考:链接
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) {
if (results[1]) {
var arrAddress = results;
console.log(results);
$.each(arrAddress, function(i, address_component) {
if (address_component.types[0] == "locality") {
console.log("City: " + address_component.address_components[0].long_name);
itemLocality = address_component.address_components[0].long_name;
}
});
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
回答by Onur Y?ld?r?m
geolocator.jscan do that. (I'm the author).
geolocator.js可以做到这一点。(我是作者)。
Getting City Name (Limited Address)
获取城市名称(有限地址)
geolocator.locateByIP(options, function (err, location) {
console.log(location.address.city);
});
Getting Full Address Information
获取完整地址信息
Example below will first try HTML5 Geolocation API to obtain the exact coordinates. If fails or rejected, it will fallback to Geo-IP look-up. Once it gets the coordinates, it will reverse-geocode the coordinates into an address.
下面的示例将首先尝试 HTML5 Geolocation API 来获取准确的坐标。如果失败或被拒绝,它将回退到 Geo-IP 查找。一旦获得坐标,它就会将坐标反向地理编码为地址。
var options = {
enableHighAccuracy: true,
fallbackToIP: true, // fallback to IP if Geolocation fails or rejected
addressLookup: true
};
geolocator.locate(options, function (err, location) {
console.log(location.address.city);
});
This uses Google APIs internally (for address lookup). So before this call, you should configure geolocator with your Google API key.
这在内部使用 Google API(用于地址查找)。因此,在此调用之前,您应该使用您的 Google API 密钥配置 geolocator。
geolocator.config({
language: "en",
google: {
version: "3",
key: "YOUR-GOOGLE-API-KEY"
}
});
Geolocatorsupports geo-location (via HTML5 or IP lookups), geocoding, address look-ups (reverse geocoding), distance & durations, timezone information and a lot more features...
Geolocator支持地理定位(通过 HTML5 或 IP 查找)、地理编码、地址查找(反向地理编码)、距离和持续时间、时区信息以及更多功能......
回答by Jafo
After some searching and piecing together a couple of different solutions along with my own stuff, I came up with this function:
经过一番搜索并将几个不同的解决方案与我自己的东西拼凑在一起后,我想出了这个函数:
function parse_place(place)
{
var location = [];
for (var ac = 0; ac < place.address_components.length; ac++)
{
var component = place.address_components[ac];
switch(component.types[0])
{
case 'locality':
location['city'] = component.long_name;
break;
case 'administrative_area_level_1':
location['state'] = component.long_name;
break;
case 'country':
location['country'] = component.long_name;
break;
}
};
return location;
}
回答by Vindhyachal Kumar
You can use https://ip-api.io/to get city Name. It supports IPv6.
您可以使用https://ip-api.io/获取城市名称。它支持 IPv6。
As a bonus it allows to check whether ip address is a tor node, public proxy or spammer.
作为奖励,它允许检查 IP 地址是 Tor 节点、公共代理还是垃圾邮件发送者。
Javascript Code:
Javascript代码:
$(document).ready(function () {
$('#btnGetIpDetail').click(function () {
if ($('#txtIP').val() == '') {
alert('IP address is reqired');
return false;
}
$.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
function (result) {
alert('City Name: ' + result.city)
console.log(result);
});
});
});
HTML Code
HTML代码
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div>
<input type="text" id="txtIP" />
<button id="btnGetIpDetail">Get Location of IP</button>
</div>
JSON Output
JSON 输出
{
"ip": "64.30.228.118",
"country_code": "US",
"country_name": "United States",
"region_code": "FL",
"region_name": "Florida",
"city": "Fort Lauderdale",
"zip_code": "33309",
"time_zone": "America/New_York",
"latitude": 26.1882,
"longitude": -80.1711,
"metro_code": 528,
"suspicious_factors": {
"is_proxy": false,
"is_tor_node": false,
"is_spam": false,
"is_suspicious": false
}
}
回答by Jonathan
As @PirateApp mentioned in his comment, it's explicitly against Google's Maps API Licensing to use the Maps API as you intend.
正如@PirateApp 在他的评论中提到的那样,按照您的意图使用 Maps API 明确违反了 Google 的 Maps API 许可。
You have a number of alternatives, including downloading a Geoip database and querying it locally or using a third party API service, such as my service ipdata.co.
您有多种选择,包括下载 Geoip 数据库并在本地查询或使用第三方 API 服务,例如我的服务ipdata.co。
ipdata gives you the geolocation, organisation, currency, timezone, calling code, flag and Tor Exit Node status data from any IPv4 or IPv6 address.
ipdata 为您提供来自任何 IPv4 或 IPv6 地址的地理位置、组织、货币、时区、调用代码、标志和 Tor 退出节点状态数据。
And is scalable with 10 global endpoints each able to handle >10,000 requests per second!
并且可扩展,具有 10 个全局端点,每个端点每秒能够处理 >10,000 个请求!
This answer uses a 'test' API Key that is very limited and only meant for testing a few calls. Signup for your own Free API Key and get up to 1500 requests daily for development.
这个答案使用了一个非常有限的“测试”API 密钥,仅用于测试几个调用。注册您自己的免费 API 密钥,每天最多可收到 1500 个开发请求。
$.get("https://api.ipdata.co?api-key=test", function(response) {
$("#ip").html("IP: " + response.ip);
$("#city").html(response.city + ", " + response.region);
$("#response").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1><a href="https://ipdata.co">ipdata.co</a> - IP geolocation API</h1>
<div id="ip"></div>
<div id="city"></div>
<pre id="response"></pre>
The fiddle; https://jsfiddle.net/ipdata/6wtf0q4g/922/
回答by user3124360
Here is another go at it .. Adding more to the accepted answer possibly more comprehensive .. of course switch -case will make it look for elegant.
这是另一个尝试..在接受的答案中添加更多可能更全面..当然 switch -case 将使它看起来优雅。
function parseGeoLocationResults(result) {
const parsedResult = {}
const {address_components} = result;
for (var i = 0; i < address_components.length; i++) {
for (var b = 0; b < address_components[i].types.length; b++) {
if (address_components[i].types[b] == "street_number") {
//this is the object you are looking for
parsedResult.street_number = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "route") {
//this is the object you are looking for
parsedResult.street_name = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "sublocality_level_1") {
//this is the object you are looking for
parsedResult.sublocality_level_1 = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "sublocality_level_2") {
//this is the object you are looking for
parsedResult.sublocality_level_2 = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "sublocality_level_3") {
//this is the object you are looking for
parsedResult.sublocality_level_3 = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "neighborhood") {
//this is the object you are looking for
parsedResult.neighborhood = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "locality") {
//this is the object you are looking for
parsedResult.city = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "administrative_area_level_1") {
//this is the object you are looking for
parsedResult.state = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "postal_code") {
//this is the object you are looking for
parsedResult.zip = address_components[i].long_name;
break;
}
else if (address_components[i].types[b] == "country") {
//this is the object you are looking for
parsedResult.country = address_components[i].long_name;
break;
}
}
}
return parsedResult;
}