ImageBuilder类
# 概述
在 Openlayers 中,CanvasImageBuilder
类会将图片添加到对应坐标上,该类继承于CanvasBuilder
类,关于CanvasBuilder
类,可以参考这篇文章
# 源码分析
# CanvasImageBuilder
类的源码实现
CanvasImageBuilder
类的源码实现如下:
class CanvasImageBuilder extends CanvasBuilder {
constructor(tolerance, maxExtent, resolution, pixelRatio) {
super(tolerance, maxExtent, resolution, pixelRatio);
// 表示碰撞检测图像。碰撞检测用于帮助在地图中检测用户点击的位置是否与图像相关。
this.hitDetectionImage_ = null;
// 表示实际的图像对象。这个属性将存储用于绘制的图像。
this.image_ = null;
// 表示图像的像素比例。可以与 pixelRatio 属性结合使用,影响图像在不同设备上的显示效果
this.imagePixelRatio_ = undefined;
// anchorX_ 和 anchorY_ 分别表示图像的锚点位置。它们决定图像在渲染时的位置对齐方式。
this.anchorX_ = undefined;
this.anchorY_ = undefined;
// 表示图像的高度,可能用于图像的大小调整
this.height_ = undefined;
// 表示图像的透明度,取值通常是从 0 到 1,决定图像的透明程度
this.opacity_ = undefined;
// originX_ 和 originY_ 分别表示图像的原点位置,这通常是图像在坐标系中的起点坐标。
this.originX_ = undefined;
this.originY_ = undefined;
// 用来控制图像是否随地图视图的旋转而旋转。默认为 undefined,可能在后期通过方法来设置
this.rotateWithView_ = undefined;
// 表示图像的旋转角度,用于图像的旋转操作。
this.rotation_ = undefined;
// 表示图像的缩放比例,用于调整图像的大小
this.scale_ = undefined;
// 表示图像的宽度,可能用于图像的大小调整
this.width_ = undefined;
// 表示图像是否启用了“去除杂乱”的模式。当多个图像或标注重叠时,启用该模式可以避免它们互相遮挡
this.declutterMode_ = undefined;
// 用于确定是否将图像与文本一起进行去除杂乱处理。一般情况下,文本与图像一起展示时可能会发生遮挡,启用该属性可以避免这种情况
this.declutterImageWithText_ = undefined;
}
drawPoint(pointGeometry, feature, index) {
if (
!this.image_ ||
(this.maxExtent &&
!containsCoordinate(this.maxExtent, pointGeometry.getFlatCoordinates()))
) {
return;
}
this.beginGeometry(pointGeometry, feature, index);
const flatCoordinates = pointGeometry.getFlatCoordinates();
const stride = pointGeometry.getStride();
const myBegin = this.coordinates.length;
const myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);
this.instructions.push([
CanvasInstruction.DRAW_IMAGE,
myBegin,
myEnd,
this.image_,
this.anchorX_ * this.imagePixelRatio_,
this.anchorY_ * this.imagePixelRatio_,
Math.ceil(this.height_ * this.imagePixelRatio_),
this.opacity_,
this.originX_ * this.imagePixelRatio_,
this.originY_ * this.imagePixelRatio_,
this.rotateWithView_,
this.rotation_,
[
(this.scale_[0] * this.pixelRatio) / this.imagePixelRatio_,
(this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
],
Math.ceil(this.width_ * this.imagePixelRatio_),
this.declutterMode_,
this.declutterImageWithText_,
]);
this.hitDetectionInstructions.push([
CanvasInstruction.DRAW_IMAGE,
myBegin,
myEnd,
this.hitDetectionImage_,
this.anchorX_,
this.anchorY_,
this.height_,
1,
this.originX_,
this.originY_,
this.rotateWithView_,
this.rotation_,
this.scale_,
this.width_,
this.declutterMode_,
this.declutterImageWithText_,
]);
this.endGeometry(feature);
}
drawMultiPoint(multiPointGeometry, feature, index) {
if (!this.image_) {
return;
}
this.beginGeometry(multiPointGeometry, feature, index);
const flatCoordinates = multiPointGeometry.getFlatCoordinates();
const filteredFlatCoordinates = [];
for (
let i = 0, ii = flatCoordinates.length;
i < ii;
i += multiPointGeometry.getStride()
) {
if (
!this.maxExtent ||
containsCoordinate(this.maxExtent, flatCoordinates.slice(i, i + 2))
) {
filteredFlatCoordinates.push(
flatCoordinates[i],
flatCoordinates[i + 1]
);
}
}
const myBegin = this.coordinates.length;
const myEnd = this.appendFlatPointCoordinates(filteredFlatCoordinates, 2);
this.instructions.push([
CanvasInstruction.DRAW_IMAGE,
myBegin,
myEnd,
this.image_,
this.anchorX_ * this.imagePixelRatio_,
this.anchorY_ * this.imagePixelRatio_,
Math.ceil(this.height_ * this.imagePixelRatio_),
this.opacity_,
this.originX_ * this.imagePixelRatio_,
this.originY_ * this.imagePixelRatio_,
this.rotateWithView_,
this.rotation_,
[
(this.scale_[0] * this.pixelRatio) / this.imagePixelRatio_,
(this.scale_[1] * this.pixelRatio) / this.imagePixelRatio_,
],
Math.ceil(this.width_ * this.imagePixelRatio_),
this.declutterMode_,
this.declutterImageWithText_,
]);
this.hitDetectionInstructions.push([
CanvasInstruction.DRAW_IMAGE,
myBegin,
myEnd,
this.hitDetectionImage_,
this.anchorX_,
this.anchorY_,
this.height_,
1,
this.originX_,
this.originY_,
this.rotateWithView_,
this.rotation_,
this.scale_,
this.width_,
this.declutterMode_,
this.declutterImageWithText_,
]);
this.endGeometry(feature);
}
finish() {
this.reverseHitDetectionInstructions();
this.anchorX_ = undefined;
this.anchorY_ = undefined;
this.hitDetectionImage_ = null;
this.image_ = null;
this.imagePixelRatio_ = undefined;
this.height_ = undefined;
this.scale_ = undefined;
this.opacity_ = undefined;
this.originX_ = undefined;
this.originY_ = undefined;
this.rotateWithView_ = undefined;
this.rotation_ = undefined;
this.width_ = undefined;
return super.finish();
}
setImageStyle(imageStyle, sharedData) {
const anchor = imageStyle.getAnchor();
const size = imageStyle.getSize();
const origin = imageStyle.getOrigin();
this.imagePixelRatio_ = imageStyle.getPixelRatio(this.pixelRatio);
this.anchorX_ = anchor[0];
this.anchorY_ = anchor[1];
this.hitDetectionImage_ = imageStyle.getHitDetectionImage();
this.image_ = imageStyle.getImage(this.pixelRatio);
this.height_ = size[1];
this.opacity_ = imageStyle.getOpacity();
this.originX_ = origin[0];
this.originY_ = origin[1];
this.rotateWithView_ = imageStyle.getRotateWithView();
this.rotation_ = imageStyle.getRotation();
this.scale_ = imageStyle.getScaleArray();
this.width_ = size[0];
this.declutterMode_ = imageStyle.getDeclutterMode();
this.declutterImageWithText_ = sharedData;
}
}
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
186
187
188
189
190
191
192
193
# CanvasImageBuilder
类的构造函数
CanvasImageBuilder
类的构造函数接受四个参数,并且也会调用父类 (CanvasBuilder
) 的构造函数,传入以下接受的参数:
tolerance
: 用于决定容差,可能影响图像绘制的精度。maxExtent
: 地图的最大范围或最大显示范围,用于限制图像绘制的位置。resolution
: 图像的分辨率,决定了图像的像素密度。pixelRatio
: 像素比例,通常用于处理高分辨率显示屏上的图像显示。
除此之外CanvasImageBuilder
类的构造函数还初始化了一些与图像绘制和渲染相关的属性。这些属性帮助控制图像的外观和行为,如图像大小、透明度、旋转角度、锚点位置等,如上源码中所示.
# CanvasImageBuilder
类的主要方法
CanvasImageBuilder
类的主要方法如下:
drawPoint(pointGeometry,feature,index)
方法
drawPoint
方法用于将图像渲染在指定几何对象点上,首先会判断,若图像不存在,或者地图范围存在且几何对象的坐标不在范围内,则直接返回;然后调用this.beginGeometry
生成开始绘制几何对象的指令,再获取几何对象的坐标数据,以及绘制的起始和结束点位置,然后构建CanvasInstruction.DRAW_IMAGE
类型的指令,添加到绘制指令集和碰撞检测指令集中,最后调用this.endGeometry
方法添加结束绘制几何对象的指令.
drawMultiPoint(multiPointGeometry,feature,index)
方法
drawMultiPoint
方法和drawPoint
方法类似,会判断多个点是否在地图范围内,然后通过范围内的点调用this.appendFlatPointCoordinates
方法计算出起始和结束点位置,其余步骤与drawPoint
方法一样.
finish()
方法
finish
方法会调用this.reverseHitDetectionInstructions
方法反转碰撞检测指令集,然后重置一些变量,最后调用父类的finish
方法并返回结果.
setImageStyle(imageStyle,shareData)
方法
setImageStyle
方法在实际应用中会在drawPoint
或drawMultiPoint
方法被调用之前调用,接受两个参数imageStyle
图像样式和sharedData
共享数据,参数imageStyle
是一个ImageStyle
类的实例对象,setImageStyle
方法会从imageStyle
参数上调用各种实例的方法获取值,并赋值给相应的变量,然后将参数sharedData
赋值给this.declutterImageWithText_
.
# 总结
本文主要介绍了CanvasImageBuilder
类的核心实现,该类用于构建绘制图片的指令集.