@supermapgis/iclient-ol 11.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +56 -0
  2. package/control/ChangeTileVersion.js +438 -0
  3. package/control/Logo.js +99 -0
  4. package/control/ScaleLine.js +164 -0
  5. package/control/index.js +6 -0
  6. package/core/MapExtend.js +49 -0
  7. package/core/StyleUtils.js +1253 -0
  8. package/core/Util.js +478 -0
  9. package/core/index.js +6 -0
  10. package/css/ChangeTileVersion.css +347 -0
  11. package/css/index.js +5 -0
  12. package/dist/iclient-openlayers-es6.js +121806 -0
  13. package/dist/iclient-openlayers-es6.min.js +8 -0
  14. package/dist/iclient-openlayers.css +668 -0
  15. package/dist/iclient-openlayers.js +132335 -0
  16. package/dist/iclient-openlayers.min.css +8 -0
  17. package/dist/iclient-openlayers.min.js +8 -0
  18. package/index.js +9 -0
  19. package/mapping/BaiduMap.js +121 -0
  20. package/mapping/ImageSuperMapRest.js +252 -0
  21. package/mapping/ImageTileSuperMapRest.js +99 -0
  22. package/mapping/InitMap.js +125 -0
  23. package/mapping/SuperMapCloud.js +56 -0
  24. package/mapping/Tianditu.js +152 -0
  25. package/mapping/TileSuperMapRest.js +358 -0
  26. package/mapping/WebMap.js +5185 -0
  27. package/mapping/index.js +11 -0
  28. package/mapping/webmap/Util.js +176 -0
  29. package/mapping/webmap/config/MunicipalCenter.json +1 -0
  30. package/mapping/webmap/config/ProvinceCenter.json +1 -0
  31. package/mapping/webmap/config/SampleDataInfo.json +55 -0
  32. package/namespace.js +150 -0
  33. package/overlay/DataFlow.js +114 -0
  34. package/overlay/FGB.js +97 -0
  35. package/overlay/Graph.js +436 -0
  36. package/overlay/GraphMap.js +91 -0
  37. package/overlay/Graphic.js +587 -0
  38. package/overlay/HeatMap.js +444 -0
  39. package/overlay/Label.js +964 -0
  40. package/overlay/Mapv.js +146 -0
  41. package/overlay/Range.js +127 -0
  42. package/overlay/RankSymbol.js +94 -0
  43. package/overlay/Turf.js +298 -0
  44. package/overlay/Unique.js +123 -0
  45. package/overlay/VectorTileSuperMapRest.js +466 -0
  46. package/overlay/graphic/CanvasRenderer.js +177 -0
  47. package/overlay/graphic/CloverShape.js +133 -0
  48. package/overlay/graphic/Graphic.js +174 -0
  49. package/overlay/graphic/HitCloverShape.js +63 -0
  50. package/overlay/graphic/WebGLRenderer.js +356 -0
  51. package/overlay/graphic/index.js +9 -0
  52. package/overlay/index.js +21 -0
  53. package/overlay/mapv/MapvCanvasLayer.js +104 -0
  54. package/overlay/mapv/MapvLayer.js +410 -0
  55. package/overlay/mapv/index.js +5 -0
  56. package/overlay/theme/GeoFeature.js +275 -0
  57. package/overlay/theme/Theme.js +585 -0
  58. package/overlay/theme/ThemeFeature.js +46 -0
  59. package/overlay/theme/index.js +6 -0
  60. package/overlay/vectortile/DeafultCanvasStyle.js +125 -0
  61. package/overlay/vectortile/MapboxStyles.js +375 -0
  62. package/overlay/vectortile/StyleMap.js +252 -0
  63. package/overlay/vectortile/VectorTileStyles.js +554 -0
  64. package/overlay/vectortile/index.js +7 -0
  65. package/overlay/vectortile/olExtends.js +382 -0
  66. package/package.json +29 -0
  67. package/services/AddressMatchService.js +60 -0
  68. package/services/ChartService.js +74 -0
  69. package/services/DataFlowService.js +118 -0
  70. package/services/DatasetService.js +104 -0
  71. package/services/DatasourceService.js +76 -0
  72. package/services/FeatureService.js +196 -0
  73. package/services/FieldService.js +53 -0
  74. package/services/GeoprocessingService.js +156 -0
  75. package/services/GridCellInfosService.js +53 -0
  76. package/services/ImageCollectionService.js +92 -0
  77. package/services/ImageService.js +69 -0
  78. package/services/KnowledgeGraphService.js +82 -0
  79. package/services/LayerInfoService.js +85 -0
  80. package/services/MapService.js +85 -0
  81. package/services/MeasureService.js +77 -0
  82. package/services/NetworkAnalyst3DService.js +88 -0
  83. package/services/NetworkAnalystService.js +252 -0
  84. package/services/ProcessingService.js +478 -0
  85. package/services/QueryService.js +116 -0
  86. package/services/ServiceBase.js +26 -0
  87. package/services/SpatialAnalystService.js +432 -0
  88. package/services/ThemeService.js +50 -0
  89. package/services/TrafficTransferAnalystService.js +88 -0
  90. package/services/WebPrintingJobService.js +112 -0
  91. package/services/index.js +27 -0
@@ -0,0 +1,1253 @@
1
+ /* Copyright© 2000 - 2024 SuperMap Software Co.Ltd. All rights reserved.
2
+ * This program are made available under the terms of the Apache License, Version 2.0
3
+ * which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
4
+ import { Util as CommonUtil, DOTS_PER_INCH, INCHES_PER_UNIT } from '@supermapgis/iclient-common/commontypes/Util';
5
+ import { StringExt } from '@supermapgis/iclient-common/commontypes/BaseTypes';
6
+ import { StyleMap } from '../overlay/vectortile/StyleMap';
7
+ import { DeafultCanvasStyle } from '../overlay/vectortile/DeafultCanvasStyle';
8
+ import { Util } from '../core/Util';
9
+ import Canvg from 'canvg';
10
+ import Style from 'ol/style/Style';
11
+ import Icon from 'ol/style/Icon';
12
+ import CircleStyle from 'ol/style/Circle';
13
+ import FillStyle from 'ol/style/Fill';
14
+ import StrokeStyle from 'ol/style/Stroke';
15
+ import Text from 'ol/style/Text';
16
+
17
+ var padding = 8, doublePadding = padding * 2;
18
+ const ZERO = 0.0000001;
19
+
20
+ /**
21
+ * @class StyleUtils
22
+ * @classdesc 样式工具类。
23
+ * @private
24
+ */
25
+ export class StyleUtils {
26
+ /**
27
+ * @function StyleUtils.getValidStyleFromLayerInfo
28
+ * @description 通过图层信息获取有效的样式。
29
+ * @param {Object} layerInfo - 图层信息。
30
+ * @param {ol.Feature} feature - 要素。
31
+ * @param {string} url - 图层数据地址。
32
+ * @returns {ol.style.Style} 返回图层样式。
33
+ */
34
+ static getValidStyleFromLayerInfo(layerInfo, feature, url) {
35
+ var type = feature.getGeometry().getType().toUpperCase(),
36
+ shader = layerInfo.layerStyle,
37
+ style = this.getDefaultStyle(type);
38
+ if ((type === "POINT" || type === 'MULTIPOINT') && !feature.getProperties().textStyle && layerInfo.type !== 'LABEL' && !feature.getProperties().TEXT_FEATURE_CONTENT) {
39
+ if (shader) {
40
+ var symbolParameters = {
41
+ "transparent": true,
42
+ "resourceType": "SYMBOLMARKER",
43
+ "picWidth": Math.ceil(shader.markerSize * DOTS_PER_INCH * INCHES_PER_UNIT["mm"]) || 13,
44
+ "picHeight": Math.ceil(shader.markerSize * DOTS_PER_INCH * INCHES_PER_UNIT["mm"]) || 13,
45
+ "style": JSON.stringify(shader)
46
+ };
47
+ var imageUrl = CommonUtil.urlAppend(url + "/symbol.png", CommonUtil.getParameterString(symbolParameters));
48
+ style.pointFile = imageUrl;
49
+ return new Style({
50
+ image: new Icon({
51
+ src: style.pointFile
52
+ })
53
+ });
54
+ }
55
+ return this.toOLPointStyle(style);
56
+ } else if ((type === "POINT" || type === 'MULTIPOINT') && (feature.getProperties().textStyle || layerInfo.type === 'LABEL' || feature.getProperties().TEXT_STYLE_INFO)) {
57
+ style = this.getDefaultStyle('TEXT');
58
+ if (feature.getProperties().textStyle) {
59
+ shader = feature.getProperties().textStyle;
60
+ }
61
+ if (feature.getProperties().TEXT_STYLE_INFO) {
62
+ shader = JSON.parse(feature.getProperties().TEXT_STYLE_INFO).textStyle;
63
+ }
64
+ if (shader && shader !== "{}") {
65
+ var fontStr = "";
66
+ //设置文本是否倾斜
67
+ style.fontStyle = shader.italic ? "italic" : "normal";
68
+ //设置文本是否使用粗体
69
+ style.fontWeight = shader.bold ? shader.fontWeight : "normal";
70
+ //设置文本的尺寸(对应fontHeight属性)和行高,行高iserver不支持,默认5像素
71
+ //固定大小的时候单位是毫米
72
+ var text_h = shader.fontHeight * DOTS_PER_INCH * INCHES_PER_UNIT["mm"] * 0.85; //毫米转像素,服务端的字体貌似要稍微小一点
73
+ style.fontSize = text_h + "px";
74
+
75
+ //设置文本字体类型
76
+ //在桌面字体钱加@时为了解决对联那种形式,但是在canvas不支持,并且添加了@会导致
77
+ //字体大小被固定,这里需要去掉
78
+ if (shader.fontName.indexOf("@")) {
79
+ fontStr = shader.fontName.replace(/@/g, "");
80
+ } else {
81
+ fontStr = shader.fontName
82
+ }
83
+ style.fontFamily = fontStr;
84
+ style.textHeight = text_h;
85
+
86
+ //设置对齐方式
87
+ var alignStr = shader.align.replace(/TOP|MIDDLE|BASELINE|BOTTOM/, "");
88
+ style.textAlign = alignStr.toLowerCase();
89
+ var baselineStr = shader.align.replace(/LEFT|RIGHT|CENTER/, "");
90
+ if (baselineStr === "BASELINE") {
91
+ baselineStr = "alphabetic";
92
+ }
93
+ style.textBaseline = baselineStr.toLowerCase();
94
+
95
+ /*//首先判定是否需要绘制阴影,如果需要绘制,阴影应该在最下面
96
+ if(shader.shadow)
97
+ {
98
+
99
+ //桌面里面的阴影没有做模糊处理,这里统一设置为0,
100
+ style.shadowBlur=0;
101
+ //和桌面统一,往右下角偏移阴影,默认3像素
102
+ style.shadowOffsetX=3;
103
+ style.shadowOffsetY=3;
104
+ //颜色取一个灰色,调成半透明
105
+ style.shadowColor="rgba(50,50,50,0.5)";
106
+ }else{
107
+ style.shadowOffsetX=0;
108
+ style.shadowOffsetY=0;
109
+ }*/
110
+ style.haloRadius = shader.outline ? shader.outlineWidth : 0;
111
+ style.backColor = "rgba(" + shader.backColor.red + "," + shader.backColor.green + "," + shader.backColor.blue + ",1)";
112
+ style.foreColor = "rgba(" + shader.foreColor.red + "," + shader.foreColor.green + "," + shader.foreColor.blue + ",1)";
113
+ style.rotation = shader.rotation;
114
+ }
115
+ var text;
116
+ if (feature.getProperties().textStyle && feature.getProperties().texts) {
117
+ text = feature.getProperties().texts[0];
118
+ }
119
+ if (layerInfo.type === 'LABEL') {
120
+ var textField = layerInfo.textField;
121
+ if (textField && textField.indexOf('.')) {
122
+ var arr = textField.split('.');
123
+ textField = arr && arr.length > 0 && arr[arr.length - 1];
124
+ }
125
+ text = feature.getProperties().attributes ? feature.getProperties().attributes[textField] : feature.getProperties()[textField];
126
+ }
127
+ if (feature.getProperties().TEXT_FEATURE_CONTENT) {
128
+ text = feature.getProperties().TEXT_FEATURE_CONTENT;
129
+ }
130
+ if (!text) {
131
+ return this.toOLPointStyle(this.getDefaultStyle('POINT'));
132
+ }
133
+ return this.toOLTextStyle(style, text);
134
+ } else if (shader) {
135
+ //目前只实现桌面系统默认的几种symbolID,非系统默认的面用颜色填充替代,线则用实线来替代
136
+ var fillSymbolID = shader["fillSymbolID"] > 7 ? 0 : shader["fillSymbolID"];
137
+ var lineSymbolID = shader["lineSymbolID"] > 5 ? 0 : shader["lineSymbolID"];
138
+ for (var attr in shader) {
139
+ var obj = StyleMap.ServerStyleMap[attr];
140
+ var canvasStyle = obj.canvasStyle;
141
+ if (canvasStyle && canvasStyle != "") {
142
+ var value;
143
+ switch (obj.type) {
144
+ case "number":
145
+ value = shader[attr];
146
+ if (obj.unit) {
147
+ //将单位转换为像素单位
148
+ value = value * DOTS_PER_INCH * INCHES_PER_UNIT[obj.unit] * 2.5;
149
+ }
150
+ style[canvasStyle] = value;
151
+ break;
152
+ case "color":
153
+ var color = shader[attr];
154
+ var backColor = shader["fillBackColor"];
155
+ var alpha = 1;
156
+ if (canvasStyle === "fillStyle") {
157
+ if (fillSymbolID === 0 || fillSymbolID === 1) {
158
+ //当fillSymbolID为0时,用颜色填充,为1是无填充,即为透明填充,alpha通道为0
159
+ alpha = 1 - fillSymbolID;
160
+ value = "rgba(" + color.red + "," + color.green + "," + color.blue + "," + alpha + ")";
161
+ } else {
162
+ //当fillSymbolID为2~7时,用的纹理填充,但要按照前景色修改其颜色
163
+ try {
164
+ var tempCvs = document.createElement("canvas");
165
+ tempCvs.height = 8;
166
+ tempCvs.width = 8;
167
+ var tempCtx = tempCvs.getContext("2d");
168
+ var image = new Image();
169
+ if (this.layer && this.layer.fillImages) {
170
+ tempCtx.drawImage(this.layer.fillImages["System " + fillSymbolID], 0, 0);
171
+ }
172
+ var imageData = tempCtx.getImageData(0, 0, tempCvs.width, tempCvs.height);
173
+ var pix = imageData.data;
174
+ for (var i = 0, len = pix.length; i < len; i += 4) {
175
+ var r = pix[i], g = pix[i + 1], b = pix[i + 2];
176
+ //将符号图片中的灰色或者黑色的部分替换为前景色,其余为后景色
177
+ if (r < 225 && g < 225 && b < 225) {
178
+ pix[i] = color.red;
179
+ pix[i + 1] = color.green;
180
+ pix[i + 2] = color.blue;
181
+ } else if (backColor) {
182
+ pix[i] = backColor.red;
183
+ pix[i + 1] = backColor.green;
184
+ pix[i + 2] = backColor.blue;
185
+ }
186
+ }
187
+ tempCtx.putImageData(imageData, 0, 0);
188
+ image.src = tempCvs.toDataURL();
189
+
190
+ if (this.context) {
191
+ value = this.context.createPattern(image, "repeat");
192
+ }
193
+ } catch (e) {
194
+ throw Error(e.message);
195
+ }
196
+ }
197
+ } else if (canvasStyle === "strokeStyle") {
198
+ if (lineSymbolID === 0 || lineSymbolID === 5) {
199
+ //对于lineSymbolID为0时,线为实线,为lineSymbolID为5时,为无线模式,即线为透明,即alpha通道为0
200
+ alpha = lineSymbolID === 0 ? 1 : 0;
201
+ } else {
202
+ //以下几种linePattern分别模拟了桌面的SymbolID为1~4几种符号的linePattern
203
+ var linePattern = [1, 0];
204
+ switch (lineSymbolID) {
205
+ case 1:
206
+ linePattern = [9.7, 3.7];
207
+ break;
208
+ case 2:
209
+ linePattern = [3.7, 3.7];
210
+ break;
211
+ case 3:
212
+ linePattern = [9.7, 3.7, 2.3, 3.7];
213
+ break;
214
+ case 4:
215
+ linePattern = [9.7, 3.7, 2.3, 3.7, 2.3, 3.7];
216
+ break;
217
+ default:
218
+ break
219
+ }
220
+ style.lineDasharray = linePattern;
221
+ }
222
+ value = "rgba(" + color.red + "," + color.green + "," + color.blue + "," + alpha + ")";
223
+ }
224
+ style[canvasStyle] = value;
225
+ break;
226
+ default:
227
+ break;
228
+
229
+ }
230
+ }
231
+ }
232
+ }
233
+ if (type === 'LINESTRING' || type === 'MULTILINESTRING') {
234
+ return this.toOLLineStyle(style);
235
+ }
236
+ if (type === 'POLYGON' || type === 'MULTIPOLYGON') {
237
+ return this.toOLPolygonStyle(style);
238
+ }
239
+ }
240
+
241
+ /**
242
+ * @function StyleUtils.getStyleFromCarto
243
+ * @description 从 Carto 中获取有效的样式。
244
+ * @param {number} zoom -缩放级别。
245
+ * @param {number} scale - 比例尺。
246
+ * @param {Array.<Object>} shader - 渲染器对象数组。
247
+ * @param {Object} feature - 要素。
248
+ * @param {string} fromServer - 服务源。
249
+ * @param {string} url - 地址。
250
+ */
251
+ static getStyleFromCarto(zoom, scale, shader, feature, fromServer, url) {
252
+ var type = feature.getGeometry().getType().toUpperCase(),
253
+ attributes = {},
254
+ style = this.getDefaultStyle(type);
255
+ attributes.FEATUREID = feature.getProperties().id;
256
+ attributes.SCALE = scale;
257
+ var cartoStyleType = feature.getProperties().type === "TEXT" ? "TEXT" : type;
258
+ var cartoStyleMap = StyleMap.CartoStyleMap[cartoStyleType];
259
+ var fontSize, fontName;
260
+ if (shader) {
261
+ for (var i = 0, len = shader.length; i < len; i++) {
262
+ var _shader = shader[i];
263
+ var prop = cartoStyleMap[_shader.property];
264
+ var value = _shader.getValue(attributes, zoom, true);
265
+ if ((value !== null) && prop) {
266
+ if (prop === "fontSize") {
267
+ if (fromServer) {
268
+ value *= 0.8;
269
+ }
270
+ //斜杠后面为行间距,默认为0.5倍行间距
271
+ fontSize = value + "px";
272
+ style.fontSize = fontSize;
273
+ } else if (prop === "fontName") {
274
+ fontName = value;
275
+ style.fontName = fontName;
276
+ } else {
277
+ if (prop === "globalCompositeOperation") {
278
+ value = StyleMap.CartoCompOpMap[value];
279
+ if (!value) {
280
+ continue;
281
+ }
282
+ } else if (fromServer && prop === 'pointFile') {
283
+ value = url + '/tileFeature/symbols/' + value.replace(/(___)/gi, '@');
284
+ value = value.replace(/(__0__0__)/gi, '__8__8__');
285
+ }
286
+ if (prop === 'lineWidth' && value < 1) {
287
+ value = Math.ceil(value);
288
+ }
289
+ style[prop] = value;
290
+ }
291
+ }
292
+ }
293
+ }
294
+ if (feature.getProperties().type === 'TEXT') {
295
+ var text;
296
+ if (feature.getProperties().texts) {
297
+ text = feature.getProperties().texts[0];
298
+ }
299
+ if (text == null && style.textName) {
300
+ var textName = style.textName.substring(1, style.textName.length - 1);
301
+ text = feature.getProperties().attributes ? feature.getProperties().attributes[textName] : feature.getProperties()[textName];
302
+ if (text != null) {
303
+ var texts = feature.getProperties().texts || [];
304
+ texts.push(text);
305
+ feature.setProperties({ texts: texts });
306
+ }
307
+ }
308
+ return this.toOLTextStyle(style, text)
309
+ }
310
+ if (type === 'POINT' || type === 'MULTIPOINT') {
311
+ return this.toOLPointStyle(style);
312
+ }
313
+ if (type === 'LINESTRING' || type === 'MULTILINESTRING') {
314
+ return this.toOLLineStyle(style);
315
+ }
316
+ if (type === 'POLYGON' || type === 'MULTIPOLYGON') {
317
+ return this.toOLPolygonStyle(style);
318
+ }
319
+ }
320
+
321
+ /**
322
+ * @function StyleUtils.toOLPointStyle
323
+ * @description 点样式。
324
+ * @param {Object} style - 样式参数。
325
+ * @returns {ol.style.Style} 获取点样式。
326
+ */
327
+ static toOLPointStyle(style) {
328
+ if (style.pointFile !== '') {
329
+ return new Style({
330
+ image: new Icon({
331
+ src: style.pointFile
332
+ })
333
+ });
334
+ }
335
+ return new Style({
336
+ image: new CircleStyle({
337
+ radius: style.pointRadius,
338
+ fill: new FillStyle({
339
+ color: style.fillStyle
340
+ }),
341
+ stroke: new StrokeStyle({
342
+ color: style.pointHaloColor,
343
+ width: style.pointHaloRadius
344
+ })
345
+ })
346
+ });
347
+ }
348
+
349
+ /**
350
+ * @function StyleUtils.toOLLineStyle
351
+ * @description 线样式。
352
+ * @param {Object} style - 样式参数。
353
+ * @returns {ol.style.Style} 获取线的样式。
354
+ */
355
+ static toOLLineStyle(style) {
356
+ return new Style({
357
+ stroke: new StrokeStyle({
358
+ color: style.strokeStyle,
359
+ width: style.lineWidth,
360
+ lineCap: style.lineCap,
361
+ lineDash: style.lineDasharray,
362
+ lineDashOffset: style.lineDashOffset,
363
+ lineJoin: style.lineJoin,
364
+ miterLimit: style.miterLimit
365
+ })
366
+ });
367
+ }
368
+
369
+ /**
370
+ * @function StyleUtils.toOLPolygonStyle
371
+ * @description 面样式。
372
+ * @param {Object} style - 样式参数。
373
+ * @returns {ol.style.Style} 获取面的样式。
374
+ */
375
+ static toOLPolygonStyle(style) {
376
+ var fill = new FillStyle({
377
+ color: style.fillStyle
378
+ });
379
+ var stroke = new StrokeStyle({
380
+ color: style.strokeStyle,
381
+ width: style.lineWidth,
382
+ lineCap: style.lineCap,
383
+ lineDash: style.lineDasharray,
384
+ lineDashOffset: style.lineDashOffset,
385
+ lineJoin: style.lineJoin,
386
+ miterLimit: style.miterLimit
387
+ });
388
+ return new Style({
389
+ fill: fill,
390
+ stroke: stroke
391
+ });
392
+ }
393
+
394
+ /**
395
+ * @function StyleUtils.toOLTextStyle
396
+ * @description 文本样式。
397
+ * @param {Object} style - 样式对象。
398
+ * @param {string} text - 文本参数。
399
+ * @returns {ol.style.Style} 获取的文本样式。
400
+ */
401
+ static toOLTextStyle(style, text) {
402
+ return new Style({
403
+ text: new Text({
404
+ font: (style.fontStyle || '') + ' ' + (style.fontWeight || '') + ' ' + (style.fontSize || '') + ' ' + style.fontFamily,
405
+ text: text,
406
+ textAlign: style.textAlign,
407
+ textBaseline: style.textBaseline,
408
+ fill: new FillStyle({
409
+ color: style.foreColor
410
+ }),
411
+ stroke: new StrokeStyle({
412
+ color: style.backColor
413
+ }),
414
+ offsetX: style.offsetX,
415
+ offsetY: style.offsetY
416
+ })
417
+ })
418
+ }
419
+
420
+ /**
421
+ * @function StyleUtils.dashStyle
422
+ * @description 符号样式。
423
+ * @param {Object} style - 样式参数。
424
+ * @param {number} widthFactor - 宽度系数。
425
+ */
426
+ static dashStyle(style, widthFactor) {
427
+ if (!style) {
428
+ return [];
429
+ }
430
+ var w = style.strokeWidth * widthFactor;
431
+ var str = style.strokeDashstyle || style.lineDash;
432
+ switch (str) {
433
+ case 'solid':
434
+ return [0];
435
+ case 'dot':
436
+ return [1, 4 * w];
437
+ case 'dash':
438
+ return [4 * w, 4 * w];
439
+ case 'dashdot':
440
+ return [4 * w, 4 * w, 1, 4 * w];
441
+ case 'longdash':
442
+ return [8 * w, 4 * w];
443
+ case 'longdashdot':
444
+ return [8 * w, 4 * w, 1, 4 * w];
445
+ default:
446
+ if (!str) {
447
+ return [];
448
+ }
449
+ if (CommonUtil.isArray(str)) {
450
+ return str;
451
+ }
452
+ str = StringExt.trim(str).replace(/\s+/g, ",");
453
+ return str.replace(/\[|\]/gi, "").split(",");
454
+ }
455
+ }
456
+
457
+ /**
458
+ * @function StyleUtils.getStyleFromiPortalMarker
459
+ * @description 从 iPortal 标记获取样式。
460
+ * @param {Object} icon - 图标参数。
461
+ */
462
+ static getStyleFromiPortalMarker(icon) {
463
+ if (icon.indexOf("./") == 0) {
464
+ return null;
465
+ }
466
+ //兼容iportal示例的问题
467
+ // if (icon.indexOf("http://support.supermap.com.cn:8092/static/portal") == 0) {
468
+ // icon = icon.replace("http://support.supermap.com.cn:8092/static/portal", "http://support.supermap.com.cn:8092/apps/viewer/static");
469
+ // }
470
+ return new Style({
471
+ image: new Icon({
472
+ src: icon,
473
+ opacity: 1,
474
+ size: [48, 43],
475
+ anchor: [0.5, 1]
476
+ })
477
+ });
478
+ }
479
+
480
+ /**
481
+ * @function StyleUtils.getStyleFromiPortalStyle
482
+ * @description 从 iPortal 标记获取样式。
483
+ * @param {Object} iPortalStyle - iportal 样式。
484
+ * @param {string} type - 样式类型。
485
+ * @param {Object} fStyle - 要素样式。
486
+ */
487
+ static getStyleFromiPortalStyle(iPortalStyle, type, fStyle) {
488
+ var featureStyle = fStyle ? JSON.parse(fStyle) : null;
489
+ var me = this;
490
+ if (type === 'Point' || type === 'MultiPoint') {
491
+ var pointStyle = featureStyle || iPortalStyle.pointStyle;
492
+ if (pointStyle.externalGraphic) {
493
+ if (pointStyle.externalGraphic.indexOf("./") == 0) {
494
+ return null;
495
+ }
496
+ //兼容iportal示例的问题
497
+ // if (pointStyle.externalGraphic.indexOf("http://support.supermap.com.cn:8092/static/portal") == 0) {
498
+ // pointStyle.externalGraphic = pointStyle.externalGraphic.replace("http://support.supermap.com.cn:8092/static/portal", "http://support.supermap.com.cn:8092/apps/viewer/static");
499
+ // }
500
+ return new Style({
501
+ image: new Icon({
502
+ src: pointStyle.externalGraphic,
503
+ opacity: pointStyle.graphicOpacity,
504
+ size: [pointStyle.graphicWidth, pointStyle.graphicHeight]
505
+ //anchor: [-pointStyle.graphicXOffset / pointStyle.graphicWidth, -pointStyle.graphicYOffset / pointStyle.graphicHeight]
506
+ })
507
+ });
508
+ }
509
+ return new Style({
510
+ image: new CircleStyle({
511
+ fill: new FillStyle({
512
+ color: me.hexToRgba(pointStyle.fillColor, pointStyle.fillOpacity)
513
+ }),
514
+ stroke: new StrokeStyle({
515
+ color: me.hexToRgba(pointStyle.strokeColor, pointStyle.strokeOpacity),
516
+ lineCap: pointStyle.strokeLineCap,
517
+ lineDash: this.dashStyle(pointStyle, 1),
518
+ width: pointStyle.strokeWidth
519
+ }),
520
+ radius: pointStyle.pointRadius
521
+ })
522
+ });
523
+ }
524
+ if (type === 'LineString' || type === 'MultiLineString' || type === 'Box') {
525
+ var lineStyle = featureStyle || iPortalStyle.lineStyle;
526
+ return new Style({
527
+ stroke: new StrokeStyle({
528
+ color: me.hexToRgba(lineStyle.strokeColor, lineStyle.strokeOpacity),
529
+ lineCap: lineStyle.strokeLineCap,
530
+ lineDash: this.dashStyle(lineStyle, 1),
531
+ width: lineStyle.strokeWidth
532
+ })
533
+ });
534
+ }
535
+ if (type === 'Polygon' || type === 'MultiPolygon') {
536
+ var polygonStyle = featureStyle || iPortalStyle.polygonStyle;
537
+ return new Style({
538
+ fill: new FillStyle({
539
+ color: me.hexToRgba(polygonStyle.fillColor, polygonStyle.fillOpacity)
540
+ }),
541
+ stroke: new StrokeStyle({
542
+ color: me.hexToRgba(polygonStyle.strokeColor, polygonStyle.strokeOpacity),
543
+ lineCap: polygonStyle.strokeLineCap,
544
+ lineDash: this.dashStyle(polygonStyle, 1),
545
+ width: polygonStyle.strokeWidth
546
+ })
547
+ });
548
+ }
549
+ }
550
+
551
+ /**
552
+ * @function StyleUtils.hexToRgba
553
+ * @description 十六进制转 RGBA 格式。
554
+ * @param {Object} hex - 十六进制格式参数。
555
+ * @param {number} opacity -Alpha 参数。
556
+ * @returns {string} 生成的 RGBA 格式。
557
+ */
558
+ static hexToRgba(hex, opacity) {
559
+ var color = [], rgba = [];
560
+ hex = hex.replace(/#/, "");
561
+ if (hex.length == 3) {
562
+ var tmp = [];
563
+ for (let i = 0; i < 3; i++) {
564
+ tmp.push(hex.charAt(i) + hex.charAt(i));
565
+ }
566
+ hex = tmp.join("");
567
+ }
568
+ for (let i = 0; i < 6; i += 2) {
569
+ color[i] = "0x" + hex.substr(i, 2);
570
+ rgba.push(parseInt(Number(color[i])));
571
+ }
572
+ rgba.push(opacity);
573
+ return "rgba(" + rgba.join(",") + ")";
574
+ }
575
+
576
+ /**
577
+ * @function StyleUtils.getDefaultStyle
578
+ * @description 获取默认风格
579
+ * @param {string} type - 类型参数。
580
+ * @returns {string}
581
+ */
582
+ static getDefaultStyle(type) {
583
+ var style = {};
584
+ var canvasStyle = DeafultCanvasStyle[type];
585
+ for (var prop in canvasStyle) {
586
+ var val = canvasStyle[prop];
587
+ style[prop] = val;
588
+ }
589
+ return style;
590
+ }
591
+
592
+ /**
593
+ * @function StyleUtils.getDefaultStyle
594
+ * @description 将样式对象转换成openlayer要求的ol.style
595
+ * @param {string} style - 样式对象
596
+ * @param {string} type - feature的类型
597
+ * @returns {Promise<ol.style.Style>}
598
+ */
599
+ static async toOpenLayersStyle(style, type) {
600
+ style = style || this.getDefaultStyle();
601
+ let olStyle = new Style();
602
+ let newImage, newFill, newStroke;
603
+ let {
604
+ fillColor,
605
+ fillOpacity,
606
+ strokeColor,
607
+ strokeWidth,
608
+ strokeOpacity,
609
+ radius,
610
+ lineCap,
611
+ src,
612
+ scale,
613
+ offsetX,
614
+ offsetY,
615
+ //size,
616
+ //imgSize,
617
+ anchor
618
+ } = style;
619
+ let fillColorArray = this.hexToRgb(fillColor);
620
+ if (fillColorArray) {
621
+ fillColorArray.push(fillOpacity);
622
+ }
623
+
624
+ let strokeColorArray = this.hexToRgb(strokeColor);
625
+ if (strokeColorArray) {
626
+ strokeColorArray.push(strokeOpacity);
627
+ }
628
+ if (type === "POINT") {
629
+ if (src) {
630
+ if (/.+(\.svg$)/.test(src)) {
631
+ if (!this.svgDiv) {
632
+ this.svgDiv = document.createElement('div');
633
+ document.body.appendChild(this.svgDiv);
634
+ }
635
+ await this.getCanvasFromSVG(src, this.svgDiv, (canvas) => {
636
+ newImage = new Icon({
637
+ img: canvas,
638
+ scale: radius / canvas.width,
639
+ imgSize: [canvas.width, canvas.height],
640
+ anchor: [0.5, 0.5]
641
+ })
642
+ })
643
+ } else {
644
+ newImage = new Icon({
645
+ src: src,
646
+ scale: scale,
647
+ anchor: anchor
648
+ });
649
+ }
650
+ } else {
651
+ newImage = new CircleStyle({
652
+ radius,
653
+ fill: new FillStyle({
654
+ color: fillColorArray
655
+ }),
656
+ stroke: new StrokeStyle({
657
+ width: strokeWidth || ZERO,
658
+ color: strokeColorArray
659
+ }),
660
+ displacement: this.getCircleDisplacement(radius, offsetX, offsetY)
661
+ });
662
+ }
663
+ olStyle.setImage(newImage);
664
+ } else if (type === "LINE" || type === "LINESTRING" || type === 'MULTILINESTRING' || type === 'LINEARRING') {
665
+ newStroke = new StrokeStyle({
666
+ width: strokeWidth || ZERO,
667
+ color: strokeColorArray,
668
+ lineCap: lineCap || 'round',
669
+ lineDash: this.dashStyle(style, 1)
670
+ });
671
+ olStyle.setStroke(newStroke);
672
+ } else if (type === 'POLYGON' ||
673
+ type === 'MULTIPOLYGON' || type === 'REGION') {
674
+ newFill = new FillStyle({
675
+ color: fillColorArray
676
+ });
677
+ newStroke = new StrokeStyle({
678
+ width: strokeWidth || ZERO,
679
+ color: strokeColorArray,
680
+ lineCap: lineCap || 'round',
681
+ lineDash: this.dashStyle(style, 1)
682
+ });
683
+ olStyle.setFill(newFill);
684
+ olStyle.setStroke(newStroke);
685
+ } else {
686
+ let result = this.getCanvas(style);
687
+ newImage = new Icon({
688
+ img: result.canvas,
689
+ imgSize: [result.width, result.height],
690
+ scale: 1,
691
+ anchor: [0.5, 0.5]
692
+ });
693
+ olStyle.setImage(newImage);
694
+ }
695
+ return olStyle;
696
+ }
697
+
698
+ /**
699
+ * @function StyleUtils.getIconAnchor
700
+ * @description 获取图标的锚点
701
+ * @param {number} offsetX - X方向偏移分数
702
+ * @param {number} offsetY - Y方向偏移分数
703
+ * @returns {Array.<number>}
704
+ */
705
+ static getIconAnchor(offsetX=0.5, offsetY=0.5) {
706
+ return [offsetX, offsetY];
707
+ }
708
+ /**
709
+ * @function StyleUtils.getCircleDisplacement
710
+ * @description 获取圆圈的偏移
711
+ * @param {number} radius - 圆圈半径
712
+ * @param {number} offsetX - X方向偏移分数
713
+ * @param {number} offsetY - Y方向偏移分数
714
+ * @returns {Array.<number>}
715
+ */
716
+ static getCircleDisplacement(radius, offsetX=0, offsetY=0) {
717
+ const dispX = radius*offsetX, dispY = radius*offsetY;
718
+ return [dispX, -dispY];
719
+ }
720
+ /**
721
+ * @function StyleUtils.getTextOffset
722
+ * @description 获取字体图标的偏移值
723
+ * @param {string} fontSize - 字体大小,如12px
724
+ * @param {number} offsetX - X方向偏移分数
725
+ * @param {number} offsetY - Y方向偏移分数
726
+ * @returns {Object}
727
+ */
728
+ static getTextOffset(fontSize, offsetX=0, offsetY=0) {
729
+ const radius = fontSize.substr(0, fontSize.length - 2) / 2;
730
+ return {
731
+ x: radius*offsetX,
732
+ y: radius*offsetY
733
+ };
734
+ }
735
+
736
+ /**
737
+ * 获取文字标注对应的canvas
738
+ * @param style
739
+ * @returns {{canvas: *, width: number, height: number}}
740
+ */
741
+ static getCanvas(style) {
742
+ let canvas;
743
+ if (style.canvas) {
744
+ if (document.querySelector("#" + style.canvas)) {
745
+ canvas = document.getElemntById(style.canvas);
746
+ } else {
747
+ canvas = this.createCanvas(style);
748
+ }
749
+ } else {
750
+ //不存在canvas,当前feature
751
+ canvas = this.createCanvas(style);
752
+ style.canvas = canvas.id;
753
+ }
754
+ canvas.style.display = "none";
755
+ var ctx = canvas.getContext("2d");
756
+ //行高
757
+ let lineHeight = Number(style.font.replace(/[^0-9]/ig, ""));
758
+ let textArray = style.text.split('\r\n');
759
+ let lenght = textArray.length;
760
+ //在改变canvas大小后再绘制。否则会被清除
761
+ ctx.font = style.font;
762
+ let size = this.drawRect(ctx, style, textArray, lineHeight, canvas);
763
+ this.positionY = padding;
764
+ if (lenght > 1) {
765
+ textArray.forEach(function (text, i) {
766
+ if (i !== 0) {
767
+ this.positionY = this.positionY + lineHeight;
768
+ }
769
+ this.canvasTextAutoLine(text, style, ctx, lineHeight, size.width);
770
+ }, this);
771
+ } else {
772
+ this.canvasTextAutoLine(textArray[0], style, ctx, lineHeight, size.width);
773
+ }
774
+ return {
775
+ canvas: canvas,
776
+ width: size.width,
777
+ height: size.height
778
+ };
779
+ }
780
+ /**
781
+ * 创建当前feature对应的canvas
782
+ * @param {Object} style
783
+ * @returns {HTMLElement}
784
+ */
785
+ static createCanvas(style) {
786
+ let div = document.createElement('div');
787
+ document.body.appendChild(div);
788
+ let canvas = document.createElement('canvas');
789
+ canvas.id = style.canvas ? style.canvas : 'textCanvas' + Util.newGuid(8);
790
+ div.appendChild(canvas);
791
+ return canvas;
792
+ }
793
+ /**
794
+ * 绘制矩形边框背景
795
+ * @param ctx
796
+ * @param style
797
+ * @param textArray
798
+ * @param lineHeight
799
+ * @param canvas
800
+ * @returns {{width: number, height: number}}
801
+ */
802
+ static drawRect(ctx, style, textArray, lineHeight, canvas) {
803
+ let backgroundFill = style.backgroundFill, maxWidth = style.maxWidth - doublePadding;
804
+ let width, height = 0, lineCount = 0, lineWidths = [];
805
+ //100的宽度,去掉左右两边3padding
806
+ textArray.forEach(function (arrText) {
807
+ let line = '', isOverMax;
808
+ lineCount++;
809
+ for (var n = 0; n < arrText.length; n++) {
810
+ let textLine = line + arrText[n];
811
+ let metrics = ctx.measureText(textLine);
812
+ let textWidth = metrics.width;
813
+ if ((textWidth > maxWidth && n > 0) || arrText[n] === '\n') {
814
+ line = arrText[n];
815
+ lineCount++;
816
+ //有换行,记录当前换行的width
817
+ isOverMax = true;
818
+ } else {
819
+ line = textLine;
820
+ width = textWidth;
821
+ }
822
+ }
823
+ if (isOverMax) {
824
+ lineWidths.push(maxWidth);
825
+ } else {
826
+ lineWidths.push(width);
827
+ }
828
+ }, this);
829
+ width = this.getCanvasWidth(lineWidths, maxWidth);
830
+ height = lineCount * lineHeight;
831
+ height += doublePadding;
832
+ canvas.width = width;
833
+ canvas.height = height;
834
+ ctx.fillStyle = backgroundFill;
835
+ ctx.fillRect(0, 0, width, height);
836
+ return {
837
+ width: width,
838
+ height: height
839
+ }
840
+ }
841
+ /**
842
+ * 获取自适应的宽度(如果没有超过最大宽度,就用文字的宽度)
843
+ * @param lineWidths
844
+ * @param maxWidth
845
+ * @returns {number}
846
+ */
847
+ static getCanvasWidth(lineWidths, maxWidth) {
848
+ let width = 0;
849
+ for (let i = 0; i < lineWidths.length; i++) {
850
+ let lineW = lineWidths[i];
851
+ if (lineW >= maxWidth) {
852
+ //有任何一行超过最大高度,就用最大高度
853
+ return maxWidth + doublePadding;
854
+ } else if (lineW > width) {
855
+ //自己换行,就要比较每行的最大宽度
856
+ width = lineW;
857
+ }
858
+ }
859
+ return width + doublePadding;
860
+ }
861
+ /**
862
+ * 绘制文字,解决换行问题
863
+ * @param text
864
+ * @param style
865
+ * @param ctx
866
+ * @param lineHeight
867
+ */
868
+ static canvasTextAutoLine(text, style, ctx, lineHeight, canvasWidth) {
869
+ // 字符分隔为数组
870
+ ctx.font = style.font;
871
+ let textAlign = style.textAlign;
872
+ let x = this.getPositionX(textAlign, canvasWidth);
873
+ let arrText = text.split('');
874
+ let line = '', fillColor = style.fillColor;
875
+ //每一行限制的高度
876
+ let maxWidth = style.maxWidth - doublePadding;
877
+ for (var n = 0; n < arrText.length; n++) {
878
+ let testLine = line + arrText[n];
879
+ let metrics = ctx.measureText(testLine);
880
+ let testWidth = metrics.width;
881
+ if ((testWidth > maxWidth && n > 0) || arrText[n] === '\n') {
882
+ ctx.fillStyle = fillColor;
883
+ ctx.textAlign = textAlign;
884
+ ctx.textBaseline = "top";
885
+ ctx.fillText(line, x, this.positionY);
886
+ line = arrText[n];
887
+ this.positionY += lineHeight;
888
+ } else {
889
+ line = testLine;
890
+ }
891
+ }
892
+ ctx.fillStyle = fillColor;
893
+ ctx.textAlign = textAlign;
894
+ ctx.textBaseline = "top";
895
+ ctx.fillText(line, x, this.positionY);
896
+ }
897
+ /**
898
+ * 得到绘制的起点位置,根据align不同,位置也不同
899
+ * @param textAlign
900
+ * @returns {number}
901
+ */
902
+ static getPositionX(textAlign, canvasWidth) {
903
+ let x;
904
+ let width = canvasWidth - doublePadding; //减去padding
905
+ switch (textAlign) {
906
+ case 'center':
907
+ x = width / 2;
908
+ break;
909
+ case 'right':
910
+ x = width;
911
+ break;
912
+ default:
913
+ x = 8;
914
+ break;
915
+ }
916
+ return x;
917
+ }
918
+
919
+ /**
920
+ * @function StyleUtils.hexToRgb
921
+ * @description 将16进制的颜色,转换成rgb格式
922
+ * @param {string} hexColor 16进制颜色
923
+ * @returns {string} rgb格式的颜色
924
+ */
925
+ static hexToRgb(hexColor) {
926
+ if (!hexColor) {
927
+ return;
928
+ }
929
+ var s = hexColor.replace('#', '').split('');
930
+ var rgb = [s[0] + s[1], s[2] + s[3], s[4] + s[5]];
931
+ rgb = rgb.map(function (hex) {
932
+ return parseInt(hex, 16);
933
+ });
934
+ return rgb;
935
+ }
936
+
937
+ /**
938
+ * @function StyleUtils.formatRGB
939
+ * @description 将颜色数组转换成标准的rgb颜色格式
940
+ * @param {Array} colorArray - 颜色数组
941
+ * @returns {string} 'rgb(0,0,0)'或者 'rgba(0,0,0,0)'
942
+ */
943
+ static formatRGB(colorArray) {
944
+ let rgb;
945
+ if (colorArray.length === 3) {
946
+ rgb = 'rgb(';
947
+ colorArray.forEach(function (color, index) {
948
+ index === 2 ? rgb += color : rgb += color + ',';
949
+ });
950
+ } else {
951
+ rgb = 'rgba(';
952
+ colorArray.forEach(function (color, index) {
953
+ index === 3 ? rgb += color : rgb += color + ',';
954
+ });
955
+ }
956
+ rgb += ")"
957
+ return rgb;
958
+ }
959
+
960
+ /**
961
+ * @function StyleUtils.getCanvasFromSVG
962
+ * @description 将SVG转换成Canvas
963
+ * @param {string} svgUrl - 颜色数组
964
+ * @param {Object} divDom - div的dom对象
965
+ * @param {function} callBack - 转换成功执行的回调函数
966
+ */
967
+ static async getCanvasFromSVG(svgUrl, divDom, callBack) {
968
+ //一个图层对应一个canvas
969
+ const canvgs = window.canvg && window.canvg.default ? window.canvg.default : Canvg;
970
+ let canvas = document.createElement('canvas');
971
+ canvas.id = 'dataviz-canvas-' + Util.newGuid(8);
972
+ canvas.style.display = "none";
973
+ divDom.appendChild(canvas);
974
+ try {
975
+ const ctx = canvas.getContext('2d');
976
+ const v = await canvgs.from(ctx, svgUrl, {
977
+ ignoreMouse: true,
978
+ ignoreAnimation: true,
979
+ forceRedraw: () => false
980
+ })
981
+ v.start();
982
+ if (canvas.width > 300 || canvas.height > 300) {
983
+ return;
984
+ }
985
+ callBack(canvas);
986
+ } catch (e) {
987
+ return;
988
+ }
989
+ }
990
+
991
+ /**
992
+ * @function StyleUtils.stopCanvg
993
+ * @description 调用Canvg实例的stop();
994
+ */
995
+ static stopCanvg() {
996
+ this.canvgsV.forEach(v => v.stop());
997
+ this.canvgsV = [];
998
+ }
999
+
1000
+ /**
1001
+ * @function StyleUtils.getMarkerDefaultStyle 获取默认标注图层feature的样式
1002
+ * @param {string} featureType feature的类型
1003
+ * @param {string} server 当前地图前缀
1004
+ * @returns {Object} style对象
1005
+ */
1006
+ static getMarkerDefaultStyle(featureType, server) {
1007
+ let style;
1008
+ switch (featureType) {
1009
+ case 'POINT':
1010
+ style = {
1011
+ src: `${server}apps/dataviz/static/imgs/markers/mark_red.png`,
1012
+ scale: 1,
1013
+ anchor: [0.5, 1]
1014
+ };
1015
+ break;
1016
+ case 'LINE':
1017
+ case 'LINESTRING':
1018
+ case 'MULTILINESTRING':
1019
+ style = {
1020
+ strokeColor: '#3498db',
1021
+ strokeOpacity: 1,
1022
+ strokeWidth: 5,
1023
+ lineCap: 'round',
1024
+ lineDash: 'solid'
1025
+ };
1026
+ break;
1027
+ case 'REGION':
1028
+ case 'POLYGON':
1029
+ case 'MULTIPOLYGON':
1030
+ style = {
1031
+ fillColor: '#1abd9c',
1032
+ fillOpacity: 1,
1033
+ strokeColor: '#3498db',
1034
+ strokeOpacity: 1,
1035
+ strokeWidth: 3,
1036
+ lineCap: 'round',
1037
+ lineDash: 'solid'
1038
+ };
1039
+ break;
1040
+ }
1041
+ return style;
1042
+ }
1043
+
1044
+ /**
1045
+ * @function StyleUtils.getOpenlayerStyle 获取专题图对应的openlayers格式的style
1046
+ * @param {string} styleParams 样式参数
1047
+ * @param {string} featureType feature类型
1048
+ * @param {boolean} isRank 是否为等级符号
1049
+ * @returns {Promise<ol.style.Style>}
1050
+ */
1051
+ static async getOpenlayersStyle(styleParams, featureType, isRank) {
1052
+ let style;
1053
+ if (styleParams.type === "BASIC_POINT") {
1054
+ style = await this.toOpenLayersStyle(styleParams, featureType);
1055
+ } else if (styleParams.type === "SYMBOL_POINT") {
1056
+ style = this.getSymbolStyle(styleParams, isRank);
1057
+ } else if (styleParams.type === "SVG_POINT") {
1058
+ style = await this.getSVGStyle(styleParams);
1059
+ } else if (styleParams.type === 'IMAGE_POINT') {
1060
+ style = this.getImageStyle(styleParams);
1061
+ }
1062
+ return style;
1063
+ }
1064
+
1065
+ /**
1066
+ * @function StyleUtils.getSymbolStyle 获取符号样式
1067
+ * @param {Object} parameters - 样式参数
1068
+ * @returns {Object} style对象
1069
+ */
1070
+ static getSymbolStyle(parameters, isRank) {
1071
+ let text = '';
1072
+ if (parameters.unicode) {
1073
+ text = String.fromCharCode(parseInt(parameters.unicode.replace(/^&#x/, ''), 16));
1074
+ }
1075
+ // 填充色 + 透明度
1076
+ let fillColor = StyleUtils.hexToRgb(parameters.fillColor);
1077
+ fillColor.push(parameters.fillOpacity);
1078
+ // 边框充色 + 透明度
1079
+ let strokeColor = StyleUtils.hexToRgb(parameters.strokeColor);
1080
+ strokeColor.push(parameters.strokeOpacity);
1081
+
1082
+ let fontSize = isRank ? 2 * parameters.radius + "px" : parameters.fontSize;
1083
+
1084
+ const {offsetX, offsetY, rotation=0} = parameters;
1085
+ const offset = StyleUtils.getTextOffset(fontSize, offsetX, offsetY);
1086
+ return new Style({
1087
+ text: new Text({
1088
+ text: text,
1089
+ font: fontSize + " supermapol-icons",
1090
+ placement: 'point',
1091
+ textAlign: 'center',
1092
+ fill: new FillStyle({
1093
+ color: fillColor
1094
+ }),
1095
+ backgroundFill: new FillStyle({
1096
+ color: [0, 0, 0, 0]
1097
+ }),
1098
+ stroke: new StrokeStyle({
1099
+ width: parameters.strokeWidth || 0.000001,
1100
+ color: strokeColor
1101
+ }),
1102
+ offsetX: offset.x,
1103
+ offsetY: offset.y,
1104
+ rotation
1105
+ })
1106
+ });
1107
+ }
1108
+ /**
1109
+ * @function StyleUtils.getSVGStyle 获取svg的样式
1110
+ * @param {Object} styleParams - 样式参数
1111
+ * @returns {Promise<ol.style.Style>}
1112
+ */
1113
+ static async getSVGStyle(styleParams) {
1114
+ let style, that = this;
1115
+ if (!that.svgDiv) {
1116
+ that.svgDiv = document.createElement('div');
1117
+ document.body.appendChild(that.svgDiv);
1118
+ }
1119
+ const { url, radius, offsetX, offsetY, fillOpacity, rotation } = styleParams;
1120
+ let anchor = this.getIconAnchor(offsetX, offsetY);
1121
+ await StyleUtils.getCanvasFromSVG(url, that.svgDiv, function (canvas) {
1122
+ style = new Style({
1123
+ image: new Icon({
1124
+ img: that.setColorToCanvas(canvas, styleParams),
1125
+ scale: 2 * radius / canvas.width,
1126
+ imgSize: [canvas.width, canvas.height],
1127
+ anchor: anchor || [0.5, 0.5],
1128
+ opacity: fillOpacity,
1129
+ anchorOrigin: 'bottom-right',
1130
+ rotation
1131
+ })
1132
+ });
1133
+ });
1134
+ return style;
1135
+ }
1136
+
1137
+ /**
1138
+ * @function StyleUtils.setColorToCanvas 将颜色,透明度等样式设置到canvas上
1139
+ * @param {Object} canvas - 渲染的canvas对象
1140
+ * @param {Object} parameters - 样式参数
1141
+ * @returns {Object} style对象
1142
+ */
1143
+ static setColorToCanvas(canvas, parameters) {
1144
+ let context = canvas.getContext('2d');
1145
+ let fillColor = StyleUtils.hexToRgb(parameters.fillColor);
1146
+ fillColor && fillColor.push(parameters.fillOpacity);
1147
+ let strokeColor = StyleUtils.hexToRgb(parameters.strokeColor);
1148
+ strokeColor && strokeColor.push(parameters.strokeOpacity);
1149
+ context.fillStyle = StyleUtils.formatRGB(fillColor);
1150
+ context.fill();
1151
+ context.strokeStyle = StyleUtils.formatRGB(strokeColor);
1152
+ context.lineWidth = parameters.strokeWidth;
1153
+ context.stroke();
1154
+ return canvas;
1155
+ }
1156
+ /**
1157
+ * @function StyleUtils.getImageStyle 获取图片样式
1158
+ * @param {Object} styleParams - 样式参数
1159
+ * @returns {Object} style对象
1160
+ */
1161
+ static getImageStyle(styleParams) {
1162
+ let size = styleParams.imageInfo.size,
1163
+ scale = 2 * styleParams.radius / size.w;
1164
+ let imageInfo = styleParams.imageInfo;
1165
+ let imgDom = imageInfo.img;
1166
+ if (!imgDom || !imgDom.src) {
1167
+ imgDom = new Image();
1168
+ //要组装成完整的url
1169
+ imgDom.src = imageInfo.url;
1170
+ }
1171
+ const { offsetX, offsetY, rotation } = styleParams;
1172
+ let anchor = this.getIconAnchor(offsetX, offsetY);
1173
+ return new Style({
1174
+ image: new Icon({
1175
+ img: imgDom,
1176
+ scale,
1177
+ imgSize: [size.w, size.h],
1178
+ anchor: anchor || [0.5, 0.5],
1179
+ anchorOrigin: 'bottom-right',
1180
+ rotation
1181
+ })
1182
+ });
1183
+ }
1184
+ /**
1185
+ * @function StyleUtils.getRoadPath 获取道路样式
1186
+ * @param {Object} style - 样式参数
1187
+ * @param {Object} outlineStyle - 轮廓样式参数
1188
+ * @returns {Object} style对象
1189
+ */
1190
+ static getRoadPath(style, outlineStyle) {
1191
+ const { strokeWidth=ZERO, lineCap, strokeColor, strokeOpacity } = style;
1192
+ // 道路线都是solid
1193
+ let strokeColorArray = this.hexToRgb(strokeColor);
1194
+ strokeColorArray && strokeColorArray.push(strokeOpacity);
1195
+ var stroke = new Style({
1196
+ stroke: new StrokeStyle({
1197
+ width: strokeWidth || ZERO,
1198
+ color: strokeColorArray,
1199
+ lineCap: lineCap || 'round',
1200
+ lineDash: [0]
1201
+ })
1202
+ });
1203
+
1204
+ const { strokeColor: outlineColor } = outlineStyle;
1205
+ let outlineColorArray = this.hexToRgb(outlineColor);
1206
+ // opacity使用style的透明度。保持两根线透明度一致
1207
+ outlineColorArray && outlineColorArray.push(strokeOpacity);
1208
+ let outlineWidth = outlineStyle.strokeWidth || (strokeWidth === 0 ? ZERO : strokeWidth + 2); //外部宽度=内部样式宽度 + 2
1209
+ var outlineStroke = new Style({
1210
+ stroke: new StrokeStyle({
1211
+ width: outlineWidth, //外部宽度=内部样式宽度 + 2
1212
+ color: outlineColorArray,
1213
+ lineCap: lineCap || 'round',
1214
+ lineDash: [0]
1215
+ })
1216
+ });
1217
+ return [outlineStroke, stroke];
1218
+ }
1219
+ /**
1220
+ * @function StyleUtils.getPathway 获取铁路样式
1221
+ * @param {Object} style - 样式参数
1222
+ * @param {Object} outlineStyle - 轮廓样式参数
1223
+ * @returns {Object} style对象
1224
+ */
1225
+ static getPathway(style, outlineStyle) {
1226
+ let { strokeWidth=ZERO, strokeColor, strokeOpacity } = style;
1227
+ // 道路线都是solid, lineCap都是直角
1228
+ const lineDash = (w => [w, w + strokeWidth * 2])(4 * strokeWidth), lineCap= 'square';
1229
+ let strokeColorArray = this.hexToRgb(strokeColor);
1230
+ strokeColorArray && strokeColorArray.push(strokeOpacity);
1231
+ var stroke = new Style({
1232
+ stroke: new StrokeStyle({
1233
+ width: strokeWidth*0.5 || ZERO,
1234
+ color: strokeColorArray,
1235
+ lineCap,
1236
+ lineDash
1237
+ })
1238
+ });
1239
+
1240
+ const { strokeColor: outlineColor } = outlineStyle;
1241
+ let outlineColorArray = this.hexToRgb(outlineColor);
1242
+ // opacity使用style的透明度。保持两根线透明度一致
1243
+ outlineColorArray && outlineColorArray.push(strokeOpacity);
1244
+ var outlineStroke = new Style({
1245
+ stroke: new StrokeStyle({
1246
+ width: strokeWidth || ZERO,
1247
+ color: outlineColorArray,
1248
+ lineCap
1249
+ })
1250
+ });
1251
+ return [outlineStroke, stroke];
1252
+ }
1253
+ }