在线地图已经是很平常的应用,Google Map 甚至可以用作驾驶导航仪,然而,这些应用的实现涉及到千丝万缕的艰辛工作,仅仅是定位你现在的位置,就有很多技术,有幸的是,如今在你的 Web 站点中,你可以通过短短的几行代码,获得一个用户的地理位置,本文介绍的是用在 Web 中的各种地理定位技术。
通过 IP 地址获得用户的地理位置信息
互联网不过是一个巨大的网络,上面的每一台电脑对应一个 IP 地址,通过这个 IP 地址,可以知道这个用户在什么位置,我们可以通过查询 Maxmind GeoIP 数据库 获得,Maxmind 还提供了一个 JavaScript 接口 让你在网站上实现这一功能。
这个方法(演示 )有一个问题,就是说,你获得的 IP 地理位置信息未必非常准确,因为这个 IP 是你的 ISP 分配给你的,你获得的事实上是 ISP 的地理位置,另外,如果你使用 VPN,你实际的得到可能是十万八千里之外的地方了。
通过 W3C Geo API 获得用户地理位置
通过 IP 地址获取用户地理位置还有一个棘手的问题,就是安全和隐私问题,毕竟,并不是每个用户都愿意自己的地理位置信息被别人知道,鉴于此,人们开发了很多技术,Google Gears 拥有一个 Geo-Location 服务 ,Plazes 帮助你保存你的位置 ,而 Yahoo Fire Eagle 算得上这类技术中最顺手的一个。然而这些技术共同的问题是,它们要求用户要么安装一个插件,要么需要访问特定的 Web 服务,这有些麻烦。
W3C 有一个 Geo-Location API 可以帮助浏览器制造商,在浏览器中集成地理信息功能。Firefox 3.5 以上的浏览器支持 W3C Geo-LocationAPI ,同样支持该 API 的还有 iPhone 上的 Safari 浏览器 (需要 OS3.0 以上)。需要通过浏览器查询自己地理位置的用户,在浏览器中,会显示一个对话条,请求你的授权。如下图所示:
以下是请求使用该功能的代码:
下面的演示 ,可以很好地演示上面两种地理信息获取技术的不同,可以看到,他们在测量用户地理位置 方面有很多不同。
将经度/维度转换为地名
将经度/维度信息转换为地位,称为 “反 Geo-Location ”,网络上有很多这类服务可以使用,其中最著名的是 the geo-names Web service , 但它仍有几个问题,比如,它的结果是以美国为中心的。另一个可免费使用,且支持全球信息,但知道的人并不多的服务来自一个让人有点意外的地方,Flickr 。Flickr 的 flickr.places.findByLatLon 服务可以根据经纬度信息返回地名,你可以在 app explorer 做下体验,但目前最简单的方法是使用 Yahoo Query Language ( Yahoo 查询语言,简称 YQL). YQL 的样子如下:
使用 YQL 查询语言,你可以得到 XML 或 JSon 格式的数据,下图是在 JavaScript 中是使用该查询语言的例子:
结合上面的例子,在反 Geo-Location 查询的帮助下,我们得到了详细的地名信息 :
经纬度的问题
经纬度虽然可以定位地球上的一个位置,但经纬度有时候容易引起歧义,为了解决这个问题,Yahoo 和 Flickr (Twitter 很快也会支持)支持另一种定位方法,叫 Where On Earth Identifier (简称 WOEID) 。使用该方法,我们可以很容易获取来自某个区域的 Flickr 图片。
这样几句 JavaScript 代码就可以显示来自指定地理位置的图片:
这些代码还可以打包成函数,下面的代码,将显示来自巴黎的10幅照片,你可以自己在 YQL console 中体验:
在文字内容中自动挖掘地理信息
假如你想获得一段文字,或者一个网页内容所提到的地名的地理位置的信息,Yahoo 提供了一个很好的服务,叫 Placemaker 。从 Yahoo 那里获取一个 developer key 就可以使用该服务了。只需创建一个发布表单发布到 http://wherein.yahooapis.com/v1/document ,将 Developer Key 以 appid 发布,需要查询的文字以 documentContent 发布,将文字类型以 documentType 发布,同时用 outputType 定义返回数据类型,如下:
你也可以在这里亲自体验一下 ,使用 PHP 调用该 API ,甚至可以对输出数据的格式进行设置 。这里还有一个使用 PlaceMaker 设计 GeoMaker 服务,简单输入文字或 URL,选择位置,就可以返回地图。
因为还可以在 JavaScript 中通过 YQL 使用 PlaceMaker,我们可以通过几段客户端脚本使用同样的功能:
你需要三样东西,一段位于某个 HTML 对象中的,包含地理位置的文字,一个 Google Maps API Key (申请 ) 以及以下代码:
在网页中插入地图
在线地图有很多,Google Map 是其中的领先者,除了 Google,Yahoo, 微软都提供地图服务,还有一个叫做 Open Street Maps 的开放地图服务,在上次海地地震救援中被派上用场 。在网页中插入交互地图最简单的方法是使用 Mapstraction ,它提供一个 JavaScript 库,24ways 曾发表过一篇很好的介绍文章 。如果你只想在网页上放上你的地图,指示你的位置,而不想使用太多 JavaScript, Google static maps API 是最好的选择,它会生成静态地图,以下代码可以将这个静态地图插入你的网页(Google 还提供了一个创建静态地图的工具 ):
本文国际来源:http://www.smashingmagazine.com/2010/03/08/entering-the-wonderful-world-of-geo-location/
Why Geo Matters
First of all, why is it important to consider physical location on this planet (at this moment) when we develop Web products? There are a few answers to this.
The first answer is mobility. The days of people sitting in front of desktop machines at home are over. Sales of mobile devices, laptops and netbooks have overtaken those of bulky stationary computers in the last few years. The power of processors now allows us to use smaller, more mobile hardware to perform the same tasks. So, if people use their hardware on the go, we should bring our systems to them. Which brings us to the second—very important—point: relevance.
Giving the user content that is relevant to the physical space they are in at the moment makes a lot of sense. We are creatures of habit. While we love the reach of the Internet, we also want to be able to find things in our local area easily: people to meet, cafes to frequent, interesting buildings and museums to learn about. The advertising industry—especially of the adult and dating variety—realized this years ago. I am sure you have come across one of the following before:
![Adultpersonals in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141209679.jpg)
I am sure these ads are more successful than the ones that show only user names. That the photos and names are the same for every location doesn’t seem to be a problem (but yes, I noticed it). So how does it all work?
Getting The User’s Location Via IP
Every computer on a network has a number that identifies it: its IP address. The Internet is nothing but a massive network, and your IP number is assigned to you by the service provider that you have used to connect to that network. Because the numbers that service providers assign change from one geographical location to the next (much like telephone numbers), you can make quite a good estimate of where your visitors are from.
To find out where a certain phone number is from, you use a phone book. To find out where an IP is from, you can use the Maxmind GeoIP database. Maxmind also provides a JavaScript solution that you can use on websites:
03 |
var info = document.getElementById( 'info' ); |
04 |
var lat = geoip_latitude(); |
05 |
var lon = geoip_longitude(); |
06 |
var city = geoip_city(); |
07 |
var out = '<h3>Information from your IP</h3>' + |
09 |
'<li>Latitude: ' + lat + '</li>' + |
10 |
'<li>Longitude: ' + lon + '</li>' + |
11 |
'<li>City: ' + city + '</li>' + |
12 |
'<li>Region: ' + geoip_region() + '</li>' + |
13 |
'<li>Region Name: ' + geoip_region_name() + '</li>' + |
14 |
'<li>Postal Code: ' + geoip_postal_code() + '</li>' + |
15 |
'<li>Country Code: ' + geoip_country_code() + '</li>' + |
16 |
'<li>Country Name: ' + geoip_country_name() + '</li>' + |
![Geolocation in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141214144.jpg)
This gives you some information on the user (try it out for yourself). The challenge, though, is relevance. Your IP location is the location of the IP that your provider has assigned to you. Depending on your provider, this could be quite a ways off (in my case, I live in London, but my provider used to show me as living in Rochester). Another problem is if you work for a company that uses a VPN. At Yahoo, for example, I have to connect to the VPN to read my company email, and I have to choose a location to connect to:
![Vpn in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141215245.jpg)
So, for a solution like the one highlighted above, I would show up as being in a totally different part of the world (which might be useful for watching Internet TV in the UK while I am in the US). IP geo-location, then, is an approximation, not a dead-on science.
Getting The User’s Location Via The W3C Geo API
Guessing geographical location via IP is possible, but it can also be pretty creepy. Being able to take advantage of your location is useful, but security-conscious users and people who are generally suspicious of the Internet are not happy with the idea of their movements being monitored by a computer. This makes sense: if I can monitor your whereabouts day and night, I would know where and when to rob your house without you being there.
There are a lot of solutions to the challenge of having good-quality geo-location and maintaining privacy. Google Gears has a geo-location service; Plazes helps you store your location; and Yahoo’s Fire Eagle is probably the most polished way to securely maintain your location on the Web.
The problem with all of these services is that they require the user to either install a plug-in or visit a Web service to update their location. This is not fun; browsers should do the work for you.
We now have a W3C recommendation for a geo-location API that allows browsers to request the geographical location of the user. This makes it less creepy, and you get real data back.
Firefox 3.5 and above supports the W3C geo-location API. So does Safari on the iPhone if you run OS 3.0 or above. If you use the API, the browser will ask the user whether they want to share their location with your website.
![Geowarning in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141216946.jpg)
Once the user allows you to get their location, you get much more detailed latitude and longitude values. Using the API is very easy:
02 |
if (navigator.geolocation){ |
04 |
navigator.geolocation.getCurrentPosition( |
08 |
var lat = position.coords.latitude; |
09 |
var lon = position.coords.longitude; |
Compare the IP and W3C solutions side by side. As you can see, there can be quite a difference in measuring the visitor’s location. The extent of the difference is shown in the following demo:
![Difference in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141218239.jpg)
Converting Latitude And Longitude Back Into A Name
Having more information is nice, but we have lost the name of the city and all the other nice data that came with the Maxmind database. Because the location has changed, we cannot just grab that old data; we have to find a way to convert latitude and longitude coordinates into a name. This process is called “reverse geo-coding,” and several services on the Web allow you to do it. Probably the most well-known is the geo-names Web service, but it has a few issues. For starters, the results are very US-centric.
One freely available but lesser-known reverse geo-coder that works worldwide comes from a surprising source: Flickr. The flickr.places.findByLatLon service returns a location from a latitude and longitude coordinates. You can try it out in the app explorer, but by far the easiest way to use it is by using the Yahoo Query Language (or YQL). YQL deserves its own article, but let’s just say that, instead of having to authenticate with the Flickr API and read the docs, reverse geo-coding becomes as easy as this:
1 |
select * from flickr.places where lat=37.416115 and lon=-122.0245671 |
Using the YQL Web service, you can get the result back as XML or JSON. So, to use the service in JavaScript, all you need is the following:
01 |
<script type= "text/javascript" charset= "utf-8" > |
02 |
function getPlaceFromFlickr(lat,lon,callback){ |
04 |
var yql = 'select * from flickr.places where lat=' +lat+ ' and lon=' +lon; |
08 |
encodeURIComponent(yql)+ '&format=json&diagnostics=' + |
09 |
'false&callback=' +callback; |
12 |
var s = document.createElement( 'script' ); |
13 |
s.setAttribute( 'src' ,url); |
14 |
document.getElementsByTagName( 'head' )[0].appendChild(s); |
19 |
if ( typeof (o.query.results.places.place) != 'undefined' ){ |
20 |
alert(o.query.results.places.place.name); |
25 |
getPlaceFromFlickr(37.416115,-122.02456, 'output' ); |
Combine that with the other services, and we get a more detailed result and can put a name to the coordinates:
![Reversegeocode in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141219539.jpg)
The Trouble With Latitude And Longitude
While latitude and longitude coordinates are a good way to describe a location on Earth, it is also ambiguous. The coordinates could represent either the centre of a city or a point of interest (such as a museum or a pub) in that spot.
WOEID to the Rescue
To work around the problem, Yahoo and Flickr (and soon will Twitter) support another way to pinpoint a location. The Where On Earth Identifier (or WOEID) is a more granular way to describe locations on Earth. Because Flickr supports it, we can easily get get photos from a particular area:
1 |
select * from flickr.photos.search where woe_id in ( |
2 |
select place.woeid from flickr.places where lat=37.416115 and lon=-122.02456 |
Using this and a few lines of JavaScript, showing geo-located photos is pretty easy:
![Geolocated-photos in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141221690.jpg)
This has also been wrapped in a simple-to-use YQL solution. The following code will display 10 photos of Paris:
03 |
var container = document.getElementById('photos'); |
04 |
container.innerHTML = o.results; |
08 |
select %20*%20from%20flickr.photolist%20where%20location%3D%22<STRONG>paris%2Cfr</ STRONG > |
09 |
%22%20and%20text%3D%22%22%20and%20amount%3D< STRONG >10</ STRONG >&format=xml& |
10 |
env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=< STRONG >photos</ STRONG >"> |
You can also play with this in the YQL console.
Why Not Search For The Location’s Name?
The main question about implementations such as the one above is why couldn’t we just do a search on Flickr for the city, instead of doing all the complex geo-lookups? The reason is false positives. Take Paris, for example: if you want to show photos of Paris on a travel website, you don’t want Paris Hilton to show up in there. Same goes for Jack London. You may also want to show photos of London, England, not London, Ontario. Geographic data is full of these kinds of gotchas, and the term for finding the right one is “disambiguation.” See the Wikipedia article on “Victoria” to see just how many geographical contexts this term can have.
Turning Text Into Geo-Data
Finding a visitor’s geographic location is all well and good, but it doesn’t mean much if you can’t link it to information for that area. This is where it gets tricky. For Flickr (and soon Twitter), this is easy, because both services are able to attach geographical locations to the content you put in them. This is not so for most of the information on the Web, though, and this is when we resort to clever algorithms, machine-learning, pattern-matching and all the other think-tank stuff that computers and the scientists in front of them do.
Say you want to identify the geographical locations that a particular text or Web page talks about. Yahoo offers a service for that called Placemaker, and it is pretty easy to use. You need to get a developer key and send this as appid
, send a text as documentContent
, define the type of the text as documentType
and define the type of data you want back as outputType
. All of this needs to be sent as a POST
to http://wherein.yahooapis.com/v1/document
:
2 |
< textarea id = "text" name = "documentContent" >Hi there, I am Chris. |
3 |
I live in London, I am currently in Sunnyvale and will soon be in |
4 |
Atlanta and Las Vegas.</ textarea > |
5 |
< div >< input type = "submit" name = "sub" value = "get locations" ></ div > |
6 |
< input type = "hidden" name = "appid" value="<STRONG>{YOUR_APP_ID}</ STRONG >"> |
7 |
< input type = "hidden" name = "documentType" value = "text/plain" > |
8 |
< input type = "hidden" name = "outputType" value = "xml" > |
You can try this out yourself. Using PHP to call the API instead of a simple form, you can even format the output nicely. See it in action here:
![Placemaker-results in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141223834.jpg)
While developers who have played around with Web services won’t find Placemaker hard to use, the service can be daunting for the average developer. That is why I built GeoMaker some time ago. GeoMaker allows you to enter a text or URL, select the locations you want to include in the final outcome, and get the locations either as a map to copy and paste or as micro-formats.
![Geomaker in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141225717.jpg)
However, because there is also a YQL solution for using PlaceMaker in JavaScript, we can do the same with a few lines of client-side code to enhance an HTML document. Check out the following example:
![Textandmap in Entering The Wonderful World of Geo Location](/UploadFiles/Article_UploadFiles/201003/20100318141227738.jpg)
To use this, you need three things: a text with geographical locations in them in an element with an ID, a Google Maps API key (which you can get here) and the following few lines of code:
3 |
addmap.config.mapkey = 'COPY YOUR API KEY HERE'; |
4 |
addmap.analyse('content'); |
This makes it incredibly easy to give your visitors a sense of what part of the world a text is related to.
Adding Maps To Your Documents
Online maps have been around for a while now (and Google Maps was instrumental in the rise of AJAX), and many providers out there allow you to add maps to your documents. Google is probably the leader, but Yahoo also has maps, as does Microsoft and many more. There is even a fully open map service called Open Street Maps, which has been instrumental in the recent rescue efforts in Haiti.
If you want interactive maps, probably the easiest thing to use is Mapstraction, which is a JavaScript library that does away with the discrepancies between the various map providers and gives you a single interface for all of them. 24ways published a good introduction to it three years ago.
Probably the simplest way to show a map that supports markers and paths in your document without having to dive into JavaScript is the Google static maps API. It creates maps as images, and all you need to do is provide the map information in the src
URI of the image. For example, in the script example above, this would be:
5 |
&key=<EM>YOUR_MAP_KEY</EM> |
6 |
&markers=color:blue|label:1|37.4447,-122.161 |
7 |
&markers=color:blue|label:2|37.3385,-121.886 |
8 |
&markers=color:blue|label:3|37.3716,-122.038 |
9 |
&markers=color:blue|label:4|37.7792,-122.42 |
You can define the size and type of the map. If all you provide is the location of markers, the API will automatically find the right zoom level and area to ensure that all markers are visible. Google’s website even offers a detailed tool to create static maps, including markers and paths.
Geo Is A Space To Watch
I hope this has given you some insight into all of the things you can do to bring the earth to your product and to put your product on the map. Geo-location and geo-aware services are already huge, and they’ll be even more important this year. There will be more services—some mobile providers are ready to roll out new hardware and software—and now you can be a part of it.
What the geo-world needs now is a designer’s eye, and this is where you can help the geo-geeks create apps that matter, that look great and that make a difference in our visitors’ lives. For inspiration, check out Mapumental, which allows you to pinpoint a place to live in London, or see how Google Earth and some 3-D Objects allow you to race a milk truck on real map data.
上一篇:具有二次开发功能的手机GIS平台免费下载
下一篇:地理空间信息一站式服务