SimpleGeometry类
# 概述
本文主要介绍 Openlayers 中的SimplyGeometry类,该类继承于Geometry类,也是普通几何对象如点线面的基类或父类。SimplyGeometry类一般地也不会被实例化,只会被继承,因为它不会被渲染。
# 源码分析
# SimplyGeometry类源码
SimplyGeometry类源码实现如下:
class SimplyGeometry extends Geometry {
constructor() {}
computedExtent(extent) {
return createOrUpdateFromFlatCoordinates(
this.flatCoordinates,
0,
this.flatCoordinates.length,
this.stride,
extent
);
}
getCoordinates() {
return abstract();
}
getFirstCoordinate() {
return this.flatCoordinates.slice(0, this.stride);
}
getFlatCoordinates() {
return this.flatCoordinates;
}
getLastCoordinate() {
return this.flatCoordinates.slice(
this.flatCoordinates.length - this.stride
);
}
getLayout() {
return this.layout;
}
getSimplifiedGeometry(squaredTolerance) {
if (this.simplifiedGeometryRevision !== this.getRevision()) {
this.simplifiedGeometryMaxMinSquaredTolerance = 0;
this.simplifiedGeometryRevision = this.getRevision();
}
if (
squaredTolerance < 0 ||
(this.simplifiedGeometryMaxMinSquaredTolerance !== 0 &&
squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance)
) {
return this;
}
const simplifiedGeometry =
this.getSimplifiedGeometryInternal(squaredTolerance);
const simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();
if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {
return simplifiedGeometry;
}
this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
return this;
}
getSimplifiedGeometryInternal(squaredTolerance) {
return this;
}
getStride() {
return this.stride;
}
setFlatCoordinates(layout, flatCoordinates) {
this.stride = getStrideForLayout(layout);
this.layout = layout;
this.flatCoordinates = flatCoordinates;
}
setCoordinates(coordinates, layout) {
abstract();
}
setLayout(layout, coordinates, nesting) {
let stride;
if (layout) {
stride = getStrideForLayout(layout);
} else {
for (let i = 0; i < nesting; ++i) {
if (coordinates.length === 0) {
this.layout = "XY";
this.stride = 2;
return;
}
coordinates = /** @type {Array<unknown>} */ (coordinates[0]);
}
stride = coordinates.length;
layout = getLayoutForStride(stride);
}
this.layout = layout;
this.stride = stride;
}
applyTransform(transformFn) {
if (this.flatCoordinates) {
transformFn(
this.flatCoordinates,
this.flatCoordinates,
this.layout.startsWith("XYZ") ? 3 : 2,
this.stride
);
this.changed();
}
}
rotate(angle, anchor) {
const flatCoordinates = this.getFlatCoordinates();
if (flatCoordinates) {
const stride = this.getStride();
rotate(
flatCoordinates,
0,
flatCoordinates.length,
stride,
angle,
anchor,
flatCoordinates
);
this.changed();
}
}
scale(sx, sy, anchor) {
if (sy === undefined) {
sy = sx;
}
if (!anchor) {
anchor = getCenter(this.getExtent());
}
const flatCoordinates = this.getFlatCoordinates();
if (flatCoordinates) {
const stride = this.getStride();
scale(
flatCoordinates,
0,
flatCoordinates.length,
stride,
sx,
sy,
anchor,
flatCoordinates
);
this.changed();
}
}
translate(deltaX, deltaY) {
const flatCoordinates = this.getFlatCoordinates();
if (flatCoordinates) {
const stride = this.getStride();
translate(
flatCoordinates,
0,
flatCoordinates.length,
stride,
deltaX,
deltaY,
flatCoordinates
);
this.changed();
}
}
}
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
# SimplyGeometry类的构造函数
SimplyGeometry类的构造函数就是定义了如下变量:
this.layout:默认值为XY,表示二维坐标,可选值还有XYZ(表示三维坐标)、XYM(表示二维坐标,M为附加属性)和XYZM(表示三维坐标,M为附加属性)。this.stride:默认值为 2,步幅,可以理解为this.layout的长度。this.flatCoordinates:是一个一维数组,用来存储几何图形的坐标数据。
# SimplyGeometry类主要方法
SimplyGeometry类的主要方法如下:
computeExtent方法:内部就是调用createOrUpdateFromFlatCoordinate方法去计算几何对象的包围盒extentgetCoordinates方法:未实现,实际上就是获取几何对象的坐标getFirstCoordinate方法:获取几何对象的第一个坐标getFlatCoordinates方法:获取几何对象的一维数组,即this.flatCoordinatesgetLastCoordinate方法:获取几何对象的最后一个坐标getLayout方法:获取变量this.layout的值getSimplifiedGeometry方法:创建一个简化的几何对象,运用Douglas Peucker算法getSimplifiedGeometryInternal方法:获取简化几何对象getStride方法:获取步幅,即this.stride的值setFlatCoordinates方法:接受两个参数layout和flatCoordinates,调用getStrideForLayout通过参数layout计算stride,赋值this.layout和this.flatCoordinatessetCoordinates方法:未实现setLayout方法:设置this.layout和this.strideapplyTransform方法:应用转换函数,参数是一个函数;判断若this.flatCoordinates存在,则调用转换函数,最后调用this.changed方法rotate方法:给定一个坐标,使几何对象绕着该坐标旋转一定角度;接受两个参数angle旋转角度和anchor锚点;调用this.getFlatCoordinates获取几何对象的一维坐标,若它存在,则调用this.getStride获取步幅,然后调用rotate方法进行旋转,这操作会修改flatCoordinates;最后调用this.changed方法scale方法:接受三个参数,水平方向缩放因子sx、垂直方向缩放因子sy和锚点anchor;判断,sy不存在时,则sy=sx;判断,若锚点anchor不存在,则以几何对象的包围盒的中心点为锚点;调用this.getFlatCoordinates获取this.flatCoordinates,判断,若它存在,则调用scale方法对几何对象进行缩放,最后调用this.changed方法translate方法:接受两个参数deltaX和deltaY,分别表示在水平方向和垂直方向的偏移量,实际上是调用translate方法对几何对象在水平垂直两个方向上进行平移变化,最后调用this.changed方法
# 总结
本文介绍了SimpleGeometry类的源码实现和主要方法介绍,SimpleGeometry类的几何变换,包括旋转、缩放和平移都是对flatCoordinates进行操作,对于点线面都是如此,这在一定程度上降低了几何变换的复杂度。