ruantao1989


  • Home

  • Archives

  • Categories

  • About

OpenLayers学习9-元素Element,经纬度LngLat,尺寸Size

Posted on 2015-02-05   |   In OpenLayers学习   |  

Element不是一个类(不是从Class扩展出来的), 感觉是对Dom操作的包装对象.
看了一下类图, Element仅仅作为SVG和VML的父类使用, 这样组织的好处还没体会到

Read more »

OpenLayers学习8-Bounds(首个类)

Posted on 2015-02-03   |   In OpenLayers学习   |  

Bounds边界, 这是第一次看OpenLayers类的代码, 好好体会了一下他怎么组织代码:

OpenLayers.Bounds在完成OpenLayers.Class()类的声明之后, OpenLayers.Bounds只是指向构造函数.
当new OpenLayers.Bounds()时, 产生一个实例, 此实例才是所需对象

实例构造时传入”左下右上”四个参数, 类中的全部方法以此”左下右上”为判断的基础,
实例方法纯完面向对象, 很少有js里面向过程的思想
类的静态方法写法类似:OpenLayers.Bounds.fromArray = function() {return …}, 补充完善OO.

Read more »

OpenLayers学习7-工具类Util_4

Posted on 2015-02-02   |   In OpenLayers学习   |  

一:尺寸计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//计算出popup的尺寸, left值会被写成-9999px, 防止滚动条闪烁
//size包含w 和 h参数,
//option: displayClass是css类名, containerElement是父对象
OpenLayers.Util.getRenderedDimensions = function(contentHTML, size, options) {
var w, h;
//临时div对象的容器
var container = document.createElement("div");
container.style.visibility = "hidden";
//popup容器优先是options.containerElement, 然后是body
var containerElement = (options && options.containerElement)
? options.containerElement : document.body;
// IE7不能从父对象继承position:aboslute
var parentHasPositionAbsolute = false;
var superContainer = null;
var parent = containerElement;
while (parent && parent.tagName.toLowerCase()!="body") {
//获取父对象的position值
var parentPosition = OpenLayers.Element.getStyle(parent, "position");
if(parentPosition == "absolute") {
parentHasPositionAbsolute = true;//父对象是absolute标记
break;
} else if (parentPosition && parentPosition != "static") {
break;
}
parent = parent.parentNode;
}
if(parentHasPositionAbsolute && (containerElement.clientHeight === 0 ||
containerElement.clientWidth === 0) ){
//不能继承aboslute就手工在外边套一层
superContainer = document.createElement("div");
superContainer.style.visibility = "hidden";
superContainer.style.position = "absolute";
superContainer.style.overflow = "visible";
superContainer.style.width = document.body.clientWidth + "px";
superContainer.style.height = document.body.clientHeight + "px";
superContainer.appendChild(container);
}
container.style.position = "absolute";
//写入指定的w和h
if (size) {
if (size.w) {
w = size.w;
container.style.width = w + "px";
} else if (size.h) {
h = size.h;
container.style.height = h + "px";
}
}
//写入指定css类名
if (options && options.displayClass) {
container.className = options.displayClass;
}
//内容div
var content = document.createElement("div");
content.innerHTML = contentHTML;
//计算尺寸时需要overflow: visible
content.style.overflow = "visible";
if (content.childNodes) {
for (var i=0, l=content.childNodes.length; i<l; i++) {
if (!content.childNodes[i].style) continue;
content.childNodes[i].style.overflow = "visible";//子元素overflow都改成visible
}
}
//把内容div写入临时容器
container.appendChild(content);
//把临时容器写入页面
if (superContainer) {
containerElement.appendChild(superContainer);
} else {
containerElement.appendChild(container);
}
//没指定w的话
if (!w) {
w = parseInt(content.scrollWidth);
//宽就是scrollWidth
container.style.width = w + "px";
}
//记录下来h
if (!h) {
h = parseInt(content.scrollHeight);
}
//遍历删除子元素
container.removeChild(content);
if (superContainer) {
superContainer.removeChild(container);
containerElement.removeChild(superContainer);
} else {
containerElement.removeChild(container);
}
return new OpenLayers.Size(w, h);//返回w 和 h
};
//获得滚动条宽度
OpenLayers.Util.getScrollbarWidth = function() {
//默认宽度 初始化时没有, 在这个函数末尾追加
var scrollbarWidth = OpenLayers.Util._scrollbarWidth;
if (scrollbarWidth == null) {
//初始化计算
var scr = null;
var inn = null;
var wNoScroll = 0;
var wScroll = 0;
//外层div, 在视野外计算
scr = document.createElement('div');
scr.style.position = 'absolute';
scr.style.top = '-1000px';
scr.style.left = '-1000px';
scr.style.width = '100px';//比较小
scr.style.height = '50px';
//没有滚动条
scr.style.overflow = 'hidden';
//内层, 写死大小
inn = document.createElement('div');
inn.style.width = '100%';
inn.style.height = '200px';//比较大
//外层套内层
scr.appendChild(inn);
//body套外层
document.body.appendChild(scr);
//原始内层的实际宽度offsetWidth(包含滚动条宽度)
wNoScroll = inn.offsetWidth;
//外层显示滚动条
scr.style.overflow = 'scroll';
//有滚动条以后的实际宽度offsetWidth
wScroll = inn.offsetWidth;
//计算完了, 删掉div
document.body.removeChild(document.body.lastChild);
//记录结果
OpenLayers.Util._scrollbarWidth = (wNoScroll - wScroll);//内层没滚动条的宽度 - 有滚动条的宽度
scrollbarWidth = OpenLayers.Util._scrollbarWidth;
}
return scrollbarWidth;
};

OpenLayers学习6-工具类Util_3

Posted on 2015-02-01   |   In OpenLayers学习   |  

一:DOM位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//获取viewport元素
//除了IE都是document.documentElement(XHTML)
//IE有两种可能: 可能是document.body(没doctype), 或document.documentElement(XHTML);
OpenLayers.Util.getViewportElement = function() {
var viewportElement = arguments.callee.viewportElement;
if (viewportElement == undefined) {
viewportElement = (OpenLayers.BROWSER_NAME == "msie" &&
document.compatMode != 'CSS1Compat') ? document.body :
document.documentElement;
arguments.callee.viewportElement = viewportElement;
}
return viewportElement;
};
//计算一个DOM元素在页面上的位置(隐藏的元素返回0,0)
//结果是数组[left, top]
OpenLayers.Util.pagePosition = function(forElement) {
//
var pos = [0, 0];
var viewportElement = OpenLayers.Util.getViewportElement();
if (!forElement || forElement == window || forElement == viewportElement) {
//根对象和window返回0,0
return pos;
}
// 判断是否是Gecko内核,
//查了一下FF 3.6之前的Gecko内核使用document.getBoxObjectFor
var BUGGY_GECKO_BOX_OBJECT =
OpenLayers.IS_GECKO && document.getBoxObjectFor &&
OpenLayers.Element.getStyle(forElement, 'position') == 'absolute' &&
(forElement.style.top == '' || forElement.style.left == '');
var parent = null;
var box;
if (forElement.getBoundingClientRect) { // IE
//其实IE6+都支持, 包括ff和chrome等
box = forElement.getBoundingClientRect();
var scrollTop = window.pageYOffset || viewportElement.scrollTop;
var scrollLeft = window.pageXOffset || viewportElement.scrollLeft;
pos[0] = box.left + scrollLeft;
pos[1] = box.top + scrollTop;
} else if (document.getBoxObjectFor && !BUGGY_GECKO_BOX_OBJECT) { // gecko
//估计新的ff到不了这个判断了
box = document.getBoxObjectFor(forElement);
var vpBox = document.getBoxObjectFor(viewportElement);
pos[0] = box.screenX - vpBox.screenX;
pos[1] = box.screenY - vpBox.screenY;
} else { // safari/opera
pos[0] = forElement.offsetLeft;
pos[1] = forElement.offsetTop;
parent = forElement.offsetParent;
if (parent != forElement) {
while (parent) {
pos[0] += parent.offsetLeft;
pos[1] += parent.offsetTop;
parent = parent.offsetParent;
}
}
var browser = OpenLayers.BROWSER_NAME;
//减掉body.offsetTop
if (browser == "opera" || (browser == "safari" &&
OpenLayers.Element.getStyle(forElement, 'position') == 'absolute')) {
pos[1] -= document.body.offsetTop;
}
//处理滚动的情况(body不减scrollLeft和scrollTop)
parent = forElement.offsetParent;
while (parent && parent != document.body) {
pos[0] -= parent.scrollLeft;
if (browser != "opera" || parent.tagName != 'TR') {
pos[1] -= parent.scrollTop;
}
parent = parent.offsetParent;
}
}
return pos;
};

二: URL操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//返回url+ port+ args
/*
* Valid options:
* ignoreCase - {Boolean} lowercase url,
* ignorePort80 - {Boolean} don't include explicit port if port is 80,
* ignoreHash - {Boolean} Don't include part of url after the hash (#).
* splitArgs - {Boolean} Split comma delimited params into arrays? Default is
* true.
*/
OpenLayers.Util.createUrlObject = function(url, options) {
options = options || {};
// 不是以"字串://"开头
if(!(/^\w+:\/\//).test(url)) {
var loc = window.location;
var port = loc.port ? ":" + loc.port : "";
//组装完整url
//host.split(":")先按冒号切成数组, shift()把[1]也就是冒号后边的端口号给弹出
var fullUrl = loc.protocol + "//" + loc.host.split(":").shift() + port;
if(url.indexOf("/") === 0) {
//相对路径, 第一位是"/"
url = fullUrl + url;
} else {
//相对路径, 第一位不是"/", 组装一下
var parts = loc.pathname.split("/");
parts.pop();
url = fullUrl + parts.join("/") + "/" + url;
}
}
//忽略大小写, 就都转成小写
if (options.ignoreCase) {
url = url.toLowerCase();
}
//新建a标签DOM, 借用a处理url
var a = document.createElement('a');
a.href = url;
var urlObject = {};
//去掉host:port中的端口号
urlObject.host = a.host.split(":").shift();
//协议名
urlObject.protocol = a.protocol;
//追加80端口
if(options.ignorePort80) {
urlObject.port = (a.port == "80" || a.port == "0") ? "" : a.port;
} else {
urlObject.port = (a.port == "" || a.port == "0") ? "80" : a.port;
}
//井号
urlObject.hash = (options.ignoreHash || a.hash === "#") ? "" : a.hash;
//args
var queryString = a.search;
if (!queryString) {
var qMark = url.indexOf("?");
queryString = (qMark != -1) ? url.substr(qMark) : "";
}
urlObject.args = OpenLayers.Util.getParameters(queryString,
{splitArgs: options.splitArgs});
//针对IE, 第一位不是斜杠, 补一个"/"
urlObject.pathname = (a.pathname.charAt(0) == "/") ? a.pathname : "/" + a.pathname;
return urlObject;
};
//清掉url里"?"或"&"末尾的字串
OpenLayers.Util.removeTail = function(url) {
var head = null;
var qMark = url.indexOf("?");
var hashMark = url.indexOf("#");
if (qMark == -1) {
//没问号的, 有井号, 就截井号
head = (hashMark != -1) ? url.substr(0,hashMark) : url;
} else {
//有问号, 有井号, 用Math.min判断下哪个在前, 截取
head = (hashMark != -1) ? url.substr(0,Math.min(qMark, hashMark))
: url.substr(0, qMark);
}
return head;
};

三:浏览器兼容检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//从userAgent判断是不是gecko内核
OpenLayers.IS_GECKO = (function() {
var ua = navigator.userAgent.toLowerCase();
return ua.indexOf("webkit") == -1 && ua.indexOf("gecko") != -1;
})();
//测试是否支持canvas
//反正如果支持canvas的话也不用考虑内存回收的问题
OpenLayers.CANVAS_SUPPORTED = (function() {
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
})();
//配置项: 立即执行从navigator.userAgent获取浏览器名称
OpenLayers.BROWSER_NAME = (function() {
var name = "";
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf("opera") != -1) {
name = "opera";
} else if (ua.indexOf("msie") != -1) {
name = "msie";
} else if (ua.indexOf("safari") != -1) {
name = "safari";
} else if (ua.indexOf("mozilla") != -1) {
if (ua.indexOf("firefox") != -1) {
name = "firefox";
} else {
name = "mozilla";
}
}
return name;
})();
//获取配置项
OpenLayers.Util.getBrowserName = function() {
return OpenLayers.BROWSER_NAME;
};

OpenLayers学习5-工具类Util_2

Posted on 2015-02-01   |   In OpenLayers学习   |  

一: 鼠标操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//判断div是不是触发evt对象的根对象(最父级对象)
//这个和事件关系比较紧密, 还不知道为什么这么处理...
OpenLayers.Util.mouseLeft = function (evt, div) {
//兼容IE, 获得事件源
var target = (evt.relatedTarget) ? evt.relatedTarget : evt.toElement;
//直到追溯至根节点
while (target != div && target != null) {
target = target.parentNode;
}
//如果div是根对象, 返回true
return (target != div);
};
//浮点精度
OpenLayers.Util.DEFAULT_PRECISION = 14;
//把对象转成浮点型
OpenLayers.Util.toFloat = function (number, precision) {
if (precision == null) {
precision = OpenLayers.Util.DEFAULT_PRECISION;//默认精度
}
//本来就是"number"型, 直接parseFloat
if (typeof number !== "number") {
number = parseFloat(number);
}
return precision === 0 ? number : //精度0
parseFloat(number.toPrecision(precision));//指数形式
};

二: 距离计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//计算两点距离
//角度转弧度
OpenLayers.Util.rad = function(x) {return x*Math.PI/180;};
//弧度转角度
OpenLayers.Util.deg = function(x) {return x*180/Math.PI;};
//a:长半轴, b短半轴, c扁率
OpenLayers.Util.VincentyConstants = {
a: 6378137,
b: 6356752.3142,
f: 1/298.257223563
};
//计算两点距离
//提供两个带lat和lon的对象, 计算出以km为单位的距离
//计算公式完全看不懂...
OpenLayers.Util.distVincenty = function(p1, p2) {
var ct = OpenLayers.Util.VincentyConstants;
var a = ct.a, b = ct.b, f = ct.f;
var L = OpenLayers.Util.rad(p2.lon - p1.lon);
var U1 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p1.lat)));
var U2 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p2.lat)));
var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
var lambda = L, lambdaP = 2*Math.PI;
var iterLimit = 20;
while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0) {
var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
(cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda));
if (sinSigma==0) {
return 0; // co-incident points
}
var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
var sigma = Math.atan2(sinSigma, cosSigma);
var alpha = Math.asin(cosU1 * cosU2 * sinLambda / sinSigma);
var cosSqAlpha = Math.cos(alpha) * Math.cos(alpha);
var cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha;
var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
lambdaP = lambda;
lambda = L + (1-C) * f * Math.sin(alpha) *
(sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
}
if (iterLimit==0) {
return NaN; // formula failed to converge
}
var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
var s = b*A*(sigma-deltaSigma);
var d = s.toFixed(3)/1000; // round to 1mm precision
return d;
};
//计算出经纬度(给定经纬度, 角度, 距离)
//公式看不懂
OpenLayers.Util.destinationVincenty = function(lonlat, brng, dist) {
var u = OpenLayers.Util;
var ct = u.VincentyConstants;
var a = ct.a, b = ct.b, f = ct.f;
var lon1 = lonlat.lon;
var lat1 = lonlat.lat;
var s = dist;
var alpha1 = u.rad(brng);
var sinAlpha1 = Math.sin(alpha1);
var cosAlpha1 = Math.cos(alpha1);
var tanU1 = (1-f) * Math.tan(u.rad(lat1));
var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
var sigma1 = Math.atan2(tanU1, cosAlpha1);
var sinAlpha = cosU1 * sinAlpha1;
var cosSqAlpha = 1 - sinAlpha*sinAlpha;
var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
var sigma = s / (b*A), sigmaP = 2*Math.PI;
while (Math.abs(sigma-sigmaP) > 1e-12) {
var cos2SigmaM = Math.cos(2*sigma1 + sigma);
var sinSigma = Math.sin(sigma);
var cosSigma = Math.cos(sigma);
var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
sigmaP = sigma;
sigma = s / (b*A) + deltaSigma;
}
var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
(1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
var L = lambda - (1-C) * f * sinAlpha *
(sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
var revAz = Math.atan2(sinAlpha, -tmp); // final bearing
return new OpenLayers.LonLat(lon1+u.deg(L), u.deg(lat2));
};

三: URL操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//从URL里解析参数, 参数里有逗号的话会写入数组
//第二个参数options, 若true表示把含逗号的参数写入数组, 默认true
OpenLayers.Util.getParameters = function(url, options) {
options = options || {};
//优先用传入的url, 否则用location.href
url = (url === null || url === undefined) ? window.location.href : url;
var paramsString = "";
if (OpenLayers.String.contains(url, '?')) {
var start = url.indexOf('?') + 1;//从?后边开始截取
var end = OpenLayers.String.contains(url, "#") ?
url.indexOf('#') : url.length;//有#截到#, 否则截到最后一位
paramsString = url.substring(start, end);
}
var parameters = {};//准备空的结果对象
var pairs = paramsString.split(/[&;]/);//按照"&"切分成数组
for(var i=0, len=pairs.length; i<len; ++i) {
var keyValue = pairs[i].split('=');//每个部分按"="切分
//若有key
if (keyValue[0]) {
var key = keyValue[0];
//对key解码
try {
key = decodeURIComponent(key);
} catch (err) {
key = unescape(key);
}
//val里"+"替换成空格
var value = (keyValue[1] || '').replace(/\+/g, " ");
//对val解码
try {
value = decodeURIComponent(value);
} catch (err) {
value = unescape(value);
}
//有些OGC的参数里带"," 按逗号切分
if (options.splitArgs !== false) {
value = value.split(",");
}
//要是没逗号, 就不写入数组
if (value.length == 1) {
value = value[0];
}
parameters[key] = value;//写入对象
}
}
return parameters;
};
//自增id的记录
OpenLayers.Util.lastSeqID = 0;
//根据前缀,生成"前缀_自增id"
OpenLayers.Util.createUniqueID = function(prefix) {
if (prefix == null) {
prefix = "id_";
} else {
prefix = prefix.replace(OpenLayers.Util.dotless, "_");//把"."换成"_"
}
OpenLayers.Util.lastSeqID += 1; //自增
return prefix + OpenLayers.Util.lastSeqID;
};

四: 比例尺相关的计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//Scale = 图上距离/实地距离 , Resolution = 一像素代表多少地图单位
//单位对象配置
//相对来说是动态的配置对象, 比我之前在init函数里计算的思路要好
OpenLayers.INCHES_PER_UNIT = {
'inches': 1.0,
'ft': 12.0,
'mi': 63360.0,
'm': 39.37,
'km': 39370,
'dd': 4374754,
'yd': 36
};
OpenLayers.INCHES_PER_UNIT["in"]= OpenLayers.INCHES_PER_UNIT.inches;
OpenLayers.INCHES_PER_UNIT["degrees"] = OpenLayers.INCHES_PER_UNIT.dd;
OpenLayers.INCHES_PER_UNIT["nmi"] = 1852 * OpenLayers.INCHES_PER_UNIT.m;//动态的配置
OpenLayers.METERS_PER_INCH = 0.02540005080010160020;
OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT, {
"Meter": 1.0 / OpenLayers.METERS_PER_INCH, //EPSG:9001
"Foot": 0.30480060960121920243 / OpenLayers.METERS_PER_INCH, //EPSG:9003
...
//DPI的默认值
OpenLayers.DOTS_PER_INCH = 72;
//比例尺计算,
//已经是分数形式的( 1.0) ? (1.0 / scale)
: scale;
return normScale;
};
//由Scale计算出Resolution, 默认单位是"degrees"
OpenLayers.Util.getResolutionFromScale = function (scale, units) {
var resolution;
if (scale) {
if (units == null) {
units = "degrees";
}
var normScale = OpenLayers.Util.normalizeScale(scale);
resolution = 1 / (normScale * OpenLayers.INCHES_PER_UNIT[units]
* OpenLayers.DOTS_PER_INCH);
}
return resolution;
};
//由Resolution计算对应的Scale, 默认单位是"degrees"
OpenLayers.Util.getScaleFromResolution = function (resolution, units) {
if (units == null) {
units = "degrees";
}
var scale = resolution * OpenLayers.INCHES_PER_UNIT[units] *
OpenLayers.DOTS_PER_INCH;
return scale;
};

OpenLayers学习4-工具类Util_1

Posted on 2015-01-29   |   In OpenLayers学习   |  

本来想直接看OpenLayers.Map对象(7277行), 然后按着使用api的顺序继续读代码
后来看了下估计直接看看不懂, 先扫一扫零碎和独立的代码吧.

最独立的应该就是Util 先从Util开始, 预计Util写两到三篇(看了三分之一就感觉收获颇丰, 真tmNb)

Read more »

OpenLayers学习3-BaseTypes对基础类型对象的扩展

Posted on 2015-01-27   |   In OpenLayers学习   |  

OpenLayers里从新封装了原生的基本对象, 比如String对象,
设计上, 解决了原生方法不够使的问题, 也没破坏基本对象的prototype, 不会和其他类库冲突

这些类就像Util工具, 没什么上下文的状态,
调用时候就直接调用: OpenLayers.String.startsWith(AAA,BBB) 通过处理拿到结果完事

Read more »

OpenLayers学习-使用geoServer发布的本地WMS服务

Posted on 2015-01-25   |   In OpenLayers学习   |  

公司的API和OpenLayers都用了好长时间了, 从没研究过调用的服务是怎么发出来的.
今天用geoServer学一下. 这博文没什么技术含量, 就是步骤太多 记录下:

Read more »

js继承3:__proto__,prototype和new

Posted on 2015-01-20   |   In js入门   |  

原型链里最重要的属性就是prototype, prototype里存储了从上游拷贝而来的属性
Chrome里用proto表示prototype的指向,
比如说: X = new Y();
X对象的proto指向X对象的原型链上游Y, 再由Y的proto指向Y对象的原型链上游, 从而构成一条原型链条.

Read more »

js继承2:图解原型链中prototype和constructor的关系

Posted on 2015-01-20   |   In js入门   |  

一:问题的起因是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//1 声明对象
function F() {
};
//2 重写原型
F.prototype = {
_name: 'ruantao.duapp.com',
getName: function() {
return this._name;
}
};
//3 出现问题, f.constructor === F为false
var f = new F();
console.log(f.constructor === F); //输出 false
//实际上 f.constructor 指向function Object()

问题在于:
F.prototype被赋值为字面量对象{}, 而{}相当于是new Object().
所以解决问题的方法如下:
所以说, 想要修正F的prototype原型链, 需要在F.prototype的字面量中, 赋值

1
2
F.prototype = {
constructor: F// !!!注意==> 讨论的问题里并未修正F的prototype原型链, 实际上应该修改指向

二: 到这其实目标已经完成了

但是上述代码除了修正了F的原型链, 还意外的说明实例f.constructor指向了Object
那么第一个问题来了:
1.Object的constructor指向哪呢?
Object.constructor//function Function() { [native code] }
//指向”Function”
//其实js内置对象Array, Sting, Number, Function的constructor都指向”Function”

如果说类(function F())中有有prototype, 对象(var f = new F())中有constructor,
那么第二个问题来了:
2.Object有prototype么? Object.prototype里有什么呢?
Object.prototype//Object {}
//空的什么都没有, 这也佐证了F.prototype被赋值为字面量对象{}后, constructor是错误的

第三个问题更有意思:
3.Object.prototype.constructor是什么呢? (也就是说最开始错误的指向哪了呢)
Object.prototype.constructor//function Object() { [native code] }

顺这个思路 第四第五第六第n个问题如下:
Object.prototype.constructor.prototype是什么?
Object.prototype.constructor.prototype.constructor是什么?
… …
Object.constructor.constructor是什么呢?
… …
通过答案其实发现prototype和constructor是循环引用的

三:先来说Object对象的原型链

Object对象的原型链比较特殊:画个草图说明一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 博文作者:ruantao1989{@}gmail.com
* 引自博客:ruantao.duapp.com/blog
*/
//左侧是各个对象的prototype, 中间是对象 , 右侧是constructor的指向
+--------+
| |
v |
+-----------------------+ |
| 1.Function对象 | |
| | |
| Function.constructor|---+
function Empty()<-------| Function.prototype |
+-----------------------+
^
|
+-------------+
|
+-----------------------+ |
| 1.Object对象 | |
| | |
| Object.constructor |---------+
Object{}实例,这就到头了<----| Object.prototype |
+-----------------------+

从上图能看出prototype和constructor是怎么循环引用的, 下面来说最开始碰到的问题

四:prototype和constructor是怎么循环引用的呢

1:先说是不经过修正的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
+--------+
| |
v |
+-----------------------+ |
| 1.Function对象 | |
| | |
| Function.constructor|---+
function Empty()<-------| Function.prototype |
+-----------------------+
^
|
+---------------+
|
+-----------------------+ |
| 2.对象:function F() | |
| | |
| F.constructor |-----------+ //此处如果不经过constructor的修正,则指向Object
Object {} <-------| F.prototype |
+-----------------------+
^
|
+-------------------+
|
+-----------------------+ |
| 3.实例: f = new F() | |
| | |
| f.constructor |---------------+
undefined <---| f.prototype |
+-----------------------+

2:是经过修正的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+----------------+
| |
v |
+-----------------------+ |
| 1.对象:function F() | |
| | |
| F.constructor |-----------+ 修正构造的指针F.prototype={ constructor: F,
F.prototype = { <-------| F.prototype |
constructor: F, +-----------------------+
_name: 'ruantao.duapp.com', ^
getName: function() { |
} +-------------------+
} |
+-----------------------+ |
| 2.实例: f = new F() | |
| | |
| f.constructor |---------------+
undefined <-------| f.prototype |
+-----------------------+

这样画完就清晰多了

1…456…8
ruantao1989

ruantao1989

思行合一

78 posts
10 categories
RSS
Links
  • 旧博客
  • Lofter
© 2016 ruantao1989
Powered by Hexo
Theme - NexT.Pisces