OpenLayers源码学习16:图层Layer_2 Posted on 2015-03-16 | In OpenLayers学习 | 这里边是layer的基本功能, 主要是Baselayer Functions 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 // 初始化分辨率 initResolutions: function() { // 求分辨率的策略 // 1. 如果分辨率定义在layer config中则使用 // 2. else, 如果scales定义在layer config则转换成分辨率 // 3. else, 从layer config中的maxResolution,minResolution, // numZoomLevels, maxZoomLevel 计算分辨率 //------------------------------------------------- // 4. 到此还没有分辨率, 尝试从map里直接去取分辨率 // 5. else, 从map的 scales计算分辨率 // 6. else, 从map中的maxResolution,minResolution, // numZoomLevels, maxZoomLevel 计算分辨率 var i, len, p; var props = {}, alwaysInRange = true; // 从本layer的配置里拿, 创建props副本 for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) { p = this.RESOLUTION_PROPERTIES[i]; props[p] = this.options[p]; if(alwaysInRange && this.options[p]) {//之前有alwaysInRange为真, 配置里 alwaysInRange = false; } } if(this.options.alwaysInRange == null) { this.alwaysInRange = alwaysInRange; } //本图层配置里里没resolutions, 去找配置的scales if(props.resolutions == null) { props.resolutions = this.resolutionsFromScales(props.scales); } //还没有, 就从其他配置中计算 if(props.resolutions == null) { props.resolutions = this.calculateResolutions(props); } // 还没有算出来, 就从map的配置里计算 if(props.resolutions == null) { for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) { p = this.RESOLUTION_PROPERTIES[i]; props[p] = this.options[p] != null ? this.options[p] : this.map[p]; } if(props.resolutions == null) { props.resolutions = this.resolutionsFromScales(props.scales); } if(props.resolutions == null) { props.resolutions = this.calculateResolutions(props); } } //查询配置里的maxResolution var maxResolution; if(this.options.maxResolution && this.options.maxResolution !== "auto") { maxResolution = this.options.maxResolution; } if(this.options.minScale) { maxResolution = OpenLayers.Util.getResolutionFromScale( this.options.minScale, this.units); } //查询配置里的minResolution var minResolution; if(this.options.minResolution && this.options.minResolution !== "auto") { minResolution = this.options.minResolution; } if(this.options.maxScale) { minResolution = OpenLayers.Util.getResolutionFromScale( this.options.maxScale, this.units); } if(props.resolutions) { //对resolutions数组排序, 倒序 props.resolutions.sort(function(a, b) { return (b - a); }); //没指定maxResolution的话, 就要取数组里最大的一个 if(!maxResolution) { maxResolution = props.resolutions[0]; } //数组最小的一个 if(!minResolution) { var lastIdx = props.resolutions.length - 1; minResolution = props.resolutions[lastIdx]; } } this.resolutions = props.resolutions;//存储排序好的分辨率数组 if(this.resolutions) { len = this.resolutions.length; this.scales = new Array(len);//创建定长的scales数组 for(i=0; i<len; i++) { this.scales[i] = OpenLayers.Util.getScaleFromResolution( this.resolutions[i], this.units);//缓存 转换后的数组 } this.numZoomLevels = len;//numZoomLevels是总级别数 } this.minResolution = minResolution; if(minResolution) { this.maxScale = OpenLayers.Util.getScaleFromResolution( minResolution, this.units);//转换maxScale } this.maxResolution = maxResolution; if(maxResolution) { this.minScale = OpenLayers.Util.getScaleFromResolution( maxResolution, this.units);//minScale } }, // 从比例尺计算分辨率 resolutionsFromScales: function(scales) { if(scales == null) { return; } var resolutions, i, len; len = scales.length; resolutions = new Array(len);//定长数组 for(i=0; i<len; i++) { resolutions[i] = OpenLayers.Util.getResolutionFromScale( scales[i], this.units);//遍历赋值 } return resolutions; }, //计算分辨率 calculateResolutions: function(props) { var viewSize, wRes, hRes; // 计算maxResolution var maxResolution = props.maxResolution; if(props.minScale != null) { maxResolution = OpenLayers.Util.getResolutionFromScale(props.minScale, this.units); } else if(maxResolution == "auto" && this.maxExtent != null) { viewSize = this.map.getSize(); wRes = this.maxExtent.getWidth() / viewSize.w;//通过长宽计算分辨率 hRes = this.maxExtent.getHeight() / viewSize.h; maxResolution = Math.max(wRes, hRes); } // 计算minResolution var minResolution = props.minResolution; if(props.maxScale != null) { minResolution = OpenLayers.Util.getResolutionFromScale(props.maxScale, this.units); } else if(props.minResolution == "auto" && this.minExtent != null) { viewSize = this.map.getSize(); wRes = this.minExtent.getWidth() / viewSize.w; hRes = this.minExtent.getHeight()/ viewSize.h; minResolution = Math.max(wRes, hRes); } // 这种情况下计算maxResolution, 通过瓦片尺寸 if(typeof maxResolution !== "number" && typeof minResolution !== "number" && this.maxExtent != null) { var tileSize = this.map.getTileSize(); maxResolution = Math.max( this.maxExtent.getWidth() / tileSize.w, this.maxExtent.getHeight() / tileSize.h ); } // 通过maxResolution和minResolution计算numZoomLevels var maxZoomLevel = props.maxZoomLevel; var numZoomLevels = props.numZoomLevels; if(typeof minResolution === "number" && typeof maxResolution === "number" && numZoomLevels === undefined) { var ratio = maxResolution / minResolution; numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1; } else if(numZoomLevels === undefined && maxZoomLevel != null) { numZoomLevels = maxZoomLevel + 1; } // 有些时候条件不够计算不出resolutions if(typeof numZoomLevels !== "number" || numZoomLevels <= 0 || (typeof maxResolution !== "number" && typeof minResolution !== "number")) { return; } // 到现在已经计算出numZoomLevels 和maxResolution or minResolution var resolutions = new Array(numZoomLevels); var base = 2; if(typeof minResolution == "number" && typeof maxResolution == "number") { // if maxResolution and minResolution are set, we calculate // the base for exponential scaling that starts at // maxResolution and ends at minResolution in numZoomLevels // steps. base = Math.pow( (maxResolution / minResolution), (1 / (numZoomLevels - 1)) ); } var i; if(typeof maxResolution === "number") { for(i=0; i<numZoomLevels; i++) { resolutions[i] = maxResolution / Math.pow(base, i);//遍历赋值 } } else { for(i=0; i<numZoomLevels; i++) { resolutions[numZoomLevels - 1 - i] = minResolution * Math.pow(base, i); } } return resolutions; }, //获得当前分辨率 Resolution[zoom] getResolution: function() { var zoom = this.map.getZoom(); return this.getResolutionForZoom(zoom); }, // 获得Extent(就是Bounds) getExtent: function() { return this.map.calculateBounds(); }, // 从指定extent计算zoom getZoomForExtent: function(extent, closest) { var viewSize = this.map.getSize(); var idealResolution = Math.max( extent.getWidth() / viewSize.w, extent.getHeight() / viewSize.h ); return this.getZoomForResolution(idealResolution, closest); }, getDataExtent: function () { //to be implemented by subclasses }, // 从zoom值获得Resolution getResolutionForZoom: function(zoom) { zoom = Math.max(0, Math.min(zoom, this.resolutions.length - 1)); var resolution; if(this.map.fractionalZoom) { var low = Math.floor(zoom); var high = Math.ceil(zoom); resolution = this.resolutions[low] - ((zoom-low) * (this.resolutions[low]-this.resolutions[high])); } else { resolution = this.resolutions[Math.round(zoom)]; } return resolution; }, //从分辨率获得zoom getZoomForResolution: function(resolution, closest) { var zoom, i, len; if(this.map.fractionalZoom) { var lowZoom = 0; var highZoom = this.resolutions.length - 1; var highRes = this.resolutions[lowZoom]; var lowRes = this.resolutions[highZoom]; var res; for(i=0, len=this.resolutions.length; i= resolution) { highRes = res; lowZoom = i; } if(res 0) { zoom = lowZoom + ((highRes - resolution) / dRes); } else { zoom = lowZoom; } } else { var diff; var minDiff = Number.POSITIVE_INFINITY; for(i=0, len=this.resolutions.length; i minDiff) { break; } minDiff = diff; } else { if (this.resolutions[i] < resolution) { break; } } } zoom = Math.max(0, i-1); } return zoom; }, //从当前的像素坐标, 计算经纬度 getLonLatFromViewPortPx: function (viewPortPx) { var lonlat = null; var map = this.map; if (viewPortPx != null && map.minPx) { var res = map.getResolution(); var maxExtent = map.getMaxExtent({restricted: true}); var lon = (viewPortPx.x - map.minPx.x) * res + maxExtent.left; var lat = (map.minPx.y - viewPortPx.y) * res + maxExtent.top; lonlat = new OpenLayers.LonLat(lon, lat); if (this.wrapDateLine) { lonlat = lonlat.wrapDateLine(this.maxExtent); } } return lonlat; }, //已知经纬度, 计算像素坐标 getViewPortPxFromLonLat: function (lonlat, resolution) { var px = null; if (lonlat != null) { resolution = resolution || this.map.getResolution(); var extent = this.map.calculateBounds(null, resolution); px = new OpenLayers.Pixel( (1/resolution * (lonlat.lon - extent.left)), (1/resolution * (extent.top - lonlat.lat)) ); } return px; }, // 设置图层透明度 setOpacity: function(opacity) { if (opacity != this.opacity) { this.opacity = opacity; var childNodes = this.div.childNodes; for(var i = 0, len = childNodes.length; i < len; ++i) { var element = childNodes[i].firstChild || childNodes[i];//优先给第一个子元素 var lastChild = childNodes[i].lastChild; //如果是iframe的话, 就给lastChild.parentNode设置透明度 if (lastChild && lastChild.nodeName.toLowerCase() === "iframe") { element = lastChild.parentNode; } OpenLayers.Util.modifyDOMElement(element, null, null, null, null, null, null, opacity); } //触发map的图层修改 if (this.map != null) { this.map.events.triggerEvent("changelayer", { layer: this, property: "opacity" }); } } }, getZIndex: function () { return this.div.style.zIndex; }, setZIndex: function (zIndex) { this.div.style.zIndex = zIndex; }, //调整 Bounds adjustBounds: function (bounds) { if (this.gutter) { //边距x分辨率 var mapGutter = this.gutter * this.map.getResolution(); bounds = new OpenLayers.Bounds(bounds.left - mapGutter, bounds.bottom - mapGutter, bounds.right + mapGutter, bounds.top + mapGutter);//往外扩了一圈 } if (this.wrapDateLine) { // wrapDateLine为真是需要 var wrappingOptions = { 'rightTolerance':this.getResolution(), 'leftTolerance':this.getResolution() }; bounds = bounds.wrapDateLine(this.maxExtent, wrappingOptions); } return bounds; }, CLASS_NAME: "OpenLayers.Layer"});