You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							445 lines
						
					
					
						
							16 KiB
						
					
					
				
			
		
		
	
	
							445 lines
						
					
					
						
							16 KiB
						
					
					
				| (function (root, factory) {  
 | |
|     if (typeof exports === 'object') {  
 | |
|         module.exports = factory();
 | |
|     } else if (typeof define === 'function' && define.amd) {  
 | |
|         define(factory);  
 | |
|     } else {
 | |
|         root.BMapLib = root.BMapLib || {};
 | |
|         root.BMapLib.LuShu = root.BMapLib.Lushu || factory();  
 | |
|     }  
 | |
| })(this, function() {
 | |
|     var baidu = {};
 | |
|     baidu.dom = {};
 | |
|     baidu.dom.g = function(id) {
 | |
|         if ('string' == typeof id || id instanceof String) {
 | |
|             return document.getElementById(id);
 | |
|         } else if (id && id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {
 | |
|             return id;
 | |
|         }
 | |
|         return null;
 | |
|     };
 | |
|     baidu.g = baidu.G = baidu.dom.g;
 | |
|     baidu.lang = baidu.lang || {};
 | |
|     baidu.lang.isString = function(source) {
 | |
|         return '[object String]' == Object.prototype.toString.call(source);
 | |
|     };
 | |
|     baidu.isString = baidu.lang.isString;
 | |
|     baidu.dom._g = function(id) {
 | |
|         if (baidu.lang.isString(id)) {
 | |
|             return document.getElementById(id);
 | |
|         }
 | |
|         return id;
 | |
|     };
 | |
|     baidu._g = baidu.dom._g;
 | |
|     baidu.dom.getDocument = function(element) {
 | |
|         element = baidu.dom.g(element);
 | |
|         return element.nodeType == 9 ? element : element.ownerDocument || element.document;
 | |
|     };
 | |
|     baidu.browser = baidu.browser || {};
 | |
|     baidu.browser.ie = baidu.ie = /msie (\d+\.\d+)/i.test(navigator.userAgent) ? (document.documentMode || + RegExp['\x241']) : undefined;
 | |
|     baidu.dom.getComputedStyle = function(element, key) {
 | |
|         element = baidu.dom._g(element);
 | |
|         var doc = baidu.dom.getDocument(element),
 | |
|             styles;
 | |
|         if (doc.defaultView && doc.defaultView.getComputedStyle) {
 | |
|             styles = doc.defaultView.getComputedStyle(element, null);
 | |
|             if (styles) {
 | |
|                 return styles[key] || styles.getPropertyValue(key);
 | |
|             }
 | |
|         }
 | |
|         return '';
 | |
|     };
 | |
|     baidu.dom._styleFixer = baidu.dom._styleFixer || {};
 | |
|     baidu.dom._styleFilter = baidu.dom._styleFilter || [];
 | |
|     baidu.dom._styleFilter.filter = function(key, value, method) {
 | |
|         for (var i = 0, filters = baidu.dom._styleFilter, filter; filter = filters[i]; i++) {
 | |
|             if (filter = filter[method]) {
 | |
|                 value = filter(key, value);
 | |
|             }
 | |
|         }
 | |
|         return value;
 | |
|     };
 | |
|     baidu.string = baidu.string || {};
 | |
|     baidu.string.toCamelCase = function(source) {
 | |
| 
 | |
|         if (source.indexOf('-') < 0 && source.indexOf('_') < 0) {
 | |
|             return source;
 | |
|         }
 | |
|         return source.replace(/[-_][^-_]/g, function(match) {
 | |
|             return match.charAt(1).toUpperCase();
 | |
|         });
 | |
|     };
 | |
|     baidu.dom.getStyle = function(element, key) {
 | |
|         var dom = baidu.dom;
 | |
|         element = dom.g(element);
 | |
|         key = baidu.string.toCamelCase(key);
 | |
| 
 | |
|         var value = element.style[key] ||
 | |
|                     (element.currentStyle ? element.currentStyle[key] : '') ||
 | |
|                     dom.getComputedStyle(element, key);
 | |
| 
 | |
|         if (!value) {
 | |
|             var fixer = dom._styleFixer[key];
 | |
|             if (fixer) {
 | |
|                 value = fixer.get ? fixer.get(element) : baidu.dom.getStyle(element, fixer);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (fixer = dom._styleFilter) {
 | |
|             value = fixer.filter(key, value, 'get');
 | |
|         }
 | |
|         return value;
 | |
|     };
 | |
|     baidu.getStyle = baidu.dom.getStyle;
 | |
|     baidu.dom._NAME_ATTRS = (function() {
 | |
|         var result = {
 | |
|             'cellpadding': 'cellPadding',
 | |
|             'cellspacing': 'cellSpacing',
 | |
|             'colspan': 'colSpan',
 | |
|             'rowspan': 'rowSpan',
 | |
|             'valign': 'vAlign',
 | |
|             'usemap': 'useMap',
 | |
|             'frameborder': 'frameBorder'
 | |
|         };
 | |
| 
 | |
|         if (baidu.browser.ie < 8) {
 | |
|             result['for'] = 'htmlFor';
 | |
|             result['class'] = 'className';
 | |
|         } else {
 | |
|             result['htmlFor'] = 'for';
 | |
|             result['className'] = 'class';
 | |
|         }
 | |
| 
 | |
|         return result;
 | |
|     })();
 | |
|     baidu.dom.setAttr = function(element, key, value) {
 | |
|         element = baidu.dom.g(element);
 | |
|         if ('style' == key) {
 | |
|             element.style.cssText = value;
 | |
|         } else {
 | |
|             key = baidu.dom._NAME_ATTRS[key] || key;
 | |
|             element.setAttribute(key, value);
 | |
|         }
 | |
|         return element;
 | |
|     };
 | |
|     baidu.setAttr = baidu.dom.setAttr;
 | |
|     baidu.dom.setAttrs = function(element, attributes) {
 | |
|         element = baidu.dom.g(element);
 | |
|         for (var key in attributes) {
 | |
|             baidu.dom.setAttr(element, key, attributes[key]);
 | |
|         }
 | |
|         return element;
 | |
|     };
 | |
|     baidu.setAttrs = baidu.dom.setAttrs;
 | |
|     baidu.dom.create = function(tagName, opt_attributes) {
 | |
|         var el = document.createElement(tagName),
 | |
|             attributes = opt_attributes || {};
 | |
|         return baidu.dom.setAttrs(el, attributes);
 | |
|     };
 | |
|     baidu.object = baidu.object || {};
 | |
|     baidu.extend =
 | |
|     baidu.object.extend = function(target, source) {
 | |
|         for (var p in source) {
 | |
|             if (source.hasOwnProperty(p)) {
 | |
|                 target[p] = source[p];
 | |
|             }
 | |
|         }
 | |
|         return target;
 | |
|     };
 | |
| 
 | |
|     /**
 | |
|      * @exports LuShu as BMapLib.LuShu
 | |
|      */
 | |
|     var LuShu = function(map, path, opts) {
 | |
|         try {
 | |
|             BMap;
 | |
|         } catch (e) {
 | |
|             throw Error('Baidu Map JS API is not ready yet!');
 | |
|         }
 | |
|         if (!path || path.length < 1) {
 | |
|             return;
 | |
|         }
 | |
|         this._map = map;
 | |
|         this._path = path;
 | |
|         this.i = 0;
 | |
|         this._setTimeoutQuene = [];
 | |
|         this._projection = this._map.getMapType().getProjection();
 | |
|         this._opts = {
 | |
|             icon: null,
 | |
|             speed: 4000,
 | |
|             defaultContent: '',
 | |
|             showInfoWindow: false
 | |
|         };
 | |
|         this._setOptions(opts);
 | |
|         this._rotation = 0;
 | |
| 
 | |
|         if (!this._opts.icon instanceof BMap.Icon) {
 | |
|             this._opts.icon = defaultIcon;
 | |
|         }
 | |
|     }
 | |
|     LuShu.prototype._setOptions = function(opts) {
 | |
|         if (!opts) {
 | |
|             return;
 | |
|         }
 | |
|         for (var p in opts) {
 | |
|             if (opts.hasOwnProperty(p)) {
 | |
|                 this._opts[p] = opts[p];
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     LuShu.prototype.start = function() {
 | |
|         var me = this,
 | |
|             len = me._path.length;
 | |
|         this._opts.onstart && this._opts.onstart(me)
 | |
|         if (me.i && me.i < len - 1) {
 | |
|             if (!me._fromPause) {
 | |
|                 return;
 | |
|             }else if(!me._fromStop){
 | |
| 	            me._moveNext(++me.i);
 | |
|             }
 | |
|         }else {
 | |
|             !me._marker && me._addMarker();
 | |
|             me._timeoutFlag = setTimeout(function() {
 | |
|                     !me._overlay && me._addInfoWin();
 | |
|                     me._moveNext(me.i);
 | |
|             },400);
 | |
|         }
 | |
|         this._fromPause = false;
 | |
|         this._fromStop = false;
 | |
|     },
 | |
|     LuShu.prototype.stop = function() {
 | |
|         this.i = 0;
 | |
|         this._fromStop = true;
 | |
|         clearInterval(this._intervalFlag);
 | |
|         this._clearTimeout();
 | |
|         for (var i = 0, t = this._opts.landmarkPois, len = t.length; i < len; i++) {
 | |
|             t[i].bShow = false;
 | |
|         }
 | |
|         this._opts.onstop && this._opts.onstop(this)
 | |
|     };
 | |
|     LuShu.prototype.pause = function() {
 | |
|         clearInterval(this._intervalFlag);
 | |
|         this._fromPause = true;
 | |
|         this._clearTimeout();
 | |
|         this._opts.onpause && this._opts.onpause(this)
 | |
|     };
 | |
|     LuShu.prototype.hideInfoWindow = function() {
 | |
|         this._opts.showInfoWindow = false;
 | |
|         this._overlay && (this._overlay._div.style.visibility = 'hidden');
 | |
|     };
 | |
|     LuShu.prototype.showInfoWindow = function() {
 | |
|         this._opts.showInfoWindow = true;
 | |
|         this._overlay && (this._overlay._div.style.visibility = 'visible');
 | |
|     };
 | |
|     LuShu.prototype.dispose = function () {
 | |
|         clearInterval(this._intervalFlag);
 | |
|         this._setTimeoutQuene && this._clearTimeout();
 | |
|         if (this._map) {
 | |
|             this._map.removeOverlay(this._overlay);
 | |
|             this._map.removeOverlay(this._marker);
 | |
|         }
 | |
|     };
 | |
|     baidu.object.extend(LuShu.prototype, {
 | |
|         _addMarker: function(callback) {
 | |
|             if (this._marker) {
 | |
|                 this.stop();
 | |
|                 this._map.removeOverlay(this._marker);
 | |
|                 clearTimeout(this._timeoutFlag);
 | |
|             }
 | |
|             this._overlay && this._map.removeOverlay(this._overlay);
 | |
|             var marker = new BMap.Marker(this._path[0]);
 | |
|             this._opts.icon && marker.setIcon(this._opts.icon);
 | |
|             this._map.addOverlay(marker);
 | |
|             marker.setAnimation(BMAP_ANIMATION_DROP);
 | |
|             this._marker = marker;
 | |
|         },
 | |
|         _addInfoWin: function() {
 | |
|             var me = this;
 | |
|             !CustomOverlay.prototype.initialize && initCustomOverlay();
 | |
|             var overlay = new CustomOverlay(me._marker.getPosition(), me._opts.defaultContent);
 | |
|             overlay.setRelatedClass(this);
 | |
|             this._overlay = overlay;
 | |
|             this._map.addOverlay(overlay);
 | |
|             this._opts.showInfoWindow ? this.showInfoWindow() : this.hideInfoWindow()
 | |
|         },
 | |
|         _getMercator: function(poi) {
 | |
|             return this._map.getMapType().getProjection().lngLatToPoint(poi);
 | |
|         },
 | |
|         _getDistance: function(pxA, pxB) {
 | |
|             return Math.sqrt(Math.pow(pxA.x - pxB.x, 2) + Math.pow(pxA.y - pxB.y, 2));
 | |
|         },
 | |
|         _move: function(initPos,targetPos,effect) {
 | |
|             var me = this,
 | |
|                 currentCount = 0,
 | |
|                 timer = 10,
 | |
|                 step = this._opts.speed / (1000 / timer),
 | |
|                 init_pos = this._projection.lngLatToPoint(initPos),
 | |
|                 target_pos = this._projection.lngLatToPoint(targetPos),
 | |
|                 count = Math.round(me._getDistance(init_pos, target_pos) / step);
 | |
|             if (count < 1) {
 | |
|                 me._moveNext(++me.i);
 | |
|                 return;
 | |
|             }
 | |
|             me._intervalFlag = setInterval(function() {
 | |
| 	            if (currentCount >= count) {
 | |
| 	                clearInterval(me._intervalFlag);
 | |
| 		        	if(me.i > me._path.length){
 | |
| 						return;
 | |
| 		        	}
 | |
| 	                me._moveNext(++me.i);
 | |
| 	            } else {
 | |
|                     currentCount++;
 | |
|                     var x = effect(init_pos.x, target_pos.x, currentCount, count),
 | |
|                         y = effect(init_pos.y, target_pos.y, currentCount, count),
 | |
|                         pos = me._projection.pointToLngLat(new BMap.Pixel(x, y));
 | |
|                     if(currentCount == 1){
 | |
|                         var proPos = null;
 | |
|                         if(me.i - 1 >= 0){
 | |
|                             proPos = me._path[me.i - 1];
 | |
|                         }
 | |
|                         if(me._opts.enableRotation == true){
 | |
|                             me.setRotation(proPos,initPos,targetPos);
 | |
|                         }
 | |
|                         if(me._opts.autoView){
 | |
|                             if(!me._map.getBounds().containsPoint(pos)){
 | |
|                                 me._map.setCenter(pos);
 | |
|                             }   
 | |
|                         }
 | |
|                     }
 | |
|                     me._marker.setPosition(pos);
 | |
|                     me._setInfoWin(pos);
 | |
|                 }
 | |
| 	        },timer);
 | |
|         },
 | |
|         setRotation : function(prePos,curPos,targetPos){
 | |
|             var me = this;
 | |
|             var deg = 0;
 | |
|             //start!
 | |
|             curPos =  me._map.pointToPixel(curPos);
 | |
|             targetPos =  me._map.pointToPixel(targetPos);   
 | |
| 
 | |
|             if(targetPos.x != curPos.x){
 | |
|                 var tan = (targetPos.y - curPos.y)/(targetPos.x - curPos.x),
 | |
|                 atan  = Math.atan(tan);
 | |
|                 deg = atan*360/(2*Math.PI);
 | |
|                 //degree  correction;
 | |
|                 if(targetPos.x < curPos.x){
 | |
|                     deg = -deg + 90 + 90;
 | |
| 
 | |
|                 } else {
 | |
|                     deg = -deg;
 | |
|                 }
 | |
| 
 | |
|                 me._marker.setRotation(-deg);   
 | |
| 
 | |
|             }else {
 | |
|                 var disy = targetPos.y- curPos.y ;
 | |
|                 var bias = 0;
 | |
|                 if(disy > 0)
 | |
|                     bias=-1
 | |
|                 else
 | |
|                     bias = 1
 | |
|                 me._marker.setRotation(-bias * 90);  
 | |
|             }
 | |
|             return;
 | |
|         },
 | |
|         linePixellength : function(from,to){ 
 | |
|             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) );
 | |
|         },
 | |
|         pointToPoint : function(from,to ){
 | |
|             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)
 | |
|         },
 | |
|         _moveNext: function(index) {
 | |
|             var me = this;
 | |
|             if (index < this._path.length - 1) {
 | |
|                 me._move(me._path[index], me._path[index + 1], me._tween.linear);
 | |
|             } else {
 | |
|                 me.stop()
 | |
|             }
 | |
|         },
 | |
|         _setInfoWin: function(pos) {
 | |
|             var me = this;
 | |
|             me._overlay.setPosition(pos, me._marker.getIcon().size);
 | |
|             var index = me._troughPointIndex(pos);
 | |
|             if (index != -1) {
 | |
|                 clearInterval(me._intervalFlag);
 | |
|                 me._overlay.setHtml(me._opts.landmarkPois[index].html);
 | |
|                 me._overlay.setPosition(pos, me._marker.getIcon().size);
 | |
|                 me._pauseForView(index);
 | |
|             }else {
 | |
|                 me._overlay.setHtml(me._opts.defaultContent);
 | |
|             }
 | |
|         },
 | |
|         _pauseForView: function(index) {
 | |
|             var me = this;
 | |
|             var t = setTimeout(function() {
 | |
|                 me._moveNext(++me.i);
 | |
|             },me._opts.landmarkPois[index].pauseTime * 1000);
 | |
|             me._setTimeoutQuene.push(t);
 | |
|         },
 | |
|         _clearTimeout: function() {
 | |
|             for (var i in this._setTimeoutQuene) {
 | |
|                 clearTimeout(this._setTimeoutQuene[i]);
 | |
|             }
 | |
|             this._setTimeoutQuene.length = 0;
 | |
|         },
 | |
|         _tween: {
 | |
|             linear: function(initPos, targetPos, currentCount, count) {
 | |
|                 var b = initPos, c = targetPos - initPos, t = currentCount,
 | |
|                 d = count;
 | |
|                 return c * t / d + b;
 | |
|             }
 | |
|         },
 | |
|         _troughPointIndex: function(markerPoi) {
 | |
|             var t = this._opts.landmarkPois, distance;
 | |
|             for (var i = 0, len = t.length; i < len; i++) {
 | |
|                 if (!t[i].bShow) {
 | |
|                     distance = this._map.getDistance(new BMap.Point(t[i].lng, t[i].lat), markerPoi);
 | |
|                     if (distance < 10) {
 | |
|                         t[i].bShow = true;
 | |
|                         return i;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|            return -1;
 | |
|         }
 | |
|     });
 | |
|     function CustomOverlay(point,html) {
 | |
|         this._point = point;
 | |
|         this._html = html;
 | |
|     }
 | |
| 
 | |
|     function initCustomOverlay() {
 | |
|         CustomOverlay.prototype = new BMap.Overlay();
 | |
|         CustomOverlay.prototype.initialize = function(map) {
 | |
|             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;'});
 | |
|             div.innerHTML = this._html;
 | |
|             map.getPanes().floatPane.appendChild(div);
 | |
|             this._map = map;
 | |
|             return div;
 | |
|         }
 | |
|         CustomOverlay.prototype.draw = function() {
 | |
|             this.setPosition(this.lushuMain._marker.getPosition(), this.lushuMain._marker.getIcon().size);
 | |
|         }
 | |
|         baidu.object.extend(CustomOverlay.prototype, {
 | |
|             setPosition: function(poi,markerSize) {
 | |
|                 var px = this._map.pointToOverlayPixel(poi),
 | |
|                     styleW = baidu.dom.getStyle(this._div, 'width'),
 | |
|                     styleH = baidu.dom.getStyle(this._div, 'height'),
 | |
|                     overlayW = parseInt(this._div.clientWidth || styleW, 10),
 | |
|                     overlayH = parseInt(this._div.clientHeight || styleH, 10);
 | |
|                 this._div.style.left = px.x - overlayW / 2 + 'px';
 | |
|                 this._div.style.bottom = -(px.y - markerSize.height) + 'px';
 | |
|             },
 | |
|             setHtml: function(html) {
 | |
|                 this._div.innerHTML = html;
 | |
|             },
 | |
|             setRelatedClass: function(lushuMain) {
 | |
|                 this.lushuMain = lushuMain;
 | |
|             }
 | |
|         });
 | |
|     }
 | |
| 
 | |
|     return LuShu
 | |
| });
 |