放弃GAE的blog,回到wordpress
也不是因为micolog的程序不好,更多的是因为GAE被这封那封,现在连picasa web都好不了,可悲啊。
还是转回wordpress吧,至少是个PHP的程序,国内也好找地方安顿,最多不用国外的虚拟主机行了。
gae.sharesh.cn域名保留,毕竟这个域名要用来A解析的,其他的几个都要靠他的,所以就不准备废弃。
只是这里停止更新了,以后再更新的话就去sharesh.cn/blog了。没有什么好说的,GAE我也更改了多次IP了,头大。
也不是因为micolog的程序不好,更多的是因为GAE被这封那封,现在连picasa web都好不了,可悲啊。
还是转回wordpress吧,至少是个PHP的程序,国内也好找地方安顿,最多不用国外的虚拟主机行了。
gae.sharesh.cn域名保留,毕竟这个域名要用来A解析的,其他的几个都要靠他的,所以就不准备废弃。
只是这里停止更新了,以后再更新的话就去sharesh.cn/blog了。没有什么好说的,GAE我也更改了多次IP了,头大。
网上一牛人的代码,已经沿袭了很多年了,我算是保存一下,以免下次用到的时候不担心。
--2 实现全角与半角字符转换的处理函数
CREATE FUNCTION f_Convert(
@str NVARCHAR(4000), --要转换的字符串
@flag bit --转换标志,0转换成半角,1转换成全角
)RETURNS nvarchar(4000)
AS
BEGIN
DECLARE @pat nvarchar(8),@step int,@i int,@spc int
IF @flag=0
SELECT @pat=N'%[!-~]%',@step=-65248,
@str=REPLACE(@str,N' ',N' ')
ELSE
SELECT @pat=N'%[!-~]%',@step=65248,
@str=REPLACE(@str,N' ',N' ')
SET @i=PATINDEX(@pat COLLATE LATIN1_GENERAL_BIN,@str)
WHILE @i>0
SELECT @str=REPLACE(@str,
SUBSTRING(@str,@i,1),
NCHAR(UNICODE(SUBSTRING(@str,@i,1))+@step))
,@i=PATINDEX(@pat COLLATE LATIN1_GENERAL_BIN,@str)
RETURN(@str)
END
GO
调用的时候记得函数前面加dbo.就可以了,select或者update就随便用了。
报警点,可以狭义的理解为电子狗,就是对电子警察的报警,而这里所谓的电子警察主要为测速照相的摄像头,当然也包括违章、闯红灯等等摄像头。从广义上讲,报警点就不仅仅局限于电子狗了,从现阶段各大导航软件公司的做法来看,亦是如此,报警点现在可以对事故多发地段、学校门口、连续转弯道路等进行报警。狭义的报警点是为了避免大家吃罚单(从现阶段的用户心里来看就是为了不让电子眼拍到而产生罚款),而广义的报警点已经远远超过了仅仅避免违章的避免违章的境地,进入了让用户开车更安全的层面。广义的报警点甚至可以延伸的更远。
那么,我们如何来做好报警点呢?这里就涉及到了报警模型,本文将从软件、数据的层面来提出几个报警点模型,欢迎大家共同讨论。当然,测雷达波的电子狗不在本文讨论范围,本文中的报警点是固定的点位,带有坐标的点位。
从市场上来看,一般都将电子狗区分为固定测速电子狗和流动测速电子狗,当然好一点的则是固定流动一体的电子狗。
从个人的理解来看,最早出现的是流动测速电子狗,侦测雷达波段进行报警,从早期来看交通部门也基本上都采用雷达波来测试,而这样的测速仪器一般都是固定的波段,所以只要用个侦测雷达波的芯片加上简单的设计就可以做成电子狗,据说好的芯片现阶段还需要从国外进口。但这一招基本上不灵了,因为许多城市都开始采用地感线圈测速,即道路上前后安置两根固定距离的测速线,车辆压过以后直接得到时间差,速度也就直接可以得到了,如果超速则立即启动摄像头拍照。听说还有更先进的测速设备,照相机连续拍摄两张照片,根据照片谍影加上照相机拍照的时间差而得到速度。当然,上面说的是测速类的,而一般测违章并线、闯红灯等等还是采用的地感线圈。所以,基于雷达波的电子狗在渐渐的失去市场,而这样的电子狗现在也非常便宜,效果也就越来越差了,所以那些配备了电子狗的司机朋友经常说许多测速点都不报警。并且,此原理也有局限性,比如有时候会无缘无故报警,为什么,可能是因为马路附近的工厂等产生的非电子警察的雷达波,但频率却和电子眼一致,不过这个应该测交通部门的流动测速车(就是一辆车顶装有雷达测速设备的警车)应该比较准。顺便说个好玩的,据说台湾地区有些人为了让那些采用地感线圈的电子警察也被测雷达波的电子狗侦测到,就采用“手雷”的形式,就是将带有雷达波发射功能的一个小东西丢在这个十字路口的附近,不过我们会担心成本会不会太高啊、电池使用时间多长啊、会不会被清洁工阿姨清扫掉啊。讲了这么多的雷达波测速电子狗,但他们不在我们的讨论范围,因为硬件的局限加上流动的原因。
固定测速电子狗就比较简单了,因为固定那么肯定和位置有关,就是事先已经知道了在哪个位置有电子警察,将这些位置预装到电子狗中就可以了。但怎么确定这个电子狗的位置,难道告诉电子狗说在A和B的路口有个往东方向拍摄的电子警察,这肯定是不可取的,并且怎么让电子狗知道你的位置并和电子警察位置匹配,由此看来只有一个办法,就是采用GPS,电子警察的位置也就是X和Y的经纬度,而车辆位置直接使用GPS定位,当接近电子警察点位一定范围的时候便开始报警。 从这里也不难理解为什么固定测速电子狗比较贵了,因为他们同导航设备一样,也采用了GPS,那么GPS接收芯片的成本是不能少的,当然现在来看GPS芯片也是在不断的掉价。不过,看这市场让我不明白的是,为什么用户会买一个千把块钱的电子狗却不买导航仪,毕竟导航仪现在也是超级的便宜那,可能是因为贵的电子狗专业而导航仪并不是专业电子狗吧。固定测速电子狗的好处可能是能够对非雷达波的测速设备报警,当然其实固定测速电子狗最重要的是和报警数据有关,如果没有及时更新那么固定测速电子狗是无法报警的,因为数据中不存在新的点位,所以我也能够明白为什么卖固定测速电子狗的商家说这个能够更新数据什么的。而虽然说固定电子狗的原理就是简单的接近报警,但是如何接近并按照什么条件进行报警,这就变化多端了。另外,车载导航设备中所谓的电子狗功能也基本上是固定报警点,根据固定点位和一定的条件产生报警。由此,我们从数据和软件的角度讨论一下报警点数据和报警模型。
在谈报警模型之前,首先要了解一下报警点情况,以最常见的电子警察为例,除了坐标位置以外,还有方向,比如往东还是往西方向,如果再细分一下,分为拍车前部还是拍车的后尾。
1, 接近报警,最简单的报警:
假设在坐标位置为x和y的地方有一个报警点,我们设置一个半径为z的警示圆,当车辆进入该警示圆则自动报警。模型如下:
图中红色点表示报警点,红色的圆表示半径为z的警示圆。
优点:只要进入警示圆就会报警。
缺点:没有方向。图中蓝色箭头从圆中心穿越会报警,而紫色箭头虽然没有从圆中心穿越,但也会报警,同时如果从蓝色箭头的逆向进入,也同样会报警。
补充一点,如果使用圆进行判断有难度的话,可以改用正方形,以报警点为中心绘制边长为两倍z的正方形,同样也能达到报警的目的,只是这样的做法虽然更加简单,但精确度会降低很多,正方形正切圆后圆外边的部分就是不符合精度要求的。变换后的模型:
2,带角度的报警:
接近报警是最简单的报警,由于它自身的弊端,我们应该如何改进。改进方法就是让报警带上角度,这样就解决了没有方向的问题,这也是最常能够考虑到的方法。模型如下:
如上图所示,绿色的表示角度范围,角度可以自行调整大小。只要从绿色范围进入的,就进行报警,而红色范围内的不报警,上图所示的蓝色箭头肯定报警,而紫色箭头不报警,同样,蓝色箭头的逆向也不会报警。另外,角度大小的调整可以控制报警的精确度,太小了可能会少报,而太大了可能会多报。
此方法较好的解决了接近报警的不足。大部分的报警模型应该采用此方法。
3,双重区域叠加报警(带角度报警的变相方法):
带角度报警的方法确实非常的好,那么是否有一种比角度更加简单的模型呢?有的,就是双重区域叠加报警法,此方法较少见,但也是拥有一定意义上的角度功能,简单的说就是大圆套小圆,如果进入叠加区域则报警。模型如下:
图中绿色区域为报警区域,如果沿着蓝色箭头方向进入绿色区域则报警,而如果从蓝色箭头的逆向进入绿色区域则不报警。也就是说,要求同时进入到两个区域才能进行报警,如果先进入大圆区域后再进入小圆区域,则不报警,此点是让报警带上角度的关键。
但如果使用圆形,可能不容易判断,如果把圆形改成正方形,则报警的判断相对来说要变的容易的多:
4,缓冲区报警:
虽然现在的测速探头都是一个坐标点位,但很多的时候拍摄的是一条道路,但这个道路可能不是直的(至少在摄像头前的一段),正好是拐弯处(比如匝道),这样的话导致角度报警会产生较大的偏差。严格的说,报警本身就是针对道路的报警,就是说摄像探头的范围一般都是针对道路的,不可能面对一片非道路区域,角度也就是对着道路的角度了,所以如果根据道路的形态建立一个buffer,在这个buffer区域内进行报警就会变的非常的完美了。模型非常简单,如下图所示:
图片画的有点夸张了,但大概的意思即是如此。报警点在末端,根据蓝色的道路建立一个buffer,得到红色线条所示的区域,该区域即为报警区域,如果从buffer的头部(图中的上部,和报警点相对的另一端)进入buffer就进行报警。
从缓冲区报警延伸开来,如果地图数据供应商将摄像探头和道路ID对应起来,那应该就是比较完美的做法了。
从个人理解的角度,简单谈了这几种报警模型,有可能有更好的报警方法,欢迎补充。本文的前半部分的介绍是在三个月前完成的,而在模型讲解部分是今天赶出来的,风格有较大的差异,后面的模型讲解也过于简单了一些,有点虎头蛇尾的味道,请多多包涵。最后留下两个问题给大家思考:
1,探头在马路另一侧(就是探头在绿化带隔壁的马路上,但拍摄的却是这一侧的探头)的该如何报警?
1,对于拍车屁股(常规的是逆着车行驶方向拍摄车头部分的车牌,但此类型探头是顺着车行驶方向拍摄车尾部分的车牌)的探头该如何报警?
今天讲解照片处理工作流,其实也就是从拍完照片到发布到PicasaWeb的整个过程,这个过程可能仅仅是个人的过程,但拿出来和大家分享探讨。
拍照已经成为习惯,对于使用相机拍的照片我基本上都会放到网上,现阶段来看已经有6000多张照片,非常感谢Google Picasa Web功能,能够让我存放并进行二次开发(此点以后再讲),而照片从SD卡中拿出后到照片传到Picasa Web,中间应该做一些什么处理呢?根据我的需要,我要处理的内容有:
1,批量缩放:将原来3072×2304像素的照片进行缩小,因为这样的一张照片太大了,如果直接上传肯定浪费很多空间,并且显示速度也不快,所以我准备将其批量缩放至640×480,容量小很多,并且显示速度也够快,这样的像素就放网上随便看看了。
2,添加GPS信息:因为我一路记录航迹,一边拍照,为了最终能将我的照片钉在Google Earth或者Google Map,我要将GPS信息添加到照片中,其实就是EXIF中的一个GPS属性信息,此点也要求批量处理。这里基本的原理就是,先将相机的时间和GPS时间保持成完全一致,这样拍出的照片就能根据拍照时间来对应到航迹中的点位或者航迹段。
3,添加水印:虽然不加水印也无妨,但为了更多的人看到图片后能够访问,或者保护一点点所谓的版权,所以基本上都会打上水印,至少要用水印说明一下这照片是你的吧,我想,大部分人都希望的吧。
4,在Picasa Web中能够显示照片的标题信息,这一点的用处在于回看所有照片,你对照片进行说明,比如某某公园正门,人家一看就非常的明了这照片的意思。许多的人都使用将照片命名成中文名称的方式,就是用文件名来说明照片内容,其实这是不科学的,因为中文名在网络中对于URL来说不友好,而有时候当你上传照片后会自动重命名文件,导致名称说明无效。此点确实是非常需要解决的问题。这里我以Picasa Web为例,其实Picasa Web中照片的说明是在IPTC中的信息。
5,批量在EXIF中添加信息:因为EXIF可以有很多的信息可以添加,比如版权、名称、作者、相机型号、甚至曝光度、ISO等等,对于我来说,基本上需要批量添加名称、版权、作者等信息,上传后才能让用户了解到更多的信息,虽然这是不可以直接看见的信息。
OK,对于以上几点,我们的工作流也是按照这个来进行的,不过,根据你自己的需要,你可以调整工作流,比如第一第二你根本不需要处理。根据这个工作流,我用到的软件有:
Google Picasa3:Google出品的超级简单易用的照片浏览处理软件,强烈推荐。
GPicSync:强大的给照片添加GPS信息的软件,而且还是开源软件,并且能够导出KML/KMZ格式
PhotoWatermark:照片批量水印软件,简单易用。
cPicture:强大的照片处理软件,不过我基本上只用它来批量处理EXIF信息。
其余软件来看,像AcdSee:简单的查看EXIF、IPTC信息的软件;IrfanView:和AcdSee功能类似的开源看图软件,只是我用的不是很习惯,最多用他的批量处理转换功能对照片进行一些批量处理;PhotoInfo:微软的工具,基本上是用来批量修改IPTC的吧。这三个基本上最多算是辅助吧。
下面仍然按照工作流我们来用软件处理照片:
批量缩放:将照片导入到Google Picasa中后,使用导出为HTML页面功能,选择一个像素、路径和模板就可以直接将你的照片全部导出到一个目录,其中images就是缩放后的所有照片所在目录,你也可以在IE中查看最终缩放效果。顺便说一句,导出为HTML页面这个功能还支持模板的,你完全可以定制一个符合你自己需求的模板来,模板文件在web\templates目录下。要知道我以前偷懒的时候是,将模板文件制作好,然后通过Picasa输出HTML后,直接将这些文件上传到服务器,就可以浏览了,当然这是极端懒人的做法,呵呵。既然说到这了就顺便推荐一个模板的网站吧:www.paulvanroekel.nl/picasa,虽然模板不多,但总的来说还不错,可以参考学习,我比较喜欢Lightbox的那款模板。
添加GPS信息这一点可以参考我的照片导航高级教程一文,说的比较清楚,本文就直接略过好了。
添加水印使用PhotoWatermark软件即可,非常的不错,不过你先要做好水印,我是在正中和右下角共做了两个水印,这个软件用法也很简单,在此也不多再赘述。
关于显示标题问题,将添加水印完成的照片导入到Picasa中,然后浏览图片,直接输入说明内容即可,在照片的下边“制作图片说明”就替换成你自己的内容了,Picasa其实是修改了IPTC的caption属性内容。由于添加水印软件无法保留IPTC信息,所以此步骤就放在这一段进行了,不然我肯定是首先处理IPTC信息。
而EXIF中需要修改的有名称、说明、版权等信息,找到所有图片后,你点击左下的EXIF信息修改功能,跳出一个框出来,就是名称、版权、说明等信息内容的填写,这点保存可就是批量处理哦。这里需要注意一点的是,IPTC内容的caption属性,不要改成你自己的,不然所有刚刚上面一步做的你又白做了,留空就表示保持原样。
最后就是上传图片了,当然是用Picasa的上传到网络相册功能就可以了。简单吧。在此我强烈推荐PicasaWeb,还在寻找网络相册的朋友就不要找了,Google提供了1GB的免费空间,还支持外联,速度等各方面更是不用考虑,而且能够使用PicasaWeb如此方便的上传,还犹豫什么?赶紧去注册一个吧。163相册、巴巴变、Windows Live相册等等和PicasaWeb根本无法比拟。
大概就讲到这吧,算是推荐几个软件吧,如有问题或者更好的软件推荐,欢迎mail我。
虽然Micolog提供了从WordPress文件导入日志的功能,但WordPress到Micolog的转换总不是那么完美,简单的来说,表现有二:
1,如果item中包含<title>*******.jpg</title>字样,导入自动中段。我也不知道为什么WordPress导出的xml文件中会存在这么怪的内容,又不是日志,纳闷。
2,图片无法导入。如果你日志搬家,从WordPress转换到Micolog,那么原来的图片怎么办?要么以静态文件形式上传到GAE,并建立好相应的路径,但如果文件太多,肯定会担心超过1000文件的限制。最好的办法当然是按照Micolog的格式,将所有图片导入到GAE的数据库中。
今天我们就来解决这两个问题,按照我的需求,用python写了一段code,运行后就可以将WordPress完美导入Micolog。我们先来将具体操作,然后讲原理。具体操作如下:
0,备份你的所有的WordPress的文件到本地(本工具主要用到上传的文件)。进入WordPress的后台,将所有日志导出为wordpress.xml。这两个在后面需要用到,所以在开始前请先处理完毕。
1,编辑app.yaml文件,配置remote_api路径,如下:(具体路径可以自行修改)。(当然,这里还包括了micolog的上传等,请自行解决,如果已经上传了micolog的,请初始化数据,并进入数据库中将除了blog数据外的所有数据删除。)
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin
2,下载我的WordPress2Micolog.py文件,编辑该文件中的几个参数为自己的参数:
#这是应用程序ID
app_id='myappid'
#如果是本地处理,则将host改成你自己的url路径,如果直接在appengine上处理,则使用appspot.com
host = '127.0.0.1:8080'
#host = '%s.appspot.com' % app_id
#remote_api的路径
remoteurl='/remote_api'
#原有Wordpress的URL
wpurl = 'http://share.sharesh.cn'
#本地Wordpress的路径
wppath = 'E:\\PHPnow\\htdocs\\blog'
#WordPress.xml文件所在目录
xmlpath = 'E:\\PHPnow\\htdocs\\blog'
3,运行WordPress2Micolog.py文件(建议使用python2.5自带的IDLE运行,如果有错误还能看到具体问题所在),等待。此步骤主要是上传所有图片,并根据wordpress.xml文件生成micolog.xml文件,micolog.xml文件中图片的路径已经是micolog的路径了。
4,进入micolog后台,导入,选择刚才生成的micolog.xml文件,直接导入即可。补充几句:建议使用FireFox导入,不要使用IE导入;如果中途发生中断,则是GAE超时,在micolog.xml文件中找到导入的最后一个记录的item,将catalog、tag和已经导入的item项目全部删除,留下没有导入的item项目,保存文件,再次导入,直到完成即可。完成后建议在micolog后台的工具中重新建立一下文章链接。
下面说说思路:
看了整个流程也基本明白我的思路了吧,其实重要之处在于WordPress2Micolog.py,这个文件的作用是什么呢?主要完成三件事情:1,将xml文件中多余的item项目删除,以保证上传到micolog中没有问题;2,根据xml文件中的img和a,将所有图片上传到数据库;3,根据已经上传了的图片修正xml文件中的img的src和a的href路径。
所以我分成了两个function,第一个function就是wordpress到临时文件,将无效的item删除,并将所有图片上传到数据库中,第二个function是根据数据库中的图片生成新的有效的图片链接,并最终生成xml文件。
不过,工具也有问题的地方,由于我没有png和bmp等图片格式,所以我只判断了jpg格式的文件,在item的判断中仅仅判断了jpg,而在上传到数据库的时候呢,又是直接将类型定义为了image/jpeg。另外就是数据库中的name我设置成了原始的图片url,而不是jpg的名称。总的来说并不影响,如果你的情况特殊,那么请按照代码自行修改即可。
顺便测试了一下micolog导出wordpress的功能,发现wordpress完全可以通过,只是,图片和wordpress2micolog一样,无法直接下载并更新链接,看来以后我要是micolog导出到wordpress的话,还需要再写一个工具,my god。
一直没有发表日志,今天终于写上一篇来充充数。py的code写的很菜,如果看到我写的python觉得很好笑,请给出一定的指点,但确实让我这样的小菜菜也花了我不少时间,所以感叹,写code真是一件痛苦的事情那。
最后说一下我测试通过的情况,提供给大家作参考:wordpress.xml:1.75M;post:144;jpg file:799;micolog.xml:486K。本地测试通过,用时大概而是多分钟。而正式上传到GAE的过程中,失败了好几次,不过好在我分成了两个function,所以wp2temp的function完成以后如果temp2micolog的function失败,那么把wp2temp的function注释掉,让其直接进入到temp2micolog的function即可。这里需要说明的是,如果wp2temp的function中途失败,请务必到数据库中将所有的图片删除掉,不过删除后不知道为什么数据库竟然占着空间不变小,郁闷,这个就下次再考虑吧,但也看来,我的程序还是需要改进的,至少能够断点续传吧。最终的测试结果是:上传799个图片花费40分钟;重写micolog.xml花费60分钟。总共花费100分钟,够让人晕的,看来还真要改进改进。
最后的最后:感谢step1
自从上次发布了Google Maps API离线开发包以后,就有人来问我,为什么离线状态下不能显示地图,能否显示自己的DIY地图。严格来说,这是两个问题,为什么不能显示地图是因为Google的地图图片本身就不在本地,所以离线状态下是肯定不能显示地图的,不过能够标点画线等动作下有没有地图图片并不重要,而能否显示自己的DIY地图,其实Gmaps API本身就带了,GOverlay/GTileLayer等函数就是能够添加自己的图片,只是我不喜欢只添加一张图片到Gmap上,觉得意义不大,但又没有找到好的tile的切割工具,所以这个功能我一直没有尝试。今天,我向大家推荐GMapImageCutter工具,一个能够将图片切割成tile的工具,并且还帮你生成了HTML文件,直接就能够浏览,厉害。
其实这个工具最早是在IT168上看到的,我就下载了下来,但一直没有安装java环境,所以一直没有怎么用,IT168的文章我也没有怎么看,但大致知道怎么一回事,今天安装了java环境所以就可以跑起来试试看了,用下来感觉非常的好。所以就打包上来和大家分享,除了工具,还带了我的Google Maps API的离线开发包,还带了北京师范大学和北京动物园两个地图的DEMO,这两个DEMO只要部署到IIS或者Apache上就可以使用,即使是在离线状态下。
OK,下面我们就来讲讲这个工具的使用吧。GMapImageCutter.jar这是该工具,是java的程序,通过命令行方式就能使用:javaw -Xms512M -Xmx1024M -jar gmapimagecutter.jar。当然我们只要运行GMapImageCutter.bat就可以(这里首先要保证的是你有java的环境,安装个J2SE)。运行后可以看到如下图所示的界面(这里我已经打开了北京动物园的图片了):
该工具自动判断图片大小,然后选择一个缩放级别,当然你也可以自己调节缩放级别,只是对于图片来说,调高缩放级别,那么你的图片就被拉升了,这样就模糊了,具体看你自己的需求,你也可以把图片做的非常大然后缩放级别就可以调到非常高。按照这样的理论,你甚至可以生成Google Map的全部图片,17个层级的所有图片,呵呵,这里当然是玩笑了,虽然工具上可以调到17级别,一是你做不出这么大的图片,二是即使做出来切割也不知道要经过多少时间,三是切割出来的文件会非常的大,存放都是一个问题。OK,说多了。下面你点击create按钮,开始就可以切割了,等待完成你会看到在图片的相同目录下生成了一个html文件和一个图片目录,调整一下html中Google Map Key为你自己的key,你就可以发布你自己的地图了,简单吧,一个DIY的WEBMAP就此诞生了。
只是我调整了一下html中的代码,让其运行在我的离线开发包上,结果也能显示没有任何问题,这样的话你甚至可以脱离在线的Gmaps API,使用我的离线开发包发布你自己的地图在你自己的服务器上,所有的一切都是你自己的,并且重要的是还能够用Gmaps API来开发,比如我在BNE demo map中加入了一个marker点,后面你想做什么就完全由你自己去想了,画线画面添加点位等等等,你都可以自己完成,俨然就是一个自己的比较强大的WEBGIS(强大之处就是支持Gmaps API开发,呵呵)。
压缩包内文件说明:
GMapImageCutter1.4:GMapImageCutter工具
DemoPicture:样例图片,北京师范大学平面图和北京动物园平面图
gmap:Google Maps API离线开发包,内附北京师范大学和北京动物园地图demo
预览效果:
将gmap目录拷贝到IIS的主目录下,在IE或者FireFox浏览器地址栏输入:
http://127.0.0.1/gmap/BNUmap.html
http://127.0.0.1/gmap/BeijingZoo.html
即可浏览北京师范大学和北京动物园的demo地图效果
其中北京师范大学demo地图进行了简单的修改,取消了地图自适应长宽的内容,并增加了一个marker
如果你不想使用Google Maps API离线开发包,只需要将html文件中调用的maps_my.js替换成你申请的Google Maps API的地址即可
你也可以使用GMapImageCutter切割一下两张样例图片试试看效果。
当然,该工具也是有些弊端的,或者说是需要考虑改进的地方的。
首先,有一个层级是图片的原始大小,而小于该层级则是对图片的缩小,大于该层级是对图片的放大,这样的情况下除了图片原始大小状态下保证图片质量最好外,其余层级都可能对图片造成模糊甚至看不清,如何保证每一层级下都是清晰的图片,这一点需要进一步的考虑,不会做一些不同比例尺的图片然后再进行切割吧,也许这也算是一种方法吧。
其次,图片都是从Google Map的最小层级开始的,也就是说这个图片的坐标范围是纬度方面是南极到北极,经度方面是东经到西经,那如果该图片本身就是某一经纬度的范围,比如是30-31/120-121,那么如果将该图片贴图到该经纬度范围这才是最完美的也是大部分人所需要的,这个问题该如何解决,可能需要进一步的思考。
总的来说GMapImageCutter确实是非常不错的tile生成工具。
下载地址:http://files.cnblogs.com/Tangf/GMapImageCutter_WebMapDemo.rar (GMapImageCutter工具+样例图片+DEMO地图+Google maps API离线开发包)
在上次的照片导航教程中,我们讲述了如何利用航点和Google Earth进行照片导航,今天我们来讲照片导航的高级教程,用更高级的工具和方法自动批量照片导航,其实就是用工具批量将照片添加经纬度。
首先我们说一下具体的原理:既然用工具批量将照片添加经纬度,那么肯定要有经纬度的东西和照片进行匹配才能处理。对的,没错,这个带有经纬度的就是我们需要的航迹,将航迹和照片进行匹配,用软件将航迹中的经纬度信息添加到照片中,而这里依照的关系就是时间,相同时间点的航迹匹配相同时间点的照片。所以,这里的关键是出发和拍照前首先要将时间调整到一致。当然,部分软件也有自动调整时间差来做对应的功能,但个人觉得将时间匹配到一致是最好的,省得到时候自己还要算时间差。OK,今天带上我们的设备:一台255W,一台柯达相机,可以了,出发,目标是朝阳公园。
用了下午四个小时的时间,我算是走完了整个公园,不一定全面,但至少走了整整一大圈,累死了,来看看我的路线吧,这就是我所走过的全部路线了。总共走了11.3公里,平均速度为每小时3公里,不容易那。
言归正传,具体如何操作请听我慢慢道来。
第一步,取出数据
使用USB数据线将255W设备和电脑连接,等待电脑将设备闪存识别为驱动器,进入内存驱动器,在Garmin目录下的GPX目录下找到Current.gpx的文件,拷贝出来,以做备用。其实,这就是所有的航迹文件了,你完全可以用MapSource工具打开进行查看,上图的截图就是在MapSource中打开后的截图。
第二步,取出照片
这一步就不多讲了,大家都知道,将照片从SD卡保存到电脑硬盘。
第三步,安装工具并匹配坐标,最最最关键的一步。
今天我们要使用到的工具呢,是GpicSync,虽然其余的工具也可以,比如PhotoMapper、pixGPS等,但这个可能功能比较强大,加上还有简体中文,最重要的还是开源软件,所以就用这个了。当然,这些软件我也没有怎么用过,但应该是比较简单的,所以我是边做边写。
先下载该软件,下载地址:http://code.google.com/p/ gpicsync/,然后安装该软件,完成后打开该软件,我们就可以看到如下图所示:
最上面两个框第一个是照片文件夹,下面一个是GPX文件的路径,至于下面的选项,基本上都不要选,除了备份相片。在UTC时差上输入8,因为gpx文件的时间是UTC时间,而我相机的时间设置的是北京时间,而对于相片定位相差少于多少秒的选项中,默认300秒即可,因为你本身已经把时间对准了并不存在太大的误差,从最后的时间上来看这个差距一般少于一分钟,300秒相对来说是比较宽松的。然后点“开始同步”,OK,你的相片就开始自动添加坐标信息了。稍等片刻,然后提示完成,这样的话除了将照片添加坐标信息外,该软件同时生成了缩略图和kml文件,你只要使用Google Earth打开该kml文件就可以看到你所有的照片了,如下图所示:
酷吧,朝阳公园这个kml文件下有Photos和Track两个目录,Photos就是你所有的相片,而Track就是你的航迹所在路径。可见,该软件是多么的强大了吧,甚至都可以建立在线照片分享,这些强大的功能也等我下次再来讲解吧。
Google Earth如果玩的熟的话,甚至可以建立一个飞行视图,点图层上方那根轴线的右侧那个按钮,就可以从头开始飞行一下你走过的路,再来看一遍照片。当然也可以保存这段飞行纪录,直接点击后就可以观看。甚至你都可以将这些内容直接打包成kmz文件,分享给朋友,不过照片不要太多太大哦,我这里三百多张照片共400多M,打开后就差不多要死机了,最好先将照片处理一下。
最后需要注意的一个地方就是,软件生产的kml文件是默认编码的,因为我们的系统都是中文版,所以一般都是默认GB2312的简体中文编码,需要将kml文件打开另存为UTF8编码的文件,这样的话Google Earth打开有中文字符的文件才不会乱码。
OK,至此我们的照片导航高级教程也算是完成了,至于更高级的功能以及美化等,我们下次再来分享吧。现在你就可以把这些照片放入到任我游760中进行照片导航了,试试看吧。
=======================================
朝阳公园半日游顺利结束,处理完毕后最终我上传到PicasaWeb,经过与Google Map和Google Earth对比,发现还是有一定的偏差,距离不是很大,但能够明显的感觉出来,因为我拍照时候站立的位置和照片在Google Map中的位置有十米左右的偏差,可能时间匹配上还不够准确吧,应该调整一下就好,但整个的思路说明完全可以走通了,下次就是更加完善的工作了。来看一下我的294张朝阳公园的照片吧:
我自己的相册地址:http://photo.sharesh.cn/beijing/ChaoyangPark/
Google PicasaWeb地址:http://picasaweb.google.com/tangf2004/ZMlLdJ
在Google Map(请调整为卫星视图)中查看我的照片:http://picasaweb.google.com/lh/albumMap?uname=tangf2004&aid=5316202756299254193#map
当然也可以在Google Earth中查看:http://picasaweb.google.com/data/feed/base/user/tangf2004/albumid/5316202756299254193?alt=kml&kind=photo&hl=zh_CN
在Google Map中打开这近300张照片也是有点慢的,并且也吃内存。为了更好的兼容,此次我最终使用了真实坐标来标记照片,因为我还带了一台60CSx进行地球坐标轨迹的记录。最后,此次照片最大的失误是忘了加水印,不想再麻烦所以就这样吧,不过我在EXIF里已经写了版权等信息了。下次我们继续讲照片的处理,主要是在自动调色、批量大小调整、上传到相册、EXIF信息修改等小细节问题了,让你和我一样拥有一个免费而强大的相册系统,真心感谢Google。呵呵
手机带导航功能(硬件)是一种趋势
个人认为,手机导航分为两个阶段。
第一阶段:运营商告诉手机用户说,我们有手机导航了。01 年的时候移动就基于移动梦网推出了位置服务,03 年的时候联通推出了定位之星的服务,这些就是很好的例证。运行模式可能是:用户发送指令消息至服务中心,服务中心通过GPRS定位返回用户当前位置。然后用户发送指令消息以获得周边“餐饮”、“停车场”等服务。这样的模式多为文字模式,最多附加部分图片。而即使能够导航,多为文字信息导航或者语音导航,不可能是地图式实时导航。
这个阶段在硬件上没有太多的限制,大部分手机用户都能使用,仅仅需要运营商的网络支持即可。但这个阶段不能完全称之为手机导航,最多应该称之为手机定位。而且,这么枯燥的手机导航功能,一点也没有新意也不吸引人。
第二阶段:手机+GPS 接收模块。刚开始的时候,智能手机通过外接的蓝牙GPS 模块实现手机导航功能。而后期,随着芯片主板厂商的发力(如 MTK),研发出一体化解决方案,手机就直接带有导航功能。这个时候,导航手机将成为音乐手机、拍照手机之后的又一大亮点。手机导航也将成为手机的一个标配。
手机导航软件:遍地开花
对于第一阶段运营商提供的导航功能,我们不能称之为导航软件。并且,这样的导航功能存在很大的缺陷:实时性差,定位精度低。运营商提供的导航功能在以后的竞争中将会被淘汰。而采用集成导航的手机硬件厂商,由于实时性好、定位精度高,将在未来主导整个市场。
第二阶段(手机和导航已经集成)的硬件厂商已经把硬件做好了,硬件厂商就想,总该配个导航软件吧,不然我的 GPS 硬件不就形同虚设?于是,许多原本便携导航的软件公司就开发了手机导航软件,比如灵图、凯立德等,当然也有Garmin、Route66甚至Nokia等国际公司。
但问题也随之而来,手机硬件配了导航软件,第一,导航软件不会免费,一定增加了手机成本,第二,导航是否能够让用户接受也是一个问题。
手机导航软件存在的问题:a,功能单一,只是导航功能,创意功能等待开发。b,操作不方便,没有PND 方便。c,受到硬件平台的制约,导航软件的性能各不相同,没有PND 稳定。d,软件不免费,再好用心里也有一个门槛。
导航软件如何“破冰”
对于混乱复杂但又前途光明的导航软件该何去何从呢?如何做好手机导航,个人有几点感想:
第一,软件必须免费。
免费的东西因为没有门槛,所以容易让许多用户接受,同时也让硬件厂商容易接受。免费让导航产品的普及率提高,能够迅速占领市场。
第二,各种功能能够组合,并且实现简单。
软件虽然免费,但免费的仅仅是一部分功能,比如免费查看查询道路。但搜索POI 以及导航,需要付费。而且能够根据客户需求,提供多样化的个性POI和导航。比如只需要上海的POI 查询和导航功能,或者仅仅是全国的餐饮查询等。
同时,各种功能能够简单组合。比如,一个带 Route 属性的文件让用户下载,用户注册后即可导航。用户下载一个上海的 POI 文件并注册后即可启动 POI 查询功能。
第三,多种创意功能。
创意功能方面如天气预报、当前点位坐标图片互传等等,必须不断开发出有创意的功能。当然,创意功能的开发也是一个痛苦的过程,因为重点在创意,技术实现也许不是难题。
这里特别突出一个RichPOI(富兴趣点)功能,在这个功能可以做更多的文章。
第四,服务多样化。
因为手机用户群的不同,所以需求也大不相同,这样需要多样化服务。比如,一个商务人事从北京出差到上海,以前注册了一年的北京 POI 查询功能,发现很好用,于是想在出差期间注册一个月的上海 POI 查询功能。OK,没有问题。比如对于学生人群,对学校附近的比较关心,可以开发出学校附近的特色 POI 查询。
第五,突出富信息功能,让内容提供商(CP)介入。
这个社会已经是信息社会,信息就是价值。但对于软件提供商,提供丰富的信息内容,不在行也不能够做好。而已经掌握丰富信息内容的信息公司(比如大众点评,甚至携程)又不知道如何通过更多的渠道让他的信息赚钱。OK,现在,我们软件提供商给信息商一个平台,让其成为内容提供商,共同分成。
对于内容提供商,又找到了一条盈利的道路了。既然能够盈利,内容提供商愿意推广他的内容。而对于软件提供商来说,不仅提供内容互动平台盈利,并且内容提供商的内容推广也是对软件的一种宣传。越多的内容提供商介入,将会确立软件在手机导航市场的地位。
第六,手机网络和互联网并存。
虽然手机是一个网络,但随着3G 的来临,手机网络和互联网越来越融合。但是,两个网络还是各有优劣,即使互联网直接可以在手机上使用。由于手机网络速度、操作不方便等限制,有手机的用户使用的更多的是电脑互联网。
手机网络和互联网络应该是互补的两者。手机能够浏览地图,那么互联网上的地图(是指WebMap,如 Mapbar、Mapabc、51ditu 等)就更普遍了。而两者如果互补,将会是一件很有意思的事情。比如,手机保存的兴趣点放到网上去浏览,在网络上建立我的喜爱点网络库(如GoogleMap的myMap功能),让更多的人浏览。同时,可以分享他的喜爱点(比如一个美丽的景点、一个口味很好的餐馆)给朋友,让其他的朋友也能导航到这个地方。
应该讲,互联网将给手机导航一个扩展的平台,并且,互联网平台是一个比较成熟的平台。
第七,互动。
口传口是一种非常好的宣传方式,让用户互动是提高用户之间口传口的很好途径。如何让用户通过互动?比如,互传一个短信是最简单互动。那么通过软件互传一个带有位置图片的彩信,也是一个互动。有很多时候不知道该软件的用户收到该彩信后觉得非常好奇,一定会问朋友怎么能传带位置的图片的,这也是一种扩大用户的途径。
Google 通过免费的方式让用户了解了 Google Map 和 Google Earth,通过 KML和Google Map API 的方式让用户互动,让更多的用户凝聚到他的产品之下。那么,手机导航的互动又何尝不应该如此呢?通过自制兴趣点、自制地图、分享喜爱点、分享轨迹等功能来进行互动,让更多的人凝聚在软件产品之下。
互动不仅仅如此,比如用户自己制作了一批信息点,然后通过互联网分享给他的手机朋友,这也是互动。更长远的,用户自制了一个地图,叠加到原来地图的上面,并分享给朋友。(比如学校在软件中没有详细地图,学生自制后叠加到软件中的地图上,分享给朋友,增加了互动)
学生,是一个很大的手机用户群体,并且手机档次普遍比较高,同时又是知识份子,所以对新奇事务充满了好奇,又有很强的表现自己的欲望。学生将是很大的手机导航软件用户群(使用导航功能的不一定多,但定位互动等功能将是他们重点,并且,手机导航在学生市场还没有推广)。
有一个词:SaaS(Software as a Service),现在日益热门,中文直译就是“软件即服务”。对,软件就是服务,软件所有权属于供应商,供应商不断完善软件平台,而用户则按照需求和周期来租赁供应商的服务。在今天,IBM都已经是一家服务型的公司,而Nokia更是加大了对增值业务的投入(81亿美金买入NAVTEQ就是绝佳的例子),那么SaaS的全新理念是否也可以引入到GIS、GPS、LBS、MobileNavigation等行业呢?重点正如文中的所言,用户买到的是手机导航的服务,而不是软件。
End_________________________华丽的分割线______________________
本文首发3snews《3S新闻周刊》第18期。虽然文中主要文字写于两年前,但想法至今没有改变,让我们一起来期待手机导航市场的繁荣吧。
先给出我的链接吧:http://photo.sharesh.cn (我的二级域名)或者http://shareshcn.appspot.com (Google提供的二级域名),总共三个页面,主页面是地图,然后有一个相册页面,然后就是照片列表页面。一直以来用Micolog建立GAE网站,但其实不算网站,只算是个blog而已,并且没有实际的写代码,所以不能算是我的GAE程序,而今天终于完成了这个GAE的网站,虽然可能只是写了几十行代码加上三个静态页面而已,但这确实是我经历了差不多三个多星期后的结果,从一无所知到开始查资料开始尝试代码最终完成这样的一个网站,酸甜苦辣只有自己知道啊。
一直以来我不满意国内主机的速度,加上为了以后分享照片和地图更加方便,所以准备将网站改版,决定全部搬到Google app engine上去。只是我的情况可能有点特殊:1,我有6000张照片,这样就差不多有12000个文件样子(缩略图和照片一样多),文件大概在500M样子,如果全部放到GAE,不太可能,因为文件数量和大小有限制;2,对于部分链接采用新的固定链接,而旧的URL能够转向到新的URL来。3,依然保留原有的地图内容,对于46个地方都需要在地图上标识出来(原来用的是Mapbar的JS做的WebMap,可以见sharesh.cn/default.htm)。对于以上三点,最终是如何解决的呢?
首先对于照片,由于国内主机速度慢,我不可能外联国内主机的图片,而国外主机,速度也不行,至少是访问速度,不过比国内主机要好一些,所以这样的话国内国外主机就全部被我放弃了,最多算是作为镜像吧。但我想起了以前的很好用的pwa.js,就是一个html+一个js做的相册,用的是Picasa Web Albums Data API,两个文件就能实现相册,强悍吧。可惜URL不是很好,不太符合我的SEO要求,再说如果这样的话,就是放两个静态文件给GAE,那也太大材小用了吧(虽然为了达到目的我不管是否大材小用,最近申请了Microsoft的Azure,准备折腾个镜像出来,不过难)。不过,照片我已经决定放Google PicasaWeb了,1G的免费空间干嘛不用,而且有这么好的API,图片还能够外联,速度又是非常快,不用太浪费了。于是重新整理了照片,将这6000多张照片全部上传上去了,结果也就用了一半还不到,太感谢Google了,让我所有的静态图片终于有地方存放了。最终的照片就是用Picasa Web Albums Data API做个二次开发了。
然后,需要考虑链接问题,最初的时候只考虑上海的2000张照片,所以就直接域名后面跟album了,而来到北京后又继续分享,然后做成了域名加beijing再加album的形式,因为我不想在网站FTP的根目录下变的乱糟糟的,上海的就准备是域名加shanghai加album了。如果是PHP主机,也许用.htaccess的301转向就可以达到目的,但GAE上如何处理呢?这确实是一个需要解决的问题,但GAE好像还不错,转向应该比.htaccess要强悍很多,具体我在技术总结中提到。
最后就是地图,早期用mapbar开发,是用ASP读取XML的形式,可以实现,但GAE不支持ASP的,所以这条路肯定死掉。但我后来给朋友做过一个WebMap的页面(请见杂谈:一个小型WebMap项目的架构和技术实现(GmapAPI+jQuery+XML)一文),其实就是一个静态页面,只是用了jQuery读取了XML文件而已,并且是用Google Maps API来开发的,总体来说,实现地图效果用Gmap API非常的简单方便,加上Mapbar的JS总觉得效率或者其他问题,所以不准备再使用。我在第一个星期设计整个GAE网站的时候也准备用jQuery+XML来实现,后来真的做出来了,非常的简单,将gpx文件改成xml,然后给jQuery读取。但最终我却又舍弃了这个方法,虽然GAE确实完全支持静态文件,主要是觉得静态文件也有不方便的地方,甚至在操作上也不方便。最后最后,就决定用GAE的datastore了,至少这个datastore是我可以登录后台进行管理的,可以添加、删除、更新等,而如果将静态文件传到GAE,那么只有覆盖的份,删除是不行的。考虑到最终的便捷性所以地图就准备Gmap API+Datastore的方式了。
写到这里基本上明白我的思路了吧,开发基本上用python+Datastore+Google Maps API+Picasa Web Album Data API,最后存放到Google App Engine上。由于只有三个界面,所以截了三个图来看一下吧,具体可以通过我的地址访问:http://photo.sharesh.cn 或者http://shareshcn.appspot.com 。下一篇凌乱的appengine/PicasaWeb API/Gmap API技术要点总结,做一些技术要点的说明。如果有时间完善一下的话,准备做一个基于GAE的开源程序,是地图+相册的形式,但整体思路暂时还没有考虑好。
首页的地图(本来两个marker的,但用theworld保存成png的时候就变成两个黑块了):
相册列表页面:
照片列表页面:
最后说一下GFW的事情,早在3月4日的时候疯掉了ghs.google.com的最后一个IP,后来在9号样子恢复了一个IP,而在昨天14号下午所有的appspot.com无法访问,至少我下午无法登录,但通过代理可以,这么早就不幸被Step1言中,但是昨天通过A记录的自己的域名倒是可以访问的,GFW真是辗转反侧,不服不行啊,真要把人给弄疯掉的。另外,今天appspot.com终于又可以访问了,够疯。
上一篇我的第一个GAE网站(地图+相册)已经讲了大体的思路,此篇讲讲实现过程中的一些技术要点,可能讲的比较零散,因为整个过程中碰到了比较多的问题,但最终还是解决了,将这过程中的经验分享给大家。
#Picasa Web Albums Data API的二次开发
其实Picasa Web Albums Data API的二次开发还是非常简单的,细看pwa.js文件(SF上的一个开源的项目,用一个js实现了picasa web albums的全部调用),也就几十行的代码,大致分成显示所有的相册(picasaweb函数)、显示相册内的相片(albums函数)、显示一张照片这几个函数(photo函数),其余的都是辅助函数,那么如何调用和触发的呢。触发的语句就是调用不同的JS,下面这三行是整个JS的开始:
if (_GET['albumid']) {
_$('<script type="text/javascript" src="http://picasaweb.google.com/data/feed/base/user/' + username + '/albumid/' + _GET['albumid'] + '?category=photo&alt=json&callback=browsePhoto"></script>');
} else {
_$('<script type="text/javascript" src="http://picasaweb.google.com/data/feed/base/user/' + username + '?category=album&alt=json&callback=picasaweb&access=public"></script>');}
这是根据当前URL中albumid的值来判断并调用不同的JS,如果URL中包含albumid则显示相册中的所有照片,如果没有albumid那么就显示所有相册列表。由于pwa.js提供的相册列表的URL链接不满意,所以我准备重写所有的相册的URL,以让其符合我的要求。这里需要做一个解释的地方是:script中src所带的callback参数,其实就是回调函数,在调用完JS后就交给callback的参数(其实就是function名)来处理了。上面的browsePhoto函数就是用于显示相册中照片列表或者显示单独一张较大尺寸的照片,但也是用了if语句来转向处理再来调用albums函数或者photo函数。具体细节可以看相应的函数,重要的是了解picasa web api返回的数据,是带了许多分支节点的JS,但调用非常的简单,j.feed.entry[i],j就是调用回来的所有数据,feed是总的开始,如同xml中的xml总结点,而entry是一个一个的对象,entry更有细小的对象,具体可以下载一个JS下来分析一下就可以了。
所以相册的整体思路就是相册列表由我自己完成,而相册中照片列表和单张照片显示则使用pwa.js来完成。由JS调用的URL上能够看出,我只要手动告诉它该相册的ID就可以调用并显示相册中的照片列表了,而自动获取ID的方式我也无法知道对应的是哪个相册,这样就URL也不好管理了,而且Google的相册名称也不是我要的英文名,而是一个乱七八糟的名字,失望。
由此,我需要将自己的URL路径名称和相册的ID同时存放到数据库中,然后读取出来就可以对应。
#数据结构和数据上传
由于需求简单,所以对于我来说数据结构也是超级简单。而虽然说datastore是非关系型数据库(简单来说就是一个excel表,只是比excel高级一些),但对于我来说已经足够用了,并且我就喜欢简单的东西,不希望复杂。而我的数据结构也确实非常的简单,根据上面的情况,以及显示地图的需要,所以基本上定义为纬度、经度、城市、英文名、中文名、信息、相册ID这几个字段。在GAE中的定义为:
class PointList(db.Model):
Lat = db.StringProperty()
Lon = db.StringProperty()
AlbumID = db.StringProperty()
City = db.StringProperty()
NameEn= db.StringProperty()
Name = db.StringProperty()
Information = db.StringProperty()
这就表示已经设置好数据组织格式了。如果上传了数据,那么就能看到PointList,就是相当于一个数据表了。
由于46笔数据,虽然说不多,但我也不希望自己一个一个录入吧,所以首先整理成一份CSV的数据表格,然后批量上传到GAE或者本地开发环境上。由于GAE不支持中文,如果将带有中文的CSV文件上传到GAE上则无法上传。查了非常多的资料以后,终于根据K_ReVerTer的资料将数据上传上去了,关于此点我还特地写了一文:将中文csv数据上传到GAE Datastore(Bulk Data Uploader工具),不过K_ReVerTer又发现了新的上传方式,我还没有研究过,大家可以一起看看:向Google App Engine上传数据的几个心得(上)。此处就不再多说。
#GAE中定义URL以及URL转向
一般情况下大家都认为定义URL是app.yaml的事情,没错它确实是可以定义URL,比如:
- url: /static
static_dir: static
- url: /admin/.*
script: admin.py
- url: /.*
script: main.py
上面举例了static静态文件夹的url,而admin/后的内容全部交由admin.py来处理,而直接域名或无法匹配到上面内容的则最终交给main.py来处理,顺便说一下这是的处理按顺序处理的,如果没有任何对应则出现404错误。
但我总不能将我的46个URL全部用app.yaml来对应吧,要累死人的,并且也不利于以后的添加。最后就交给main.py来处理了:
application = webapp.WSGIApplication([('/', MainPage),
('/photo/', AlbumPage),
('/shanghai/(.*)/', PhotoPage),
('/(.*)/', ReURLPage),
],
debug=True)
这里的大致意思是域名直接访问则交给MainPage处理,如果是/photo/路径则交给AlbumPage处理,而PhotoPage和ReURLPage则需要处理(.*),其实就是表示一个字符串。举实际的例子来说吧,外滩使用theBund的路径,如果出现/theBund/则跳转到/shanghai/theBund/的路径,ReURLPage负责跳转,PhotoPage负责显示照片。大致明白我的意思了吧。
顺便说一下URL转向,最早的时候我用了比较笨的方法,但也可以达到最终目的,我在py中写到:self.response.out.write('<html><head>
<meta http-equiv="refresh" content="0;url=/shanghai/theBund/" />
<title>ShareSh.cn</title><body>Loading...</body></head></html>'),其实就是用meta的refresh方法。
然而不经意间,竟然发现一个GAE还能self.redirect("/shanghai/theBund/"),redirect直接URL跳转,还是蛮好用的。
#数据读取和使用静态模板文件
其实在GAE的入门教程中已经写了如何使用模板文件的例子,不过粗略看过以后是不知所云的,最终在碰到问题的时候才印象深刻。首先写一个html的文件,内容你已经组织好,那么如何使用python写一些内容到这个html文件中呢,比如title你总想要一个名称吧,总不能固定不变吧,而对于像Google map的调用方面,你也肯定需要加载许多的对象吧。OK,我们的静态文件中只要加入“{{key}}”就可以了,这个key你可以随便自定义,可以放于多个地方,比如我的静态文件中的title标题:<title>{{photoname}}--分享上海北京(ShareSh.cn)</title>,其中photoname就是我在py中会提供给html文件,同时对于数据库中的多个数据,还可以循环,比如我显示图片和链接的例子:
{% for point in points %}
<a href="/{{point.City}}/{{point.Nameen}}/" title="{{point.Nameen}}">{{point.Name}}</a>
{% endfor %}
points是select datastore后的对象,而point是在此定义的单独的对象,而point.Name则是对应一条记录中Name字段的值。真是没有想到python是如此简单就将复杂的东西全部表现出来了,这是我非常喜欢的地方。
而关于数据库就非常的简单了,看我具体的例子:
class AlbumPage(webapp.RequestHandler):
def get(self):
points = db.GqlQuery("SELECT * FROM PointList")
path = os.path.join(os.path.dirname(__file__), 'album.html')
tvalues = {
'points': points
}
self.response.out.write(template.render(path, tvalues))
points就是select后的结果,album.html就是上文的模板文件,由此也就明白了py是如何将数据传给静态模板文件的了吧。
select语句还可以使用where查询,比如:albums = db.GqlQuery("SELECT * FROM PointList WHERE Nameen= :1", id),PointList是表,Nameen是字段,id是外部的值。
其实我的Gmap的显示也是用了py的数据库循环,因为就是定义一个marker然后addoverlay,循环46次就可以标识出所有的marker了。
#多个域名下调用Google Maps API不同的key
由于GAE自身一个域名:shareshcn.appspot.com,我自己又定义了一个域名:photo.sharesh.cn,这样的话Gmap的key我就有两个了,但script语句只能一个key:<script src="http://maps.google.com/maps?file=api&v=2&key=yourdomainkey type="text/javascript"></script>,怎么办?对于GAE来说,个人认为解决的思路有三种:
1,如我在Google Maps API离线开发包(没有网络也可以开发Gmap了)一文中所说,先申请一个不是这两个域名的key,然后下载src对应的文件,定义为maps.js,去掉其中的GValidateKey这个判断前的!,不再提示,然后你在网站中就直接调用自己maps.js就可以了,不用去调用Google的src。
此方法理论上可行,我并没有尝试,可以说此方法不再受多少个域名限制,但是个人担心Google再验证或者js无法更新等问题,我不使用此方法。
2,使用JS判断URL,然后调用不同的script:
if (window.location.href.indexOf('yourdomain')>=0){document.write("<script src=\"http://maps.google.com/maps?file=api&v=2&key=yourdomainkey type=\"text/javascript\"></script>");}
我认为是可行的,但在实际使用过程中不可行,难道是GAE的特殊性?或者和调用的先后顺序有关?我的这个js判断是在body的load之前的啊,是在所有内容之前的啊。没有办法,我再度放弃这个方法。
3,使用GAE的模板模式,并用python判断Host:
这个思路也是非常明确的,首先在html文件中定义好关键字,比如我的:<script src="http://maps.google.com/maps?file=api&v=2&key={{gmapkey}}" type="text/javascript"></script>
然后我在py中判断不同的域名来提供不同的Google maps key。具体写法如下:
class MainPage(webapp.RequestHandler):
def get(self):
if self.request.headers["Host"] == "yourdomain":
gmapkey = "yourdomainkey"
if self.request.headers["Host"] == "yourdomain2":
gmapkey = "yourdomain2key"
points = db.GqlQuery("SELECT * FROM PointList")
path = os.path.join(os.path.dirname(__file__), 'main.html')
tvalues = {
'gmapkey': gmapkey,
'points': points
}
self.response.out.write(template.render(path, tvalues))
要知道self.request.headers["Host"] 这个我也是摸索了半天才出来的,python中如何获取当前域名,就是用这个方法来实现的,网上找了一些资料没有找到,并且还走了一些弯路,我用print self.request.headers["Host"] 准备打印在页面上判断这种用法是正确的,但不知道为什么GAE就是不显示,其余的像Content-Type参数就是可以打印显示出来的,郁闷吧,但你用Host来逻辑运算是没有问题的,所以我尝试了一下if判断,然后print自己的字符串,发现可用,由此我才知道Host无法直接打印出来但可以逻辑运算的,虽然花的时间并不是太多,但这确实有点弯路,看来没有学习过python还真不容易。
最终来说,使用python判断不同URL并调用不同的JS是完全正确的,并且也是非常有效的,因为此点首先就是在服务器上生成的html,不存在时间先后问题。如果大家有更好的不同域名调用gmap key的方法,不妨告知一下。
洋洋洒洒又是好几千字,写了五个方面的要点,也许每个要点都能单独写个文,不过太小的事情总不是很愿意写,比如本来想推荐一下picasa的自定义模板输出功能的,但没太多的话说,所以一直没说。本来把名字写成是零散,最后改成了凌乱,确实很凌乱,可能我意思明确,但写出来,自己感觉都是不知所云,罢,就这么凌乱吧。