K_Reverter的网页开发记录

要么不做,要么就当作艺术品来做!

闭关纪要21.地图人站点的IP查询经纬度和经纬度查询行政区划的服务

        现在我的闭关已经接近尾声,按照最初的计划我准备拿出一个月左右的时间研究JavaScript的代码混淆的,后来因为对Google App Engine的引擎的研究日渐深入,而且也觉得代码混淆比我想象的要复杂,因此,取消了研究代码混淆的计划,而专注于网站相关的研究。

        本文要介绍的是我在Google App Engine上实现的3个REST接口服务:

        1.通过经纬度查询行政区划的服务,传递一个经纬度坐标,返回的结果为该位置的行政区划,通常来讲,用来实现地图上的“面包屑导航”功能。

        2.通过IP查询经纬度,传递一个IP(或者不传,缺省使用连接客户端的IP),返回结果为该IP的位置文字描述和经纬度

        3.加载一个简单的笑话信息,这是一个很简单搞笑的功能。

        本来,这些功能在地图人网站上原本就有,不过以前是我使用ASP.NET开发的,和网站运行在一个主机上,为避免主机性能受影响这些接口没有公布,而且在接口程序上做了站内限制,现在我将地图人网站的所有类似服务都迁移到了Google App Engine上,而Google App Engine的性能和稳定性是比较可靠的,因此我将这些服务公布出来供大家参考引用。

        上次,因为网站的18万条数据因为GAE的一个BUG没有能够成功上传到GAE上,因此,影响了网站服务代码的迁移,不过我最近才知道,原来GAE是可以访问本地文件的(汗!我可能是被‘云’弄得晕乎乎了,连本地文件都不敢访问了),而我的那些数据包含明显的规律,使用本地文件访问比数据库更快,因此我毅然决定重写代码,依靠访问文件的方式来提供服务,跳过了那个BUG,并且带来更好的性能。

        不过Google的单个文件大小最多为1M,这一点挺害人的,毕竟18W条的数据要压缩成1M的文件可不容易,因此我很费劲的研究了几晚上的Python二进制文件读写,以及数据类型什么的,最后终于成功的将数据压缩到800K,这样才能够完美的提供通过经纬度查询行政区划。

        下面介绍一下每个服务的调用过程和实现,需要说明的是,除了第三个服务在上一篇文章《闭关纪要20.在Google App Engine之中解析RSS》之中已经公开了源码之外,其他的两个服务因为和数据相关,公开源码也没有意义,因此就不公开,不过第二个服务通过IP查询的,我的主要源码就是使用的别人的开源代码做了简单的整合,根据我的思路,很容易就可以自己实现了。

        1.通过经纬度查询行政区划,这个服务通过读取本地二进制文件匹配出某个经纬度的行政区划编号,然后通过编号在Google DataStore之中查询行政区划信息,经过我的观察,性能还算不错,按照Google App Engine后台的统计显示,平均CPU时间消耗为80,算是比较少的,虽然这个服务看起来比较复杂。服务调用示例:

        http://dituren-service.appspot.com/services/rgeo_ll?ll=39.94691582580937,116.38320347900391&c=onRgeoLoaded

        其中,参数ll是逗号分隔经纬度,注意是纬度在前,经度在后,参数c是REST回调函数名称,上例返回的内容为:

        onRgeoLoaded({area:'北京市-西城区',regionCode:'110102'});

        返回的对象之中,area属性是减号分隔的按层级的地区名称,regionCode属性是行政区划编码,如果没有成功匹配到行政区划,将以空参数调用回调函数

        需要注意的是,因为这个接口仅仅进行国内行政区划的查询,因此建议仅仅对纬度范围(从3到54),经度范围(从73到136)范围内的内容进行查询匹配,否则,白白连接一下,没有任何意义;

        2.通过IP查询经纬度,这个服务首先要感谢gohsy,我的IP查询功能采用他的代码,而且连IP库也是采用他的版本,我本来想替换一个更全(至少文件更大)的IP库的,可惜后来发现超过1M的文件传不上去,而gohsy的IP库文件居然刚好是1M,不知道他怎么弄的,我就不客气的使用了,在采用这个库实现了通过IP得到一个地址的文字描述之后,我通过Google的地址解析服务去匹配经纬度,这个思路很清晰,不过我会在数据库之中缓存Google的地址解析结果,避免频繁的向Google请求地址匹配造成性能和稳定性问题,这个服务因为存在获取URL内容的功能,因此性能不稳定,从统计来看,平均CPU时间消耗为140,不过这个服务才运行了几个小时,随着缓存地址匹配数据的增多,平均CPU占用一定会下降。服务调用示例:

        http://dituren-service.appspot.com/services/ip_lookup?c=onIpLookupLoaded&ip=202.204.59.204

        其中,参数ip就是一个IP(废话),如果IP参数不存在,则直接缺省采用客户端连接IP,参数c是REST回调函数名称,返回的内容为:

        onIpLookupLoaded({ip:'202.204.59.204',address:'北京市 北京科技大学',lat:39.987700,lon:116.361576,zoom:14})

        返回的对象之中,ip属性就是当前IP,不管是否传递了ip参数,都会返回一个IP,address属性是在IP库之中查询的结果字符串,lat,lon是经纬度信息,zoom属性是较合适的显示缩放等级,因为匹配有精度的问题,例如匹配到“北京科技大学”和匹配到“北京市”都有经纬度,不过显示给用户的缩放登机最好是有所不同的,这个缩放等级是按照Google的地图做标准的,如果在51ditu接口上使用,考虑用17-zoom。

        需要注意的是,因为IP查询采用网上的IP库,地址匹配采用Google的接口,我仅仅做一个简单的整合,因此,不能对数据的正确性和准确率作出保证,呵呵

        3.加载一个笑话,本来这个功能就是上不得台盘的一个小玩意,不能和上面的两个接口相比,不过,我也随便的介绍一下,这个功能源码已经公开在《闭关纪要20.在Google App Engine之中解析RSS

        有时候,因为网速的问题,地图加载缓慢(地图API通常都比较大,而且地图相关的附加功能多),让用户等待地图下载的过程之中,在地图显示区域先加载个笑话或其他文字内容是不错的,不过要求这个内容要在主体内容加载之前开始加载(否则就失去意义了),而且要求加载比较快,尽量不要进一步拖慢页面加载速度,在主体内容加载完成之后,就显示主体内容,原来的临时内容被替换。

        因为页面上不能每次打开都是同样的内容(如果是这样的话,直接写在静态页面上就可以了,而且让用户每次都看一个内容也就失去了打发等待页面加载时间的意义)所以页面内容还要自动变换,不过最好可供变换的内容不要太多,就可以使用缓存的优势使加载速度更快。

        基于以上的思路,开发了一个以下服务,客户端动态的变化一个随机数字id,向这个服务发送请求,这个服务返回指定id的内容:

        http://dituren-service.appspot.com/services/joke_random?c=onJokeLoaded&id=12

        参数id是传递过来的随机整数,注意为什么不在服务端随机显示呢,因为在服务端随机显示的话就无法启用缓存了;参数c是REST回调函数名称,本服务返回的内容示例为:

        onJokeLoaded({title:"贵族幼儿园面试",content:"小露丝去考贵族幼儿园,面试时老师取出一张10元的钞票问:这是什么?小露丝很快回答:这是奶奶给乞丐的废纸.老师说:好了,不用考了,你已被录取了。"})

        title参数是标题,content参数是内容(全是废话),页面上先定义好onJokeLoaded函数,将笑话显示在指定的地方,页面主体内容加载完成后,再擦除内容就可以实现了。

        以上就是我的网站上提供的3个相关的服务的说明,这些服务并没有考虑使用XML格式,而是采用REST的JavaScript格式,是希望可以直接调用而不会遭遇跨域的问题(因为这些服务都是在专用域名service.dituren.cn上的,和我自己的网站也不是在同一个域)以上服务返回的内容全部是UTF-8格式的JavaScript内容,调用的时候需要注意编码问题

        本文仅仅是对这些服务接口本身进行介绍,后面我会将这些服务封装成简单的用户可以在直接使用的脚本对象,这些对象将会在我正准备更新的K_Map(原来名字叫K_ReverterMap的一些地图相关的类)之中公布,现在想起来K_Map的一些类已经好久没有更新过了。

        这以后,我还会逐步的增加相关的服务,例如根据经纬度查询天气信息什么的,反正相关的东西,我都可以拿来研究!

posted on 2009-01-07 21:41 K_Reverter 阅读(2432) 评论(11)  编辑 收藏 网摘 所属分类: 关于Step1站点Google App Engine

评论

#1楼 2009-01-08 09:19 暗点      

这个将会在很多的项目中普及的,关注楼主。最近也想做这方面的。期待楼主的K_map   回复  引用  查看    

#2楼 2009-01-08 09:20 疯子阿飞      

我使用过N个国外的根据IP查询经纬度、地理名称的服务都是收费的。

看到博主的文章无比兴奋,同时也忧心忡忡。

兴奋的是国人也可以搞出老外引以为豪的东西,兴奋以后终于可以有一个国内的接口可以使用了。

忧心的是这个接口是否稳定,是否会因为博主的网站、域名、公司或个人的种种原因开发几天、几个月就不能用了。
  回复  引用  查看    

#3楼[楼主] 2009-01-08 09:45 K_Reverter      

@疯子阿飞
我完全不能保证此接口的绝对稳定,不过有几点说明一下:
1.网站,因为提供服务的不是一个网站,而是Google App Engine服务,而且是免费的,因此不会收费或什么其他的原因造成不稳定
2.域名,除了使用service.dituren.cn如果你觉得想更可靠,可直接使用appspot的域名dituren-service.appspot.com,也就是Google的域名了,应该更加稳定
3.因为不是收费的,所以不存在公司或个人的什么问题;
但是有以下几个问题:
1.GAE是有可能被封的,这个风险是存在的
2.我会更新服务,这期间可能会造成不稳定,不过首先更新都是晚上,其次,这是我的网站依赖的服务,我不会让它不稳定
3.如果确实存在很多人访问,造成我的GAE超出使用限制,我会对访问较多的网站提供新的GAE部署地址以分流,但不会停止这个服务
以上就是这些服务的稳定性说明,是否使用以及怎么使用就可以自己决定了
  回复  引用  查看    

#4楼 2009-01-08 09:55 G yc {Son of VB.NET}      

楼主, Python二进制文件读写

能指教我一下吗?谢谢。
  回复  引用  查看    

#5楼[楼主] 2009-01-08 11:03 K_Reverter      

建议你到以下连接:
http://s.gohsy.com/" target="_new">http://s.gohsy.com/
看看gohsy如何通过本地二进制文件来读取IP库信息的,就知道怎么用了
  回复  引用  查看    

#6楼[楼主] 2009-01-08 11:05 K_Reverter      

搞错了,源码下载链接在这里:
http://gohsy.com/down/index.php?act=view&id=9" target="_new">http://gohsy.com/down/index.php?act=view&id=9
  回复  引用  查看    

#7楼 2009-01-08 12:18 G yc {Son of VB.NET}      

好的~

实际上,我还不太会用这个。

主要是,最近想弄个网站入口, 之前用过的一个不能设置首页。
想用这GAE,不知道能做一个,静态网站。

就是,直接将 HTML页面上传(数据库) ,然后就可以浏览了~


另外, 之前下过一个例子,里面,好像写了一个ZIP解压缩的东西。
或许,楼主也许,可以试试这个。 将那个IP数据库在压缩一下。
  回复  引用  查看    

#8楼[楼主] 2009-01-08 14:11 K_Reverter      

ZIP解压是很容易的,最关键的问题是如果采用ZIP压缩,必然会影响性能,因此,我打算想办法将IP库进行拆分,例如按照IP第一段分成256个IP库文件,就每个很小了,而且这样的话,性能也应该会有提升   回复  引用  查看    

#9楼[楼主] 2009-01-09 00:50 K_Reverter      

今天晚上再次对IP查询服务进行了升级,主要包含如下更新:
1.将原来的1M的精简版IP数据更新为2009-01-05的最新版本,数据大小7.43M包含更加详细的地址信息
2.将一个大的IP数据包切割为9个分段的IP数据包以便能上传到GAE服务器上,根据IP范围选择不同的包,并不会因为数据的变大而影响性能
3.地址匹配经纬度的算法进行了升级,如果匹配失败,则会删除部分关键词进行重新匹配,直到匹配成功,这样可以保证绝大部分的点地址都能匹配到内容,因为需要多次匹配,因此性能可能会下降,不过因为存在匹配缓存,所以实际影响不会太大
  回复  引用  查看    

#10楼 2009-02-11 16:11 taiful[未注册用户]

为什么在IE7中出错,在IE6不出错   回复  引用    

#11楼[楼主] 2009-02-12 14:26 K_Reverter      

我这只是一个简单的查询服务而已,和浏览器无关的,你最好检查一下自己的查询代码   回复  引用  查看    

发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1371402




相关文章:

相关链接: