文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/
1.背景
一周前由于国家天地图升级,造成多个项目地图无法显示。问题原因在于前端直接在线请求的天地图WMTS服务,未进行缓存,所以当天地图服务关闭后我方也被波及。采用前端直接获取服务本身还是有不少优点:
- 互联网服务本身已进行了各种加速优化
- 与采用CDN原理相同,避免请求造成我方后台压力过大,并且可以规避浏览器对同一IP请求时并发数量限制
但是为立刻处理业主提出的后续优化方案,我基于已有的瓦片趴取工具,提出了整体瓦片预先缓存的方案。将缓存工具提供给工程让其在天地图恢复后进行瓦片下载,后续所有请求均走本地瓦片。但是该方案是存在两个天然弊端的:
- 如果需要展示的范围过大,下载数据非常耗时
- 无法自动更新,数据更新后又要重新下载更新
在必须采用缓存策略的情况下,如何可以减少现场实施同事的工作量?这里提出后台瓦片实时缓存方案。
2.方案设计
- 在线瓦片请求首先转发至后端
- 后端根据传入的layername、level、col、row,去查找本地是否有对应的缓存瓦片
- 若没有则根据传入的原始瓦片URL请求下载对应瓦片,将下载的瓦片缓存至本地对应的目录下,并同时将下载的数据返回前端
- 若有则直接读取本地瓦片返回前端
该方案对应的编码涉及到前端瓦片请求URL的重构和后端对应的瓦片缓存逻辑实现。
3.方案实现
3.1前端请求重构
所谓瓦片请求只是一种泛称,具体到类型可以分为很多种,比如通用Webtile类型、百度地图类型、WMStile类型(用WMS服务来模拟瓦片请求)等等。以通用的Webtile为例:
getTileUrl:function(level, row, col){
var tileUrl = ""; var levelValue = this._levelToLevelValue[level]; var scale = this.tileInfo.lods[level].scale; tileUrl = this.urlTemplate.replace(/\${level\}/gi, levelValue).replace(/\${row\}/gi, row).replace(/\${col\}/gi, col).replace(/\${scale\}/gi, scale).replace(/\${layer\}/gi, this.layername); if(this.useProxy==1){ tileUrl=gis.global.tileCahceUrl+"?layerName="+encodeURI(this.layerName)+"&level="+ levelValue+"&col="+col+"&row="+row+"&raw="+encodeURIComponent(tileUrl); } tileUrl = this.addTimestampToURL(tileUrl); return tileUrl; }
3.2后台对应模块实现
BufferedInputStream bis = null;
OutputStream os = null;
byte[] buf = new byte[1024]; int len = 0; bis = new BufferedInputStream(is); os = response.getOutputStream(); FileOutputStream fos = null; if (!hasFile) { // 若不存在,则判断文件路径中各文件夹是否存在, if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } fos = new FileOutputStream(file); } while ((len = bis.read(buf)) != -1) { os.write(buf, 0, len); if(!hasFile){ fos.write(buf,0,len); } } bis.close(); is.close(); os.close(); if(!hasFile){ fos.close(); }
4.效果展示
可见前端请求后的瓦片在后台都进行了缓存。再次请求时将直接获取缓存瓦片。
5.几点优化
- 设置清空缓存数据参数。当该参数开启时自动清除所有缓存,以最新瓦片进行再次缓存
- 后端与地图图片自动生成相关的模块也均需调用缓存瓦片获取接口
- 配置控制是否开启缓存机制,避免不必要的频繁瓦片请求给后端造成压力
-----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/
如果您觉得本文确实帮助了您,可以微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^