Jinuss's blog Jinuss's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

前端可视化
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 框架

  • core模块

  • dom模块

  • control

  • geometry

    • Point
    • Bounds
      • 概述
      • 源码分析
        • 源码实现
        • 注意事项
      • 总结
    • Transformation
    • LineUtil
    • PolyUtil
  • geo

  • layer

  • Map

  • 《Leaflet源码》笔记
  • geometry
东流
2025-04-09
目录

Bounds

# 概述

Bounds在 Leaflet 中表示一个矩形边界区域,由两个点组成,分别是左下角min和右上角的点max。实例的形式为:{min:{x:1,y:2},max:{x:3,y:4}}

# 源码分析

# 源码实现

Bounds.js的源码实现如下:

// `Bounds`构造函数,通常用于初始化一个矩形边界,支持多种输入格式,主要是遍历所有点,调用`extend`方法扩展计算边界
export function Bounds(a, b) {
  if (!a) {
    return;
  }

  var points = b ? [a, b] : a;

  for (var i = 0, len = points.length; i < len; i++) {
    this.extend(points[i]);
  }
}

// 构造函数的原型上扩展方法
Bounds.prototype = {
  // 动态扩展边界,比较更新`min`和`max`
  extend: function (obj) {
    var min2, max2;
    if (!obj) {
      return this;
    }

    if (obj instanceof Point || typeof obj[0] === "number" || "x" in obj) {
      min2 = max2 = toPoint(obj);
    } else {
      obj = toBounds(obj);
      min2 = obj.min;
      max2 = obj.max;

      if (!min2 || !max2) {
        return this;
      }
    }

    if (!this.min && !this.max) {
      this.min = min2.clone();
      this.max = max2.clone();
    } else {
      this.min.x = Math.min(min2.x, this.min.x);
      this.max.x = Math.max(max2.x, this.max.x);
      this.min.y = Math.min(min2.y, this.min.y);
      this.max.y = Math.max(max2.y, this.max.y);
    }
    return this;
  },

  // 返回矩形区域中心点
  getCenter: function (round) {
    return toPoint(
      (this.min.x + this.max.x) / 2,
      (this.min.y + this.max.y) / 2,
      round
    );
  },
  // 站在电脑屏幕角度,和用户左右相反
  // 返回左下角点
  getBottomLeft: function () {
    return toPoint(this.min.x, this.max.y);
  },
  // 返回右上角点
  getTopRight: function () {
    return toPoint(this.max.x, this.min.y);
  },

  // 站在电脑屏幕角度,和用户上下相反
  // 返回左上点
  getTopLeft: function () {
    return this.min;
  },
  // 返回右下角点
  getBottomRight: function () {
    return this.max;
  },
  // 返回矩形区域的宽高
  getSize: function () {
    return this.max.subtract(this.min);
  },
  // 检查矩形区域是否完全包含另一个矩形区域或者点
  contains: function (obj) {
    var min, max;

    if (typeof obj[0] === "number" || obj instanceof Point) {
      obj = toPoint(obj);
    } else {
      obj = toBounds(obj);
    }

    if (obj instanceof Bounds) {
      min = obj.min;
      max = obj.max;
    } else {
      min = max = obj;
    }

    return (
      min.x >= this.min.x &&
      max.x <= this.max.x &&
      min.y >= this.min.y &&
      max.y <= this.max.y
    );
  },
  // 检查两个矩形区域是否相交,包含边界接触
  intersects: function (bounds) {
    bounds = toBounds(bounds);

    var min = this.min,
      max = this.max,
      min2 = bounds.min,
      max2 = bounds.max,
      xIntersects = max2.x >= min.x && min2.x <= max.x,
      yIntersects = max2.y >= min.y && min2.y <= max.y;

    return xIntersects && yIntersects;
  },
  // 检查两个边界是否重叠,严格相交,不包含边界接触
  overlaps: function (bounds) {
    bounds = toBounds(bounds);

    var min = this.min,
      max = this.max,
      min2 = bounds.min,
      max2 = bounds.max,
      xOverlaps = max2.x > min.x && min2.x < max.x,
      yOverlaps = max2.y > min.y && min2.y < max.y;

    return xOverlaps && yOverlaps;
  },
  // 检查矩形区域是否有效,即是否包含`min`和`max`两个点
  isValid: function () {
    return !!(this.min && this.max);
  },
  // 按比例扩大边界用于缓冲区域
  pad: function (bufferRatio) {
    var min = this.min,
      max = this.max,
      heightBuffer = Math.abs(min.x - max.x) * bufferRatio,
      widthBuffer = Math.abs(min.y - max.y) * bufferRatio;

    return toBounds(
      toPoint(min.x - heightBuffer, min.y - widthBuffer),
      toPoint(max.x + heightBuffer, max.y + widthBuffer)
    );
  },
  // 判断两个边界是否颜色相等
  equals: function (bounds) {
    if (!bounds) {
      return false;
    }

    bounds = toBounds(bounds);

    return (
      this.min.equals(bounds.getTopLeft()) &&
      this.max.equals(bounds.getBottomRight())
    );
  },
};

// 工厂方法,用于创建`Bounds`实例,支持多种输入格式
export function toBounds(a, b) {
  if (!a || a instanceof Bounds) {
    return a;
  }
  return new Bounds(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

# 注意事项

  1. ​​ 坐标顺序 ​​:Bounds 的 min 和 max 是 Point 对象,遵循 [x, y](经度在前,纬度在后)。
  2. ​ 空边界处理 ​​:未初始化的 Bounds(min 或 max 为 null)调用方法可能出错。
  3. 性能优化 ​​:频繁调用 extend 时,建议批量传入点数组而非逐个扩展。

# 总结

Bounds是 Leaflet 中用于表示矩形边界区域的类,它由两个点组成,分别是左下角min和右上角的点max。Bounds类提供了一系列方法用于操作和处理矩形边界,例如扩展边界、获取中心点、检查包含关系等。

编辑 (opens new window)
上次更新: 2025/04/18, 05:42:33
Point
Transformation

← Point Transformation→

最近更新
01
GeoJSON
05-08
02
Circle
04-15
03
CircleMarker
04-15
更多文章>
Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式