0%

ArcGIS JS API 4.17更改测量控件黄白相间的默认样式

当我们使用ArcGIS JS API开发项目时,经常会用到地图测量控件,用于测量地图上两点之间的距离、一片区域的面积或周长等,但是ArcGIS JS API测量控件自带的默认样式是黄白相间的大粗线,这在用户看来是很不美观的,所以就需要我们对其进行一些样式优化。

问题描述

在使用ArcGIS API for JavaScript 4.17开发项目时,有一个需求是需要在地图上添加距离测量和面积测量的控件,这其实很简单,直接调用ArcGIS JS API自带的测量控件就可以实现,但是客户对控件自带的黄白相间、并且略粗的默认样式不满意,所以需要修改ArcGIS JS API自带的测量控件默认样式。

我们先来看看ArcGIS JS API自带的默认样式:

img

然后再来看看客户想要的样式:

img

img

其实说白了就是要更改默认样式的宽度和颜色。

解决思路

遇到这种需求的话,下意识就去看看ArcGIS JS API的官网有没有提供可以直接使用的API,但是经过一番查找后发现是没有的,那接下来就只能找找其他的地图JS库里面有没有了,如果有的话就试试能不能用于ArcGIS的底图,其实除了这种做法之外还有另一种做法,就是找到ArcGIS JS API的源码文件,直接改里面的css样式代码就可以,最后在”AriaGIS“大佬的帮助下发现确实是行得通的,但是考虑到目前项目中使用的ArcGIS JS API地址是在线的官网地址,所以没法用这种方法,那就只能再想想其他办法了。
最后找了好久没找到最优的方法,就先自己写了一个方法,但是最近在逛ArcGIS知乎的时候发现我当初的帖子有大佬回复了,并且还附加demo,所以我就拿来试试,结果测试发现是可行的。知乎帖子链接如下:

1
http://zhihu.geoscene.cn/question/38481

解决方法

解决方法的话其实很简单,就是监听测量控件的激活事件,然后修改它的绘制句柄里面自带的样式属性即可。但是虽然说简单,自己找了好久也没找到,所以大佬还是牛批啊。下面分别介绍在二维和三维下的修改方法,demo代码就是对大佬的代码做了一下简单修改过后的。

1、二维下的测量控件样式更改(关键代码)

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
const measurement = new Measurement();
// 监听测量控件的激活事件
measurement.watch('activeWidget', function (evt) {
if (evt !== null) {
// 分别修改距离测量和面积测量句柄的默认样式
if (measurement.activeTool === 'distance') {
evt.viewModel.palette.handleColor = [
255,
64,
64,
0.5,
];
evt.viewModel.palette.pathPrimaryColor = [
255,
48,
48,
1,
];
evt.viewModel.palette.pathSecondaryColor = [
255,
48,
48,
1,
];
evt.viewModel.palette.handleWidth = 8;
evt.viewModel.palette.pathWidth = 2;
} else {
evt.viewModel.palette.fillColor = [
255,
48,
48,
0.3,
];
evt.viewModel.palette.handleColor = [
255,
64,
64,
0.5,
];
evt.viewModel.palette.pathColor = [
255,
48,
48,
0.8,
];
}
}
});
measurement.activeTool = 'distance'; // 距离测量
measurement.activeTool = 'area'; // 面积测量

2、三维下的测量控件样式更改(关键代码)

三维下如果按照二维的方式修改的话会报错,具体原因是三维下绘制句柄中并没有palette属性导致的,所以三维下测量控件的样式更改暂未找到方法,最后跟用户沟通,取消了三维中的测量功能,但是回到公司后验证发现,三维下的测量确实比较复杂,而且我感觉ArcGIS JS API三维下的测量已经做的很厉害了,哈哈,没必要修改啊,比如下面的效果图这样:

img

img

1
如果实在想更改的话,就等我后期再找找资源吧,此处代码待更新

完整代码

1、二维下的测量控件样式更改

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>
Measurement widget | Sample | ArcGIS API for JavaScript 4.17
</title>
<style>
html,
body,
#viewDiv {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#toolbarDiv {
position: absolute;
top: 15px;
right: 15px;
cursor: default;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
#infoDiv {
position: absolute;
top: 15px;
left: 60px;
}
#infoDiv input {
border: none;
box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 2px;
}
.esri-widget--button.active,
.esri-widget--button.active:hover,
.esri-widget--button.active:focus {
cursor: default;
background-color: #999696;
}
.esri-widget--button.active path,
.esri-widget--button.active:hover path,
.esri-widget--button.active:focus path {
fill: #e4e4e4;
}
</style>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.17/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.17/"></script>
<script>
require([
'esri/Map',
'esri/views/MapView',
'esri/widgets/Measurement',
], function (Map, MapView, Measurement) {
const map = new Map({
basemap: 'osm',
});
const mapView = new MapView({
container: 'viewDiv',
zoom: 6,
center: [26.1025, 44.4268],
map: map,
});
const measurement = new Measurement();
// 监听测量控件的激活事件
measurement.watch('activeWidget', function (evt) {
if (evt !== null) {
// 分别修改距离测量和面积测量句柄的默认样式
if (measurement.activeTool === 'distance') {
evt.viewModel.palette.handleColor = [
255,
64,
64,
0.5,
];
evt.viewModel.palette.pathPrimaryColor = [
255,
48,
48,
1,
];
evt.viewModel.palette.pathSecondaryColor = [
255,
48,
48,
1,
];
evt.viewModel.palette.handleWidth = 8;
evt.viewModel.palette.pathWidth = 2;
} else {
evt.viewModel.palette.fillColor = [
255,
48,
48,
0.3,
];
evt.viewModel.palette.handleColor = [
255,
64,
64,
0.5,
];
evt.viewModel.palette.pathColor = [
255,
48,
48,
0.8,
];
}
}
});
const distanceButton = document.getElementById('distance');
const areaButton = document.getElementById('area');
const clearButton = document.getElementById('clear');
distanceButton.addEventListener('click', function () {
distanceMeasurement();
});
areaButton.addEventListener('click', function () {
areaMeasurement();
});
clearButton.addEventListener('click', function () {
clearMeasurements();
});
loadView();
function loadView() {
mapView.ui.add(measurement, 'bottom-right');
measurement.view = mapView;
}
// 距离测量
function distanceMeasurement() {
measurement.activeTool = 'distance';
distanceButton.classList.add('active');
areaButton.classList.remove('active');
}
// 面积测量
function areaMeasurement() {
measurement.activeTool = 'area';
distanceButton.classList.remove('active');
areaButton.classList.add('active');
}
// 清屏
function clearMeasurements() {
distanceButton.classList.remove('active');
areaButton.classList.remove('active');
measurement.clear();
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="toolbarDiv" class="esri-component esri-widget">
<button
id="distance"
class="esri-widget--button esri-interactive esri-icon-measure-line"
title="Distance Measurement Tool"
></button>
<button
id="area"
class="esri-widget--button esri-interactive esri-icon-measure-area"
title="Area Measurement Tool"
></button>
<button
id="clear"
class="esri-widget--button esri-interactive esri-icon-trash"
title="Clear Measurements"
></button>
</div>
</body>
</html>

2、三维下的测量控件样式更改

1
代码待更新