You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1783 lines
64 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* @fileoverview 百度地图的测距工具类,对外开放。
* 允许用户在地图上点击完成距离的测量。
* 使用者可以自定义测距线段的相关样式,例如线宽、颜色、测距结果所用的单位制等等。
* 主入口类是<a href="symbols/BMapLib.DistanceTool.html">DistanceTool</a>
* 基于Baidu Map API 1.2。
*
* @author Baidu Map Api Group
* @version 1.2
*/
/**
* @namespace BMap的所有library类均放在BMapLib命名空间下
*/
(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.Heatmap = root.BMapLib.DistanceTool || factory();
}
})(this, function() {
var baidu = baidu || {guid : "$BAIDU$"};
var context = {};
(function() {
// 一些页面级别唯一的属性需要挂载在window[baidu.guid]上
context[baidu.guid] = {};
/**
* 将源对象的所有属性拷贝到目标对象中
* @name baidu.extend
* @function
* @grammar baidu.extend(target, source)
* @param {Object} target 目标对象
* @param {Object} source 源对象
* @returns {Object} 目标对象
*/
baidu.extend = function (target, source) {
for (var p in source) {
if (source.hasOwnProperty(p)) {
target[p] = source[p];
}
}
return target;
};
/**
* @ignore
* @namespace
* @baidu.lang 对语言层面的封装,包括类型判断、模块扩展、继承基类以及对象自定义事件的支持。
* @property guid 对象的唯一标识
*/
baidu.lang = baidu.lang || {};
/**
* 返回一个当前页面的唯一标识字符串。
* @function
* @grammar baidu.lang.guid()
* @returns {String} 当前页面的唯一标识字符串
*/
baidu.lang.guid = function() {
return "TANGRAM__" + (context[baidu.guid]._counter ++).toString(36);
};
context[baidu.guid]._counter = context[baidu.guid]._counter || 1;
/**
* 所有类的实例的容器
* key为每个实例的guid
*/
context[baidu.guid]._instances = context[baidu.guid]._instances || {};
/**
* Tangram继承机制提供的一个基类用户可以通过继承baidu.lang.Class来获取它的属性及方法。
* @function
* @name baidu.lang.Class
* @grammar baidu.lang.Class(guid)
* @param {string} guid 对象的唯一标识
* @meta standard
* @remark baidu.lang.Class和它的子类的实例均包含一个全局唯一的标识guid。
* guid是在构造函数中生成的因此继承自baidu.lang.Class的类应该直接或者间接调用它的构造函数。<br>
* baidu.lang.Class的构造函数中产生guid的方式可以保证guid的唯一性及每个实例都有一个全局唯一的guid。
*/
baidu.lang.Class = function(guid) {
this.guid = guid || baidu.lang.guid();
context[baidu.guid]._instances[this.guid] = this;
};
context[baidu.guid]._instances = context[baidu.guid]._instances || {};
/**
* 判断目标参数是否string类型或String对象
* @name baidu.lang.isString
* @function
* @grammar baidu.lang.isString(source)
* @param {Any} source 目标参数
* @shortcut isString
* @meta standard
*
* @returns {boolean} 类型判断结果
*/
baidu.lang.isString = function (source) {
return '[object String]' == Object.prototype.toString.call(source);
};
/**
* 判断目标参数是否为function或Function实例
* @name baidu.lang.isFunction
* @function
* @grammar baidu.lang.isFunction(source)
* @param {Any} source 目标参数
* @returns {boolean} 类型判断结果
*/
baidu.lang.isFunction = function (source) {
return '[object Function]' == Object.prototype.toString.call(source);
};
/**
* 重载了默认的toString方法使得返回信息更加准确一些。
* @return {string} 对象的String表示形式
*/
baidu.lang.Class.prototype.toString = function(){
return "[object " + (this._className || "Object" ) + "]";
};
/**
* 释放对象所持有的资源,主要是自定义事件。
* @name dispose
* @grammar obj.dispose()
*/
baidu.lang.Class.prototype.dispose = function(){
delete context[baidu.guid]._instances[this.guid];
for(var property in this){
if (!baidu.lang.isFunction(this[property])) {
delete this[property];
}
}
this.disposed = true;
};
/**
* 自定义的事件对象。
* @function
* @name baidu.lang.Event
* @grammar baidu.lang.Event(type[, target])
* @param {string} type 事件类型名称。为了方便区分事件和一个普通的方法,事件类型名称必须以"on"(小写)开头。
* @param {Object} [target]触发事件的对象
* @meta standard
* @remark 引入该模块会自动为Class引入3个事件扩展方法addEventListener、removeEventListener和dispatchEvent。
* @see baidu.lang.Class
*/
baidu.lang.Event = function (type, target) {
this.type = type;
this.returnValue = true;
this.target = target || null;
this.currentTarget = null;
};
/**
* 注册对象的事件监听器。引入baidu.lang.Event后Class的子类实例才会获得该方法。
* @grammar obj.addEventListener(type, handler[, key])
* @param {string} type 自定义事件的名称
* @param {Function} handler 自定义事件被触发时应该调用的回调函数
* @param {string} [key] 为事件监听函数指定的名称可在移除时使用。如果不提供方法会默认为它生成一个全局唯一的key。
* @remark 事件类型区分大小写。如果自定义事件名称不是以小写"on"开头,该方法会给它加上"on"再进行判断,即"click"和"onclick"会被认为是同一种事件。
*/
baidu.lang.Class.prototype.addEventListener = function (type, handler, key) {
if (!baidu.lang.isFunction(handler)) {
return;
}
!this.__listeners && (this.__listeners = {});
var t = this.__listeners, id;
if (typeof key == "string" && key) {
if (/[^\w\-]/.test(key)) {
throw("nonstandard key:" + key);
} else {
handler.hashCode = key;
id = key;
}
}
type.indexOf("on") != 0 && (type = "on" + type);
typeof t[type] != "object" && (t[type] = {});
id = id || baidu.lang.guid();
handler.hashCode = id;
t[type][id] = handler;
};
/**
* 移除对象的事件监听器。引入baidu.lang.Event后Class的子类实例才会获得该方法。
* @grammar obj.removeEventListener(type, handler)
* @param {string} type 事件类型
* @param {Function|string} handler 要移除的事件监听函数或者监听函数的key
* @remark 如果第二个参数handler没有被绑定到对应的自定义事件中什么也不做。
*/
baidu.lang.Class.prototype.removeEventListener = function (type, handler) {
if (baidu.lang.isFunction(handler)) {
handler = handler.hashCode;
} else if (!baidu.lang.isString(handler)) {
return;
}
!this.__listeners && (this.__listeners = {});
type.indexOf("on") != 0 && (type = "on" + type);
var t = this.__listeners;
if (!t[type]) {
return;
}
t[type][handler] && delete t[type][handler];
};
/**
* 派发自定义事件使得绑定到自定义事件上面的函数都会被执行。引入baidu.lang.Event后Class的子类实例才会获得该方法。
* @grammar obj.dispatchEvent(event, options)
* @param {baidu.lang.Event|String} event Event对象或事件名称(1.1.1起支持)
* @param {Object} options 扩展参数,所含属性键值会扩展到Event对象上(1.2起支持)
* @remark 处理会调用通过addEventListenr绑定的自定义事件回调函数之外还会调用直接绑定到对象上面的自定义事件。
* 例如:<br>
* myobj.onMyEvent = function(){}<br>
* myobj.addEventListener("onMyEvent", function(){});
*/
baidu.lang.Class.prototype.dispatchEvent = function (event, options) {
if (baidu.lang.isString(event)) {
event = new baidu.lang.Event(event);
}
!this.__listeners && (this.__listeners = {});
options = options || {};
for (var i in options) {
event[i] = options[i];
}
var i, t = this.__listeners, p = event.type;
event.target = event.target || this;
event.currentTarget = this;
p.indexOf("on") != 0 && (p = "on" + p);
baidu.lang.isFunction(this[p]) && this[p].apply(this, arguments);
if (typeof t[p] == "object") {
for (i in t[p]) {
t[p][i].apply(this, arguments);
}
}
return event.returnValue;
};
/**
* 为类型构造器建立继承关系
* @name baidu.lang.inherits
* @function
* @grammar baidu.lang.inherits(subClass, superClass[, className])
* @param {Function} subClass 子类构造器
* @param {Function} superClass 父类构造器
* @param {string} className 类名标识
* @remark 使subClass继承superClass的prototype
* 因此subClass的实例能够使用superClass的prototype中定义的所有属性和方法。<br>
* 这个函数实际上是建立了subClass和superClass的原型链集成并对subClass进行了constructor修正。<br>
* <strong>注意如果要继承构造函数需要在subClass里面call一下具体见下面的demo例子</strong>
* @shortcut inherits
* @meta standard
* @see baidu.lang.Class
*/
baidu.lang.inherits = function (subClass, superClass, className) {
var key, proto,
selfProps = subClass.prototype,
clazz = new Function();
clazz.prototype = superClass.prototype;
proto = subClass.prototype = new clazz();
for (key in selfProps) {
proto[key] = selfProps[key];
}
subClass.prototype.constructor = subClass;
subClass.superClass = superClass.prototype;
if ("string" == typeof className) {
proto._className = className;
}
};
/**
* @ignore
* @namespace baidu.dom 操作dom的方法。
*/
baidu.dom = baidu.dom || {};
/**
* 从文档中获取指定的DOM元素
*
* @param {string|HTMLElement} id 元素的id或DOM元素
* @meta standard
* @return {HTMLElement} DOM元素如果不存在返回null如果参数不合法直接返回参数
*/
baidu._g = baidu.dom._g = function (id) {
if (baidu.lang.isString(id)) {
return document.getElementById(id);
}
return id;
};
/**
* 从文档中获取指定的DOM元素
* @name baidu.dom.g
* @function
* @grammar baidu.dom.g(id)
* @param {string|HTMLElement} id 元素的id或DOM元素
* @meta standard
*
* @returns {HTMLElement|null} 获取的元素查找不到时返回null,如果参数不合法,直接返回参数
*/
baidu.g = 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;
};
/**
* 在目标元素的指定位置插入HTML代码
* @name baidu.dom.insertHTML
* @function
* @grammar baidu.dom.insertHTML(element, position, html)
* @param {HTMLElement|string} element 目标元素或目标元素的id
* @param {string} position 插入html的位置信息取值为beforeBegin,afterBegin,beforeEnd,afterEnd
* @param {string} html 要插入的html
* @remark
*
* 对于position参数大小写不敏感<br>
* 参数的意思beforeBegin&lt;span&gt;afterBegin this is span! beforeEnd&lt;/span&gt; afterEnd <br />
* 此外如果使用本函数插入带有script标签的HTML字符串script标签对应的脚本将不会被执行。
*
* @shortcut insertHTML
* @meta standard
*
* @returns {HTMLElement} 目标元素
*/
baidu.insertHTML = baidu.dom.insertHTML = function (element, position, html) {
element = baidu.dom.g(element);
var range,begin;
if (element.insertAdjacentHTML) {
element.insertAdjacentHTML(position, html);
} else {
// 这里不做"undefined" != typeof(HTMLElement) && !window.opera判断其它浏览器将出错
// 但是其实做了判断,其它浏览器下等于这个函数就不能执行了
range = element.ownerDocument.createRange();
// FF下range的位置设置错误可能导致创建出来的fragment在插入dom树之后html结构乱掉
// 改用range.insertNode来插入html, by wenyuxiang @ 2010-12-14.
position = position.toUpperCase();
if (position == 'AFTERBEGIN' || position == 'BEFOREEND') {
range.selectNodeContents(element);
range.collapse(position == 'AFTERBEGIN');
} else {
begin = position == 'BEFOREBEGIN';
range[begin ? 'setStartBefore' : 'setEndAfter'](element);
range.collapse(begin);
}
range.insertNode(range.createContextualFragment(html));
}
return element;
};
/**
* 为目标元素添加className
* @name baidu.dom.addClass
* @function
* @grammar baidu.dom.addClass(element, className)
* @param {HTMLElement|string} element 目标元素或目标元素的id
* @param {string} className 要添加的className允许同时添加多个class中间使用空白符分隔
* @remark
* 使用者应保证提供的className合法性不应包含不合法字符className合法字符参考http://www.w3.org/TR/CSS2/syndata.html。
* @shortcut addClass
* @meta standard
*
* @returns {HTMLElement} 目标元素
*/
baidu.ac = baidu.dom.addClass = function (element, className) {
element = baidu.dom.g(element);
var classArray = className.split(/\s+/),
result = element.className,
classMatch = " " + result + " ",
i = 0,
l = classArray.length;
for (; i < l; i++){
if ( classMatch.indexOf( " " + classArray[i] + " " ) < 0 ) {
result += (result ? ' ' : '') + classArray[i];
}
}
element.className = result;
return element;
};
/**
* @ignore
* @namespace baidu.event 屏蔽浏览器差异性的事件封装。
* @property target 事件的触发元素
* @property pageX 鼠标事件的鼠标x坐标
* @property pageY 鼠标事件的鼠标y坐标
* @property keyCode 键盘事件的键值
*/
baidu.event = baidu.event || {};
/**
* 事件监听器的存储表
* @private
* @meta standard
*/
baidu.event._listeners = baidu.event._listeners || [];
/**
* 为目标元素添加事件监听器
* @name baidu.event.on
* @function
* @grammar baidu.event.on(element, type, listener)
* @param {HTMLElement|string|window} element 目标元素或目标元素id
* @param {string} type 事件类型
* @param {Function} listener 需要添加的监听器
* @remark
* 1. 不支持跨浏览器的鼠标滚轮事件监听器添加<br>
* 2. 改方法不为监听器灌入事件对象以防止跨iframe事件挂载的事件对象获取失败
* @shortcut on
* @meta standard
* @see baidu.event.un
*
* @returns {HTMLElement|window} 目标元素
*/
baidu.on = baidu.event.on = function (element, type, listener) {
type = type.replace(/^on/i, '');
element = baidu._g(element);
var realListener = function (ev) {
// 1. 这里不支持EventArgument, 原因是跨frame的事件挂载
// 2. element是为了修正this
listener.call(element, ev);
},
lis = baidu.event._listeners,
filter = baidu.event._eventFilter,
afterFilter,
realType = type;
type = type.toLowerCase();
// filter过滤
if(filter && filter[type]){
afterFilter = filter[type](element, type, realListener);
realType = afterFilter.type;
realListener = afterFilter.listener;
}
// 事件监听器挂载
if (element.addEventListener) {
element.addEventListener(realType, realListener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + realType, realListener);
}
// 将监听器存储到数组中
lis[lis.length] = [element, type, listener, realListener, realType];
return element;
};
/**
* 为目标元素移除事件监听器
* @name baidu.event.un
* @function
* @grammar baidu.event.un(element, type, listener)
* @param {HTMLElement|string|window} element 目标元素或目标元素id
* @param {string} type 事件类型
* @param {Function} listener 需要移除的监听器
* @shortcut un
* @meta standard
*
* @returns {HTMLElement|window} 目标元素
*/
baidu.un = baidu.event.un = function (element, type, listener) {
element = baidu._g(element);
type = type.replace(/^on/i, '').toLowerCase();
var lis = baidu.event._listeners,
len = lis.length,
isRemoveAll = !listener,
item,
realType, realListener;
//如果将listener的结构改成json
//可以节省掉这个循环,优化性能
//但是由于un的使用频率并不高同时在listener不多的时候
//遍历数组的性能消耗不会对代码产生影响
//暂不考虑此优化
while (len--) {
item = lis[len];
// listener存在时移除element的所有以listener监听的type类型事件
// listener不存在时移除element的所有type类型事件
if (item[1] === type
&& item[0] === element
&& (isRemoveAll || item[2] === listener)) {
realType = item[4];
realListener = item[3];
if (element.removeEventListener) {
element.removeEventListener(realType, realListener, false);
} else if (element.detachEvent) {
element.detachEvent('on' + realType, realListener);
}
lis.splice(len, 1);
}
}
return element;
};
/**
* 阻止事件的默认行为
* @name baidu.event.preventDefault
* @function
* @grammar baidu.event.preventDefault(event)
* @param {Event} event 事件对象
* @meta standard
*/
baidu.preventDefault = baidu.event.preventDefault = function (event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
};
})();
/**
* @exports DistanceTool as BMapLib.DistanceTool
*/
var DistanceTool = function(map, opts){
if (!map) {
return;
}
/**
* OperationMask透明覆盖层在地图上进行鼠标绘制操作时使用
*/
var OperationMask = this.OperationMask = {
/**
* map对象
* @type {Map}
*/
_map : null,
/**
* HTML字符串
* @type {String}
*/
_html : "<div style='background:transparent url(http://api.map.baidu.com/images/blank.gif);position:absolute;left:0;top:0;width:100%;height:100%;z-index:1000' unselectable='on'></div>",
/**
* html元素
* @type {HTMLElement}
*/
_maskElement : null,
/**
* 鼠标指针
* @type {String}
*/
_cursor: 'default',
/**
* 操作层是否在使用中
* @type {Boolean}
*/
_inUse: false,
/**
* 透明覆盖层的显示
*
* @param {Map} map map对象
* @return 无返回值
*/
show : function(map) {
if (!this._map) {
this._map = map;
}
this._inUse = true;
if (!this._maskElement) {
this._createMask(map);
}
this._maskElement.style.display = 'block';
},
/**
* 创建覆盖层
*
* @param {Map} map map对象
* @return 无返回值
*/
_createMask : function(map) {
this._map = map;
if (!this._map) {
return;
}
baidu.insertHTML(this._map.getContainer(), "beforeEnd", this._html);
var elem = this._maskElement = this._map.getContainer().lastChild;
var stopAndPrevent = function(e) {
stopBubble(e);
return baidu.preventDefault(e);
}
baidu.on(elem, 'mouseup', function(e) {
if (e.button == 2) {
stopAndPrevent(e);
}
});
baidu.on(elem, 'contextmenu', stopAndPrevent);
elem.style.display = 'none';
},
/**
* 获取当前绘制点的地理坐标
*
* @param {Event} e e对象
* @param {Boolean} n 是否向上查到相对于地图container元素的坐标位置
* @return Point对象的位置信息
*/
getDrawPoint : function(e, n) {
e = global.event || e;
var x = e.layerX || e.offsetX || 0;
var y = e.layerY || e.offsetY || 0;
var t = e.target || e.srcElement;
if (t != OperationMask.getDom(this._map) && n == true) {
while (t && t != this._map.getContainer()) {
if (!(t.clientWidth == 0 &&
t.clientHeight == 0 &&
t.offsetParent &&
t.offsetParent.nodeName.toLowerCase() == 'td')) {
x += t.offsetLeft;
y += t.offsetTop;
}
t = t.offsetParent;
}
}
if (t != OperationMask.getDom(this._map) &&
t != this._map.getContainer()) {
return;
}
if (typeof x === 'undefined' ||
typeof y === 'undefined') {
return;
}
if (isNaN(x) || isNaN(y)) {
return;
}
return this._map.pixelToPoint(new BMap.Pixel(x, y));
},
/**
* 透明覆盖层的隐藏
*
* @return 无返回值
*/
hide : function() {
if (!this._map) {
return;
}
this._inUse = false;
if (this._maskElement) {
this._maskElement.style.display = 'none';
}
},
/**
* 获取HTML容器
*
* @param {Map} map map对象
* @return HTML容器元素
*/
getDom : function(map) {
if (!this._maskElement) {
this._createMask(map);
}
return this._maskElement;
},
/**
* 设置鼠标样式
*
* @type {String} cursor 鼠标样式
* @return 无返回值
*/
_setCursor : function(cursor) {
this._cursor = cursor || 'default';
if (this._maskElement) {
this._maskElement.style.cursor = this._cursor;
}
}
};
/**
* map对象
* @private
* @type {Map}
*/
this._map = map;
opts = opts || {};
/**
* _opts是默认参数赋值。
* 下面通过用户输入的opts对默认参数赋值
* @private
* @type {Json}
*/
this._opts = baidu.extend(
baidu.extend(this._opts || {}, {
/**
* 测距提示
* @private
* @type {String}
*/
tips : "测距",
/**
* 测距过程中,提示框文字
* @private
* @type {String}
*/
followText : "单击确定地点,双击结束",
/**
* 测距结果所用的单位制,可接受的属性为"metric"表示米制和"us"表示美国传统单位
* @private
* @type {String}
*/
unit : "metric",
/**
* 折线颜色
* @private
* @type {String}
*/
lineColor : "#ff6319",
/**
* 折线线宽
* @private
* @type {Number}
*/
lineStroke : 2,
/**
* 折线透明度
* @private
* @type {Number}
*/
opacity : 0.8,
/**
* 折线样式
* @private
* @type {String}
*/
lineStyle : "solid",
/**
* 跟随鼠标样式
* @private
* @type {String}
*/
cursor : "http://api.map.baidu.com/images/ruler.cur",
/**
* 转折点的ICON样式
* @private
* @type {BMap.Icon}
*/
secIcon : null,
/**
* 转折点的ICON样式
* @private
* @type {BMap.Icon}
*/
closeIcon : null
})
, opts);
/**
* 跟随的title覆盖物
* @private
* @type {BMap.Label}
*/
this._followTitle = null;
/**
* 折线包含所有点的数组
* @private
* @type {Array}
*/
this._points = [];
/**
* 折线所包含的所有path数组
* @private
* @type {Array}
*/
this._paths = [];
/**
* 折线结点图片数组
* @private
* @type {Array}
*/
this._dots = [];
/**
* 折线测距包含所有线段的距离
* @private
* @type {Array}
*/
this._segDistance = [];
/**
* 覆盖物的数组
* @private
* @type {Array}
*/
this._overlays = [];
/**
* 是否在调用map.clearOverlays清除画线需要建立的相关overlay元素
* @private
* @type {Boolean}
*/
this._enableMassClear = true,
/**
* 单位制,存储语言包中定义的单位名称
* @private
* @type {Json}
*/
this._units = {
// metric 表示米制
metric : {
/**
* 米制的名称
* @type {String}
*/
name : "metric",
/**
* 和米制的换算关系
* @type {Number}
*/
conv : 1,
/**
* 米制单位下两个单位制之间的换算关系
* @type {Number}
*/
incon : 1000,
/**
* 米制单位下较小单位
* @type {String}
*/
u1 : "米",
/**
* 米制单位下较大单位
* @type {String}
*/
u2 : "公里"
},
// us 表示美国传统单位各参数意义同上metric
us : {
name : "us",
conv : 3.2808,
incon : 5279.856,
u1 : "英尺",
u2 : "英里"
}
};
/**
* 是否已经开启了测距状态
* @private
* @type {Boolean}
*/
this._isOpen = false;
/**
* 未点击任何一点时,鼠标移动时的跟随提示文字
* @private
* @type {String}
*/
this._startFollowText = "单击确定起点";
/**
* 地图移动的计时器
* @private
* @type {Object}
*/
this._movingTimerId = null;
/**
* 测距需要添加的CSS样式
* @private
* @type {Json}
*/
this._styles = {
"BMapLib_diso" : "height:17px;width:5px;position:absolute;background:url(http://api.map.baidu.com/images/dis_box_01.gif) no-repeat left top"
,"BMapLib_disi" : "color:#7a7a7a;position:absolute;left:5px;padding:0 4px 1px 0;line-height:17px;background:url(http://api.map.baidu.com/images/dis_box_01.gif) no-repeat right top"
,"BMapLib_disBoxDis" : "color:#ff6319;font-weight:bold"
};
if (this._opts.lineStroke <= 0) {
this._opts.lineStroke = 2;
}
if (this._opts.opacity > 1) {
this._opts.opacity = 1;
} else if (this._opts.opacity < 0) {
this._opts.opacity = 0;
}
if (this._opts.lineStyle != "solid" &&
this._opts.lineStyle != "dashed") {
this._opts.lineStyle = "solid";
}
if (!this._units[this._opts.unit]) {
this._opts.unit = "metric";
}
this.text = "测距";
}
// 通过baidu.lang下的inherits方法让DistanceTool继承baidu.lang.Class
baidu.lang.inherits(DistanceTool, baidu.lang.Class, "DistanceTool");
/**
* 地图区域的移动事件绑定
* @return 无返回值
*/
DistanceTool.prototype._bind = function(){
// 设置鼠标样式
this._setCursor(this._opts.cursor);
var me = this;
var OperationMask = this.OperationMask;
// 在装载地图的页面元素上,绑定鼠标移动事件
baidu.on(this._map.getContainer(), "mousemove", function(e){
if (!me._isOpen) {
return;
}
if (!me._followTitle) {
return;
}
e = global.event || e;
var t = e.target || e.srcElement;
// 如果触发该事件的页面元素不是遮盖效果层,则返回,无操作
if (t != OperationMask.getDom(me._map)) {
me._followTitle.hide();
return;
}
if (!me._mapMoving) {
me._followTitle.show();
}
// 设置鼠标移动过程中,跟随的文字提示框的位置
var pt = OperationMask.getDrawPoint(e, true);
me._followTitle.setPosition(pt);
});
// 创建鼠标跟随的文字提示框
if (this._startFollowText) {
var t = this._followTitle = new BMap.Label(this._startFollowText, {offset : new BMap.Size(14, 16)});
this._followTitle.setStyles({color : "#333", borderColor : "#ff0103"});
}
};
/**
* 开启地图的测距状态
* @return {Boolean}开启测距状态成功返回true否则返回false。
*
* @example <b>参考示例:</b><br />
* myDistanceToolObject.open();
*/
DistanceTool.prototype.open = function(){
var OperationMask = this.OperationMask;
// 判断测距状态是否已经开启
if (this._isOpen == true){
return true;
}
// 已有其他地图上的鼠标操作工具开启
if (DistanceTool._toolInUse) {
return;
} else {
this._isOpen = true;
DistanceTool._toolInUse = true;
}
// 判断是否是否在移动过程中
if (this._mapMoving){
delete this._mapMoving;
}
var me = this;
// 增加鼠标在地图区域移动的事件
// 通过binded参数避免多次绑定
if (!this._binded) {
this._binded = true;
// 绑定控件项事件
this._bind();
// 地图的移动过程中,需要隐藏相关的提示框
this._map.addEventListener("moving", function(){
me._hideCurrent();
});
}
// 将文字提示框作为BMap.Label元素提交给Map Api进行管理
if (this._followTitle) {
this._map.addOverlay(this._followTitle);
this._followTitle.hide();
}
/**
* 测距过程中,点击地图时,触发的操作
* @ignore
* @param {Object} e event对象
*/
var distClick = function(e) {
var map = me._map;
if (!me._isOpen) {
return;
}
// 通过event对象计算得出点击位置的物理坐标poi为一个BMap.Point对象
e = global.event || e;
var poi = OperationMask.getDrawPoint(e, true);
// 验证计算得出的该点的位置合理性
if (!me._isPointValid(poi)) {
return;
}
// 记录当前点的屏幕位置
me._bind.initX = e.pageX || e.clientX || 0;
me._bind.initY = e.pageY || e.clientY || 0;
// 这个if循环内的计算是判断当前这个点与存储内的最后一个点的距离
// 如果距离过小比如小于5可以认为是用户的误点可以忽略掉
if (me._points.length > 0){
var lstPx = map.pointToPixel(me._points[me._points.length - 1]);
var thisPx = map.pointToPixel(poi);
var dis = Math.sqrt(Math.pow(lstPx.x - thisPx.x, 2) + Math.pow(lstPx.y - thisPx.y, 2));
if (dis < 5) {
return;
}
}
me._bind.x = e.layerX || e.offsetX || 0;
me._bind.y = e.layerY || e.offsetY || 0;
me._points.push(poi);
// 添加测距结点
me._addSecPoint(poi);
// 调整跟踪鼠标的标签
if (me._paths.length == 0) {
me._formatTitle(1, me._opts.followText, me._getTotalDistance());
}
// 修改确定线的颜色
if (me._paths.length > 0) {
me._paths[me._paths.length - 1].show();
me._paths[me._paths.length - 1].setStrokeOpacity(me._opts.opacity);
}
var path = new BMap.Polyline([poi, poi], {enableMassClear : me._enableMassClear});
me._map.addOverlay(path);
me._paths.push(path);
me._overlays.push(path);
// 测距模式下线样式固定
path.setStrokeWeight(me._opts.lineStroke);
path.setStrokeColor(me._opts.lineColor);
path.setStrokeOpacity(me._opts.opacity / 2);
path.setStrokeStyle(me._opts.lineStyle);
// 如果地图正在移动则隐藏掉
if (me._mapMoving){
path.hide();
}
if (me._points.length > 1) {
var siblingPath = me._paths[me._points.length - 2];
siblingPath.setPositionAt(1, poi);
}
// 生成节点旁边的距离显示框
var disText = "";
if (me._points.length > 1) {
// 非起点的节点,显示当前的距离
var segDis = me._setSegDistance(me._points[me._points.length - 2], me._points[me._points.length - 1]);
var meters = me._getTotalDistance();
disText = me._formatDisStr(meters);
} else {
disText = "起点";
}
var disLabel = new BMap.Label(disText, {offset : new BMap.Size(10, -5), enableMassClear : me._enableMassClear});
disLabel.setStyles({color : "#333", borderColor : "#ff0103"});
me._map.addOverlay(disLabel);
me._formatSegLabel(disLabel, disText);
me._overlays.push(disLabel);
poi.disLabel = disLabel;
disLabel.setPosition(poi);
/**
* 测距过程中,每次点击底图添加节点时,派发事件的接口
* @name DistanceTool#onaddpoint
* @event
* @param {Event Object} e 回调函数会返回event参数包括以下返回值
* <br />{"<b>point</b> : {BMap.Point} 最新添加上的节点BMap.Point对象,
* <br />"<b>pixel</b>{BMap.pixel} 最新添加上的节点BMap.Pixel对象,
* <br />"<b>index</b>{Number} 最新添加的节点的索引,
* <br />"<b>distance</b>{Number} 截止最新添加的节点的总距离}
*
* @example <b>参考示例:</b><br />
* myDistanceToolObject.addEventListener("addpoint", function(e) { alert(e.distance); });
*/
// 生成名为onaddpoint的baidu.lang.Event对象
// 并给该event对象添加上point、pixel、index和distance等属性字段
// 然后在此刻将绑定在onaddpoint上事件全部赋予event参数然后派发出去
var event = new baidu.lang.Event("onaddpoint");
event.point = poi;
event.pixel = me._map.pointToPixel(poi);
event.index = me._points.length - 1;
event.distance = me._getTotalDistance().toFixed(0);
me.dispatchEvent(event);
};
/**
* 测距过程中,鼠标在地图上移动时,触发的操作
* @ignore
* @param {Object} e event对象
*/
var distMove = function(e) {
if (!me._isOpen){
return;
}
// 通过判断数组me._paths的长度判断当前是否已经有测量节点
// 也就是,如果没有节点,则还没有开始测量
if (me._paths.length > 0) {
// 通过event参数计算当前点的位置
e = global.event || e;
var curX = e.pageX || e.clientX || 0;
var curY = e.pageY || e.clientY || 0;
if (typeof me._bind.initX == "undefined") {
me._bind.x = e.layerX || e.offsetX || 0;
me._bind.y = e.layerY || e.offsetY || 0;
me._bind.initX = curX;
me._bind.initY = curY;
}
var x = me._bind.x + curX - me._bind.initX;
var y = me._bind.y + curY - me._bind.initY;
// 修改最后一条折线的终点位置,使之随着鼠标移动画线
var path = me._paths[me._paths.length - 1];
var poi = me._map.pixelToPoint(new BMap.Pixel(x, y));
path.setPositionAt(1, poi);
if (!me._mapMoving) {
path.show();
}
var dx = 0;
var dy = 0;
// 计算当前鼠标位置,是否靠近边界、或者已经出了边界
// 如果在边界位置,则需要向对应的方向移动地图,来进行测量
// 每次移动的距离设定为8
if (x < 10) {
dx = 8;
} else if (x > me._map.getSize().width - 10){
dx = -8;
}
if (y < 10) {
dy = 8;
} else if (y > me._map.getSize().height - 10){
dy = -8;
}
// 如果dx和dy都等于0表明不需要移动地图
if (dx != 0 || dy != 0){
// 此时需要向一个方向,平移地图
if (!distMove._movingTimerId){
me._mapMoving = true;
me._map.panBy(dx, dy, {noAnimation : true});
me._movingTimerId = distMove._movingTimerId = setInterval(function(){
me._map.panBy(dx, dy, {noAnimation : true});
}, 30);
// 地图移动过程中,隐藏线段和标签
path.hide();
me._followTitle && me._followTitle.hide();
}
} else {
if (distMove._movingTimerId) {
// 此时用户不在需要移动地图来测量,可以清除计时器
clearInterval(distMove._movingTimerId);
delete distMove._movingTimerId;
delete me._movingTimerId;
// 显示跟随提示框,并修改线路位置
var lstP = me._paths[me._paths.length - 1];
var poiN = me._map.pixelToPoint(new BMap.Pixel(x, y));
if (!lstP) {
return;
}
lstP.setPositionAt(1, poiN);
lstP.show();
if (me._followTitle) {
me._followTitle.setPosition(poiN);
me._followTitle.show();
}
me._bind.i = 0;
me._bind.j = 0;
delete me._mapMoving;
}
}
// 实时更新文字提示框中的距离
if (me._followTitle) {
var td = me._getTotalDistance();
var dis = me._map.getDistance(me._points[me._points.length - 1], poi);
me._updateInstDis(me._followTitle, td + dis);
}
} else {
// 此时用户还没有开始测量,只是鼠标随便在地图上移动
if (me._followTitle) {
me._followTitle.show();
e = global.event || e;
var t = e.target || e.srcElement;
if (t != OperationMask.getDom()) {
me._followTitle.hide();
}
}
}
};
/**
* 测距要结束时,双击地图,触发的操作
* @ignore
* @param {Object} e event对象
*/
var distDblclick = function(e) {
if (!me._isOpen) {
return;
}
// 结束时,删除绑定的事件
baidu.un(OperationMask.getDom(me._map), "click", distClick);
baidu.un(document, "mousemove", distMove);
baidu.un(OperationMask.getDom(me._map), "dblclick", distDblclick);
baidu.un(document, "keydown", distKeyDown);
baidu.un(OperationMask.getDom(me._map), "mouseup", distMouseUp);
// 调用close()关闭测距状态
setTimeout(function(){
me.close();
}, 50);
};
/**
* 测距时的键盘操作
* @ignore
* @param {Object} e event对象
*/
var distKeyDown = function(e){
e = global.event || e;
if (e.keyCode == 27){
// [ESC]退出本次测距
me._clearCurData();
setTimeout(function(){
me.close();
}, 50);
}
};
/**
* 测距过程中,鼠标弹起时,触发的操作
* @ignore
* @param {Object} e event对象
*/
var distMouseUp = function(e) {
e = global.event || e;
var ieVersion = 0;
if (/msie (\d+\.\d)/i.test(navigator.userAgent)) {
ieVersion = document.documentMode || + RegExp['\x241'];
}
if (ieVersion &&
e.button != 1 ||
e.button == 2){
me.close();
}
};
// 初始化存储数据
me._initData();
// 调整title的内容
this._formatTitle();
// 创建透明覆盖层,并设置鼠标样式
OperationMask.show(this._map);
this._setCursor(this._opts.cursor);
// 绑定全部事件
baidu.on(OperationMask.getDom(this._map), "click", distClick);
baidu.on(document, "mousemove", distMove);
baidu.on(OperationMask.getDom(this._map), "dblclick", distDblclick);
baidu.on(document, "keydown", distKeyDown);
baidu.on(OperationMask.getDom(this._map), "mouseup", distMouseUp);
// 将绑定的事件、和对应的绑定对象,记录在数组中
this.bindFunc = [
{elem : OperationMask.getDom(this._map), type : "click", func : distClick},
{elem : OperationMask.getDom(this._map), type : "dblclick", func : distDblclick},
{elem : document, type : "mousemove", func : distMove},
{elem : document, type : "keydown", func : distKeyDown},
{elem : OperationMask.getDom(this._map), type : "mouseup", func : distMouseUp}];
return true;
};
/**
* 画线结束时派发drawend事件
* @return 无返回值
*/
DistanceTool.prototype._dispatchLastEvent = function() {
/**
* 测距时,每次双击底图结束当前测距折线时,派发事件的接口
* @name DistanceTool#ondrawend
* @event
* @param {Event Object} e 回调函数会返回event参数包括以下返回值
* <br />{"<b>points</b> : {BMap.Point} 所有测量时打下的节点BMap.Point对象,
* <br />"<b>overlays</b>{Array} 所有测量时生成的线段BMap.Overlay对象,
* <br />"<b>distance</b>{Number} 测量解释时的最终距离}
*
* @example <b>参考示例:</b><br />
* myDistanceToolObject.addEventListener("drawend", function(e) { alert(e.distance); });
*/
// 生成名为ondrawend的baidu.lang.Event对象
// 并给该event对象添加上points、overlays和distance等属性字段
// 然后在此刻将绑定在ondrawend上事件全部赋予event参数然后派发出去
var event = new baidu.lang.Event("ondrawend");
event.points =
this._points ?
this._points.slice(0) :
[];
event.overlays =
this._paths ?
this._paths.slice(0, this._paths.length - 1) :
[];
event.distance = this._getTotalDistance().toFixed(0);
this.dispatchEvent(event);
};
/**
* 关闭测距状态
* @return 无返回值
*
* @example <b>参考示例:</b><br />
* myDistanceToolObject.close();
*/
DistanceTool.prototype.close = function(){
var OperationMask = this.OperationMask;
if (this._isOpen == false){
return;
}
this._isOpen = false;
DistanceTool._toolInUse = false;
if (this._mapMoving){
delete this._mapMoving;
}
var me = this;
me._dispatchLastEvent();
if (me._points.length < 2){
// 不是有效绘制,清除所有内容
me._clearCurData();
} else {
me._paths[me._paths.length - 1].remove();
me._paths[me._paths.length - 1] = null;
me._paths.length = me._paths.length - 1;
// 移除最近一次标记
var pt = me._points[me._points.length - 1];
if (pt.disLabel){
pt.disLabel.remove();
}
me._processLastOp();
}
OperationMask.hide();
// 删除绑定的事件
for (var i = 0, l = this.bindFunc.length; i < l; i ++){
baidu.un(this.bindFunc[i].elem, this.bindFunc[i].type, this.bindFunc[i].func);
}
// 停止地图移动
if (me._movingTimerId){
clearInterval(me._movingTimerId);
me._movingTimerId = null;
}
if (this._followTitle){
this._followTitle.hide();
}
};
/**
* 清除本次测距的暂存数据
* @return 无返回值
*/
DistanceTool.prototype._clearCurData = function(){
var OperationMask = this.OperationMask;
for (var i = 0, l = this._points.length; i < l; i ++){
if (this._points[i].disLabel){
this._points[i].disLabel.remove();
}
}
for (var i = 0, l = this._paths.length; i < l; i ++){
this._paths[i].remove();
}
for (var i = 0, l = this._dots.length; i < l; i ++){
this._dots[i].remove();
}
this._initData();
};
/**
* 初始化存储数组
* @return 无返回值
*/
DistanceTool.prototype._initData = function(){
// 初始化point数组
this._points.length = 0;
// 初始化path数组
this._paths.length = 0;
// 初始化分段距离数组
this._segDistance.length = 0;
// 初始化结点图像数组
this._dots.length = 0;
};
/**
* 计算两点之间距离并存放在分段距离数组中
* @param {Point}
* @param {Point}
* @return {Number} 两个地理点之间的距离
*/
DistanceTool.prototype._setSegDistance = function(pt0, pt1){
if (!pt0 || !pt1){
return;
}
var dis = this._map.getDistance(pt0, pt1);
this._segDistance.push(dis);
return dis;
};
/**
* 获得总距离
* @return {Number} 总距离
*/
DistanceTool.prototype._getTotalDistance = function(){
var totalDis = 0;
for (var i = 0, l = this._segDistance.length; i < l; i ++){
totalDis += this._segDistance[i];
}
return totalDis;
};
/**
* 将米制单位的数值换算成为目标单位下的数值
* @type {Number} 需要转换的数值
* @type {String} 字符串描述的目标单位,
* "metric" 表示米制单位,
* "us" 表示美国传统单位制
* @return {Number} 转换后的数值
*/
DistanceTool.prototype._convertUnit = function(num, unit){
unit = unit || "metric";
if (this._units[unit]){
return num * this._units[unit].conv;
}
return num;
};
/**
* 添加测距结点
* @param {BMap.Point} 节点
* @return 无返回值
*/
DistanceTool.prototype._addSecPoint = function(pt){
var ico =
this._opts.secIcon ?
this._opts.secIcon :
new BMap.Icon("http://api.map.baidu.com/images/mapctrls.png", new BMap.Size(11, 11), {imageOffset: new BMap.Size(-26, -313)});
var secPt = new BMap.Marker(pt, {
icon : ico,
clickable : false,
baseZIndex : 3500000,
zIndexFixed : true,
enableMassClear : this._enableMassClear
});
this._map.addOverlay(secPt);
this._dots.push(secPt);
};
/**
* 格式化距离字符串
* @param {Number} 距离
* @return {String} 格式化的字符串
*/
DistanceTool.prototype._formatDisStr = function(distance){
var u = this._opts.unit;
var unit = this._units[u].u1;
var dis = this._convertUnit(distance, u);
if (dis > this._units[u].incon){
dis = dis / this._units[u].incon;
unit = this._units[u].u2;
dis = dis.toFixed(1);
} else {
dis = dis.toFixed(0);
}
return dis + unit;
};
/**
* 设置鼠标样式
* @param {String} cursor 鼠标样式
* @return 没有返回值
*/
DistanceTool.prototype._setCursor = function(cursor){
var OperationMask = this.OperationMask;
// 由于webkit内核浏览器下cursor设置后默认不会居中所以需要对偏移值进行设置
var csr =
/webkit/.test(navigator.userAgent.toLowerCase()) ?
"url(" + this._opts.cursor + ") 3 6, crosshair" :
"url(" + this._opts.cursor + "), crosshair"
OperationMask._setCursor(csr);
};
/**
* 获取鼠标样式
* @return {String} 跟随的鼠标样式
*/
DistanceTool.prototype._getCursor = function(){
return this._opts.cursor;
};
/**
* 调整分段距离样式
* @param {BMap.Label} label 提示框的Label
* @param {String} 需要填入的文字
* @return 没有返回值
*/
DistanceTool.prototype._formatSegLabel = function(label, text){
label.setStyle({"border" : "none", "padding" : "0"});
label.setContent("<span style='" + this._styles.BMapLib_diso + "'><span style='" + this._styles.BMapLib_disi + "'>" + text + "</span></span>");
};
/**
* 处理最后一次操作,当用户双击或测距被强行退出时调用
* @return 没有返回值
*/
DistanceTool.prototype._processLastOp = function() {
var me = this;
// 删除上次移动临时数据
delete me._bind.x;
delete me._bind.y;
delete me._bind.initX;
delete me._bind.initY;
// 验证路径
if (me._paths.length > me._points.length - 1){
var l = me._paths.length - 1;
me._paths[l].remove();
me._paths[l] = null;
me._paths.length = l;
}
// 保存本次测距对象
var disObj = {};
disObj.points = me._points.slice(0);
disObj.paths = me._paths.slice(0);
disObj.dots = me._dots.slice(0);
disObj.segDis = me._segDistance.slice(0);
// 判断总距离和按钮位置
var lstPx = me._map.pointToPixel(disObj.points[disObj.points.length - 1]);
var prePx = me._map.pointToPixel(disObj.points[disObj.points.length - 2]);
var btnOffset = [0, 0];
var disOffset = [0, 0];
if (lstPx.y - prePx.y >= 0){
// 距离位于下端
disOffset = [-5, 11];
} else {
// 距离位于上端
disOffset = [-5, -35];
}
if (lstPx.x - prePx.x >= 0){
// 按钮位于右侧
btnOffset = [14, 0];
} else {
// 按钮位于左侧
btnOffset = [-14, 0];
}
// 显示总距离
var pt = disObj.points[disObj.points.length - 1];
pt.disLabel = new BMap.Label("", {offset: new BMap.Size(-15, -40), enableMassClear: me._enableMassClear});
pt.disLabel.setStyles({color: "#333", borderColor: "#ff0103"});
me._map.addOverlay(pt.disLabel);
pt.disLabel.setOffset(new BMap.Size(disOffset[0], disOffset[1]));
pt.disLabel.setPosition(pt);
me._formatTitle(2, "", "", pt.disLabel);
// 添加关闭按钮
var bico =
this._opts.closeIcon ?
this._opts.closeIcon :
new BMap.Icon("http://api.map.baidu.com/images/mapctrls.gif", new BMap.Size(12, 12), {imageOffset: new BMap.Size(0, -14)});
disObj.closeBtn = new BMap.Marker(disObj.points[disObj.points.length - 1],
{icon : bico,
offset : new BMap.Size(btnOffset[0], btnOffset[1]),
baseZIndex : 3600000,
enableMassClear : me._enableMassClear}
);
me._map.addOverlay(disObj.closeBtn);
disObj.closeBtn.setTitle("清除本次测距");
// 点击关闭按钮,绑定关闭按钮事件
disObj.closeBtn.addEventListener("click", function(e){
// 关闭本次测距,清除相关存储和变量
for (var i = 0, l = disObj.points.length; i < l; i ++){
disObj.points[i].disLabel.remove();
disObj.points[i].disLabel = null;
}
for (var i = 0, l = disObj.paths.length; i < l; i ++){
disObj.paths[i].remove();
disObj.paths[i] = null;
}
for (var i = 0, l = disObj.dots.length; i < l; i ++){
disObj.dots[i].remove();
disObj.dots[i] = null;
}
disObj.closeBtn.remove();
disObj.closeBtn = null;
stopBubble(e);
/**
* @ignore
* 测距结束后,点击线段上最后一个节点旁的关闭按钮时,派发事件的接口
* @name DistanceTool#onremovepolyline
* @event
* @param {Event Object} e 回调函数会返回event参数
*
* @example <b>参考示例:</b><br />
* myDistanceToolObject.addEventListener("removepolyline", function(e) { alert(e.type); });
*/
// 生成名为onremovepolyline的baidu.lang.Event对象
// 然后在此刻将绑定在onremovepolyline上事件全部赋予event参数然后派发出去
var event = new baidu.lang.Event("onremovepolyline");
me.dispatchEvent(event);
});
me._initData();
};
/**
* 生成测距过程中的文字提示框
* @param {String} type
* @param {String} text
* @param {String} distance
* @param {Label} label
* @return 无返回值
*/
DistanceTool.prototype._formatTitle = function(type, text, distance, label){
var title = label || this._followTitle;
if (!title){
return;
}
title.setStyle({"lineHeight" : "16px", "zIndex" : "85", "padding" : "3px 5px"});
var t = this._startFollowText || "";
var htmls = [];
if (type == 1){
// 测距过程中的提示
title.setOffset(0, 25);
var u = this._opts.unit;
var unit = this._units[u].u1;
var dis = this._convertUnit(distance, u);
if (dis > this._units[u].incon){
dis = dis / this._units[u].incon;
unit = this._units[u].u2;
dis = dis.toFixed(1);
} else {
dis = dis.toFixed(0);
}
htmls.push("<span>总长:<span style='" + this._styles.BMapLib_disBoxDis+"'>" + dis + "</span>" + unit + "</span><br />");
htmls.push("<span style='color:#7a7a7a'>" + text + "</span>");
} else if (type == 2) {
// 结束时的总距离展示
var u = this._opts.unit;
var unit = this._units[u].u1;
var dis = this._convertUnit(this._getTotalDistance(), u);
if (dis > this._units[u].incon){
dis = dis / this._units[u].incon;
unit = this._units[u].u2;
dis = dis.toFixed(1);
} else{
dis = dis.toFixed(0);
}
htmls.push("总长:<span style='" + this._styles.BMapLib_disBoxDis + "'>" + dis + "</span>" + unit);
} else {
title.setOffset(0, 25);
htmls.push(t);
}
title.setContent(htmls.join(""));
};
/**
* 更新label的距离
* @param HTMLElement label的DOM元素
* @param Number 距离
*/
DistanceTool.prototype._updateInstDis = function(label, dis){
// 换算距离
var u = this._opts.unit;
var unit = this._units[u].u1;
if (dis > this._units[u].incon){
dis = dis / this._units[u].incon;
unit = this._units[u].u2;
dis = dis.toFixed(1);
} else {
dis = dis.toFixed(0);
}
// 修改Label的内容
if (label) {
var htmls = [];
htmls.push("<span>总长:<span style='" + this._styles.BMapLib_disBoxDis + "'>" + dis + "</span>" + unit + "</span><br />");
htmls.push("<span style='color:#7a7a7a'>" + this._opts.followText + "</span>");
label.setContent(htmls.join(""));
}
};
/**
* 隐藏相关的线段和提示框文字
* @return 无返回值
*/
DistanceTool.prototype._hideCurrent = function(){
if (!this._isOpen){
return;
}
if (this._paths.length > 0){
var p = this._paths[this._paths.length - 1];
p.hide();
}
this._followTitle && this._followTitle.hide();
};
/**
* 验证传入点的位置合理性
* @param {BMap.Point} pt 需要被验证的point点
* @return 无返回值
*/
DistanceTool.prototype._isPointValid = function(pt){
if (!pt){
return false;
}
var mapBounds = this._map.getBounds();
var sw = mapBounds.getSouthWest(),
ne = mapBounds.getNorthEast();
if (pt.lng < sw.lng ||
pt.lng > ne.lng ||
pt.lat < sw.lat ||
pt.lat > ne.lat) {
return false;
}
return true;
};
/**
* 停止事件冒泡传播,
* 闭包,对外不暴露
*
* @type {Event} e e对象
*/
function stopBubble(e){
var e = global.event || e;
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
};
return DistanceTool;
});