文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/
一周前由于国家天地图升级,造成多个项目地图无法显示。问题原因在于前端直接在线请求的天地图WMTS服务,未进行缓存,所以当天地图服务关闭后我方也被波及。采用前端直接获取服务本身还是有不少优点:
互联网服务本身已进行了各种加速优化
与采用CDN原理相同,避免请求造成我方后台压力过大,并且可以规避浏览器对同一IP请求时并发数量限制
但是为立刻处理业主提出的后续优化方案,我基于已有的瓦片趴取工具,提出了整体瓦片预先缓存的方案。将缓存工具提供给工程让其在天地图恢复后进行瓦片下载,后续所有请求均走本地瓦片。但是该方案是存在两个天然弊端的:
如果需要展示的范围过大,下载数据非常耗时
无法自动更新,数据更新后又要重新下载更新
在必须采用缓存策略的情况下,如何可以减少现场实施同事的工作量?这里提出后台瓦片实时缓存方案。
在线瓦片请求首先转发至后端
后端根据传入的layername、level、col、row,去查找本地是否有对应的缓存瓦片
若没有则根据传入的原始瓦片URL请求下载对应瓦片,将下载的瓦片缓存至本地对应的目录下,并同时将下载的数据返回前端
若有则直接读取本地瓦片返回前端
该方案对应的编码涉及到前端瓦片请求URL的重构和后端对应的瓦片缓存逻辑实现。
所谓瓦片请求只是一种泛称,具体到类型可以分为很多种,比如通用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;}
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();}
可见前端请求后的瓦片在后台都进行了缓存。再次请求时将直接获取缓存瓦片。
设置清空缓存数据参数。当该参数开启时自动清除所有缓存,以最新瓦片进行再次缓存
后端与地图图片自动生成相关的模块也均需调用缓存瓦片获取接口
配置控制是否开启缓存机制,避免不必要的频繁瓦片请求给后端造成压力
-----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/
联系客服