OpenLayers学习14-投影Projection Posted on 2015-02-10 | In OpenLayers学习 | 做投影转换的类默认可以转换 geographic (EPSG:4326等) 和 web mercator (EPSG:900913等), 计算公式在最后边其他投影的转换需要单独引入proj4js : http://proj4js.org/ 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133OpenLayers.Projection = OpenLayers.Class({ // Proj4js.Proj实例对象 proj: null, // projCode字串 projCode: null, //title正则 titleRegEx: /\+title=[^\+]*/, // 构造, 包装pro4js projection对象 initialize: function(projCode, options) { OpenLayers.Util.extend(this, options); this.projCode = projCode; if (typeof Proj4js == "object") { //缓存new Proj4js对象 this.proj = new Proj4js.Proj(projCode); } }, // 有proj缓存用proj.srsCode, 否则用projCode getCode: function() { return this.proj ? this.proj.srsCode : this.projCode; }, // this.proj缓存里的.proj.units getUnits: function() { return this.proj ? this.proj.units : null; }, //返回code toString: function() { return this.getCode(); }, //判等 equals: function(projection) { var p = projection, equals = false; if (p) { if (!(p instanceof OpenLayers.Projection)) { p = new OpenLayers.Projection(p);//不是对象的, 构造一下. 这没用CLSS_NAME判断 } if ((typeof Proj4js == "object") && this.proj.defData && p.proj.defData) { //忽略title equals = this.proj.defData.replace(this.titleRegEx, "") == p.proj.defData.replace(this.titleRegEx, ""); } else if (p.getCode) { var source = this.getCode(), target = p.getCode(); //使用同一投影??? equals = source == target || !!OpenLayers.Projection.transforms[source] && OpenLayers.Projection.transforms[source][target] === OpenLayers.Projection.nullTransform; } } return equals; }, //GC, 删掉缓存对象 //delete和直接null还不一样, delete以后本实例就没有这一项了. 等于这个对象就废了 destroy: function() { delete this.proj; delete this.projCode; }, CLASS_NAME: "OpenLayers.Projection" }); // 缓存对象, 后边执行过程里往里addOpenLayers.Projection.transforms = {}; //默认值对象: //Keys 就是 SRS code, 84没用过...OpenLayers.Projection.defaults = { "EPSG:4326": {//经纬度 units: "degrees", maxExtent: [-180, -90, 180, 90], yx: true }, "CRS:84": { units: "degrees", maxExtent: [-180, -90, 180, 90] }, "EPSG:900913": {//墨卡托 units: "m", maxExtent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34] }}; // 切换from和to的投影类型OpenLayers.Projection.addTransform = function(from, to, method) { if (method === OpenLayers.Projection.nullTransform) { var defaults = OpenLayers.Projection.defaults[from]; if (defaults && !OpenLayers.Projection.defaults[to]) { OpenLayers.Projection.defaults[to] = defaults; } } //要是缓存中没有, 初始化一个新的 if(!OpenLayers.Projection.transforms[from]) { OpenLayers.Projection.transforms[from] = {}; } // 缓存的[from][to] 里边存的是method方法 OpenLayers.Projection.transforms[from][to] = method;}; //转换方法, 从缓存中读: 缓存[源] 和 缓存[目标], 返回经过转换的point对象OpenLayers.Projection.transform = function(point, source, dest) { if (source && dest) { if (!(source instanceof OpenLayers.Projection)) { source = new OpenLayers.Projection(source);//source实例 } if (!(dest instanceof OpenLayers.Projection)) { dest = new OpenLayers.Projection(dest);//dest实例 } if (source.proj && dest.proj) { point = Proj4js.transform(source.proj, dest.proj, point);//使用Proj4js.transform转换 } else { var sourceCode = source.getCode(); var destCode = dest.getCode(); var transforms = OpenLayers.Projection.transforms; //同时有 缓存[源] 和 缓存[目标] if (transforms[sourceCode] && transforms[sourceCode][destCode]) { transforms[sourceCode][destCode](point);//证明之前add过, 调用转换方法 } } } return point;}; // 只是返回原point点OpenLayers.Projection.nullTransform = function(point) { return point;}; 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748//默认自带经纬度和墨卡托的转换, map方法做各个转换的映射(function() { var pole = 20037508.34; //反转墨卡托 function inverseMercator(xy) { xy.x = 180 * xy.x / pole; xy.y = 180 / Math.PI * (2 * Math.atan(Math.exp((xy.y / pole) * Math.PI)) - Math.PI / 2); return xy; } //转换墨卡托 function forwardMercator(xy) { xy.x = xy.x * pole / 180; var y = Math.log(Math.tan((90 + xy.y) * Math.PI / 360)) / Math.PI * pole; xy.y = Math.max(-20037508.34, Math.min(y, 20037508.34)); return xy; } //映射方法 function map(base, codes) { var add = OpenLayers.Projection.addTransform; var same = OpenLayers.Projection.nullTransform; var i, len, code, other, j; for (i=0, len=codes.length; i<len; ++i) { code = codes[i]; //墨卡托与经纬度坐标的相互转换 add(base, code, forwardMercator); add(code, base, inverseMercator); for (j=i+1; j<len; ++j) { other = codes[j]; //墨卡托与墨卡托 或 经纬度与经纬度 的转换 add(code, other, same); add(other, code, same); } } } //墨卡托列表 / 经纬度列表 var mercator = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"], geographic = ["CRS:84", "urn:ogc:def:crs:EPSG:6.6:4326", "EPSG:4326"], i; for (i=mercator.length-1; i>=0; --i) { map(mercator[i], geographic);//墨卡托和经纬度的一一对应 } for (i=geographic.length-1; i>=0; --i) { map(geographic[i], mercator);//经纬度和墨卡托的一一对应 } })();