openlayers 加载瓦片详解 一
在这先说点题外话,本人在研究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)方法加载本地图片(天地图)
- 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"
- });
测试页面
- <!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" type="text/css">
- <link rel="stylesheet" href="style.css" type="text/css">
- <script src="../lib/OpenLayers.js"></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" type="text/css">
- <link rel="stylesheet" href="style.css" type="text/css">
- <script src="../lib/OpenLayers.js"></script>
- <script src="../lib/Firebug/firebug.js"></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>
openlayers 加载瓦片详解 一的更多相关文章
- C编译器、链接器、加载器详解
摘自http://blog.csdn.net/zzxian/article/details/16820035 C编译器.链接器.加载器详解 一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代 ...
- Spring Boot 配置加载顺序详解
使用 Spring Boot 会涉及到各种各样的配置,如开发.测试.线上就至少 3 套配置信息了.Spring Boot 可以轻松的帮助我们使用相同的代码就能使开发.测试.线上环境使用不同的配置. 在 ...
- jboss之启动加载过程详解
今天看了看jboss的boot.log和server.log日志,结合自己的理解和其他的资料,现对jboss的启动和加载过程做出如下总结: boot.xml是服务器的启动过程的日志,不涉及后续的操作过 ...
- 插件化框架解读之Android 资源加载机制详解(二)
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680Android提供了一种非常灵活的资源系统,可以根据不同的条件提供 ...
- jquery插件图片延时加载实例详解
效果预览:http://keleyi.com/keleyi/phtml/image/index.htm 使用方法:1.导入JS插件 <script src="http://keleyi ...
- JS魔法堂:IMG元素加载行为详解
一.前言 在<JS魔法堂:jsDeferred源码剖析>中我们了解到img元素加载失败可以作为函数异步执行的优化方案,本文打算对img元素的加载行为进行更深入的探讨. 二.资源加载的相关属 ...
- java中带继承类的加载顺序详解及实战
一.背景: 在面试中,在java基础方面,类的加载顺序经常被问及,很多时候我们是搞不清楚到底类的加载顺序是怎么样的,那么今天我们就来看看带有继承的类的加载顺序到底是怎么一回事?在此记下也方便以后复习巩 ...
- (转)面试题--JAVA中静态块、静态变量加载顺序详解
public class Test { //1.第一步,准备加载类 public static void main(String[] args) { new Test(); //4.第四步,new一个 ...
- Hive学习之四 《Hive分区表场景案例应用案例,企业日志加载》 详解
文件的加载,只需要三步就够了,废话不多说,来直接的吧. 一.建表 话不多说,直接开始. 建表,对于日志文件来说,最后有分区,在此案例中,对年月日和小时进行了分区. 建表tracktest_log,分隔 ...
随机推荐
- asp.net mvc3 数据验证(二)——错误信息的自定义及其本地化
原文:asp.net mvc3 数据验证(二)--错误信息的自定义及其本地化 一.自定义错误信息 在上一篇文章中所做的验证,在界面上提示的信息都是系统自带的,有些读起来比较生硬.比如: ...
- css中字符换行的一些问题
-------我们在处理文章的内容的过程中由于文章内容混杂有中文.英文.数字等其他字符,而我们常见的英文和数字是无法在包裹元素中自动换行,这往往会导致元素被撑破,如下图所示: css中word-bre ...
- Linux Telnet安装配置
本文以红帽6.2 64位版本为例,其它linux类似: linux默认是使用SSH服务的 而不安装telnet服务 ,所以需要手动安装telnet. 1.telnet的安装包有两个,分别是: teln ...
- 关于Java String对象创建的几点疑问
我们通过JDK源码会知道String实质是字符数组,而且是不可被继承(final)和具有不可变性(immutable).可以如果想要了解String的创建我们需要先了解下JVM的内存结构. 1.JVM ...
- 警惕使用WebClient.DownloadFile(string uri,string filePath)方法
原文:警惕使用WebClient.DownloadFile(string uri,string filePath)方法 WebClient.DownloadFile(string uri,string ...
- 四个漂亮的CSS样式表
1. 单像素边框CSS表格 这是一个非经常常使用的表格样式. 源码: <!-- CSS goes in the document HEAD or added to your external s ...
- 如何有效的遍历django的QuerySet
最近做了一个小的需求,在django模型中通过前台页面的表单的提交(post),后台对post的参数进行解析,通过models模型查询MySQL,将数据结构进行加工,返回到前台页面进行展示.由于对dj ...
- ADFS 2.0 配置简介 PartⅠ – 安装ADFS
Active Directory Federation Service 也即联盟身份认证服务是微软的单点登录解决方案 (SSO),配置步骤相当多,中文资料也比较少,写在这里希望对后来人有所帮助 ...
- Lambda表达式、依赖倒置
ASP.NET MVC学前篇之Lambda表达式.依赖倒置 ASP.NET MVC学前篇之Lambda表达式.依赖倒置 前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx= ...
- iOS基础 - 触摸事件与手势识别
一.iOS的输入事件 UIKit可识别三种类型的输入事件: 触摸事件 运动(加速计)事件 远程控制事件 二.UIEvent iOS中许多事件对象都是UIEvent类的实例,记录事件产生的时刻和类型 U ...