zoukankan      html  css  js  c++  java
  • 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="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{100%;height:100%;margin:0;}
    	</style>
      </head>
      <body onload="init()">
        <div id="map"  class="smallmap"  style="100%; height:100%; backround-color:Red;"></div>
      </body>
    </html>
    



     

  • 相关阅读:
    poj1182 食物链
    poj1611 The Suspects
    poj3436 Computer Factory
    (转) GPG入门教程
    cronolog安装配置
    RHCA-436-4 rhcs conga
    pxe引导gparted live万能分区
    linux下拔号pptp
    GNU parted简略用法
    hostapd故障解决(1.1,2.0,2.2)
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3190133.html
Copyright © 2011-2022 走看看