在这先说点题外话,本人在研究webgl 三维球过程中惊人发现,openlayers 的开发人员也在研究webgl并经证实他们也正在研发基于

webgl的三维gis开源平台,这可能是首个开源的三维平台,在现在三维大趋势下,看来 openlayers  前景还是一片大好,闲话少说,静候佳音。

在这将分4篇文章来系统的详细的介绍openlayers 是怎么来加载本地及服务器瓦片,为了提高开发人员的工作效率 采用倒叙,

在第一篇先给实用的算法及简单的参数说明,后面介绍原理,彻底的理解其工作原理。

第一篇 :加载瓦片的算法类

第二篇 :瓦片制作

第三篇 :瓦片参数确定

第四篇 :openlayers 加载的瓦片投影

第一篇加载瓦片的算法类

1、先给个类图简单的介绍下

我们在客户端看到的瓦片其实是一个图片列表 也就是上面的grid 类  ,每张图片都是通过http从后来请求过来的图片也就是方法getURL(bound),

每张图片都有自己的url 也就是他的请求地址,而且grid的列表的每个单元格都有边框也就是bound,那要获取每个单元格中正确的图片都是通过bound来计

算而获取到相应的图片,如想要加载自己瓦片就需要重写grid中的getURL(bound)方法,这也就是最下排6个不同类型的瓦片根据自己的瓦片特点及地图服务

的特点编写的类,如果你有自己的瓦片却跟上面的几种都不相同也不相似,那你可以选择重写grid类,如果你的瓦片操作跟下面的6中服务相同或者类似,那

可以根据自己工作考虑重写那面6个类中的其中某一个中的getURL(bound)的方法。在计算的过程中能涉及到多个参数将在下篇来详细介绍,在这给几个重写

getURL(bound)的例子, 第一个例子是网上的不过在工作中验证过,绝对可用,写的还不错给大家个参考。

1、重写grid类中的getURL(bound)方法加载本地图片(天地图)

  1. OpenLayers.Layer.TiandituLayer = OpenLayers.Class(OpenLayers.Layer.Grid,
  2. {
  3.  
  4. TileType : null,
  5. mirrorUrls : null,
  6. topLevel : null,
  7. bottomLevel : null,
  8. topLevelIndex : 0,
  9. bottomLevelIndex : 20,
  10. topTileFromX : -180,
  11. topTileFromY : 90,
  12. topTileToX : 180,
  13. topTileToY : -90,
  14. isBaseLayer : true,
  15. initialize : function(name, url, options) {
  16.  
  17. options.topLevel = options.topLevel ? options.topLevel
  18. : this.topLevelIndex;
  19. options.bottomLevel = options.bottomLevel ? options.bottomLevel
  20. : this.bottomLevelIndex;
  21. options.maxResolution = this
  22. .getResolutionForLevel(options.topLevel);
  23. options.minResolution = this
  24. .getResolutionForLevel(options.bottomLevel);
  25. var newArguments = [ name, url, {}, options ];
  26. OpenLayers.Layer.Grid.prototype.initialize.apply(this,
  27. newArguments);
  28. },
  29.  
  30. clone : function(obj) {
  31.  
  32. if (obj == null) {
  33. obj = new OpenLayers.Layer.TDTLayer(this.name, this.url,
  34. this.options);
  35. }
  36.  
  37. obj = OpenLayers.Layer.Grid.prototype.clone
  38. .apply(this, [ obj ]);
  39.  
  40. return obj;
  41. },
  42.  
  43. getURL : function(bounds) {
  44. var level = this.getLevelForResolution(this.map.getResolution());
  45. var coef = 360 / Math.pow(2, level);
  46. var Row = this.topTileFromX < this.topTileToX ? Math.round((bounds.left - this.topTileFromX) / coef) : Math.round((this.topTileFromX - bounds.right) / coef);
  47. var Col = this.topTileFromY < this.topTileToY ? Math.round((bounds.bottom - this.topTileFromY) / coef): Math.round((this.topTileFromY - bounds.top) / coef);
  48.  
  49. var type = this.TileType;
  50. if (type == "EMap") {
  51. if (level >= 2 && level <= 10) {
  52. type = "A0512_EMap";
  53. } else if (level == 11 || level == 12) {
  54. type = "B0627_EMap1112";
  55. } else if (level >= 13 && level <= 18) {
  56. type = "siwei0608";
  57. }
  58. }else if(type=="RMap"){
  59. if (level >= 2 && level <= 7) {
  60. type = "sbsm0210";
  61. } else if (level >= 8 && level <= 10) {
  62. type = "sbsm0210";
  63. } else if (level >= 11 && level <= 14) {
  64. type = "e11";
  65. }else if (level >= 15 && level <= 18) {
  66. type = "sbsm1518";
  67. }
  68. }
  69.  
  70. var url = this.url;
  71.  
  72. if (this.mirrorUrls != null) {
  73. url = this.selectUrl(Row, this.mirrorUrls);
  74. }
  75.  
  76. return this.getFullRequestString({
  77. T : type,
  78. X : Row,
  79. Y : Col,
  80. L : level
  81. }, url);
  82. },
  83. selectUrl : function(a, b) {
  84. return b[a % b.length]
  85. },
  86. getLevelForResolution : function(res) {
  87. var ratio = this.getMaxResolution() / res;
  88. if (ratio < 1)
  89. return 0;
  90. for ( var level = 0; ratio / 2 >= 1;) {
  91. level++;
  92. ratio /= 2;
  93. }
  94. return level;
  95. },
  96. getResolutionForLevel : function(level) {
  97. return 360 / 256 / Math.pow(2, level);
  98. },
  99. getMaxResolution : function() {
  100. return this.getResolutionForLevel(this.topLevelIndex)
  101. },
  102. getMinResolution : function() {
  103. return this.getResolutionForLevel(this.bottomLevelIndex)
  104. },
  105. addTile : function(bounds, position) {
  106. var url = this.getURL(bounds);
  107. return new OpenLayers.Tile.Image(this, position, bounds, url,
  108. this.tileSize);
  109. },
  110.  
  111. CLASS_NAME : "OpenLayers.Layer.TiandituLayer"
  112. });

测试页面

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  6. <meta name="apple-mobile-web-app-capable" content="yes">
  7. <title>OpenLayers Tiled Map Service Example</title>
  8. <link rel="stylesheet" href="../theme/default/style.css" type="text/css">
  9. <link rel="stylesheet" href="style.css" type="text/css">
  10. <script src="../lib/OpenLayers.js"></script>
  11. <script type="text/javascript">
  12.  
  13. var map, layer;
  14.  
  15. function init(){
  16. var extent = new OpenLayers.Bounds(-180.0, -90.0, 180.0, 90.0);
  17. var tempScales = [295497593.05875003,147748796.52937502,73874398.264687508,36937199.132343754,18468599.566171877];
  18. var mapOptions = {
  19. maxExtent: extent
  20. };
  21. var options= {
  22. mapType:"EMap",
  23. topLevel: 3,
  24. bottomLevel: 20
  25.  
  26. };
  27. map = new OpenLayers.Map("map",mapOptions);
  28.  
  29. layer = new OpenLayers.Layer.TiandituLayer("qincy", "http://tile0.tianditu.com/DataServer",options);
  30. map.addLayer(layer);
  31. map.addControls([new OpenLayers.Control.MousePosition()]);
  32.  
  33. map.setCenter(new OpenLayers.LonLat(106,39), 3);
  34.  
  35. }
  36. </script>
  37. </head>
  38. <body onload="init()">
  39. <div id="map" style="width:1000px;height:500px"></div>
  40. </body>
  41. </html>

2、重写TileCache类加载本地图片。

  1. /**
  2. * 对自定义规则切割的图片进行拼装的类
  3. */
  4. SimpleTileCache=OpenLayers.Class(OpenLayers.Layer.TileCache,{
  5. initialize:function(name,url,options){
  6. var tempoptions = OpenLayers.Util.extend(
  7. {'format': 'image/png',isBaseLayer:true},options);
  8. OpenLayers.Layer.TileCache.prototype.initialize.apply(this,[name, url, {}, tempoptions]);
  9. this.extension = this.format.split('/')[1].toLowerCase();
  10. this.extension = (this.extension == 'jpg') ? 'jpeg' : this.extension;
  11. this.transitionEffect="resize";
  12. this.buffer=2;
  13. },
  14. /**
  15. * 按地图引擎切图规则实现的拼接方式
  16. */
  17. getURL: function(bounds) {
  18. var res = this.map.getResolution();
  19. var bbox = this.map.getMaxExtent();
  20. var size = this.tileSize;
  21. //计算列号
  22. var tileX = Math.round((bounds.left - bbox.left) / (res * size.w));
  23. //计算行号
  24. var tileY = Math.round((bbox.top-bounds.top) / (res * size.h));
  25. //当前的等级
  26. var tileZ = this.map.zoom;
  27. if(tileX<0) tileX=tileX+Math.round(bbox.getWidth()/bounds.getWidth());
  28. if(tileY<0) tileY=tileY+Math.round(bbox.getHeight()/bounds.getHeight());
  29. return this.getTilePic(tileX,tileY,tileZ);
  30. },
  31. getTilePic: function(tileX,tileY,tileZ){
  32. var dir = '';
  33. if(tileZ > 6) {
  34. var delta = Math.pow(2,tileZ-5);
  35. var rowDir = 'R'+ Math.floor(tileY /delta);
  36. var colDir = 'C'+Math.floor(tileX /delta);
  37. dir = tileZ + "/" + rowDir + "/" + colDir + "/";
  38. } else {
  39. dir= tileZ + '/';
  40. }
  41. var tileNo = tileZ + "-" + tileX + "-" + tileY;
  42. var sUrl = this.url + dir + tileNo + '.png';
  43. return sUrl;
  44. },
  45. clone: function (obj) {
  46. if (obj == null) {
  47. obj = new SimpleTileCache(this.name,this.url,this.options);
  48. }
  49. obj = OpenLayers.Layer.TileCache.prototype.clone.apply(this, [obj]);
  50. return obj;
  51. },
  52. CLASS_NAME: "SimpleTileCache"
  53. });

3、直接修改TileCache类中的getURL方法

修改后 的 TileCache.js

  1. OpenLayers.Layer.TileCache = OpenLayers.Class(OpenLayers.Layer.Grid, {
  2.  
  3. isBaseLayer: true,
  4.  
  5. format: 'image/png',
  6.  
  7. serverResolutions: null,
  8.  
  9. initialize: function(name, url, layername, options) {
  10. this.layername = layername;
  11. OpenLayers.Layer.Grid.prototype.initialize.apply(this,
  12. [name, url, {}, options]);
  13. this.extension = this.format.split('/')[1].toLowerCase();
  14. this.extension = (this.extension == 'jpg') ? 'jpeg' : this.extension;
  15. },
  16.  
  17. clone: function (obj) {
  18.  
  19. if (obj == null) {
  20. obj = new OpenLayers.Layer.TileCache(this.name,
  21. this.url,
  22. this.layername,
  23. this.getOptions());
  24. }
  25.  
  26. //get all additions from superclasses
  27. obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
  28.  
  29. // copy/set any non-init, non-simple values here
  30.  
  31. return obj;
  32. },
  33.  
  34. getURL: function(bounds) {
  35. var res = this.map.getResolution();
  36. var x = Math.round ((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
  37. var y = Math.round ((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
  38. var z = this.map.getZoom();
  39. var path =z+9+ "/" + x + "/" + y + "." + this.type;
  40. var url = this.url;
  41. if (url instanceof Array) {
  42. url = this.selectUrl(path, url);
  43. }
  44. //我用resin 发布的地图瓦片的位置
  45. url="http://192.168.0.90:88/roadmap2/"+path;
  46. return url
  47. },
  48.  
  49. /*getURL: function(bounds) {
  50. var res = this.getServerResolution();
  51. var bbox = this.maxExtent;
  52. var size = this.tileSize;
  53. var tileX = Math.round((bounds.left - bbox.left) / (res * size.w));
  54. var tileY = Math.round((bounds.bottom - bbox.bottom) / (res * size.h));
  55. var tileZ = this.serverResolutions != null ?
  56. OpenLayers.Util.indexOf(this.serverResolutions, res) :
  57. this.map.getZoom();
  58.  
  59. var components = [
  60. this.layername,
  61. OpenLayers.Number.zeroPad(tileZ, 2),
  62. OpenLayers.Number.zeroPad(parseInt(tileX / 1000000), 3),
  63. OpenLayers.Number.zeroPad((parseInt(tileX / 1000) % 1000), 3),
  64. OpenLayers.Number.zeroPad((parseInt(tileX) % 1000), 3),
  65. OpenLayers.Number.zeroPad(parseInt(tileY / 1000000), 3),
  66. OpenLayers.Number.zeroPad((parseInt(tileY / 1000) % 1000), 3),
  67. OpenLayers.Number.zeroPad((parseInt(tileY) % 1000), 3) + '.' + this.extension
  68. ];
  69. var path = components.join('/');
  70. var url = this.url;
  71. if (OpenLayers.Util.isArray(url)) {
  72. url = this.selectUrl(path, url);
  73. }
  74. url = (url.charAt(url.length - 1) == '/') ? url : url + '/'; //url+path
  75. //alert(url+path);
  76. return "http://192.168.0.90:88/roadmap/1/0/0.png"
  77. },*/
  78.  
  79. CLASS_NAME: "OpenLayers.Layer.TileCache"
  80. });

测试页面

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  6. <meta name="apple-mobile-web-app-capable" content="yes">
  7. <title>OpenLayers TileCache Example</title>
  8. <link rel="stylesheet" href="../theme/default/style.css" type="text/css">
  9. <link rel="stylesheet" href="style.css" type="text/css">
  10. <script src="../lib/OpenLayers.js"></script>
  11. <script src="../lib/Firebug/firebug.js"></script>
  12. <script type="text/javascript">
  13. //alert("adsf");
  14. var proj='EPSG:900913'; //900913
  15. var map, layer;
  16. var proj2 = new OpenLayers.Projection("EPSG:4326");
  17. var agsTileOrigin = new OpenLayers.LonLat(-180,85);
  18. agsTileOrigin.transform(proj2, new OpenLayers.Projection("EPSG:900913"));
  19. //alert(agsTileOrigin.);
  20. var mapExtent = new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34);
  21. function init(){
  22.  
  23. //添加编辑图层 图层名称为editLayer
  24. var EditLayer=new OpenLayers.Layer.Vector("EidtLayer");
  25. //添加地图
  26. map = new OpenLayers.Map( 'map', {
  27. numZoomLevels:3, //缩放级别
  28. resolutions:[305.7481,152.8741,76.437], //分别率 单位是米
  29. controls:[
  30. new OpenLayers.Control.EditingToolbar(EditLayer), //添加编辑控件
  31. new OpenLayers.Control.Navigation(),
  32. new OpenLayers.Control.PanZoomBar(),
  33. new OpenLayers.Control.LayerSwitcher({'ascending':false}),
  34. new OpenLayers.Control.Permalink(),
  35. new OpenLayers.Control.ScaleLine(),
  36. new OpenLayers.Control.Permalink('permalink'),
  37. new OpenLayers.Control.MousePosition(),
  38. new OpenLayers.Control.OverviewMap(),
  39. new OpenLayers.Control.KeyboardDefaults()
  40. ]
  41. });
  42. layer = new OpenLayers.Layer.TileCache("TileCache Layer",
  43. "http://c0.tilecache.osgeo.org/wms-c/cache/",
  44. "basic",
  45. {
  46. serverResolutions:[305.7481,152.8741,76.437],
  47. projection:proj,
  48. type:'png'
  49. }
  50. );
  51.  
  52. map.addLayers([layer, EditLayer]);
  53. var lob_ll=new OpenLayers.LonLat(121.34457, 31.329235);
  54. map.setCenter(lob_ll.transform(proj2, new OpenLayers.Projection("EPSG:900913")), 0);
  55. }
  56. </script>
  57. <style type="text/css">
  58. html,body{width:100%;height:100%;margin:0;}
  59. </style>
  60. </head>
  61. <body onload="init()">
  62. <div id="map" class="smallmap" style="width:100%; height:100%; backround-color:Red;"></div>
  63. </body>
  64. </html>

openlayers 加载瓦片详解 一的更多相关文章

  1. C编译器、链接器、加载器详解

    摘自http://blog.csdn.net/zzxian/article/details/16820035 C编译器.链接器.加载器详解 一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代 ...

  2. Spring Boot 配置加载顺序详解

    使用 Spring Boot 会涉及到各种各样的配置,如开发.测试.线上就至少 3 套配置信息了.Spring Boot 可以轻松的帮助我们使用相同的代码就能使开发.测试.线上环境使用不同的配置. 在 ...

  3. jboss之启动加载过程详解

    今天看了看jboss的boot.log和server.log日志,结合自己的理解和其他的资料,现对jboss的启动和加载过程做出如下总结: boot.xml是服务器的启动过程的日志,不涉及后续的操作过 ...

  4. 插件化框架解读之Android 资源加载机制详解(二)

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680Android提供了一种非常灵活的资源系统,可以根据不同的条件提供 ...

  5. jquery插件图片延时加载实例详解

    效果预览:http://keleyi.com/keleyi/phtml/image/index.htm 使用方法:1.导入JS插件 <script src="http://keleyi ...

  6. JS魔法堂:IMG元素加载行为详解

    一.前言 在<JS魔法堂:jsDeferred源码剖析>中我们了解到img元素加载失败可以作为函数异步执行的优化方案,本文打算对img元素的加载行为进行更深入的探讨. 二.资源加载的相关属 ...

  7. java中带继承类的加载顺序详解及实战

    一.背景: 在面试中,在java基础方面,类的加载顺序经常被问及,很多时候我们是搞不清楚到底类的加载顺序是怎么样的,那么今天我们就来看看带有继承的类的加载顺序到底是怎么一回事?在此记下也方便以后复习巩 ...

  8. (转)面试题--JAVA中静态块、静态变量加载顺序详解

    public class Test { //1.第一步,准备加载类 public static void main(String[] args) { new Test(); //4.第四步,new一个 ...

  9. Hive学习之四 《Hive分区表场景案例应用案例,企业日志加载》 详解

    文件的加载,只需要三步就够了,废话不多说,来直接的吧. 一.建表 话不多说,直接开始. 建表,对于日志文件来说,最后有分区,在此案例中,对年月日和小时进行了分区. 建表tracktest_log,分隔 ...

随机推荐

  1. asp.net mvc3 数据验证(二)——错误信息的自定义及其本地化

    原文:asp.net mvc3 数据验证(二)--错误信息的自定义及其本地化 一.自定义错误信息         在上一篇文章中所做的验证,在界面上提示的信息都是系统自带的,有些读起来比较生硬.比如: ...

  2. css中字符换行的一些问题

    -------我们在处理文章的内容的过程中由于文章内容混杂有中文.英文.数字等其他字符,而我们常见的英文和数字是无法在包裹元素中自动换行,这往往会导致元素被撑破,如下图所示: css中word-bre ...

  3. Linux Telnet安装配置

    本文以红帽6.2 64位版本为例,其它linux类似: linux默认是使用SSH服务的 而不安装telnet服务 ,所以需要手动安装telnet. 1.telnet的安装包有两个,分别是: teln ...

  4. 关于Java String对象创建的几点疑问

    我们通过JDK源码会知道String实质是字符数组,而且是不可被继承(final)和具有不可变性(immutable).可以如果想要了解String的创建我们需要先了解下JVM的内存结构. 1.JVM ...

  5. 警惕使用WebClient.DownloadFile(string uri,string filePath)方法

    原文:警惕使用WebClient.DownloadFile(string uri,string filePath)方法 WebClient.DownloadFile(string uri,string ...

  6. 四个漂亮的CSS样式表

    1. 单像素边框CSS表格 这是一个非经常常使用的表格样式. 源码: <!-- CSS goes in the document HEAD or added to your external s ...

  7. 如何有效的遍历django的QuerySet

    最近做了一个小的需求,在django模型中通过前台页面的表单的提交(post),后台对post的参数进行解析,通过models模型查询MySQL,将数据结构进行加工,返回到前台页面进行展示.由于对dj ...

  8. ADFS 2.0 配置简介 PartⅠ – 安装ADFS

        Active Directory Federation Service 也即联盟身份认证服务是微软的单点登录解决方案 (SSO),配置步骤相当多,中文资料也比较少,写在这里希望对后来人有所帮助 ...

  9. Lambda表达式、依赖倒置

    ASP.NET MVC学前篇之Lambda表达式.依赖倒置 ASP.NET MVC学前篇之Lambda表达式.依赖倒置 前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx= ...

  10. iOS基础 - 触摸事件与手势识别

    一.iOS的输入事件 UIKit可识别三种类型的输入事件: 触摸事件 运动(加速计)事件 远程控制事件 二.UIEvent iOS中许多事件对象都是UIEvent类的实例,记录事件产生的时刻和类型 U ...