LatLngBounds
# 概述
LatLngBounds
类是 Leaflet 中用于表示地理坐标边界框的类,通常用于定义地图的可视区域或进行空间查询。它包含了两个 LatLng
对象,分别表示边界框的左下角和右上角。
# 源码分析
# 源码实现
LatLngBounds.js
源码实现和介绍如下:
// 构造函数:创建地理边界边框,表示由西南sw和东北ne定义的矩形区域
export function LatLngBounds(corner1, corner2) {
if (!corner1) {
return;
}
var latlngs = corner2 ? [corner1, corner2] : corner1;
for (var i = 0, len = latlngs.length; i < len; i++) {
this.extend(latlngs[i]);
}
}
// LatLngBounds的原型上定义方法
LatLngBounds.prototype = {
// 扩展边界以包含给定对象(点或者另一个矩形区域)
extend: function (obj) {
var sw = this._southWest,
ne = this._northEast,
sw2,
ne2;
if (obj instanceof LatLng) {
sw2 = obj;
ne2 = obj;
} else if (obj instanceof LatLngBounds) {
sw2 = obj._southWest;
ne2 = obj._northEast;
if (!sw2 || !ne2) {
return this;
}
} else {
return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this;
}
if (!sw && !ne) {
this._southWest = new LatLng(sw2.lat, sw2.lng);
this._northEast = new LatLng(ne2.lat, ne2.lng);
} else {
sw.lat = Math.min(sw2.lat, sw.lat);
sw.lng = Math.min(sw2.lng, sw.lng);
ne.lat = Math.max(ne2.lat, ne.lat);
ne.lng = Math.max(ne2.lng, ne.lng);
}
return this;
},
// 缓冲扩展:按比例扩展边界,生成更大的边界
pad: function (bufferRatio) {
var sw = this._southWest,
ne = this._northEast,
heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,
widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;
return new LatLngBounds(
new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer),
new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer)
);
},
// 获取边界框的中心点
getCenter: function () {
return new LatLng(
(this._southWest.lat + this._northEast.lat) / 2,
(this._southWest.lng + this._northEast.lng) / 2
);
},
// 获取边界框的西南角
getSouthWest: function () {
return this._southWest;
},
// 获取边界框的东北角
getNorthEast: function () {
return this._northEast;
},
// 获取边界框的西北角
getNorthWest: function () {
return new LatLng(this.getNorth(), this.getWest());
},
// 获取边界框的东南角
getSouthEast: function () {
return new LatLng(this.getSouth(), this.getEast());
},
// 获取边界框的西边界
getWest: function () {
return this._southWest.lng;
},
// 获取边界框的东边界
getEast: function () {
return this._northEast.lng;
},
// 获取边界框的南边界
getSouth: function () {
return this._southWest.lat;
},
// 获取边界框的北边界
getNorth: function () {
return this._northEast.lat;
},
// 判断点或者边界是否完全在当前边界内
contains: function (obj) {
if (typeof obj[0] === "number" || obj instanceof LatLng || "lat" in obj) {
obj = toLatLng(obj);
} else {
obj = toLatLngBounds(obj);
}
var sw = this._southWest,
ne = this._northEast,
sw2,
ne2;
if (obj instanceof LatLngBounds) {
sw2 = obj.getSouthWest();
ne2 = obj.getNorthEast();
} else {
sw2 = ne2 = obj;
}
return (
sw2.lat >= sw.lat &&
ne2.lat <= ne.lat &&
sw2.lng >= sw.lng &&
ne2.lng <= ne.lng
);
},
// 相交判断,检查两个边界是否有重叠区域(包括边界接触)
intersects: function (bounds) {
bounds = toLatLngBounds(bounds);
var sw = this._southWest,
ne = this._northEast,
sw2 = bounds.getSouthWest(),
ne2 = bounds.getNorthEast(),
latIntersects = ne2.lat >= sw.lat && sw2.lat <= ne.lat,
lngIntersects = ne2.lng >= sw.lng && sw2.lng <= ne.lng;
return latIntersects && lngIntersects;
},
// 重叠判断:检查两个边界是否有严格重叠区域(不包括边界接触)
overlaps: function (bounds) {
bounds = toLatLngBounds(bounds);
var sw = this._southWest,
ne = this._northEast,
sw2 = bounds.getSouthWest(),
ne2 = bounds.getNorthEast(),
latOverlaps = ne2.lat > sw.lat && sw2.lat < ne.lat, // 纬度严格重叠
lngOverlaps = ne2.lng > sw.lng && sw2.lng < ne.lng; // 经度严格重叠
return latOverlaps && lngOverlaps;
},
// 边界字符串:将边界框转换为字符串形式,通常用于URL参数或调试输出
toBBoxString: function () {
return [
this.getWest(),
this.getSouth(),
this.getEast(),
this.getNorth(),
].join(",");
},
// 判断两个边界是否相等,maxMargin 表示容差范围
equals: function (bounds, maxMargin) {
if (!bounds) {
return false;
}
bounds = toLatLngBounds(bounds);
return (
this._southWest.equals(bounds.getSouthWest(), maxMargin) &&
this._northEast.equals(bounds.getNorthEast(), maxMargin)
);
},
// 判断边界是否有效
isValid: function () {
return !!(this._southWest && this._northEast);
},
};
export function toLatLngBounds(a, b) {
if (a instanceof LatLngBounds) {
return a;
}
return new LatLngBounds(a, b);
}
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# 使用场景
- 地图视口计算
- 动态加载数据
- 碰撞检测
# 总结
通过 LatLngBounds
类,Leaflet 提供了高效的地理范围操作工具,支撑了地图的渲染优化、空间查询和交互逻辑。
编辑 (opens new window)
上次更新: 2025/04/18, 09:09:53