Point
# 概述
Leaflet 中的 Point
类是一个用于表示二维坐标点的核心工具,常见于像素坐标、屏幕偏移等场景(如地图元素的布局、事件位置计算)等,提供了一些方法来操作和转换这些坐标点。
需要注意的是在 Leaflet 中,坐标的表示是[lat,lng]
,而在 Openlayers 或者 Mapbox GL 中,则与之相反,[lng,lat]
表示坐标。
# 源码分析
# 源码实现
Point.js
源码实现和介绍如下:
// 灵活构造Point对象,将多种输入格式统一转换为`Point`实例
export function toPoint(x, y, round) {
// round 可选参数四舍五入
if (x instanceof Point) {
return x; // 如果已经是Point实例,则直接返回
}
if (Array.isArray(x)) {
return new Point(x[0], x[1]); // 如果是数组,则创建新的Point实例
}
if (x === undefined || x === null) {
return x; // 如果是undefined或null,则直接返回
}
if (typeof x === "object" && "x" in x && "y" in x) {
return new Point(x.x, x.y); // 如果是对象且包含x和y属性,则创建新的Point实例
}
return new Point(x, y, round); // 其他情况,创建新的Point实例
}
// `Point`构造函数:坐标存储与舍入
export function Point(x, y, round) {
this.x = round ? Math.round(x) : x;
this.y = round ? Math.round(y) : y;
}
// 兼容性截断处理,兼容不同浏览器的截断操作
// 正数`floor`,负数`ceil`
var trunc =
Math.trunc ||
function (v) {
return v > 0 ? Math.floor(v) : Math.ceil(v);
};
//核心方法:原型上扩展坐标运算与变化
Point.prototype = {
// 克隆方法:返回一个新的`Point`实例,与当前实例相同
clone: function () {
return new Point(this.x, this.y);
},
// 加法:返回一个新的`Point`实例,其坐标为当前实例与参数相加的结果
add: function (point) {
return this.clone()._add(toPoint(point));
},
// 私有方法:执行坐标相加操作,返回当前实例以实现链式调用
_add: function (point) {
this.x += point.x;
this.y += point.y;
return this;
},
// 减法:返回一个新的`Point`实例,其坐标为当前实例减去参数的结果
subtract: function (point) {
return this.clone()._subtract(toPoint(point));
},
// 私有方法:执行坐标相减操作,返回当前实例以实现链式调用
_subtract: function (point) {
this.x -= point.x;
this.y -= point.y;
return this;
},
// 除法:返回一个新的`Point`实例,其坐标为当前实例除以参数的结果
divideBy: function (num) {
return this.clone()._divideBy(num);
},
// 私有方法:执行坐标相除操作,返回当前实例以实现链式调用
_divideBy: function (num) {
this.x /= num;
this.y /= num;
return this;
},
// 乘法:返回一个新的`Point`实例,其坐标为当前实例乘以参数的结果
multiplyBy: function (num) {
return this.clone()._multiplyBy(num);
},
// 私有方法:执行坐标相乘操作,返回当前实例以实现链式调用
_multiplyBy: function (num) {
this.x *= num;
this.y *= num;
return this;
},
//分量乘除
scaleBy: function (point) {
return new Point(this.x * point.x, this.y * point.y);
},
unscaleBy: function (point) {
return new Point(this.x / point.x, this.y / point.y);
},
// 取整
round: function () {
return this.clone()._round();
},
_round: function () {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
return this;
},
floor: function () {
return this.clone()._floor();
},
_floor: function () {
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
return this;
},
ceil: function () {
return this.clone()._ceil();
},
_ceil: function () {
this.x = Math.ceil(this.x);
this.y = Math.ceil(this.y);
return this;
},
trunc: function () {
return this.clone()._trunc();
},
_trunc: function () {
this.x = trunc(this.x);
this.y = trunc(this.y);
return this;
},
// 距离计算:返回当前实例到参数点的欧几里得距离
distanceTo: function (point) {
point = toPoint(point);
var x = point.x - this.x,
y = point.y - this.y;
return Math.sqrt(x * x + y * y);
},
// 判断坐标是否严格相等
equals: function (p) {
return p && this.x === p.x && this.y === p.y;
},
//检查坐标绝对值是否在范围内,可用于边界判断
contains: function (point) {
point = toPoint(point);
return (
Math.abs(point.x) <= Math.abs(this.x) &&
Math.abs(point.y) <= Math.abs(this.y)
);
},
// 坐标格式化转为字符串
toString: function () {
return "Point(" + formatNum(this.x) + ", " + formatNum(this.y) + ")";
},
};
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
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
# 总结
Point
类在 Leaflet 中是一个重要的基础类,用于表示和操作二维坐标点。它提供了一系列方法来处理坐标的加减乘除、取整、距离计算等操作,使得在地图应用中进行坐标计算和布局变得更加方便和高效。
编辑 (opens new window)
上次更新: 2025/04/18, 05:42:33