首页 > 开发 > 前端 > 正文

openlayers 加载瓦片详解一:加载瓦片的算法类(转自studypower的专栏)

2016-05-18 19:08:21  来源:慕课网
  
  我们在客户端看到的瓦片其实是一个图片列表 也就是上面的grid 类 ,每张图片都是通过http从后来请求过来的图片也就是方法getURL(bound),
每张图片都有自己的url 也就是他的请求地址,而且grid的列表的每个单元格都有边框也就是bound,那要获取每个单元格中正确的图片都是通过bound来计算而获取到相应的图片,如想要加载自己瓦片就需要重写grid中的getURL(bound)方法,这也就是最下排6个不同类型的瓦片根据自己的瓦片特点及地图服务的特点编写的类,如果你有自己的瓦片却跟上面的几种都不相同也不相似,那你可以选择重写grid类,如果你的瓦片操作跟下面的6中服务相同或者类似,那可以根据自己工作考虑重写那面6个类中的其中某一个中的getURL(bound)的方法。在计算的过程中能涉及到多个参数将在下篇来详细介绍,在这给几个重写getURL(bound)的例子, 第一个例子是网上的不过在工作中验证过,绝对可用,写的还不错给大家个参考。
  1、重写grid类中的getURL(bound)方法加载本地图片(天地图)
OpenLayers.Layer.TiandituLayer = OpenLayers.Class(OpenLayers.Layer.Grid, { TileType : null, mirrorUrls : null, topLevel : null, bottomLevel : null, topLevelIndex : 0, bottomLevelIndex : 20, topTileFromX : -180, topTileFromY : 90, topTileToX : 180, topTileToY : -90, isBaseLayer : true, initialize : function(name, url, options) { options.topLevel = options.topLevel ? options.topLevel : this.topLevelIndex; options.bottomLevel = options.bottomLevel ? options.bottomLevel : this.bottomLevelIndex; options.maxResolution = this .getResolutionForLevel(options.topLevel); options.minResolution = this .getResolutionForLevel(options.bottomLevel); var newArguments = [ name, url, {}, options ]; OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments); }, clone : function(obj) { if (obj == null) { obj = new OpenLayers.Layer.TDTLayer(this.name, this.url, this.options); } obj = OpenLayers.Layer.Grid.prototype.clone .apply(this, [ obj ]); return obj; }, getURL : function(bounds) { var level = this.getLevelForResolution(this.map.getResolution()); var coef = 360 / Math.pow(2, level); var Row = this.topTileFromX < this.topTileToX ? Math.round((bounds.left - this.topTileFromX) / coef) : Math.round((this.topTileFromX - bounds.right) / coef); var Col = this.topTileFromY < this.topTileToY ? Math.round((bounds.bottom - this.topTileFromY) / coef): Math.round((this.topTileFromY - bounds.top) / coef); var type = this.TileType; if (type == "EMap") { if (level >= 2 && level <= 10) { type = "A0512_EMap"; } else if (level == 11 || level == 12) { type = "B0627_EMap1112"; } else if (level >= 13 && level <= 18) { type = "siwei0608"; } }else if(type=="RMap"){ if (level >= 2 && level <= 7) { type = "sbsm0210"; } else if (level >= 8 && level <= 10) { type = "sbsm0210"; } else if (level >= 11 && level <= 14) { type = "e11"; }else if (level >= 15 && level <= 18) { type = "sbsm1518"; } } var url = this.url; if (this.mirrorUrls != null) { url = this.selectUrl(Row, this.mirrorUrls); } return this.getFullRequestString({ T : type, X : Row, Y : Col, L : level }, url); }, selectUrl : function(a, b) { return b[a % b.length] }, getLevelForResolution : function(res) { var ratio = this.getMaxResolution() / res; if (ratio < 1) return 0; for ( var level = 0; ratio / 2 >= 1;) { level++; ratio /= 2; } return level; }, getResolutionForLevel : function(level) { return 360 / 256 / Math.pow(2, level); }, getMaxResolution : function() { return this.getResolutionForLevel(this.topLevelIndex) }, getMinResolution : function() { return this.getResolutionForLevel(this.bottomLevelIndex) }, addTile : function(bounds, position) { var url = this.getURL(bounds); return new OpenLayers.Tile.Image(this, position, bounds, url, this.tileSize); }, CLASS_NAME : "OpenLayers.Layer.TiandituLayer" });   测试页面
view plain copy print?<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="apple-mobile-web-app-capable" content="yes"> <title>OpenLayers Tiled Map Service Example</title> <link rel="stylesheet" href="../theme/default/style.css" rel="external nofollow" rel="external nofollow" type="text/css"> <link rel="stylesheet" href="style.css" rel="external nofollow" rel="external nofollow" type="text/css"> <script src="../lib/OpenLayers.js" rel="external nofollow" rel="external nofollow" ></script> <script type="text/javascript"> var map, layer; function init(){ var extent = new OpenLayers.Bounds(-180.0, -90.0, 180.0, 90.0); var tempScales = [295497593.05875003,147748796.52937502,73874398.264687508,36937199.132343754,18468599.566171877]; var mapOptions = { maxExtent: extent }; var options= { mapType:"EMap", topLevel: 3, bottomLevel: 20 }; map = new OpenLayers.Map("map",mapOptions); layer = new OpenLayers.Layer.TiandituLayer("qincy", "http://tile0.tianditu.com/DataServer",options); map.addLayer(layer); map.addControls([new OpenLayers.Control.MousePosition()]); map.setCenter(new OpenLayers.LonLat(106,39), 3); } </script> </head> <body onload="init()"> <div id="map" style="width:1000px;height:500px"></div> </body> </html>   2、重写TileCache类加载本地图片。
/**
对自定义规则切割的图片进行拼装的类
*/ SimpleTileCache=OpenLayers.Class(OpenLayers.Layer.TileCache,{ initialize:function(name,url,options){ var tempoptions = OpenLayers.Util.extend( {'format': 'image/png',isBaseLayer:true},options); OpenLayers.Layer.TileCache.prototype.initialize.apply(this,[name, url, {}, tempoptions]); this.extension = this.format.split('/')[1].toLowerCase(); this.extension = (this.extension == 'jpg') ? 'jpeg' : this.extension; this.transitionEffect="resize"; this.buffer=2; }, /** * 按地图引擎切图规则实现的拼接方式 */ getURL: function(bounds) { var res = this.map.getResolution(); var bbox = this.map.getMaxExtent(); var size = this.tileSize; //计算列号 var tileX = Math.round((bounds.left - bbox.left) / (res * size.w)); //计算行号 var tileY = Math.round((bbox.top-bounds.top) / (res * size.h)); //当前的等级 var tileZ = this.map.zoom; if(tileX<0) tileX=tileX+Math.round(bbox.getWidth()/bounds.getWidth()); if(tileY<0) tileY=tileY+Math.round(bbox.getHeight()/bounds.getHeight()); return this.getTilePic(tileX,tileY,tileZ); }, getTilePic: function(tileX,tileY,tileZ){ var dir = ''; if(tileZ > 6) { var delta = Math.pow(2,tileZ-5); var rowDir = 'R'+ Math.floor(tileY /delta); var colDir = 'C'+Math.floor(tileX /delta); dir = tileZ + "/" + rowDir + "/" + colDir + "/"; } else { dir= tileZ + '/'; } var tileNo = tileZ + "-" + tileX + "-" + tileY; var sUrl = this.url + dir + tileNo + '.png'; return sUrl; }, clone: function (obj) { if (obj == null) { obj = new SimpleTileCache(this.name,this.url,this.options); } obj = OpenLayers.Layer.TileCache.prototype.clone.apply(this, [obj]); return obj; }, CLASS_NAME: "SimpleTileCache" });   3、直接修改TileCache类中的getURL方法
  修改后 的 TileCache.js
OpenLayers.Layer.TileCache = OpenLayers.Class(OpenLayers.Layer.Grid, { isBaseLayer: true, format: 'image/png', serverResolutions: null, initialize: function(name, url, layername, options) { this.layername = layername; OpenLayers.Layer.Grid.prototype.initialize.apply(this, [name, url, {}, options]); this.extension = this.format.split('/')[1].toLowerCase(); this.extension = (this.extension == 'jpg') ? 'jpeg' : this.extension; }, clone: function (obj) { if (obj == null) { obj = new OpenLayers.Layer.TileCache(this.name, this.url, this.layername, this.getOptions()); } //get all additions from superclasses obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]); // copy/set any non-init, non-simple values here return obj; }, getURL: function(bounds) { var res = this.map.getResolution(); var x = Math.round ((bounds.left - this.maxExtent.left) / (res * this.tileSize.w)); var y = Math.round ((this.maxExtent.top - bounds.top) / (res * this.tileSize.h)); var z = this.map.getZoom(); var path =z+9+ "/" + x + "/" + y + "." + this.type; var url = this.url; if (url instanceof Array) { url = this.selectUrl(path, url); } //我用resin 发布的地图瓦片的位置 url="http://192.168.0.90:88/roadmap2/"+path; return url }, /*getURL: function(bounds) { var res = this.getServerResolution(); var bbox = this.maxExtent; var size = this.tileSize; var tileX = Math.round((bounds.left - bbox.left) / (res * size.w)); var tileY = Math.round((bounds.bottom - bbox.bottom) / (res * size.h)); var tileZ = this.serverResolutions != null ? OpenLayers.Util.indexOf(this.serverResolutions, res) : this.map.getZoom(); var components = [ this.layername, OpenLayers.Number.zeroPad(tileZ, 2), OpenLayers.Number.zeroPad(parseInt(tileX / 1000000), 3), OpenLayers.Number.zeroPad((parseInt(tileX / 1000) % 1000), 3), OpenLayers.Number.zeroPad((parseInt(tileX) % 1000), 3), OpenLayers.Number.zeroPad(parseInt(tileY / 1000000), 3), OpenLayers.Number.zeroPad((parseInt(tileY / 1000) % 1000), 3), OpenLayers.Number.zeroPad((parseInt(tileY) % 1000), 3) + '.' + this.extension ]; var path = components.join('/'); var url = this.url; if (OpenLayers.Util.isArray(url)) { url = this.selectUrl(path, url); } url = (url.charAt(url.length - 1) == '/') ? url : url + '/'; //url+path //alert(url+path); return "http://192.168.0.90:88/roadmap/1/0/0.png" },*/ CLASS_NAME: "OpenLayers.Layer.TileCache" });   测试页面
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="apple-mobile-web-app-capable" content="yes"> <title>OpenLayers TileCache Example</title> <link rel="stylesheet" href="../theme/default/style.css" rel="external nofollow" rel="external nofollow" type="text/css"> <link rel="stylesheet" href="style.css" rel="external nofollow" rel="external nofollow" type="text/css"> <script src="../lib/OpenLayers.js" rel="external nofollow" rel="external nofollow" ></script> <script src="../lib/Firebug/firebug.js" rel="external nofollow" ></script> <script type="text/javascript"> //alert("adsf"); var proj='EPSG:900913'; //900913 var map, layer; var proj2 = new OpenLayers.Projection("EPSG:4326"); var agsTileOrigin = new OpenLayers.LonLat(-180,85); agsTileOrigin.transform(proj2, new OpenLayers.Projection("EPSG:900913")); //alert(agsTileOrigin.); var mapExtent = new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34); function init(){ //添加编辑图层 图层名称为editLayer var EditLayer=new OpenLayers.Layer.Vector("EidtLayer"); //添加地图 map = new OpenLayers.Map( 'map', { numZoomLevels:3, //缩放级别 resolutions:[305.7481,152.8741,76.437], //分别率 单位是米 controls:[ new OpenLayers.Control.EditingToolbar(EditLayer), //添加编辑控件 new OpenLayers.Control.Navigation(), new OpenLayers.Control.PanZoomBar(), new OpenLayers.Control.LayerSwitcher({'ascending':false}), new OpenLayers.Control.Permalink(), new OpenLayers.Control.ScaleLine(), new OpenLayers.Control.Permalink('permalink'), new OpenLayers.Control.MousePosition(), new OpenLayers.Control.OverviewMap(), new OpenLayers.Control.KeyboardDefaults() ] }); layer = new OpenLayers.Layer.TileCache("TileCache Layer", "http://c0.tilecache.osgeo.org/wms-c/cache/", "basic", { serverResolutions:[305.7481,152.8741,76.437], projection:proj, type:'png' } ); map.addLayers([layer, EditLayer]); var lob_ll=new OpenLayers.LonLat(121.34457, 31.329235); map.setCenter(lob_ll.transform(proj2, new OpenLayers.Projection("EPSG:900913")), 0); } </script> <style type="text/css"> html,body{width:100%;height:100%;margin:0;} </style> </head> <body onload="init()"> <div id="map" class="smallmap" style="width:100%; height:100%; backround-color:Red;"></div> </body> </html>