MousePosition鼠标位置控件源码分析
# 概述
本文主要介绍 Openlayers 中的MousePosition鼠标位置控件,该控件会创建一个元素在页面的右上方用来实时显示鼠标光标的位置坐标。该控件在实际应用很有效,可以实时获取鼠标位置,但是一般控件元素都会自定义。
# 源码分析
MousePosition类是继承于Control类,关于Control类,可以参考这篇文章Control 基类介绍 (opens new window)。
# MousePosition类实现如下:
class MousePosition extends Control {
constructor(options) {
options = options ? options : {};
const element = document.createElement("div");
element.className =
options.className !== undefined ? options.className : "ol-mouse-position";
super({
element: element,
render: options.render,
target: options.target,
});
this.on;
this.once;
this.un;
this.addChangeListener(PROJECTION, this.handleProjectionChanged_);
if (options.coordinateFormat) {
this.setCoordinateFormat(options.coordinateFormat);
}
if (options.projection) {
this.setProjection(options.projection);
}
this.renderOnMouseOut_ = options.placeholder !== undefined;
this.placeholder_ = this.renderOnMouseOut_ ? options.placeholder : " ";
this.renderedHTML_ = element.innerHTML;
this.mapProjection_ = null;
this.transform_ = null;
this.wrapX_ = options.wrapX === false ? false : true;
}
handleProjectionChanged_() {
this.transform_ = null;
}
getCoordinateFormat() {
return this.get(COORDINATE_FORMAT);
}
handleMouseOut(event) {
this.updateHTML_(null);
}
getProjection() {
return this.get(PROJECTION);
}
handleMouseMove(event) {
const map = this.getMap();
this.updateHTML_(map.getEventPixel(event));
}
setMap(map) {
super.setMap(map);
if (map) {
const viewport = map.getViewport();
this.listenerKeys.push(
listen(viewport, EventType.POINTERMOVE, this.handleMouseMove, this)
);
if (this.renderOnMouseOut_) {
this.listenerKeys.push(
listen(viewport, EventType.POINTEROUT, this.handleMouseOut, this)
);
}
this.updateHTML_(null);
}
}
setCoordinateFormat(format) {
this.set(COORDINATE_FORMAT, format);
}
setProjection(projection) {
this.set(PROJECTION, getProjection(projection));
}
updateHTML_(pixel) {
let html = this.placeholder_;
if (pixel && this.mapProjection_) {
if (!this.transform_) {
const projection = this.getProjection();
if (projection) {
this.transform_ = getTransformFromProjections(
this.mapProjection_,
projection
);
} else {
this.transform_ = identityTransform;
}
}
const map = this.getMap();
const coordinate = map.getCoordinateFromPixelInternal(pixel);
if (coordinate) {
const userProjection = getUserProjection();
if (userProjection) {
this.transform_ = getTransformFromProjections(
this.mapProjection_,
userProjection
);
}
this.transform_(coordinate, coordinate);
if (this.wrapX_) {
const projection =
userProjection || this.getProjection() || this.mapProjection_;
wrapX(coordinate, projection);
}
const coordinateFormat = this.getCoordinateFormat();
if (coordinateFormat) {
html = coordinateFormat(coordinate);
} else {
html = coordinate.toString();
}
}
}
if (!this.renderedHTML_ || html !== this.renderedHTML_) {
this.element.innerHTML = html;
this.renderedHTML_ = html;
}
}
render(mapEvent) {
const frameState = mapEvent.frameState;
if (!frameState) {
this.mapProjection_ = null;
} else {
if (this.mapProjection_ != frameState.viewState.projection) {
this.mapProjection_ = frameState.viewState.projection;
this.transform_ = null;
}
}
}
}
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
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
# MousePosition类构造函数
MousePosition类构造函数接受一个参数对象options,该参数可以包含如下属性:
className:控件类名,默认为ol-mouse-positionrender:自定义render方法,默认undefinedtarget:控件容器,默认undefinedcoordinateFormat:坐标格式化,默认undefinedprojection:分辨率,默认undefinedplaceholder:提示填充字符wrapX:是否水平方向重复延申
构造函数首先会先注册projection的监听事件this.handleProjectionChanged_,若该值发生变化,则将this.transform_置null;然后判断,若options.coordinateFormat存在,则调用this.setCoordinateFormat方法;若options.projection存在,则调用this.setProjection方法;
# MousePosition类中的方法
getCoordinateFormat方法:获取坐标格式化getProjection方法:获取投影handleMouseMove方法:接受一个参数event,该方法是鼠标在地图上移动时调用,会更新控件的内容坐标的值,getEventPixel就是根据参数event获取鼠标的位置以及viewport的某些属性,然后计算屏幕坐标handleMouseOut方法:鼠标移除地图时调用setCoordinateFormat方法:设置坐标格式化setProjection方法:设置投影updateHTML_方法:根据屏幕坐标获取地理坐标render方法:在调用父类的setMap方法时会调用,主要用于设置this.mapProject_setMap方法:sepMap方法会在Map类中调用,内部首先会调用父类的setMap方法,然后判断参数map是否存在,若存在,则注册viewport视口对象pointermove类型的监听,事件为this.handleMouseMove;若构造函数参数options.placeholder设置了,还会注册viewport的pointerout的this.handleMouseOut事件。
# 总结
本文主要介绍了 Openlayers 中MousePosition鼠标位置控件的源码实现,核心就是注册viewport对象上pointermove类型的监听事件获取屏幕坐标,然后调用内部方法map.getCoordinateFromPixelInternal将屏幕坐标转化为实际的地理位置坐标。
编辑 (opens new window)
上次更新: 2024/12/19, 03:07:56