bbj-screen-widget 2.4.66 → 2.4.67
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.
- package/bbj-screen-widget.d.ts +34 -33
- package/bbj-screen-widget.metadata.json +1 -1
- package/bundles/bbj-screen-widget-core.umd.js +1 -1
- package/bundles/bbj-screen-widget-core.umd.js.map +1 -1
- package/bundles/bbj-screen-widget-core.umd.min.js +1 -1
- package/bundles/bbj-screen-widget-core.umd.min.js.map +1 -1
- package/bundles/bbj-screen-widget.umd.js +730 -353
- package/bundles/bbj-screen-widget.umd.js.map +1 -1
- package/bundles/bbj-screen-widget.umd.min.js +1 -1
- package/bundles/bbj-screen-widget.umd.min.js.map +1 -1
- package/esm2015/bbj-screen-widget.js +35 -34
- package/esm2015/core/service/baidu-map.service.js +2 -2
- package/esm2015/lib/custom-baidu-map/baidu-fence/baidu-fence.component.js +168 -88
- package/esm2015/lib/custom-baidu-map/baidu-lushu/baidu-lushu.component.js +222 -0
- package/esm2015/lib/custom-baidu-map/custom-baidu-map.component.js +2 -1
- package/esm2015/lib/custom-baidu-map/custom-baidu-map.module.js +6 -1
- package/fesm2015/bbj-screen-widget-core.js +1 -1
- package/fesm2015/bbj-screen-widget-core.js.map +1 -1
- package/fesm2015/bbj-screen-widget.js +385 -87
- package/fesm2015/bbj-screen-widget.js.map +1 -1
- package/lib/custom-baidu-map/baidu-fence/baidu-fence.component.d.ts +20 -2
- package/lib/custom-baidu-map/baidu-lushu/baidu-lushu.component.d.ts +31 -0
- package/package.json +1 -1
- package/src/assets/img/screen/car.png +0 -0
- package/src/assets/js/BMapGL/Lushu.js +815 -0
- package/src/assets/js/BMapGL/Lushu.min.js +1 -0
|
@@ -0,0 +1,815 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 百度地图的轨迹跟随类,对外开放。
|
|
3
|
+
* 用户可以在地图上自定义轨迹运动
|
|
4
|
+
* 可以自定义路过某个点的图片,文字介绍等。
|
|
5
|
+
* 主入口类是<a href="examples/index.html">LuShu</a>,
|
|
6
|
+
* 基于Baidu Map API GL 1.0
|
|
7
|
+
*
|
|
8
|
+
* @author Baidu Map Api Group
|
|
9
|
+
* @version 1.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @namespace BMapGL的所有library类均放在BMapGLLib命名空间下
|
|
14
|
+
*/
|
|
15
|
+
var BMapGLLib = window.BMapGLLib = BMapGLLib || {};
|
|
16
|
+
|
|
17
|
+
(function () {
|
|
18
|
+
var T;
|
|
19
|
+
var baidu = T = baidu || { version: 'gl 1.0' };
|
|
20
|
+
baidu.guid = '$BAIDU$';
|
|
21
|
+
(function () {
|
|
22
|
+
window[baidu.guid] = window[baidu.guid] || {};
|
|
23
|
+
baidu.dom = baidu.dom || {};
|
|
24
|
+
baidu.dom.g = function (id) {
|
|
25
|
+
if ('string' == typeof id || id instanceof String) {
|
|
26
|
+
return document.getElementById(id);
|
|
27
|
+
} else if (id && id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {
|
|
28
|
+
return id;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
baidu.g = baidu.G = baidu.dom.g;
|
|
33
|
+
baidu.lang = baidu.lang || {};
|
|
34
|
+
baidu.lang.isString = function (source) {
|
|
35
|
+
return '[object String]' == Object.prototype.toString.call(source);
|
|
36
|
+
};
|
|
37
|
+
baidu.isString = baidu.lang.isString;
|
|
38
|
+
baidu.dom._g = function (id) {
|
|
39
|
+
if (baidu.lang.isString(id)) {
|
|
40
|
+
return document.getElementById(id);
|
|
41
|
+
}
|
|
42
|
+
return id;
|
|
43
|
+
};
|
|
44
|
+
baidu._g = baidu.dom._g;
|
|
45
|
+
baidu.dom.getDocument = function (element) {
|
|
46
|
+
element = baidu.dom.g(element);
|
|
47
|
+
return element.nodeType == 9 ? element : element.ownerDocument || element.document;
|
|
48
|
+
};
|
|
49
|
+
baidu.browser = baidu.browser || {};
|
|
50
|
+
baidu.browser.ie = baidu.ie = /msie (\d+\.\d+)/i.test(navigator.userAgent) ? (document.documentMode || + RegExp['\x241']) : undefined;
|
|
51
|
+
baidu.dom.getComputedStyle = function (element, key) {
|
|
52
|
+
element = baidu.dom._g(element);
|
|
53
|
+
var doc = baidu.dom.getDocument(element),
|
|
54
|
+
styles;
|
|
55
|
+
if (doc.defaultView && doc.defaultView.getComputedStyle) {
|
|
56
|
+
styles = doc.defaultView.getComputedStyle(element, null);
|
|
57
|
+
if (styles) {
|
|
58
|
+
return styles[key] || styles.getPropertyValue(key);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return '';
|
|
62
|
+
};
|
|
63
|
+
baidu.dom._styleFixer = baidu.dom._styleFixer || {};
|
|
64
|
+
baidu.dom._styleFilter = baidu.dom._styleFilter || [];
|
|
65
|
+
baidu.dom._styleFilter.filter = function (key, value, method) {
|
|
66
|
+
var filters = baidu.dom._styleFilter;
|
|
67
|
+
var filter;
|
|
68
|
+
for (var i = 0; filter = filters[i]; i++) {
|
|
69
|
+
if (filter = filter[method]) {
|
|
70
|
+
value = filter(key, value);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return value;
|
|
74
|
+
};
|
|
75
|
+
baidu.string = baidu.string || {};
|
|
76
|
+
|
|
77
|
+
baidu.string.toCamelCase = function (source) {
|
|
78
|
+
if (source.indexOf('-') < 0 && source.indexOf('_') < 0) {
|
|
79
|
+
return source;
|
|
80
|
+
}
|
|
81
|
+
return source.replace(/[-_][^-_]/g, function (match) {
|
|
82
|
+
return match.charAt(1).toUpperCase();
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
baidu.dom.getStyle = function (element, key) {
|
|
86
|
+
var dom = baidu.dom;
|
|
87
|
+
element = dom.g(element);
|
|
88
|
+
key = baidu.string.toCamelCase(key);
|
|
89
|
+
|
|
90
|
+
var value = element.style[key] ||
|
|
91
|
+
(element.currentStyle ? element.currentStyle[key] : '') ||
|
|
92
|
+
dom.getComputedStyle(element, key);
|
|
93
|
+
|
|
94
|
+
if (!value) {
|
|
95
|
+
var fixer = dom._styleFixer[key];
|
|
96
|
+
if (fixer) {
|
|
97
|
+
value = fixer.get ? fixer.get(element) : baidu.dom.getStyle(element, fixer);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (fixer = dom._styleFilter) {
|
|
102
|
+
value = fixer.filter(key, value, 'get');
|
|
103
|
+
}
|
|
104
|
+
return value;
|
|
105
|
+
};
|
|
106
|
+
baidu.getStyle = baidu.dom.getStyle;
|
|
107
|
+
baidu.dom._NAME_ATTRS = (function () {
|
|
108
|
+
var result = {
|
|
109
|
+
'cellpadding': 'cellPadding',
|
|
110
|
+
'cellspacing': 'cellSpacing',
|
|
111
|
+
'colspan': 'colSpan',
|
|
112
|
+
'rowspan': 'rowSpan',
|
|
113
|
+
'valign': 'vAlign',
|
|
114
|
+
'usemap': 'useMap',
|
|
115
|
+
'frameborder': 'frameBorder'
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
if (baidu.browser.ie < 8) {
|
|
119
|
+
result['for'] = 'htmlFor';
|
|
120
|
+
result['class'] = 'className';
|
|
121
|
+
} else {
|
|
122
|
+
result['htmlFor'] = 'for';
|
|
123
|
+
result['className'] = 'class';
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
})();
|
|
127
|
+
|
|
128
|
+
baidu.dom.setAttr = function (element, key, value) {
|
|
129
|
+
element = baidu.dom.g(element);
|
|
130
|
+
if ('style' == key) {
|
|
131
|
+
element.style.cssText = value;
|
|
132
|
+
} else {
|
|
133
|
+
key = baidu.dom._NAME_ATTRS[key] || key;
|
|
134
|
+
element.setAttribute(key, value);
|
|
135
|
+
}
|
|
136
|
+
return element;
|
|
137
|
+
};
|
|
138
|
+
baidu.setAttr = baidu.dom.setAttr;
|
|
139
|
+
baidu.dom.setAttrs = function (element, attributes) {
|
|
140
|
+
element = baidu.dom.g(element);
|
|
141
|
+
for (var key in attributes) {
|
|
142
|
+
baidu.dom.setAttr(element, key, attributes[key]);
|
|
143
|
+
}
|
|
144
|
+
return element;
|
|
145
|
+
};
|
|
146
|
+
baidu.setAttrs = baidu.dom.setAttrs;
|
|
147
|
+
baidu.dom.create = function (tagName, opt_attributes) {
|
|
148
|
+
var el = document.createElement(tagName),
|
|
149
|
+
attributes = opt_attributes || {};
|
|
150
|
+
return baidu.dom.setAttrs(el, attributes);
|
|
151
|
+
};
|
|
152
|
+
baidu.object = baidu.object || {};
|
|
153
|
+
baidu.extend =
|
|
154
|
+
baidu.object.extend = function (target, source) {
|
|
155
|
+
for (var p in source) {
|
|
156
|
+
if (source.hasOwnProperty(p)) {
|
|
157
|
+
target[p] = source[p];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return target;
|
|
161
|
+
};
|
|
162
|
+
})();
|
|
163
|
+
|
|
164
|
+
WORLD_SIZE_MC_HALF = 20037726.372307256;
|
|
165
|
+
WORLD_SIZE_MC = WORLD_SIZE_MC_HALF * 2;
|
|
166
|
+
/**
|
|
167
|
+
* @exports LuShu as BMapGLLib.LuShu
|
|
168
|
+
*/
|
|
169
|
+
var LuShu =
|
|
170
|
+
/**
|
|
171
|
+
* LuShu类的构造函数
|
|
172
|
+
* @class LuShu <b>入口</b>。
|
|
173
|
+
* 实例化该类后,可调用,start,end,pause等方法控制覆盖物的运动。
|
|
174
|
+
|
|
175
|
+
* @constructor
|
|
176
|
+
* @param {Map} map Baidu map的实例对象.
|
|
177
|
+
* @param {Array} path 构成路线的point的数组.
|
|
178
|
+
* @param {Json Object} opts 可选的输入参数,非必填项。可输入选项包括:<br />
|
|
179
|
+
* {<br />"<b>landmarkPois</b>" : {Array} 要在覆盖物移动过程中,显示的特殊点。格式如下:landmarkPois:[<br />
|
|
180
|
+
* {lng:116.314782,lat:39.913508,html:'加油站',pauseTime:2},<br />
|
|
181
|
+
* {lng:116.315391,lat:39.964429,html:'高速公路收费站,pauseTime:3}]<br />
|
|
182
|
+
* <br />"<b>icon</b>" : {Icon} 覆盖物的icon,
|
|
183
|
+
* <br />"<b>speed</b>" : {Number} 覆盖物移动速度,单位米/秒 <br />
|
|
184
|
+
* <br />"<b>defaultContent</b>" : {String} 覆盖物中的内容 <br />
|
|
185
|
+
* }<br />.
|
|
186
|
+
* @example <b>参考示例:</b><br />
|
|
187
|
+
* var lushu = new BMapGLLib.LuShu(map,arrPois,{defaultContent:"从北京到天津",landmarkPois:[]});
|
|
188
|
+
*/
|
|
189
|
+
BMapGLLib.LuShu = function (map, path, opts) {
|
|
190
|
+
if (!path || path.length < 1) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
this._map = map;
|
|
194
|
+
//存储一条路线
|
|
195
|
+
if (opts['geodesic']) {
|
|
196
|
+
this.path = getGeodesicPath(path);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
this.path = path;
|
|
200
|
+
}
|
|
201
|
+
//移动到当前点的索引
|
|
202
|
+
this.i = 0;
|
|
203
|
+
//控制暂停后开始移动的队列的数组
|
|
204
|
+
this._setTimeoutQuene = [];
|
|
205
|
+
//进行坐标转换的类
|
|
206
|
+
// this._projection = this._map.getMapType().getProjection();
|
|
207
|
+
this._opts = {
|
|
208
|
+
icon: null,
|
|
209
|
+
//默认速度 米/秒
|
|
210
|
+
speed: 400,
|
|
211
|
+
defaultContent: ''
|
|
212
|
+
};
|
|
213
|
+
if (!opts['landmarkPois']) {
|
|
214
|
+
opts['landmarkPois'] = [];
|
|
215
|
+
}
|
|
216
|
+
this._setOptions(opts);
|
|
217
|
+
this._rotation = 0;//小车转动的角度
|
|
218
|
+
|
|
219
|
+
//如果不是默认实例,则使用默认的icon
|
|
220
|
+
if (!(this._opts.icon instanceof BMapGL.Icon)) {
|
|
221
|
+
this._opts.icon = defaultIcon;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* 根据用户输入的opts,修改默认参数_opts
|
|
226
|
+
* @param {Json Object} opts 用户输入的修改参数.
|
|
227
|
+
* @return 无返回值.
|
|
228
|
+
*/
|
|
229
|
+
LuShu.prototype._setOptions = function (opts) {
|
|
230
|
+
if (!opts) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
for (var p in opts) {
|
|
234
|
+
if (opts.hasOwnProperty(p)) {
|
|
235
|
+
this._opts[p] = opts[p];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* @description 开始运动
|
|
242
|
+
* @param none
|
|
243
|
+
* @return 无返回值.
|
|
244
|
+
*
|
|
245
|
+
* @example <b>参考示例:</b><br />
|
|
246
|
+
* lushu.start();
|
|
247
|
+
*/
|
|
248
|
+
LuShu.prototype.start = function () {
|
|
249
|
+
var me = this,
|
|
250
|
+
len = me.path.length;
|
|
251
|
+
//不是第一次点击开始,并且小车还没到达终点
|
|
252
|
+
if (me.i && me.i < len - 1) {
|
|
253
|
+
//没按pause再按start不做处理
|
|
254
|
+
if (!me._fromPause) {
|
|
255
|
+
return;
|
|
256
|
+
} else if (!me._fromStop) {
|
|
257
|
+
//按了pause按钮,并且再按start,直接移动到下一点
|
|
258
|
+
//并且此过程中,没有按stop按钮
|
|
259
|
+
//防止先stop,再pause,然后连续不停的start的异常
|
|
260
|
+
me._moveNext(++me.i);
|
|
261
|
+
}
|
|
262
|
+
} else {
|
|
263
|
+
//第一次点击开始,或者点了stop之后点开始
|
|
264
|
+
me._addMarker();
|
|
265
|
+
//等待marker动画完毕再加载infowindow
|
|
266
|
+
me._timeoutFlag = setTimeout(function () {
|
|
267
|
+
me._addInfoWin();
|
|
268
|
+
if (me._opts.defaultContent == "") {
|
|
269
|
+
me.hideInfoWindow();
|
|
270
|
+
}
|
|
271
|
+
me._moveNext(me.i);
|
|
272
|
+
}, 400);
|
|
273
|
+
}
|
|
274
|
+
//重置状态
|
|
275
|
+
this._fromPause = false;
|
|
276
|
+
this._fromStop = false;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* 结束运动
|
|
281
|
+
* @return 无返回值.
|
|
282
|
+
*
|
|
283
|
+
* @example <b>参考示例:</b><br />
|
|
284
|
+
* lushu.stop();
|
|
285
|
+
*/
|
|
286
|
+
LuShu.prototype.stop = function () {
|
|
287
|
+
this.i = 0;
|
|
288
|
+
this._fromStop = true;
|
|
289
|
+
clearInterval(this._intervalFlag);
|
|
290
|
+
this._clearTimeout();
|
|
291
|
+
//重置landmark里边的poi为未显示状态
|
|
292
|
+
for (var i = 0, t = this._opts.landmarkPois, len = t.length; i < len; i++) {
|
|
293
|
+
t[i].bShow = false;
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* 停止运动并清除overlay
|
|
299
|
+
* @return 无返回值.
|
|
300
|
+
*
|
|
301
|
+
* @example <b>参考示例:</b><br />
|
|
302
|
+
* lushu.clear();
|
|
303
|
+
*/
|
|
304
|
+
LuShu.prototype.clear = function () {
|
|
305
|
+
this._clear();
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* 暂停运动
|
|
310
|
+
* @return 无返回值.
|
|
311
|
+
*/
|
|
312
|
+
LuShu.prototype.pause = function () {
|
|
313
|
+
clearInterval(this._intervalFlag);
|
|
314
|
+
|
|
315
|
+
//标识是否是按过pause按钮
|
|
316
|
+
this._fromPause = true;
|
|
317
|
+
this._clearTimeout();
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* 隐藏上方overlay
|
|
322
|
+
* @return 无返回值.
|
|
323
|
+
*
|
|
324
|
+
* @example <b>参考示例:</b><br />
|
|
325
|
+
* lushu.hideInfoWindow();
|
|
326
|
+
*/
|
|
327
|
+
LuShu.prototype.hideInfoWindow = function () {
|
|
328
|
+
this._overlay._div.style.visibility = 'hidden';
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* 显示上方overlay
|
|
333
|
+
* @return 无返回值.
|
|
334
|
+
*
|
|
335
|
+
* @example <b>参考示例:</b><br />
|
|
336
|
+
* lushu.showInfoWindow();
|
|
337
|
+
*/
|
|
338
|
+
LuShu.prototype.showInfoWindow = function () {
|
|
339
|
+
this._overlay._div.style.visibility = 'visible';
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
//Lushu私有方法
|
|
343
|
+
baidu.object.extend(LuShu.prototype, {
|
|
344
|
+
/**
|
|
345
|
+
* 添加marker到地图上
|
|
346
|
+
* @param {Function} 回调函数.
|
|
347
|
+
* @return 无返回值.
|
|
348
|
+
*/
|
|
349
|
+
_addMarker: function (callback) {
|
|
350
|
+
if (this._marker) {
|
|
351
|
+
this.stop();
|
|
352
|
+
// 变更
|
|
353
|
+
this._map.removeOverlay(this._marker);
|
|
354
|
+
this._map.removeOverlay(this._markerL);
|
|
355
|
+
this._map.removeOverlay(this._markerR);
|
|
356
|
+
clearTimeout(this._timeoutFlag);
|
|
357
|
+
}
|
|
358
|
+
//移除之前的overlay
|
|
359
|
+
this._overlay && this._map.removeOverlay(this._overlay);
|
|
360
|
+
var marker = new BMapGL.Marker(this.path[0]);
|
|
361
|
+
this._opts.icon && marker.setIcon(this._opts.icon);
|
|
362
|
+
this._map.addOverlay(marker);
|
|
363
|
+
marker.setAnimation(BMAP_ANIMATION_DROP);
|
|
364
|
+
this._marker = marker;
|
|
365
|
+
// 变更
|
|
366
|
+
var markerL = new BMapGL.Marker(this.path[0], { left: true });
|
|
367
|
+
this._opts.icon && markerL.setIcon(this._opts.icon);
|
|
368
|
+
this._map.addOverlay(markerL);
|
|
369
|
+
markerL.setAnimation(BMAP_ANIMATION_DROP);
|
|
370
|
+
this._markerL = markerL;
|
|
371
|
+
|
|
372
|
+
var markerR = new BMapGL.Marker(this.path[0], { right: true });
|
|
373
|
+
this._opts.icon && markerR.setIcon(this._opts.icon);
|
|
374
|
+
this._map.addOverlay(markerR);
|
|
375
|
+
markerR.setAnimation(BMAP_ANIMATION_DROP);
|
|
376
|
+
this._markerR = markerR;
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* 添加上方overlay
|
|
381
|
+
* @return 无返回值.
|
|
382
|
+
*/
|
|
383
|
+
_addInfoWin: function () {
|
|
384
|
+
var me = this;
|
|
385
|
+
var overlay = new CustomOverlay(me._marker.getPosition(), me._opts.defaultContent);
|
|
386
|
+
//将当前类的引用传给overlay。
|
|
387
|
+
overlay.setRelatedClass(this);
|
|
388
|
+
this._overlay = overlay;
|
|
389
|
+
this._map.addOverlay(overlay);
|
|
390
|
+
},
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* 获取墨卡托坐标
|
|
394
|
+
* @param {Point} poi 经纬度坐标.
|
|
395
|
+
* @return 无返回值.
|
|
396
|
+
*/
|
|
397
|
+
_getMercator: function (poi) {
|
|
398
|
+
return this._map.getMapType().getProjection().lngLatToPoint(poi);
|
|
399
|
+
},
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* 计算两点间的距离
|
|
403
|
+
* @param {Point} poi 经纬度坐标A点.
|
|
404
|
+
* @param {Point} poi 经纬度坐标B点.
|
|
405
|
+
* @return 无返回值.
|
|
406
|
+
*/
|
|
407
|
+
_getDistance: function (pxA, pxB) {
|
|
408
|
+
return Math.sqrt(Math.pow(pxA.x - pxB.x, 2) + Math.pow(pxA.y - pxB.y, 2));
|
|
409
|
+
},
|
|
410
|
+
|
|
411
|
+
//目标点的 当前的步长,position,总的步长,动画效果,回调
|
|
412
|
+
/**
|
|
413
|
+
* 移动小车
|
|
414
|
+
* @param {Number} poi 当前的步长.
|
|
415
|
+
* @param {Point} initPos 经纬度坐标初始点.
|
|
416
|
+
* @param {Point} targetPos 经纬度坐标目标点.
|
|
417
|
+
* @param {Function} effect 缓动效果.
|
|
418
|
+
* @return 无返回值.
|
|
419
|
+
*/
|
|
420
|
+
_move: function (initPos, targetPos, effect) {
|
|
421
|
+
var me = this,
|
|
422
|
+
//当前的帧数
|
|
423
|
+
currentCount = 0,
|
|
424
|
+
//步长,米/秒
|
|
425
|
+
timer = 10,
|
|
426
|
+
step = this._opts.speed / (1000 / timer),
|
|
427
|
+
//初始坐标
|
|
428
|
+
init_pos = BMapGL.Projection.convertLL2MC(initPos),
|
|
429
|
+
//获取结束点的(x,y)坐标
|
|
430
|
+
target_pos = BMapGL.Projection.convertLL2MC(targetPos);
|
|
431
|
+
init_pos = new BMapGL.Pixel(init_pos.lng, init_pos.lat);
|
|
432
|
+
target_pos = new BMapGL.Pixel(target_pos.lng, target_pos.lat);
|
|
433
|
+
// 变更
|
|
434
|
+
var mcDis = me._getDistance(init_pos, target_pos);
|
|
435
|
+
var direction = null;
|
|
436
|
+
if (mcDis > 30037726) {
|
|
437
|
+
if (target_pos.x < init_pos.x) {
|
|
438
|
+
target_pos.x += WORLD_SIZE_MC;
|
|
439
|
+
direction = 'right';
|
|
440
|
+
} else {
|
|
441
|
+
target_pos.x -= WORLD_SIZE_MC;
|
|
442
|
+
direction = 'left';
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
//总的步长
|
|
446
|
+
var count = Math.round(me._getDistance(init_pos, target_pos) / step);
|
|
447
|
+
|
|
448
|
+
//如果小于1直接移动到下一点
|
|
449
|
+
if (count < 1) {
|
|
450
|
+
const t = setTimeout(() => {
|
|
451
|
+
me._moveNext(++me.i);
|
|
452
|
+
}, 0)
|
|
453
|
+
me._setTimeoutQuene.push(t);
|
|
454
|
+
}
|
|
455
|
+
//两点之间匀速移动
|
|
456
|
+
me._intervalFlag = setInterval(function () {
|
|
457
|
+
//两点之间当前帧数大于总帧数的时候,则说明已经完成移动
|
|
458
|
+
if (currentCount >= count) {
|
|
459
|
+
clearInterval(me._intervalFlag);
|
|
460
|
+
//移动的点已经超过总的长度
|
|
461
|
+
if (me.i > me.path.length) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
//运行下一个点
|
|
465
|
+
me._moveNext(++me.i);
|
|
466
|
+
} else {
|
|
467
|
+
currentCount++;
|
|
468
|
+
var x = effect(init_pos.x, target_pos.x, currentCount, count),
|
|
469
|
+
y = effect(init_pos.y, target_pos.y, currentCount, count),
|
|
470
|
+
pos = BMapGL.Projection.convertMC2LL(new BMapGL.Point(x, y));
|
|
471
|
+
if (pos.lng > 180) {
|
|
472
|
+
pos.lng = pos.lng - 360;
|
|
473
|
+
}
|
|
474
|
+
if (pos.lng < -180) {
|
|
475
|
+
pos.lng = pos.lng + 360;
|
|
476
|
+
}
|
|
477
|
+
//设置marker
|
|
478
|
+
if (currentCount == 1) {
|
|
479
|
+
var proPos = null;
|
|
480
|
+
if (me.i - 1 >= 0) {
|
|
481
|
+
proPos = me.path[me.i - 1];
|
|
482
|
+
}
|
|
483
|
+
if (me._opts.enableRotation == true) {
|
|
484
|
+
me.setRotation(proPos, initPos, targetPos, direction);
|
|
485
|
+
}
|
|
486
|
+
if (me._opts.autoView) {
|
|
487
|
+
if (!me._map.getBounds().containsPoint(pos)) {
|
|
488
|
+
me._map.setCenter(pos);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
// 变更
|
|
493
|
+
//正在移动
|
|
494
|
+
me._marker.setPosition(pos);
|
|
495
|
+
me._markerL.setPosition(pos);
|
|
496
|
+
me._markerR.setPosition(pos);
|
|
497
|
+
//设置自定义overlay的位置
|
|
498
|
+
me._setInfoWin(pos);
|
|
499
|
+
}
|
|
500
|
+
}, timer);
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* 在每个点的真实步骤中设置小车转动的角度
|
|
505
|
+
*/
|
|
506
|
+
setRotation: function (prePos, curPos, targetPos, direction) {
|
|
507
|
+
var me = this;
|
|
508
|
+
var deg = 0;
|
|
509
|
+
//start!
|
|
510
|
+
curPos = me._map.pointToPixel(curPos);
|
|
511
|
+
targetPos = me._map.pointToPixel(targetPos);
|
|
512
|
+
|
|
513
|
+
if (targetPos.x != curPos.x) {
|
|
514
|
+
var tan = (targetPos.y - curPos.y) / (targetPos.x - curPos.x),
|
|
515
|
+
atan = Math.atan(tan);
|
|
516
|
+
deg = atan * 360 / (2 * Math.PI);
|
|
517
|
+
//degree correction;
|
|
518
|
+
if ((!direction && targetPos.x < curPos.x)
|
|
519
|
+
|| (direction === 'left')) {
|
|
520
|
+
deg = -deg + 90 + 90;
|
|
521
|
+
} else {
|
|
522
|
+
deg = -deg;
|
|
523
|
+
}
|
|
524
|
+
// 变更
|
|
525
|
+
me._marker.setRotation(-deg);
|
|
526
|
+
me._markerL.setRotation(-deg);
|
|
527
|
+
me._markerR.setRotation(-deg);
|
|
528
|
+
|
|
529
|
+
} else {
|
|
530
|
+
var disy = targetPos.y - curPos.y;
|
|
531
|
+
var bias = 0;
|
|
532
|
+
if (disy > 0) {
|
|
533
|
+
bias = -1;
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
bias = 1;
|
|
537
|
+
}
|
|
538
|
+
// 变更
|
|
539
|
+
me._marker.setRotation(-bias * 90);
|
|
540
|
+
me._markerL.setRotation(-bias * 90);
|
|
541
|
+
me._markerR.setRotation(-bias * 90);
|
|
542
|
+
}
|
|
543
|
+
return;
|
|
544
|
+
},
|
|
545
|
+
|
|
546
|
+
linePixellength: function (from, to) {
|
|
547
|
+
return Math.sqrt(Math.abs(from.x - to.x) * Math.abs(from.x - to.x) + Math.abs(from.y - to.y) * Math.abs(from.y - to.y));
|
|
548
|
+
|
|
549
|
+
},
|
|
550
|
+
pointToPoint: function (from, to) {
|
|
551
|
+
return Math.abs(from.x - to.x) * Math.abs(from.x - to.x) + Math.abs(from.y - to.y) * Math.abs(from.y - to.y)
|
|
552
|
+
|
|
553
|
+
},
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* 移动到下一个点
|
|
557
|
+
* @param {Number} index 当前点的索引.
|
|
558
|
+
* @return 无返回值.
|
|
559
|
+
*/
|
|
560
|
+
_moveNext: function (index) {
|
|
561
|
+
var me = this;
|
|
562
|
+
// debugger;
|
|
563
|
+
if (index < this.path.length - 1) {
|
|
564
|
+
me._move(me.path[index], me.path[index + 1], me._tween.linear);
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* 设置小车上方infowindow的内容,位置等
|
|
570
|
+
* @param {Point} pos 经纬度坐标点.
|
|
571
|
+
* @return 无返回值.
|
|
572
|
+
*/
|
|
573
|
+
_setInfoWin: function (pos) {
|
|
574
|
+
//设置上方overlay的position
|
|
575
|
+
var me = this;
|
|
576
|
+
if (!me._overlay) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
me._overlay.setPosition(pos, me._marker.getIcon().size);
|
|
580
|
+
var index = me._troughPointIndex(pos);
|
|
581
|
+
if (index != -1) {
|
|
582
|
+
clearInterval(me._intervalFlag);
|
|
583
|
+
me._overlay.setHtml(me._opts.landmarkPois[index].html);
|
|
584
|
+
me._overlay.setPosition(pos, me._marker.getIcon().size);
|
|
585
|
+
me._pauseForView(index);
|
|
586
|
+
} else {
|
|
587
|
+
me._overlay.setHtml(me._opts.defaultContent);
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* 在某个点暂停的时间
|
|
593
|
+
* @param {Number} index 点的索引.
|
|
594
|
+
* @return 无返回值.
|
|
595
|
+
*/
|
|
596
|
+
_pauseForView: function (index) {
|
|
597
|
+
var me = this;
|
|
598
|
+
var t = setTimeout(function () {
|
|
599
|
+
//运行下一个点
|
|
600
|
+
me._moveNext(++me.i);
|
|
601
|
+
}, me._opts.landmarkPois[index].pauseTime * 1000);
|
|
602
|
+
me._setTimeoutQuene.push(t);
|
|
603
|
+
},
|
|
604
|
+
//清除暂停后再开始运行的timeout
|
|
605
|
+
_clearTimeout: function () {
|
|
606
|
+
for (var i in this._setTimeoutQuene) {
|
|
607
|
+
clearTimeout(this._setTimeoutQuene[i]);
|
|
608
|
+
}
|
|
609
|
+
this._setTimeoutQuene.length = 0;
|
|
610
|
+
},
|
|
611
|
+
/**
|
|
612
|
+
* 停止运动并清除overlay
|
|
613
|
+
* @return 无返回值.
|
|
614
|
+
*/
|
|
615
|
+
_clear: function () {
|
|
616
|
+
var me = this;
|
|
617
|
+
if (me._marker) {
|
|
618
|
+
me.stop();
|
|
619
|
+
// 清除overlay
|
|
620
|
+
me._map.removeOverlay(me._marker);
|
|
621
|
+
me._map.removeOverlay(me._markerL);
|
|
622
|
+
me._map.removeOverlay(me._markerR);
|
|
623
|
+
clearTimeout(me._timeoutFlag);
|
|
624
|
+
me._marker = null;
|
|
625
|
+
me._markerL = null;
|
|
626
|
+
me._markerR = null;
|
|
627
|
+
}
|
|
628
|
+
if (me._overlay) {
|
|
629
|
+
// 清除overlay
|
|
630
|
+
me._map.removeOverlay(me._overlay);
|
|
631
|
+
me._overlay = null;
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
//缓动效果
|
|
635
|
+
_tween: {
|
|
636
|
+
//初始坐标,目标坐标,当前的步长,总的步长
|
|
637
|
+
linear: function (initPos, targetPos, currentCount, count) {
|
|
638
|
+
var b = initPos;
|
|
639
|
+
var c = targetPos - initPos;
|
|
640
|
+
var t = currentCount;
|
|
641
|
+
var d = count;
|
|
642
|
+
return c * t / d + b;
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* 否经过某个点的index
|
|
648
|
+
* @param {Point} markerPoi 当前小车的坐标点.
|
|
649
|
+
* @return 无返回值.
|
|
650
|
+
*/
|
|
651
|
+
_troughPointIndex: function (markerPoi) {
|
|
652
|
+
var t = this._opts.landmarkPois;
|
|
653
|
+
var distance;
|
|
654
|
+
for (var i = 0, len = t.length; i < len; i++) {
|
|
655
|
+
//landmarkPois中的点没有出现过的话
|
|
656
|
+
if (!t[i].bShow) {
|
|
657
|
+
distance = this._map.getDistance(new BMapGL.Point(t[i].lng, t[i].lat), markerPoi);
|
|
658
|
+
//两点距离小于10米,认为是同一个点
|
|
659
|
+
if (distance < 10) {
|
|
660
|
+
t[i].bShow = true;
|
|
661
|
+
return i;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
return -1;
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* 获取大圆点
|
|
671
|
+
* @return {Array} 大圆点
|
|
672
|
+
*/
|
|
673
|
+
function getGeodesicPath(points) {
|
|
674
|
+
var gPath = [];
|
|
675
|
+
for (var i = 0; i < points.length - 1; i++) {
|
|
676
|
+
var great = calcGreatCirclePath(points[i], points[i + 1]);
|
|
677
|
+
gPath = gPath.concat(great);
|
|
678
|
+
}
|
|
679
|
+
gPath = gPath.concat(points[points.length - 1])
|
|
680
|
+
return gPath;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* 计算大圆上的点
|
|
685
|
+
* @param {Object} latLng1 点1
|
|
686
|
+
* @param {Object} latLng2 点2
|
|
687
|
+
* @return {Array} 扩充后的点
|
|
688
|
+
*/
|
|
689
|
+
function calcGreatCirclePath(latLng1, latLng2) {
|
|
690
|
+
// 计算需要多少个插值点,根据显示效果,每250公里需要一个。
|
|
691
|
+
if (latLng1.equals(latLng2)) {
|
|
692
|
+
// 两个相等的坐标通过下面距离计算会得到地球周长,因此提前判断
|
|
693
|
+
return [latLng1];
|
|
694
|
+
}
|
|
695
|
+
var distance = BMapGL.Projection.getDistance(toRadian(latLng1.lng), toRadian(latLng1.lat),
|
|
696
|
+
toRadian(latLng2.lng), toRadian(latLng2.lat));
|
|
697
|
+
var distance = BMapGL.Projection.getDistanceByLL(latLng1, latLng2);
|
|
698
|
+
if (distance < 250000) {
|
|
699
|
+
return [latLng1];
|
|
700
|
+
}
|
|
701
|
+
// 清空现有数据
|
|
702
|
+
// this.greatCirclePoints.length = 0;
|
|
703
|
+
var result = [];
|
|
704
|
+
// 间隔设置小于250公里是因为在靠近南北两极同样的公里数所代表的平面跨度增加
|
|
705
|
+
var count = Math.round(distance / 150000);
|
|
706
|
+
var angularDistance = calcAngularDistance(latLng1, latLng2);
|
|
707
|
+
result.push(latLng1);
|
|
708
|
+
|
|
709
|
+
for (var i = 0; i < count; i++) {
|
|
710
|
+
var eachLatLng = calcMiddlePoint(latLng1, latLng2, i / count, angularDistance);
|
|
711
|
+
result.push(eachLatLng);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
result.push(latLng2);
|
|
715
|
+
return result;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* 给两个点,计算地球大圆上的中间点
|
|
720
|
+
* https://www.movable-type.co.uk/scripts/latlong.html
|
|
721
|
+
*
|
|
722
|
+
* @param {Point} latLng1 起点
|
|
723
|
+
* @param {Point} latLng2 终点
|
|
724
|
+
* @param {number} f fraction along great circle route
|
|
725
|
+
* @param {number} delta angular distance d/R between the two points.
|
|
726
|
+
* @return {Point} 大圆上的中间点
|
|
727
|
+
*/
|
|
728
|
+
function calcMiddlePoint(latLng1, latLng2, f, delta) {
|
|
729
|
+
var lat1 = latLng1.lat;
|
|
730
|
+
var lat2 = latLng2.lat;
|
|
731
|
+
var lon1 = latLng1.lng;
|
|
732
|
+
var lon2 = latLng2.lng;
|
|
733
|
+
var phi1 = toRadian(lat1);
|
|
734
|
+
var phi2 = toRadian(lat2);
|
|
735
|
+
var lambda1 = toRadian(lon1);
|
|
736
|
+
var lambda2 = toRadian(lon2);
|
|
737
|
+
var a = Math.sin((1 - f) * delta) / Math.sin(delta);
|
|
738
|
+
var b = Math.sin(f * delta) / Math.sin(delta);
|
|
739
|
+
var x = a * Math.cos(phi1) * Math.cos(lambda1) + b * Math.cos(phi2) * Math.cos(lambda2);
|
|
740
|
+
var y = a * Math.cos(phi1) * Math.sin(lambda1) + b * Math.cos(phi2) * Math.sin(lambda2);
|
|
741
|
+
var z = a * Math.sin(phi1) + b * Math.sin(phi2);
|
|
742
|
+
var phi = Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
|
|
743
|
+
var lambda = Math.atan2(y, x);
|
|
744
|
+
return new BMapGL.Point(toAngle(lambda), toAngle(phi));
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
function toRadian(angle) {
|
|
748
|
+
return angle * Math.PI / 180;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
function toAngle(radian) {
|
|
752
|
+
return radian / Math.PI * 180;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/**
|
|
756
|
+
* 计算角距离
|
|
757
|
+
*
|
|
758
|
+
* @param {Point} latLng1 起点
|
|
759
|
+
* @param {Point} latLng2 终点
|
|
760
|
+
* @return {number} 角距离
|
|
761
|
+
*/
|
|
762
|
+
function calcAngularDistance(latLng1, latLng2) {
|
|
763
|
+
// console.log(latLng1.lat, latLng1.lng, latLng2.lat, latLng2.lng);
|
|
764
|
+
var lat1 = toRadian(latLng1.lat);
|
|
765
|
+
var lat2 = toRadian(latLng2.lat);
|
|
766
|
+
var lng1 = toRadian(latLng1.lng);
|
|
767
|
+
var lng2 = toRadian(latLng2.lng);
|
|
768
|
+
return Math.acos(Math.sin(lat1) * Math.sin(lat2)
|
|
769
|
+
+ Math.cos(lat1) * Math.cos(lat2) * Math.cos(Math.abs(lng2 - lng1)));
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* 自定义的overlay,显示在小车的上方
|
|
774
|
+
* @param {Point} Point 要定位的点.
|
|
775
|
+
* @param {String} html overlay中要显示的东西.
|
|
776
|
+
* @return 无返回值.
|
|
777
|
+
*/
|
|
778
|
+
function CustomOverlay(point, html) {
|
|
779
|
+
this._point = point;
|
|
780
|
+
this._html = html;
|
|
781
|
+
}
|
|
782
|
+
CustomOverlay.prototype = new BMapGL.Overlay();
|
|
783
|
+
CustomOverlay.prototype.initialize = function (map) {
|
|
784
|
+
var div = this._div = baidu.dom.create('div', { style: 'border:solid 1px #ccc;width:auto;min-width:50px;text-align:center;position:absolute;background:#fff;color:#000;font-size:12px;border-radius: 10px;padding:5px;white-space: nowrap;' });
|
|
785
|
+
div.innerHTML = this._html;
|
|
786
|
+
map.getPanes().floatPane.appendChild(div);
|
|
787
|
+
this._map = map;
|
|
788
|
+
return div;
|
|
789
|
+
}
|
|
790
|
+
CustomOverlay.prototype.draw = function () {
|
|
791
|
+
this.setPosition(this.lushuMain._marker.getPosition(), this.lushuMain._marker.getIcon().size);
|
|
792
|
+
}
|
|
793
|
+
baidu.object.extend(CustomOverlay.prototype, {
|
|
794
|
+
//设置overlay的position
|
|
795
|
+
setPosition: function (poi, markerSize) {
|
|
796
|
+
// 此处的bug已修复,感谢 苗冬(diligentcat@gmail.com) 的细心查看和认真指出
|
|
797
|
+
var px = this._map.pointToOverlayPixel(poi);
|
|
798
|
+
var styleW = baidu.dom.getStyle(this._div, 'width');
|
|
799
|
+
var styleH = baidu.dom.getStyle(this._div, 'height');
|
|
800
|
+
var overlayW = parseInt(this._div.clientWidth || styleW, 10);
|
|
801
|
+
var overlayH = parseInt(this._div.clientHeight || styleH, 10);
|
|
802
|
+
this._div.style.left = px.x - overlayW / 2 + 'px';
|
|
803
|
+
this._div.style.bottom = -(px.y - markerSize.height) + 'px';
|
|
804
|
+
},
|
|
805
|
+
//设置overlay的内容
|
|
806
|
+
setHtml: function (html) {
|
|
807
|
+
this._div.innerHTML = html;
|
|
808
|
+
},
|
|
809
|
+
//跟customoverlay相关的实例的引用
|
|
810
|
+
setRelatedClass: function (lushuMain) {
|
|
811
|
+
this.lushuMain = lushuMain;
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
})();
|
|
815
|
+
|