微信 获取地理位置名称
Location-based applications are all the rage. What used to be prohibitively expensive GPS devices are now sitting in the of pockets of a great many people, embedded within smartphones and other devices on an unprecedented scale, and services making use of location information are springing up all the time. The social web, for example, has become location-aware with existing services such as Facebook following the lead of frontrunners like Foursquare and Gowalla by introducing Places. Twitter has added location information to tweets, more and more services are tailoring themselves to where you are geographically, and of course advertising is getting in on the act with location-based targeting of advertisements a lucrative and expanding area.
基于位置的应用程序风行一时。 过去价格昂贵得令人望而却步的GPS设备现在正以无与伦比的规模嵌入到许多人的口袋中,并嵌入到智能手机和其他设备中,并且利用位置信息的服务一直在兴起。 例如,通过引入Places,在诸如Foursquare和Gowalla等领先者的领导下,社交网络已通过Facebook等现有服务变得具有位置感知能力。 Twitter已在推文中添加了位置信息,越来越多的服务正在根据您所在的地理位置进行调整,当然,广告正在以基于位置的广告定位为目标,从而扩大了利润丰厚的领域。
In addition to pinpoint accuracy via GPS on handheld devices, other mechanisms from IP address-based geolocation to Wi-Fi triangulation are becoming more and more sophisticated, and with the W3C solidifying support for geolocation with its Geolocation API Specification the opportunities are vast.
除了通过手持设备上的GPS精确定位之外,从基于IP地址的地理定位到Wi-Fi三角测量的其他机制也越来越复杂,并且随着W3C凭借其Geolocation API规范巩固了对地理定位的支持,机遇是巨大的。
In this article I’ll share with you one important aspect of geolocation – mapping a physical location to a descriptive place name. I’ll look at how you can use Geonames, an online service offering free access to a large collection of geographic data, to help you develop applications taking advantage of locative information.
在本文中,我将与您分享地理位置的一个重要方面-将物理位置映射到描述性的地名。 我将研究如何使用Geonames (一项可免费访问大量地理数据的在线服务)来帮助您利用位置信息开发应用程序。
什么是地理位置? (What is Geolocation?)
Location-aware applications rely on being able to locate where you are, and this is what geolocation is all about. After all, once the application knows your location, it can go on to find the nearest store, guide you through the appropriate route to a destination, or target relevant advertisements to you. Geolocation, then, is simply the mechanism for identifying your geographical location.
位置感知应用程序依赖于能够定位您的位置,而这就是地理定位的全部内容。 毕竟,一旦应用程序知道了您的位置,它就可以继续查找最近的商店,引导您通过适当的路线到达目的地,或者将相关的广告定位到您。 因此,地理位置只是识别您的地理位置的机制。
There are two challenges with geolocation – finding out where someone is, and then describing that location. There are a number of techniques for determining someone’s location and they vary in sophistication and, most importantly, in accuracy. Latitude and longitude can pinpoint your location to within meters anywhere on Earth, but the values themselves have little meaning to most people. Sometimes fine resolution isn’t really needed, and it’s sufficient enough to identify the name of the nearest city or town.
地理位置面临两个挑战:找出某人的位置,然后描述该位置。 有多种技术可以确定某人的位置,它们的复杂程度(最重要的是准确性)各不相同。 纬度和经度可以将您的位置精确定位在地球上任何地方的米内,但是这些值本身对大多数人来说意义不大。 有时实际上并不需要高分辨率,它足以识别最近的城市或城镇的名称。
地名服务 (The Geonames Service)
Geonames is an online resource offering downloadable databases of a raft of geographical information, including mappings of latitude and longitude information to real-world locations. These files are, as you might imagine, huge as well as volatile. You’re free to download and use these files yourself, but there Geonames also makes web services available one of which is what I’ll use here.
地名是一种在线资源,可提供大量地理信息的可下载数据库,包括纬度和经度信息到现实世界位置的映射。 您可能会想到,这些文件既巨大又易失。 您可以自己免费下载和使用这些文件,但是Geonames也使Web服务可用,这就是我将在此处使用的内容之一。
In order to use the web services, you’ll need to create a free account. Go to www.geonames.org and click the Login link at the top right of the page. There you’ll be able to sign in or create a new user account. Once you sign up you’ll be sent an email with a confirmation link; check your mail and confirm your account.
为了使用Web服务,您需要创建一个免费帐户。 转到www.geonames.org ,然后单击页面右上方的“登录”链接。 您可以在那里登录或创建新的用户帐户。 注册后,您会收到一封包含确认链接的电子邮件; 检查您的邮件并确认您的帐户。
After you’ve confirmed your account, click your username at the top right of the page to go to the account management page and enable your account to use the web services.
确认帐户后,单击页面右上方的用户名进入帐户管理页面,并使您的帐户能够使用Web服务。
![geonames-01 alt](https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2011/12/geonames-01.jpg)
You now have a username which permits you access to the Geonames’ web services. You may wish to familiarize yourself with the terms and conditions.
现在,您有了一个用户名,该用户名允许您访问Geonames的Web服务。 您可能希望熟悉条款和条件 。
The particular service I’ll demonstrate is findNearbyPlaceName, which does just that – finds the nearest place name to a given latitude and longitude. The documentation states that it’s a RESTlike service with data available in XML and JSON formats (if you’re not clear on what a REST service is, I recommend you read up before continuing). The decision whether to use XML or JSON is often a personal one. I prefer JSON because it’s easier to parse, more lightweight, and works beautifully with JavaScript.
我将演示的特定服务是findNearbyPlaceName ,它就是这样做的-查找与给定纬度和经度最近的地名。 该文档指出,它是一种类似REST的服务,并且具有XML和JSON格式的数据(如果您不清楚REST服务是什么,建议您先阅读一下,然后再继续)。 使用XML还是JSON的决定通常是个人决定。 我更喜欢JSON,因为它更易于解析,更轻量且可与JavaScript完美结合。
类似于REST的位置Web服务 (A RESTlike Location Web Service)
One of the great things about using a REST web service to retrieve information is that, because of its very nature, you can issue a simple GET request in order to test it out – and you can do so using just a web browser! All you need to do is provide a properly formatted URL. In your browser, enter the following URL:
使用REST Web服务检索信息的一大优点是,由于其本质,您可以发出一个简单的GET请求以对其进行测试-只需使用Web浏览器即可! 您需要做的就是提供格式正确的URL。 在浏览器中,输入以下URL:
http://api.geonames.org/findNearbyPlaceNameJSON?lat=53.4774&lng=-2.2381&username=yourusername
Let’s break it down:
让我们分解一下:
http://
is the transfer protocol. Generally, REST services exploit the ubiquity and ease of HTTP.http://
是传输协议。 通常,REST服务利用HTTP的普遍性和易用性。api.geonames.org
is the domain name which becomes the initial segment of the service’s endpoint.api.geonames.org
是域名,它成为服务端点的初始段。findNearbyPlaceNameJSON
identifies the service. Often the return format you’re requesting is passed as a parameter, file extension, or even using an ACCEPT header, but this particular service incorporates it in the service’s name.findNearbyPlaceNameJSON
标识服务。 通常,您要求的返回格式是作为参数,文件扩展名甚至使用ACCEPT标头传递的,但是此特定服务将其包含在服务名称中。lat=53.4774&lng=-2.2381
are the latitude and longitude parameters for which you are requesting the nearest place name.lat=53.4774&lng=-2.2381
是您要为其请求最近的地名的纬度和经度参数。username=yourusername
is the username which you enabled to use the service. This service accepts is as a parameter, but other REST services may implement other authorization schemes such as HTTP-Authentication.username=yourusername
您的用户名是您启用以使用该服务的用户名。 此服务接受参数作为参数,但是其他REST服务可以实现其他授权方案,例如HTTP身份验证。
The service responds to the request by sending back the following JSON (I’ve formatted it nicely here for the sake of readability):
该服务通过发送以下JSON来响应请求(出于可读性的考虑,我在这里对其进行了很好的格式化):
{"geonames":[{"countryName":"United Kingdom",
"adminCode1":"ENG",
"fclName":"city, village,...",
"countryCode":"GB",
"lng":-2.23743438720703,
"fcodeName":"seat of a second-order administrative division",
"distance":"0.39678",
"toponymName":"Manchester",
"fcl":"P",
"name":"Manchester",
"fcode":"PPLA2",
"geonameId":2643123,
"lat":53.4809464283615,
"adminName1":"England",
"population":395515}]}
As you can see, the result is an object with the property geonames
which contains an array of one object with a number of properties. The lat
and lng
properties provide the geographic location of the place the service has identified, distance
shows you how far this place is from the position you provided, and most useful is the name
property which tells you the location’s name. countryName
property tells you the country, in this case the United Kingdom.
如您所见,结果是一个对象的属性geonames
名称包含一个包含多个属性的对象的数组。 lat
和lng
属性提供服务已识别的位置的地理位置, distance
显示您与提供的位置相距多远,最有用的是name
属性,它告诉您该位置的名称。 countryName
属性会告诉您国家(在本例中为英国)。
The data also provides information about administrative divisions. The exact nature of such divisions vary from country to country; in this case adminCode1
(the first-level administrative division) identifies “England”; if you were to locate Houston in the United States using this service you’d find that adminCode1 shows “TX” for the state of Texas.
该数据还提供有关行政区划的信息。 这种划分的确切性质因国家而异; 在这种情况下, adminCode1
(第一级行政区划)标识“英格兰”; 如果要使用此服务在美国的休斯顿找到,您会发现adminCode1在德克萨斯州显示为“ TX”。
Additionally, geonameId
contains the unique identifier used in the Geonames database which, you’ll remember, is downloadable. You may have a use for this at some point if you go on to use the data for something more substantial.
此外, geonameId
包含在Geonames数据库中使用的唯一标识符,您将记住,该标识符是可下载的。 如果继续将数据用于更重要的内容,则可能会在某个时候使用它。
有针对性的提示-一个实际的例子 (Targeted Prompting – A Practical Example)
As an example, let’s assume your web site has feature that prompts the user find cinema listings, and you’d like to personalize the header text with the name of the user’s nearest town – something like, “Find cinema listings near you in Manchester”. Immediately there’s one important limitation you should be aware of: Geolocation is, in the majority of cases, performed on the client. Whether by a web browser or the device itself, this information has to be sent back to the server if you wish to use it there. JavaScript on the client-side would obtain the user’s coordinates and send them to a server-side script via Ajax which then interfaces with the web service and returns a location name.
例如,假设您的网站具有提示用户查找电影院列表的功能,并且您想用用户最近的城镇的名称来个性化标题文本,例如“在曼彻斯特附近找到电影院列表”。 。 您应该立即意识到一个重要的限制:在大多数情况下,地理定位是在客户端上执行的。 无论是通过Web浏览器还是设备本身,如果要在服务器上使用此信息,都必须将该信息发送回服务器。 客户端上JavaScript将获取用户的坐标,并通过Ajax将其发送到服务器端脚本,然后与Web服务交互并返回位置名称。
服务器端代码 (Server-side Code)
Let’s start by writing the server-side PHP code. The Geonames website does provide a PEAR package, as well as libraries for frameworks including Zend Framework and Yii, to simplify access to their services – however, I’ll use plain PHP for the purposes of this tutorial.
让我们从编写服务器端PHP代码开始。 Geonames网站的确提供了PEAR软件包 ,以及包括Zend Framework和Yii在内的框架库,以简化对其服务的访问-但是,在本教程中,我将使用纯PHP。
This simple class encapsulates the call to the findNearbyPlaceName service:
这个简单的类封装了对findNearbyPlaceName服务的调用:
<?php
class Geonames
{
protected $username;
public function __construct($username) {
$this->username = $username;
}
public function getPlaceName($lat, $lng) {
$url = sprintf(
"http://api.geonames.org/findNearbyPlaceNameJSON?lat=%f&lng=%f&username=%s",
$lat, $lng, $this->username);
$response = file_get_contents($url);
if ($response === false) {
throw new Exception("Failure to obtain data");
}
$places = json_decode($response);
if (!$places) {
throw new Exception("Invalid JSON response");
}
if (is_array($places->geonames) && count($places->geonames)) {
return $places->geonames[0]->name;
}
else {
return "Unknown";
}
}
}
The class is named Geonames
, whose constructor takes a single parameter as an argument – the username you registered earlier, which is then stored in a protected member variable.
该类名为Geonames
,其构造函数将单个参数作为参数–您之前注册的用户名,然后将其存储在受保护的成员变量中。
The getPlaceName()
method calls the findNearbyPlaceName service. Because this is a simple GET request to a RESTlike service, you can simply incorporate the parameters in the URL as you did when testing the web service through your browser earlier. I used sprintf()
to build the up URL, an approach I feel is cleaner than concatenation and also permits me to specify the format types for the placeholders; latitude and longitude are floats (%f
) and the username is a string (%s
). The URL is then passed to file_get_contents()
which receives the service’s JSON response. The response is decoded using json_decode()
and the first place name is returned from the method.
getPlaceName()
方法调用findNearbyPlaceName服务。 因为这是对类似REST的服务的简单GET请求,所以您可以像之前通过浏览器测试Web服务时一样,将参数简单地合并到URL中。 我使用sprintf()
来构建up URL,我觉得这种方法比串联更干净,并且还允许我为占位符指定格式类型; 纬度和经度是浮点数( %f
),用户名是字符串( %s
)。 然后将URL传递到file_get_contents()
,该文件接收服务的JSON响应。 使用json_decode()
对响应进行解码,并且从该方法返回第一个地名。
The script called by Ajax will receive the latitudinal and longitudinal coordinates, use them to query the Geonames web service through the new class, and return the name of the nearest location.
由Ajax调用的脚本将接收纬度和经度坐标,使用它们通过新类查询Geonames Web服务,并返回最近位置的名称。
<?php
require "../include/Geonames.php";
$lat = floatval($_GET["lat"]);
$lng = floatval($_GET["lng"]);
$geo = new Geonames("username");
$prompt = "Find cinema listings near you";
try {
$place = $geo->getPlaceName($lat, $lng);
if ($place != "Unknown") {
$prompt .= " in " . $place;
}
}
catch (Exception $e) {
error_log("Error with web service: " . $e->getMessage());
}
header("Content-Type: text/plain");
echo $prompt;
The code starts with a default message, “Find cinema listings near you”. If the call to the getPlaceName()
method doesn’t raise an exception and the name returned isn’t “Unknown”, the message is further personalized.
该代码以默认消息“查找附近的电影列表”开头。 如果对getPlaceName()
方法的调用没有引发异常,并且返回的名称不是“ Unknown”,则消息将进一步个性化。
客户端代码 (Client-side Code)
Now let’s turn our attention to the HTML page and JavaScript code that will call the PHP.
现在,我们将注意力转移到将调用PHPHTML页面和JavaScript代码上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello!</title>
<script src="jquery.js"></script>
<script>
(function ($) {
$(document).ready(function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
$("#banner").load("/prompt.php?lat="+lat+"&lng="+lng);
},
function (error) {
console.log("An error occurred obtaining position.");
});
}
else {
$("#banner").html("Default content goes here");
}
});
})(jQuery);
</script>
</head>
<body>
<div id="banner"></div>
</body>
</html>
If geolocation is supported by the browser then navigator.geolocation
will return true, otherwise some default content is inserted into the element with the ID banner
. When geolocation is supported, an attempt is made to obtain the user’s location using navigator.geolocation.getCurrentPosition()
, which is passed success and error callbacks.
如果浏览器支持地理定位,则navigator.geolocation
将返回true,否则,会将一些默认内容插入ID banner
的元素中。 当地理位置是支持的,试图获取用户的位置使用navigator.geolocation.getCurrentPosition()
这是传递成功和错误回调。
At this point the browser will ask for your permission to share your location information with the web page. If you grant permission then the success callback is executed and, if the application succeeds in retrieving the location’s name, the banner will contain a personalized invitation to explore the cinema listings. If you deny permission to the browser, the error callback is executed instead.
此时,浏览器将要求您允许与网页共享您的位置信息。 如果您授予许可,那么将执行成功回调,并且,如果应用程序成功检索位置的名称,则横幅将包含个性化的邀请,以浏览电影院列表。 如果您拒绝浏览器的权限,则会执行错误回调。
摘要 (Summary)
In this short article I’ve introduced geolocation and one way in which you can exploit it right now to personalize a visitor’s experience on a website. Although the example I’ve given is somewhat clunky in its use of AJAX to load a block into a page retrospectively, it serves to illustrate one of the technical challenges of geolocation – information is largely obtained client-side and thus there are hurdles you need to overcome, such as asking permission to use the information. Perhaps you may wish to try storing information server-side in a session once you’ve obtained it, look at improving performance using caching, or experiment with more sophisticated targeting. The next logical step is to examine how you would manage relationships between towns – what if my local village doesn’t have a cinema, what’s the nearest town or city that does? That’s for another time, but for now I encourage you to look at API support for geolocation (you could even look at the specification), look at an entirely server-side IP-based solution, or delve into the mathematics behind geolocation. Most of all, I encourage you to have fun!
在这篇简短的文章中,我介绍了地理位置以及您现在可以利用它来个性化访问者在网站上的体验的一种方法。 尽管我给出的示例在使用AJAX回顾性地将块加载到页面中时有些笨拙,但是它可以说明地理定位的技术挑战之一–信息在很大程度上是从客户端获取的,因此您需要克服障碍克服诸如请求使用信息的许可。 也许您可能希望在获取信息后在会话中尝试将其存储在会话中,着眼于使用缓存提高性能,或者尝试使用更复杂的定位。 下一步的逻辑步骤是研究如何处理城镇之间的关系-如果我当地的村庄没有电影院,最近的城镇是哪个? 那是另外一次了,但是现在我鼓励您看一下对地理定位的 API支持(您甚至可以查看规范 ),研究一个完全基于服务器端基于IP的解决方案 ,或者深入研究地理定位背后的数学原理。 最重要的是,我鼓励您玩得开心!
Image via Olivier Le Moal / Shutterstock
图片来自Olivier Le Moal / Shutterstock
翻译自: https://www.sitepoint.com/targeted-geolocation-with-geonames/
微信 获取地理位置名称