|
|
/* eslint-disable */
|
|
|
/**
|
|
|
* @fileoverview 百度地图的鼠标绘制工具,对外开放。
|
|
|
* 允许用户在地图上点击完成鼠标绘制的功能。
|
|
|
* 使用者可以自定义所绘制结果的相关样式,例如线宽、颜色、测线段距离、面积等等。
|
|
|
* 主入口类是<a href="symbols/BMapGLLib.DrawingManager.html">DrawingManager</a>,
|
|
|
* 基于Baidu Map API GL 1.0。
|
|
|
*
|
|
|
* @author Baidu Map Api Group
|
|
|
* @version 1.0
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* @namespace BMapGL的所有library类均放在BMapGLLib命名空间下
|
|
|
*/
|
|
|
var BMapGLLib = window.BMapGLLib = BMapGLLib || {};
|
|
|
|
|
|
/**
|
|
|
* 定义常量, 绘制的模式
|
|
|
* @final {Number} DrawingType
|
|
|
*/
|
|
|
var BMAP_DRAWING_MARKER = "marker", // 鼠标画点模式
|
|
|
BMAP_DRAWING_POLYLINE = "polyline", // 鼠标画线模式
|
|
|
BMAP_DRAWING_CIRCLE = "circle", // 鼠标画圆模式
|
|
|
BMAP_DRAWING_RECTANGLE = "rectangle", // 鼠标画矩形模式
|
|
|
BMAP_DRAWING_POLYGON = "polygon"; // 鼠标画多边形模式
|
|
|
|
|
|
(function() {
|
|
|
|
|
|
/**
|
|
|
* 声明baidu包
|
|
|
*/
|
|
|
var baidu = baidu || { guid: '$BAIDU$' };
|
|
|
(function () {
|
|
|
// 一些页面级别唯一的属性,需要挂载在window[baidu.guid]上
|
|
|
window[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__' + (window[baidu.guid]._counter++).toString(36);
|
|
|
};
|
|
|
|
|
|
window[baidu.guid]._counter = window[baidu.guid]._counter || 1;
|
|
|
|
|
|
/**
|
|
|
* 所有类的实例的容器
|
|
|
* key为每个实例的guid
|
|
|
*/
|
|
|
window[baidu.guid]._instances = window[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();
|
|
|
window[baidu.guid]._instances[this.guid] = this;
|
|
|
};
|
|
|
|
|
|
window[baidu.guid]._instances = window[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 window[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<span>afterBegin this is span! beforeEnd</span> 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;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取event事件,解决不同浏览器兼容问题
|
|
|
* @param {Event}
|
|
|
* @return {Event}
|
|
|
*/
|
|
|
baidu.getEvent = baidu.event.getEvent = function (event) {
|
|
|
return window.event || event;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取event.target,解决不同浏览器兼容问题
|
|
|
* @param {Event}
|
|
|
* @return {Target}
|
|
|
*/
|
|
|
baidu.getTarget = baidu.event.getTarget = function (event) {
|
|
|
var event = baidu.getEvent(event);
|
|
|
return event.target || event.srcElement;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 阻止事件的默认行为
|
|
|
* @name baidu.event.preventDefault
|
|
|
* @function
|
|
|
* @grammar baidu.event.preventDefault(event)
|
|
|
* @param {Event} event 事件对象
|
|
|
* @meta standard
|
|
|
*/
|
|
|
baidu.preventDefault = baidu.event.preventDefault = function (event) {
|
|
|
var event = baidu.getEvent(event);
|
|
|
if (event.preventDefault) {
|
|
|
event.preventDefault();
|
|
|
} else {
|
|
|
event.returnValue = false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 停止事件冒泡传播
|
|
|
* @param {Event}
|
|
|
*/
|
|
|
baidu.stopBubble = baidu.event.stopBubble = function (event) {
|
|
|
event = baidu.getEvent(event);
|
|
|
event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 判断是否为ie浏览器
|
|
|
* @property ie ie版本号
|
|
|
* @grammar baidu.browser.ie
|
|
|
* @meta standard
|
|
|
* @shortcut ie
|
|
|
* @see baidu.browser.firefox,baidu.browser.safari,baidu.browser.opera,baidu.browser.chrome,baidu.browser.maxthon
|
|
|
*/
|
|
|
baidu.browser = baidu.browser || {};
|
|
|
if (/msie (\d+\.\d)/i.test(navigator.userAgent)) {
|
|
|
//IE 8下,以documentMode为准
|
|
|
//在百度模板中,可能会有$,防止冲突,将$1 写成 \x241
|
|
|
baidu.browser.ie = baidu.ie = document.documentMode || + RegExp['\x241'];
|
|
|
}
|
|
|
|
|
|
})();
|
|
|
|
|
|
/**
|
|
|
* @exports DrawingManager as BMapGLLib.DrawingManager
|
|
|
*/
|
|
|
var DrawingManager =
|
|
|
|
|
|
/**
|
|
|
* DrawingManager类的构造函数
|
|
|
* @class 鼠标绘制管理类,实现鼠标绘制管理的<b>入口</b>。
|
|
|
* 实例化该类后,即可调用该类提供的open
|
|
|
* 方法开启绘制模式状态。
|
|
|
* 也可加入工具栏进行选择操作。
|
|
|
*
|
|
|
* @constructor
|
|
|
* @param {Map} map Baidu map的实例对象
|
|
|
* @param {Json Object} opts 可选的输入参数,非必填项。可输入选项包括:<br />
|
|
|
* {"<b>isOpen</b>" : {Boolean} 是否开启绘制模式
|
|
|
* <br />"<b>enableDrawingTool</b>" : {Boolean} 是否添加绘制工具栏控件,默认不添加
|
|
|
* <br />"<b>drawingToolOptions</b>" : {Json Object} 可选的输入参数,非必填项。可输入选项包括
|
|
|
* <br /> "<b>anchor</b>" : {ControlAnchor} 停靠位置、默认左上角
|
|
|
* <br /> "<b>offset</b>" : {Size} 偏移值。
|
|
|
* <br /> "<b>scale</b>" : {Number} 工具栏的缩放比例,默认为1
|
|
|
* <br /> "<b>drawingModes</b>" : {DrawingType<Array>} 工具栏上可以选择出现的绘制模式,将需要显示的DrawingType以数组型形式传入,如[BMAP_DRAWING_MARKER, BMAP_DRAWING_CIRCLE] 将只显示画点和画圆的选项
|
|
|
* <br />"<b>enableCalculate</b>" : {Boolean} 绘制是否进行测距(画线时候)、测面(画圆、多边形、矩形)
|
|
|
* <br />"<b>markerOptions</b>" : {MarkerOptions} 所画的点的可选参数,参考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">对应类</a>
|
|
|
* <br />"<b>circleOptions</b>" : {CircleOptions} 所画的圆的可选参数,参考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">对应类</a>
|
|
|
* <br />"<b>polylineOptions</b>" : {PolylineOptions} 所画的线的可选参数,参考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">对应类</a>
|
|
|
* <br />"<b>polygonOptions</b>" : {PolygonOptions} 所画的多边形的可选参数,参考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">对应类</a>
|
|
|
* <br />"<b>rectangleOptions</b>" : {PolygonOptions} 所画的矩形的可选参数,参考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">对应类</a>
|
|
|
*
|
|
|
* @example <b>参考示例:</b><br />
|
|
|
* var map = new BMap.Map("container");<br />map.centerAndZoom(new BMap.Point(116.404, 39.915), 15);<br />
|
|
|
* var myDrawingManagerObject = new BMapGLLib.DrawingManager(map, {isOpen: true,
|
|
|
* drawingType: BMAP_DRAWING_MARKER, enableDrawingTool: true,
|
|
|
* enableCalculate: false,
|
|
|
* drawingToolOptions: {
|
|
|
* anchor: BMAP_ANCHOR_TOP_LEFT,
|
|
|
* offset: new BMap.Size(5, 5),
|
|
|
* drawingModes : [
|
|
|
* BMAP_DRAWING_MARKER,
|
|
|
* BMAP_DRAWING_CIRCLE,
|
|
|
* BMAP_DRAWING_POLYLINE,
|
|
|
* BMAP_DRAWING_POLYGON,
|
|
|
* BMAP_DRAWING_RECTANGLE
|
|
|
* ]
|
|
|
* },
|
|
|
* polylineOptions: {
|
|
|
* strokeColor: "#333"
|
|
|
* });
|
|
|
*/
|
|
|
BMapGLLib.DrawingManager = function (map, opts) {
|
|
|
if (!map) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
instances.push(this);
|
|
|
|
|
|
opts = opts || {};
|
|
|
this.overlays = []; // 用来存储覆盖物
|
|
|
|
|
|
this._initialize(map, opts);
|
|
|
};
|
|
|
|
|
|
// 通过baidu.lang下的inherits方法,让DrawingManager继承baidu.lang.Class
|
|
|
baidu.lang.inherits(DrawingManager, baidu.lang.Class, 'DrawingManager');
|
|
|
|
|
|
/**
|
|
|
* 开启地图的绘制模式
|
|
|
*
|
|
|
* @example <b>参考示例:</b><br />
|
|
|
* myDrawingManagerObject.open();
|
|
|
*/
|
|
|
DrawingManager.prototype.open = function () {
|
|
|
// 判断绘制状态是否已经开启
|
|
|
if (this._isOpen == true) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
closeInstanceExcept(this);
|
|
|
|
|
|
this._open();
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 关闭地图的绘制状态
|
|
|
*
|
|
|
* @example <b>参考示例:</b><br />
|
|
|
* myDrawingManagerObject.close();
|
|
|
*/
|
|
|
DrawingManager.prototype.close = function () {
|
|
|
|
|
|
// 判断绘制状态是否已经开启
|
|
|
if (this._isOpen == false) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
var me = this;
|
|
|
this._close();
|
|
|
me._map.removeOverlay(tip_label);
|
|
|
setTimeout(function () {
|
|
|
me._map.enableDoubleClickZoom();
|
|
|
}, 2000);
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置当前的绘制模式,参数DrawingType,为5个可选常量:
|
|
|
* <br/>BMAP_DRAWING_MARKER 画点
|
|
|
* <br/>BMAP_DRAWING_CIRCLE 画圆
|
|
|
* <br/>BMAP_DRAWING_POLYLINE 画线
|
|
|
* <br/>BMAP_DRAWING_POLYGON 画多边形
|
|
|
* <br/>BMAP_DRAWING_RECTANGLE 画矩形
|
|
|
* @param {DrawingType} DrawingType
|
|
|
* @return {Boolean}
|
|
|
*
|
|
|
* @example <b>参考示例:</b><br />
|
|
|
* myDrawingManagerObject.setDrawingMode(BMAP_DRAWING_POLYLINE);
|
|
|
*/
|
|
|
DrawingManager.prototype.setDrawingMode = function (drawingType) {
|
|
|
// 与当前模式不一样时候才进行重新绑定事件
|
|
|
if (this._drawingType != drawingType) {
|
|
|
closeInstanceExcept(this);
|
|
|
this._setDrawingMode(drawingType);
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取当前的绘制模式
|
|
|
* @return {DrawingType} 绘制的模式
|
|
|
*
|
|
|
* @example <b>参考示例:</b><br />
|
|
|
* alert(myDrawingManagerObject.getDrawingMode());
|
|
|
*/
|
|
|
DrawingManager.prototype.getDrawingMode = function () {
|
|
|
return this._drawingType;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 打开距离或面积计算
|
|
|
*
|
|
|
* @example <b>参考示例:</b><br />
|
|
|
* myDrawingManagerObject.enableCalculate();
|
|
|
*/
|
|
|
DrawingManager.prototype.enableCalculate = function () {
|
|
|
this._enableCalculate = true;
|
|
|
this._addGeoUtilsLibrary(); // 异步调用GeoUtils
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 关闭距离或面积计算
|
|
|
*
|
|
|
* @example <b>参考示例:</b><br />
|
|
|
* myDrawingManagerObject.disableCalculate();
|
|
|
*/
|
|
|
DrawingManager.prototype.disableCalculate = function () {
|
|
|
this._enableCalculate = false;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 打开吸附功能
|
|
|
*/
|
|
|
DrawingManager.prototype.enableSorption = function() {
|
|
|
this._enableSorption = true;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 关闭吸附功能
|
|
|
*/
|
|
|
DrawingManager.prototype.disableSorption = function() {
|
|
|
this._enableSorption = false;
|
|
|
};
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 打开gpc功能
|
|
|
*/
|
|
|
DrawingManager.prototype.enableGpc = function() {
|
|
|
this._enableGpc = true;
|
|
|
this._addGPCLibrary(); // 异步调用gpc
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 关闭gpc功能
|
|
|
*/
|
|
|
DrawingManager.prototype.disableGpc = function() {
|
|
|
this._enableGpc = false;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取所有绘制的覆盖物
|
|
|
*/
|
|
|
DrawingManager.prototype.getOverlays = function() {
|
|
|
return this.overlays;
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.addOverlayData = function(overlay) {
|
|
|
return this.overlays.push(overlay);
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.setOverlaysData = function(overlays) {
|
|
|
return this.overlays = overlays;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 清除指定覆盖物数据
|
|
|
*/
|
|
|
DrawingManager.prototype.clearOverlayData = function(overlay) {
|
|
|
var map = this._map;
|
|
|
for (var i = 0; i < this.overlays.length; i++) {
|
|
|
if (this.overlays[i] === overlay) {
|
|
|
this.overlays.splice(i, 1);
|
|
|
return overlay;
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 清除指定覆盖物
|
|
|
*/
|
|
|
DrawingManager.prototype.clearOverlay = function(overlay) {
|
|
|
var map = this._map;
|
|
|
var overlay = this.clearOverlayData(overlay);
|
|
|
if (overlay) {
|
|
|
map.removeOverlay(overlay);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 清除所有绘制的覆盖物
|
|
|
*/
|
|
|
DrawingManager.prototype.clearOverlays = function() {
|
|
|
var map = this._map;
|
|
|
this.overlays.forEach(function (overlay) {
|
|
|
map.removeOverlay(overlay);
|
|
|
});
|
|
|
this.overlays.length = 0;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 鼠标绘制完成后,派发总事件的接口
|
|
|
* @name DrawingManager#overlaycomplete
|
|
|
* @event
|
|
|
* @param {Event Object} e 回调函数会返回event参数,包括以下返回值:
|
|
|
* <br />{"<b>drawingMode</b> : {DrawingType} 当前的绘制模式
|
|
|
* <br />"<b>overlay</b>:{Marker||Polyline||Polygon||Circle} 对应的绘制模式返回对应的覆盖物
|
|
|
* <br />"<b>calculate</b>:{Number} 需要开启计算模式才会返回这个值,当绘制线的时候返回距离、绘制多边形、圆、矩形时候返回面积,单位为米,
|
|
|
* <br />"<b>label</b>:{Label} 计算面积时候出现在Map上的Label对象
|
|
|
*
|
|
|
* @example <b>参考示例:</b>
|
|
|
* myDrawingManagerObject.addEventListener("overlaycomplete", function(e) {
|
|
|
* alert(e.drawingMode);
|
|
|
* alert(e.overlay);
|
|
|
* alert(e.calculate);
|
|
|
* alert(e.label);
|
|
|
* });
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* 绘制点完成后,派发的事件接口
|
|
|
* @name DrawingManager#markercomplete
|
|
|
* @event
|
|
|
* @param {Marker} overlay 回调函数会返回相应的覆盖物,
|
|
|
* <br />{"<b>overlay</b> : {Marker}
|
|
|
*
|
|
|
* @example <b>参考示例:</b>
|
|
|
* myDrawingManagerObject.addEventListener("circlecomplete", function(e, overlay) {
|
|
|
* alert(overlay);
|
|
|
* });
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* 绘制圆完成后,派发的事件接口
|
|
|
* @name DrawingManager#circlecomplete
|
|
|
* @event
|
|
|
* @param {Circle} overlay 回调函数会返回相应的覆盖物,
|
|
|
* <br />{"<b>overlay</b> : {Circle}
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* 绘制线完成后,派发的事件接口
|
|
|
* @name DrawingManager#polylinecomplete
|
|
|
* @event
|
|
|
* @param {Polyline} overlay 回调函数会返回相应的覆盖物,
|
|
|
* <br />{"<b>overlay</b> : {Polyline}
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* 绘制多边形完成后,派发的事件接口
|
|
|
* @name DrawingManager#polygoncomplete
|
|
|
* @event
|
|
|
* @param {Polygon} overlay 回调函数会返回相应的覆盖物,
|
|
|
* <br />{"<b>overlay</b> : {Polygon}
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* 绘制矩形完成后,派发的事件接口
|
|
|
* @name DrawingManager#rectanglecomplete
|
|
|
* @event
|
|
|
* @param {Polygon} overlay 回调函数会返回相应的覆盖物,
|
|
|
* <br />{"<b>overlay</b> : {Polygon}
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* 初始化状态
|
|
|
* @param {Map} 地图实例
|
|
|
* @param {Object} 参数
|
|
|
*/
|
|
|
DrawingManager.prototype._initialize = function (map, opts) {
|
|
|
|
|
|
/**
|
|
|
* map对象
|
|
|
* @private
|
|
|
* @type {Map}
|
|
|
*/
|
|
|
this._map = map;
|
|
|
|
|
|
/**
|
|
|
* 配置对象
|
|
|
* @private
|
|
|
* @type {Object}
|
|
|
*/
|
|
|
this._opts = opts;
|
|
|
|
|
|
/**
|
|
|
* 当前的绘制模式, 默认是绘制点
|
|
|
* @private
|
|
|
* @type {DrawingType}
|
|
|
*/
|
|
|
this._drawingType = opts.drawingMode || BMAP_DRAWING_MARKER;
|
|
|
|
|
|
/**
|
|
|
* 是否添加添加鼠标绘制工具栏面板
|
|
|
*/
|
|
|
if (opts.enableDrawingTool) {
|
|
|
this.enableDrawingTool();
|
|
|
}
|
|
|
|
|
|
if (opts.sorptionDistance !== undefined) {
|
|
|
this.setSorptionDistance(opts.sorptionDistance);
|
|
|
}
|
|
|
|
|
|
// 是否计算绘制出的面积
|
|
|
if (opts.enableCalculate === true) {
|
|
|
this.enableCalculate();
|
|
|
} else {
|
|
|
this.disableCalculate();
|
|
|
}
|
|
|
|
|
|
// 是否开启超限提示
|
|
|
if (opts.enableLimit === true) {
|
|
|
var limit = opts.limitOptions;
|
|
|
this.limit = limit;
|
|
|
}
|
|
|
|
|
|
// 是否开启吸附功能
|
|
|
if (opts.enableSorption === true) {
|
|
|
this.enableSorption();
|
|
|
} else {
|
|
|
this.disableSorption();
|
|
|
}
|
|
|
|
|
|
// 是否开启gpc功能
|
|
|
if (opts.enableGpc === true) {
|
|
|
this.enableGpc();
|
|
|
} else {
|
|
|
this.disableGpc();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 是否已经开启了绘制状态
|
|
|
* @private
|
|
|
* @type {Boolean}
|
|
|
*/
|
|
|
this._isOpen = !!(opts.isOpen === true);
|
|
|
if (this._isOpen) {
|
|
|
this._open();
|
|
|
}
|
|
|
|
|
|
this.setPolygonOptions(opts.polygonOptions);
|
|
|
this.setMarkerOptions(opts.markerOptions);
|
|
|
this.setCircleOptions(opts.circleOptions);
|
|
|
this.setPolylineOptions(opts.polylineOptions);
|
|
|
this.setRectangleOptions(opts.rectangleOptions);
|
|
|
this.setLabelOptions(opts.labelOptions);
|
|
|
this.controlButton = opts.controlButton == 'right' ? 'right' : 'left';
|
|
|
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.enableDrawingTool = function() {
|
|
|
var opts = this._opts;
|
|
|
if (!this._drawingTool) {
|
|
|
var drawingTool = new DrawingTool(this, opts.drawingToolOptions);
|
|
|
this._drawingTool = drawingTool;
|
|
|
}
|
|
|
this._map.addControl(this._drawingTool);
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.disableDrawingTool = function() {
|
|
|
if (this._drawingTool) {
|
|
|
this._map.removeControl(this._drawingTool);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.setSorptionDistance = function(distance) {
|
|
|
this._sorptionDistance = distance || 0;
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.setPolygonOptions = function(options) {
|
|
|
this.polygonOptions = options || {};
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.setMarkerOptions = function(options) {
|
|
|
this.markerOptions = options || {};
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.setCircleOptions = function(options) {
|
|
|
this.circleOptions = options || {};
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.setPolylineOptions = function(options) {
|
|
|
this.polylineOptions = options || {};
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.setRectangleOptions = function(options) {
|
|
|
this.rectangleOptions = options || {};
|
|
|
};
|
|
|
|
|
|
DrawingManager.prototype.setLabelOptions = function(options) {
|
|
|
this.labelOptions = options || {};
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 开启地图的绘制状态
|
|
|
* @return {Boolean},开启绘制状态成功,返回true;否则返回false。
|
|
|
*/
|
|
|
DrawingManager.prototype._open = function () {
|
|
|
|
|
|
this._isOpen = true;
|
|
|
|
|
|
// 添加遮罩,所有鼠标操作都在这个遮罩上完成
|
|
|
if (!this._mask) {
|
|
|
this._mask = new Mask();
|
|
|
}
|
|
|
|
|
|
this._map.addOverlay(this._mask);
|
|
|
this._setDrawingMode(this._drawingType);
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置当前的绘制模式
|
|
|
* @param {DrawingType}
|
|
|
*/
|
|
|
DrawingManager.prototype._setDrawingMode = function (drawingType) {
|
|
|
|
|
|
this._drawingType = drawingType;
|
|
|
|
|
|
/**
|
|
|
* 开启编辑状态时候才重新进行事件绑定
|
|
|
*/
|
|
|
if (this._isOpen) {
|
|
|
|
|
|
// 清空之前的自定义事件
|
|
|
this._mask.__listeners = {};
|
|
|
|
|
|
switch (drawingType) {
|
|
|
case BMAP_DRAWING_MARKER:
|
|
|
this._bindMarker();
|
|
|
break;
|
|
|
case BMAP_DRAWING_CIRCLE:
|
|
|
this._bindCircle();
|
|
|
break;
|
|
|
case BMAP_DRAWING_POLYLINE:
|
|
|
case BMAP_DRAWING_POLYGON:
|
|
|
this._bindPolylineOrPolygon();
|
|
|
break;
|
|
|
case BMAP_DRAWING_RECTANGLE:
|
|
|
this._bindRectangle();
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 如果添加了工具栏,则也需要改变工具栏的样式
|
|
|
*/
|
|
|
if (this._drawingTool && this._isOpen) {
|
|
|
this._drawingTool.setStyleByDrawingMode(drawingType);
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 关闭地图的绘制状态
|
|
|
* @return {Boolean},关闭绘制状态成功,返回true;否则返回false。
|
|
|
*/
|
|
|
DrawingManager.prototype._close = function () {
|
|
|
|
|
|
this._isOpen = false;
|
|
|
|
|
|
if (this._mask) {
|
|
|
this._map.removeOverlay(this._mask);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 如果添加了工具栏,则关闭时候将工具栏样式设置为拖拽地图
|
|
|
*/
|
|
|
if (this._drawingTool) {
|
|
|
this._drawingTool.setStyleByDrawingMode('hander');
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绑定鼠标画点的事件
|
|
|
*/
|
|
|
DrawingManager.prototype._bindMarker = function () {
|
|
|
|
|
|
var me = this,
|
|
|
map = this._map,
|
|
|
mask = this._mask;
|
|
|
|
|
|
/**
|
|
|
* 鼠标点击的事件
|
|
|
*/
|
|
|
var clickAction = function (e) {
|
|
|
// 往地图上添加marker
|
|
|
var marker = new BMapGL.Marker(e.point, me.markerOptions);
|
|
|
map.addOverlay(marker);
|
|
|
me._dispatchOverlayComplete(marker);
|
|
|
};
|
|
|
|
|
|
mask.addEventListener('click', clickAction);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绑定鼠标画圆的事件
|
|
|
*/
|
|
|
var tip_label = null;
|
|
|
DrawingManager.prototype._bindCircle = function () {
|
|
|
|
|
|
var me = this,
|
|
|
map = this._map,
|
|
|
mask = this._mask,
|
|
|
circle = null,
|
|
|
overlays = [],
|
|
|
centerPoint = null; // 圆的中心点
|
|
|
|
|
|
var radius = 1;
|
|
|
var moveMarker = null;
|
|
|
var polyline = null;
|
|
|
var radiusWindow = null;
|
|
|
var operateWindow = null;
|
|
|
|
|
|
var lineStyel = {
|
|
|
strokeColor: '#4E6DF1', // 边线颜色。
|
|
|
strokeWeight: 2 // 边线的宽度,以像素为单位。
|
|
|
};
|
|
|
|
|
|
var centerIcon = new BMapGL.Icon('//mapopen.bj.bcebos.com/cms/images/DrawingManager/circenter.png', new BMapGL.Size(20, 20));
|
|
|
var moveIcon = new BMapGL.Icon('///mapopen.bj.bcebos.com/cms/images/DrawingManager/nbsearch2.png', new BMapGL.Size(40, 20), {
|
|
|
imageOffset: new BMapGL.Size(0, 10)
|
|
|
});
|
|
|
|
|
|
/**
|
|
|
* 开始绘制圆形
|
|
|
*/
|
|
|
|
|
|
var startAction = function (e) {
|
|
|
if (me.controlButton == 'right' && (e.button == 1 || e.button == 0)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
centerPoint = e.point;
|
|
|
|
|
|
var centerMarker = new BMapGL.Marker(centerPoint);
|
|
|
centerIcon.setImageSize(new BMapGL.Size(20, 20));
|
|
|
centerMarker.setIcon(centerIcon);
|
|
|
centerMarker.enableDragging();
|
|
|
centerMarker.addEventListener('dragstart', centerDragstart);
|
|
|
centerMarker.addEventListener('dragging', centerDragging);
|
|
|
centerMarker.addEventListener('dragend', centerDragend);
|
|
|
map.addOverlay(centerMarker);
|
|
|
|
|
|
overlays.push(centerMarker);
|
|
|
|
|
|
circle = new BMapGL.Circle(centerPoint, radius, me.circleOptions);
|
|
|
map.addOverlay(circle);
|
|
|
mask.enableEdgeMove();
|
|
|
mask.addEventListener('mousemove', moveAction);
|
|
|
baidu.on(document, 'mouseup', endAction);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绘制圆形过程中,鼠标移动过程的事件
|
|
|
*/
|
|
|
var moveAction = function (e) {
|
|
|
radius = me._map.getDistance(centerPoint, e.point).toFixed(0);
|
|
|
circle.setRadius(radius);
|
|
|
|
|
|
map.removeOverlay(tip_label);
|
|
|
|
|
|
tip_label = new BMapGL.Label('半径:' + radius + '米<br>松开完成绘制', {
|
|
|
position: e.point, // 指定文本标注所在的地理位置
|
|
|
offset: new BMapGL.Size(10, 10) // 设置文本偏移量
|
|
|
});
|
|
|
tip_label.setStyle(me.labelOptions);
|
|
|
map.addOverlay(tip_label);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绘制圆形结束
|
|
|
*/
|
|
|
var endAction = function (e) {
|
|
|
var cz = map.getViewport(circle.getBounds());
|
|
|
cz.zoom -= 1;
|
|
|
map.setViewport(cz);
|
|
|
map.removeOverlay(tip_label);
|
|
|
|
|
|
var endPoint = new BMapGL.Point(circle.getBounds().getNorthEast().lng, centerPoint.lat);
|
|
|
mask.hide();
|
|
|
|
|
|
moveMarker = new BMapGL.Marker(endPoint);
|
|
|
moveMarker.setIcon(moveIcon);
|
|
|
moveMarker.enableDragging();
|
|
|
polyline = new BMapGL.Polyline([centerPoint, endPoint], lineStyel);
|
|
|
|
|
|
var midPoint = new BMapGL.Point((circle.getBounds().getNorthEast().lng + centerPoint.lng) / 2, centerPoint.lat);
|
|
|
radiusWindow = new Screenshot('circle', midPoint, radius, circle, me);
|
|
|
|
|
|
overlays = overlays.concat([moveMarker, polyline, radiusWindow]);
|
|
|
var limit = null;
|
|
|
if (me.limit) {
|
|
|
limit = me.limit.area;
|
|
|
}
|
|
|
|
|
|
var targetOverlay = {
|
|
|
limit: limit,
|
|
|
type: 'circle',
|
|
|
point: endPoint,
|
|
|
overlay: circle,
|
|
|
overlays: overlays
|
|
|
};
|
|
|
operateWindow = new Operate(targetOverlay, me);
|
|
|
|
|
|
map.addOverlay(moveMarker);
|
|
|
map.addOverlay(polyline);
|
|
|
map.addOverlay(radiusWindow);
|
|
|
map.addOverlay(operateWindow);
|
|
|
|
|
|
radiusWindow.addEventListener('radiuschange', function (e) {
|
|
|
var radius = e.radius;
|
|
|
circle.setRadius(radius);
|
|
|
var ePoint = getPointByDistance(centerPoint, radius, 'east');
|
|
|
var dragLeftPoint = new BMapGL.Point(ePoint.lng, centerPoint.lat);
|
|
|
var halflng = ePoint.lng > centerPoint.lng ? (circle.getBounds().getNorthEast().lng + centerPoint.lng) / 2 : (circle.getBounds().getSouthWest().lng + centerPoint.lng) / 2;
|
|
|
var halfLeftPoint = new BMapGL.Point(halflng, centerPoint.lat);
|
|
|
moveMarker.setPosition(dragLeftPoint);
|
|
|
radiusWindow.setInfo(halfLeftPoint, radius);
|
|
|
operateWindow.setPosition(dragLeftPoint, true);
|
|
|
operateWindow.updateWindow();
|
|
|
polyline.setPath([centerPoint, dragLeftPoint]);
|
|
|
});
|
|
|
|
|
|
moveMarker.addEventListener('dragging', function (e) {
|
|
|
var dragLeftPoint = new BMapGL.Point(e.latLng.lng, centerPoint.lat);
|
|
|
var halflng = e.latLng.lng > centerPoint.lng ? (circle.getBounds().getNorthEast().lng + centerPoint.lng) / 2 : (circle.getBounds().getSouthWest().lng + centerPoint.lng) / 2;
|
|
|
var isright = e.latLng.lng > centerPoint.lng ? true : false;
|
|
|
var halfLeftPoint = new BMapGL.Point(halflng, centerPoint.lat);
|
|
|
|
|
|
e.target.setPosition(dragLeftPoint);
|
|
|
radiusWindow.setInfo(halfLeftPoint, me._map.getDistance(centerPoint, e.latLng).toFixed(0));
|
|
|
operateWindow.setPosition(dragLeftPoint, isright);
|
|
|
polyline.setPath([centerPoint, dragLeftPoint]);
|
|
|
radius = me._map.getDistance(centerPoint, e.latLng).toFixed(0);
|
|
|
circle.setRadius(me._map.getDistance(centerPoint, e.latLng));
|
|
|
});
|
|
|
|
|
|
moveMarker.addEventListener('dragend', function (e) {
|
|
|
operateWindow.updateWindow();
|
|
|
});
|
|
|
|
|
|
mask.disableEdgeMove();
|
|
|
mask.removeEventListener('mousemove', moveAction);
|
|
|
mask.removeEventListener('mousemove', mousedownAction);
|
|
|
baidu.un(document, 'mouseup', endAction);
|
|
|
me.close();
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 鼠标点击起始点
|
|
|
*/
|
|
|
var mousedownAction = function (e) {
|
|
|
baidu.preventDefault(e);
|
|
|
baidu.stopBubble(e);
|
|
|
|
|
|
if (me.controlButton == 'right' && e.button == 1) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (centerPoint == null) {
|
|
|
startAction(e);
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 非绘制圆形过程中,鼠标移动过程的事件
|
|
|
*/
|
|
|
var mousemoveAction = function (e) {
|
|
|
baidu.preventDefault(e);
|
|
|
baidu.stopBubble(e);
|
|
|
|
|
|
map.removeOverlay(tip_label);
|
|
|
|
|
|
tip_label = new BMapGL.Label('按下确认中心点,拖拽确认半径', {
|
|
|
position: e.point, // 指定文本标注所在的地理位置
|
|
|
offset: new BMapGL.Size(10, 10) // 设置文本偏移量
|
|
|
});
|
|
|
tip_label.setStyle(me.labelOptions);
|
|
|
map.addOverlay(tip_label);
|
|
|
|
|
|
};
|
|
|
|
|
|
var centerDragstart = function (e) {
|
|
|
map.removeOverlay(moveMarker);
|
|
|
map.removeOverlay(polyline);
|
|
|
map.removeOverlay(radiusWindow);
|
|
|
map.removeOverlay(operateWindow);
|
|
|
};
|
|
|
var centerDragging = function (e) {
|
|
|
centerPoint = e.latLng;
|
|
|
circle.setCenter(e.latLng);
|
|
|
};
|
|
|
var centerDragend = function (e) {
|
|
|
centerPoint = e.latLng;
|
|
|
endAction(e);
|
|
|
};
|
|
|
|
|
|
|
|
|
mask.addEventListener('mousedown', mousedownAction);
|
|
|
mask.addEventListener('mousemove', mousemoveAction);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 画线和画多边形相似性比较大,公用一个方法
|
|
|
*/
|
|
|
DrawingManager.prototype._bindPolylineOrPolygon = function () {
|
|
|
|
|
|
var me = this,
|
|
|
map = this._map,
|
|
|
mask = this._mask,
|
|
|
points = [], // 用户绘制的点
|
|
|
drawPoint = null, // 实际需要画在地图上的点
|
|
|
overlay = null,
|
|
|
match = null,
|
|
|
isBinded = false;
|
|
|
function getNorthEast() {
|
|
|
var bound = arguments[0];
|
|
|
var maxlng = 0;
|
|
|
var index = 0;
|
|
|
for (var j = 0; j < bound.length; j++) {
|
|
|
if (maxlng < bound[j].lng) {
|
|
|
maxlng = bound[j].lng;
|
|
|
index = j;
|
|
|
}
|
|
|
}
|
|
|
return bound[index];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 鼠标点击的事件
|
|
|
*/
|
|
|
var startAction = function (e) {
|
|
|
if (me.controlButton == 'right' && (e.button == 1 || e.button == 0)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var point = e.point;
|
|
|
if (match) {
|
|
|
point = match;
|
|
|
}
|
|
|
points.push(point);
|
|
|
|
|
|
drawPoint = points.concat(points[points.length - 1]);
|
|
|
|
|
|
if (points.length == 1) {
|
|
|
if (me._drawingType == BMAP_DRAWING_POLYLINE) {
|
|
|
|
|
|
overlay = new BMapGL.Polyline(drawPoint, me.polylineOptions);
|
|
|
} else if (me._drawingType == BMAP_DRAWING_POLYGON) {
|
|
|
overlay = new BMapGL.Polygon(drawPoint, me.polygonOptions);
|
|
|
}
|
|
|
|
|
|
map.addOverlay(overlay);
|
|
|
} else {
|
|
|
overlay.setPath(drawPoint);
|
|
|
}
|
|
|
if (!isBinded) {
|
|
|
isBinded = true;
|
|
|
mask.enableEdgeMove();
|
|
|
mask.removeEventListener('mousemove', mousemoveAction);
|
|
|
mask.addEventListener('mousemove', moveAction);
|
|
|
mask.addEventListener('dblclick', dblclickAction);
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 鼠标移动过程的事件
|
|
|
*/
|
|
|
var moveAction = function (e) {
|
|
|
var point = e.point;
|
|
|
if (me._enableSorption) {
|
|
|
var matchs = me.getSorptionMatch(point, me.overlays, me._sorptionDistance);
|
|
|
if (matchs && matchs.length > 0) {
|
|
|
match = matchs[0].point;
|
|
|
overlay.setPositionAt(drawPoint.length - 1, matchs[0].point);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
match = null;
|
|
|
|
|
|
overlay.setPositionAt(drawPoint.length - 1, e.point);
|
|
|
|
|
|
map.removeOverlay(tip_label);
|
|
|
|
|
|
tip_label = new BMapGL.Label('单击绘制下一个点,双击完成绘制', {
|
|
|
position: e.point, // 指定文本标注所在的地理位置
|
|
|
offset: new BMapGL.Size(10, 10) // 设置文本偏移量
|
|
|
});
|
|
|
tip_label.setStyle(me.labelOptions);
|
|
|
map.addOverlay(tip_label);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 鼠标双击的事件
|
|
|
*/
|
|
|
var dblclickAction = function (e) {
|
|
|
baidu.stopBubble(e);
|
|
|
isBinded = false;
|
|
|
map.removeOverlay(tip_label);
|
|
|
mask.disableEdgeMove();
|
|
|
mask.removeEventListener('mousedown',startAction);
|
|
|
mask.removeEventListener('mousemove', moveAction);
|
|
|
mask.removeEventListener('mousemove', mousemoveAction);
|
|
|
mask.removeEventListener('dblclick', dblclickAction);
|
|
|
|
|
|
if (me.controlButton == 'right') {
|
|
|
points.push(e.point);
|
|
|
} else if (baidu.ie <= 8) {
|
|
|
|
|
|
} else {
|
|
|
points.pop();
|
|
|
}
|
|
|
|
|
|
// 裁剪
|
|
|
try {
|
|
|
if (me._enableGpc && window.gpcas && 'polygon' === me._drawingType) {
|
|
|
var res = new gpcas.geometry.PolyDefault();
|
|
|
for (var i = 0; i < points.length; i++) {
|
|
|
res.addPoint(new gpcas.Point(points[i].lng, points[i].lat));
|
|
|
}
|
|
|
for (var j = 0; j < me.overlays.length; j++) {
|
|
|
var path = me.overlays[j].getPath();
|
|
|
var target = new gpcas.geometry.PolyDefault();
|
|
|
for (var i = 0; i < path.length; i++) {
|
|
|
target.addPoint(new gpcas.Point(path[i].lng, path[i].lat));
|
|
|
}
|
|
|
var diff = res.difference(target);
|
|
|
var newPoints = diff.getPoints();
|
|
|
var outPoints = [];
|
|
|
for (var i = 0; i < newPoints.length; i++) {
|
|
|
outPoints.push(new BMapGL.Point(newPoints[i].x, newPoints[i].y));
|
|
|
}
|
|
|
res = new gpcas.geometry.PolyDefault();
|
|
|
for (var i = 0; i < newPoints.length; i++) {
|
|
|
res.addPoint(new gpcas.Point(newPoints[i].x, newPoints[i].y));
|
|
|
}
|
|
|
points = outPoints;
|
|
|
}
|
|
|
}
|
|
|
} catch(e) {
|
|
|
}
|
|
|
|
|
|
overlay.setPath(points);
|
|
|
var cz = map.getViewport(points);
|
|
|
cz.zoom -= 1;
|
|
|
map.setViewport(cz);
|
|
|
|
|
|
overlay.enableEditing();
|
|
|
var limit = null;
|
|
|
if (me.limit) {
|
|
|
limit = 'polygon' === me._drawingType ? me.limit.area : me.limit.distance;
|
|
|
}
|
|
|
|
|
|
var targetOverlay = {
|
|
|
limit: limit,
|
|
|
type: me._drawingType,
|
|
|
point: getNorthEast(points),
|
|
|
overlay: overlay,
|
|
|
overlays: []
|
|
|
};
|
|
|
|
|
|
var operateWindow = new Operate(targetOverlay, me);
|
|
|
map.addOverlay(operateWindow);
|
|
|
|
|
|
overlay.addEventListener('lineupdate', function (e) {
|
|
|
var point = getNorthEast(e.currentTarget.getPath());
|
|
|
operateWindow.setPosition(point, true);
|
|
|
operateWindow.updateWindow();
|
|
|
});
|
|
|
|
|
|
points.length = 0;
|
|
|
drawPoint.length = 0;
|
|
|
me.close();
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 非绘制多边形过程中,鼠标移动过程的事件
|
|
|
*/
|
|
|
var mousemoveAction = function (e) {
|
|
|
baidu.preventDefault(e);
|
|
|
baidu.stopBubble(e);
|
|
|
|
|
|
map.removeOverlay(tip_label);
|
|
|
|
|
|
tip_label = new BMapGL.Label('单击确认起点', {
|
|
|
position: e.point, // 指定文本标注所在的地理位置
|
|
|
offset: new BMapGL.Size(10, 10) // 设置文本偏移量
|
|
|
});
|
|
|
tip_label.setStyle(me.labelOptions);
|
|
|
map.addOverlay(tip_label);
|
|
|
};
|
|
|
|
|
|
mask.addEventListener('mousemove', mousemoveAction);
|
|
|
|
|
|
// mask.addEventListener('mouseup', startAction);
|
|
|
mask.addEventListener('mousedown', startAction);
|
|
|
|
|
|
// 双击时候不放大地图级别
|
|
|
mask.addEventListener('dblclick', function (e) {
|
|
|
|
|
|
baidu.stopBubble(e);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绑定鼠标画矩形的事件
|
|
|
*/
|
|
|
|
|
|
DrawingManager.prototype._bindRectangle = function () {
|
|
|
|
|
|
var me = this,
|
|
|
map = this._map,
|
|
|
mask = this._mask,
|
|
|
polygon = null,
|
|
|
startPoint = null;
|
|
|
|
|
|
|
|
|
// 获取4个顶点和4条边中点的坐标
|
|
|
function getRectAllPoints(pointA, pointB) {
|
|
|
var pointLT = new BMapGL.Point(pointA.lng, pointA.lat); // 左上角
|
|
|
var pointRT = new BMapGL.Point(pointB.lng, pointA.lat); // 右上角
|
|
|
var pointRB = new BMapGL.Point(pointB.lng, pointB.lat); // 右下角
|
|
|
var pointLB = new BMapGL.Point(pointA.lng, pointB.lat); // 左上角
|
|
|
|
|
|
var pointTC = new BMapGL.Point((pointA.lng + pointB.lng) / 2, pointA.lat);
|
|
|
var pointRC = new BMapGL.Point(pointB.lng, (pointA.lat + pointB.lat) / 2);
|
|
|
var pointBC = new BMapGL.Point((pointA.lng + pointB.lng) / 2, pointB.lat);
|
|
|
var pointLC = new BMapGL.Point(pointA.lng, (pointA.lat + pointB.lat) / 2);
|
|
|
|
|
|
return [pointLT, pointTC, pointRT, pointRC, pointRB, pointBC, pointLB, pointLC];
|
|
|
}
|
|
|
|
|
|
var moveIcon = new BMapGL.Icon('//mapopen.bj.bcebos.com/cms/images/DrawingManager/bullet2.png', new BMapGL.Size(10, 10));
|
|
|
moveIcon.setImageSize(new BMapGL.Size(10, 10));
|
|
|
|
|
|
/**
|
|
|
* 开始绘制矩形
|
|
|
*/
|
|
|
var startAction = function (e) {
|
|
|
|
|
|
baidu.stopBubble(e);
|
|
|
baidu.preventDefault(e);
|
|
|
if (me.controlButton == 'right' && (e.button == 1 || e.button == 0)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
startPoint = e.point;
|
|
|
|
|
|
var endPoint = startPoint;
|
|
|
polygon = new BMapGL.Polygon(me._getRectanglePoint(startPoint, endPoint), me.rectangleOptions);
|
|
|
map.addOverlay(polygon);
|
|
|
mask.enableEdgeMove();
|
|
|
mask.addEventListener('mousemove', moveAction);
|
|
|
baidu.on(document, 'mouseup', endAction);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绘制矩形过程中,鼠标移动过程的事件
|
|
|
*/
|
|
|
var moveAction = function (e) {
|
|
|
map.removeOverlay(tip_label);
|
|
|
polygon.setPath(me._getRectanglePoint(startPoint, e.point));
|
|
|
|
|
|
var points = getRectAllPoints(startPoint, e.point);
|
|
|
var width = me._map.getDistance(startPoint, points[2]).toFixed(0);
|
|
|
var height = me._map.getDistance(startPoint, points[6]).toFixed(0);
|
|
|
tip_label = new BMapGL.Label('尺寸:' + width + '米 x ' + height + '米<br>松开结束绘制', {
|
|
|
position: e.point, // 指定文本标注所在的地理位置
|
|
|
offset: new BMapGL.Size(10, 10) // 设置文本偏移量
|
|
|
});
|
|
|
tip_label.setStyle(me.labelOptions);
|
|
|
map.addOverlay(tip_label);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绘制矩形结束
|
|
|
*/
|
|
|
var endAction = function (e) {
|
|
|
mask.hide();
|
|
|
var endPoint = null;
|
|
|
var markers = [];
|
|
|
var points = getRectAllPoints(startPoint, e.point);
|
|
|
var pointsTmp = [];
|
|
|
var cz = map.getViewport(points);
|
|
|
cz.zoom -= 1;
|
|
|
map.setViewport(cz);
|
|
|
map.removeOverlay(tip_label);
|
|
|
|
|
|
var width = me._map.getDistance(startPoint, points[2]).toFixed(0);
|
|
|
var height = me._map.getDistance(startPoint, points[6]).toFixed(0);
|
|
|
var rectInfo = new Screenshot('rectangle', points[0], {
|
|
|
width: width,
|
|
|
height: height
|
|
|
}, polygon, me);
|
|
|
|
|
|
for (var i = 0; i < points.length; i++) {
|
|
|
var marker = new BMapGL.Marker(points[i]);
|
|
|
marker.setIcon(moveIcon);
|
|
|
marker.enableDragging();
|
|
|
markers.push(marker);
|
|
|
map.addOverlay(marker);
|
|
|
pointsTmp[i] = me.mc2ll(marker.point);
|
|
|
|
|
|
marker.addEventListener('mousedown', function (e) {
|
|
|
endPoint = me.mc2ll(e.target.point);
|
|
|
});
|
|
|
marker.addEventListener('dragging', function (e) {
|
|
|
var point = e.latLng;
|
|
|
for (var j = 0; j < pointsTmp.length; j++) {
|
|
|
if (endPoint.lng == pointsTmp[j].lng) {
|
|
|
points[j].lng = point.lng;
|
|
|
}
|
|
|
|
|
|
if (endPoint.lat == pointsTmp[j].lat) {
|
|
|
points[j].lat = point.lat;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
points = getRectAllPoints(points[0], points[4]);
|
|
|
for (var j = 0; j < markers.length; j++) {
|
|
|
markers[j].setPosition(points[j]);
|
|
|
}
|
|
|
width = me._map.getDistance(points[0], points[2]).toFixed(0);
|
|
|
height = me._map.getDistance(points[0], points[6]).toFixed(0);
|
|
|
rectInfo.setInfo(points[0], {
|
|
|
width: width,
|
|
|
height: height
|
|
|
});
|
|
|
operateWindow.setPosition(points[3], true);
|
|
|
polygon.setPath(points);
|
|
|
});
|
|
|
marker.addEventListener('dragend', function (e) {
|
|
|
for (var i = 0; i < markers.length; i++) {
|
|
|
var marker = markers[i];
|
|
|
pointsTmp[i] = me.mc2ll(marker.point);
|
|
|
}
|
|
|
operateWindow.updateWindow();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
rectInfo.addEventListener('rectwhchange', function (e) {
|
|
|
var width = e.width;
|
|
|
var height = e.height;
|
|
|
var pointx = getPointByDistance(points[0], width, 'east');
|
|
|
var pointy = getPointByDistance(points[0], height, 'south');
|
|
|
points[4].lng = pointx.lng;
|
|
|
points[4].lat = pointy.lat;
|
|
|
points = getRectAllPoints(points[0], points[4]);
|
|
|
for (var j = 0; j < markers.length; j++) {
|
|
|
markers[j].setPosition(points[j]);
|
|
|
}
|
|
|
rectInfo.setInfo(points[0], {
|
|
|
width: width,
|
|
|
height: height
|
|
|
});
|
|
|
operateWindow.setPosition(points[3], true);
|
|
|
polygon.setPath(points);
|
|
|
for (var i = 0; i < markers.length; i++) {
|
|
|
var marker = markers[i];
|
|
|
pointsTmp[i] = me.mc2ll(marker.point);
|
|
|
}
|
|
|
operateWindow.updateWindow();
|
|
|
});
|
|
|
|
|
|
var overlays = [markers, rectInfo];
|
|
|
var limit = null;
|
|
|
if (me.limit) {
|
|
|
limit = me.limit.area;
|
|
|
}
|
|
|
|
|
|
var overlay = {
|
|
|
limit: limit,
|
|
|
type: 'rectangle',
|
|
|
point: points[3],
|
|
|
overlay: polygon,
|
|
|
overlays: overlays
|
|
|
};
|
|
|
|
|
|
var operateWindow = new Operate(overlay, me);
|
|
|
map.addOverlay(operateWindow);
|
|
|
map.addOverlay(rectInfo);
|
|
|
|
|
|
mask.disableEdgeMove();
|
|
|
mask.removeEventListener('mousemove', moveAction);
|
|
|
mask.removeEventListener('mousemove', mousemoveAction);
|
|
|
baidu.un(document, 'mouseup', endAction);
|
|
|
me.close();
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 非绘制矩形过程中,鼠标移动过程的事件
|
|
|
*/
|
|
|
var mousemoveAction = function (e) {
|
|
|
baidu.preventDefault(e);
|
|
|
baidu.stopBubble(e);
|
|
|
|
|
|
map.removeOverlay(tip_label);
|
|
|
|
|
|
tip_label = new BMapGL.Label('按住确认起点,拖拽进行绘制', {
|
|
|
position: e.point, // 指定文本标注所在的地理位置
|
|
|
offset: new BMapGL.Size(10, 10) // 设置文本偏移量
|
|
|
});
|
|
|
tip_label.setStyle(me.labelOptions);
|
|
|
map.addOverlay(tip_label);
|
|
|
};
|
|
|
|
|
|
mask.addEventListener('mousedown', startAction);
|
|
|
mask.addEventListener('mousemove', mousemoveAction);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 添加显示所绘制图形的面积或者长度
|
|
|
* @param {overlay} 覆盖物
|
|
|
* @param {point} 显示的位置
|
|
|
*/
|
|
|
DrawingManager.prototype._calculate = function (overlay, point) {
|
|
|
var result = {
|
|
|
data: 0, // 计算出来的长度或面积
|
|
|
label: null // 显示长度或面积的label对象
|
|
|
};
|
|
|
|
|
|
if (this._enableCalculate && BMapGLLib.GeoUtils) {
|
|
|
var type = overlay.toString();
|
|
|
// 不同覆盖物调用不同的计算方法
|
|
|
switch (type) {
|
|
|
case 'Polyline': //[object Polyline]==>在3D版本中已经转为了Polyline
|
|
|
result.data = BMapGLLib.GeoUtils.getPolylineDistance(overlay);
|
|
|
break;
|
|
|
case 'Polygon':
|
|
|
result.data = BMapGLLib.GeoUtils.getPolygonArea(overlay);
|
|
|
break;
|
|
|
case 'Circle':
|
|
|
var radius = overlay.getRadius();
|
|
|
result.data = Math.PI * radius * radius;
|
|
|
break;
|
|
|
}
|
|
|
// 异常情况处理
|
|
|
if (!result.data || result.data < 0) {
|
|
|
result.data = 0;
|
|
|
console.error('计算函数异常处理');
|
|
|
} else {
|
|
|
// 保留2位小数位
|
|
|
result.data = result.data.toFixed(2);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 这里我们只需要开启计算面积功能,但并不需要在地图上添加显示面积的label,所以注释掉
|
|
|
*/
|
|
|
// result.label = this._addLabel(point, result.data);
|
|
|
}
|
|
|
return result;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 开启测距和测面功能需要依赖于GeoUtils库
|
|
|
* 所以这里判断用户是否已经加载,若未加载则用js动态加载
|
|
|
*/
|
|
|
DrawingManager.prototype._addGeoUtilsLibrary = function () {
|
|
|
if (!BMapGLLib.GeoUtils) {
|
|
|
var script = document.createElement('script');
|
|
|
script.setAttribute('type', 'text/javascript');
|
|
|
script.setAttribute('src', '//mapopen.cdn.bcebos.com/github/BMapGLLib/GeoUtils/src/GeoUtils.min.js');
|
|
|
// script.setAttribute('src', '../../GeoUtils/GeoUtils.js');
|
|
|
document.body.appendChild(script);
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 开启裁剪功能需要依赖于gpc库
|
|
|
* 所以这里判断用户是否已经加载,若未加载则用js动态加载
|
|
|
*/
|
|
|
DrawingManager.prototype._addGPCLibrary = function () {
|
|
|
if (!window.gpcas) {
|
|
|
var script = document.createElement('script');
|
|
|
script.setAttribute('type', 'text/javascript');
|
|
|
script.setAttribute('src', '//mapopen.cdn.bcebos.com/github/BMapGLLib/DrawingManager/src/gpc.js');
|
|
|
// script.setAttribute('src', '../src/gpc.js');
|
|
|
document.body.appendChild(script);
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 向地图中添加文本标注
|
|
|
* @param {Point}
|
|
|
* @param {String} 所以显示的内容
|
|
|
*/
|
|
|
DrawingManager.prototype._addLabel = function (point, content) {
|
|
|
var label = new BMapGL.Label(content, {
|
|
|
position: point
|
|
|
});
|
|
|
this._map.addOverlay(label);
|
|
|
return label;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 根据起终点获取矩形的四个顶点
|
|
|
* @param {Point} 起点
|
|
|
* @param {Point} 终点
|
|
|
*/
|
|
|
DrawingManager.prototype._getRectanglePoint = function (startPoint, endPoint) {
|
|
|
return [
|
|
|
new BMapGL.Point(startPoint.lng, startPoint.lat),
|
|
|
new BMapGL.Point(endPoint.lng, startPoint.lat),
|
|
|
new BMapGL.Point(endPoint.lng, endPoint.lat),
|
|
|
new BMapGL.Point(startPoint.lng, endPoint.lat)
|
|
|
];
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 派发成功事件
|
|
|
*/
|
|
|
DrawingManager.prototype._dispatchOverlayComplete = function (overlay, calculate) {
|
|
|
var options = {
|
|
|
overlay: overlay,
|
|
|
drawingMode: this._drawingType
|
|
|
};
|
|
|
if (calculate) {
|
|
|
options.calculate = calculate.data || null;
|
|
|
options.label = calculate.label || null;
|
|
|
}
|
|
|
|
|
|
this.dispatchEvent(this._drawingType + 'complete', overlay);
|
|
|
this.dispatchEvent('overlaycomplete', options);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 派发失败事件
|
|
|
*/
|
|
|
DrawingManager.prototype._dispatchOverlayCancel = function (overlay) {
|
|
|
var options = {
|
|
|
overlay: overlay,
|
|
|
drawingMode: this._drawingType
|
|
|
};
|
|
|
|
|
|
this.dispatchEvent(this._drawingType + 'cancel', overlay);
|
|
|
this.dispatchEvent('overlaycancel', options);
|
|
|
};
|
|
|
|
|
|
// 判断吸附算法
|
|
|
DrawingManager.prototype.getSorptionMatch = function (point, polygons, distance) {
|
|
|
distance = distance || 20;
|
|
|
var map = this._map;
|
|
|
var P = map.pointToPixel(point); // point.pixel;
|
|
|
var match = [];
|
|
|
for (var j = 0; j < polygons.length; j++) {
|
|
|
var pixels = polygons[j].getPath();
|
|
|
var first = pixels[0];
|
|
|
var last = pixels[pixels.length - 1];
|
|
|
if (!first.equals(last)) {
|
|
|
pixels.push(pixels[0]);
|
|
|
}
|
|
|
for (var i = 1; i < pixels.length; i++) {
|
|
|
var A = map.pointToPixel(pixels[i - 1]);
|
|
|
var B = map.pointToPixel(pixels[i]);
|
|
|
var vAP = [P.x - A.x, P.y - A.y];
|
|
|
var vAB = [B.x - A.x, B.y - A.y];
|
|
|
var vPB = [B.x - P.x, B.y - P.y];
|
|
|
var cAPAB = vAP[0] * vAB[0] + vAP[1] * vAB[1];
|
|
|
var lAPAB = Math.sqrt(Math.pow(vAP[0], 2) + Math.pow(vAP[1], 2)) * Math.sqrt(Math.pow(vAB[0], 2) + Math.pow(vAB[1], 2));
|
|
|
var rPAB = Math.acos(cAPAB / lAPAB);
|
|
|
var cABPB = vAB[0] * vPB[0] + vAB[1] * vPB[1];
|
|
|
var lABPB = Math.sqrt(Math.pow(vAB[0], 2) + Math.pow(vAB[1], 2)) * Math.sqrt(Math.pow(vPB[0], 2) + Math.pow(vPB[1], 2));
|
|
|
var rPBA = Math.acos(cABPB / lABPB);
|
|
|
if (rPAB < Math.PI / 2 && rPBA < Math.PI / 2) {
|
|
|
var lAP = Math.sqrt(Math.pow(vAP[0], 2) + Math.pow(vAP[1], 2));
|
|
|
var lAB = Math.sqrt(Math.pow(vAB[0], 2) + Math.pow(vAB[1], 2));
|
|
|
var lAO = Math.cos(rPAB) * lAP;
|
|
|
var pAOAB = lAO / lAB;
|
|
|
var lPO = Math.sin(rPAB) * lAP;
|
|
|
var O = [A.x + vAB[0] * pAOAB, A.y + vAB[1] * pAOAB];
|
|
|
if (lPO < distance) {
|
|
|
match.push({
|
|
|
point: map.pixelToPoint({
|
|
|
x: O[0],
|
|
|
y: O[1]
|
|
|
}),
|
|
|
length: lPO
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
match.sort(function (a, b) {
|
|
|
return a.length - b.length;
|
|
|
});
|
|
|
var ret = match.length > 0 ? match : null;
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
// 墨卡托坐标转经纬度
|
|
|
DrawingManager.prototype.mc2ll = function (point) {
|
|
|
var map = this._map;
|
|
|
var ll = map.mercatorToLnglat(point.lng, point.lat);
|
|
|
return new BMapGL.Point(ll[0], ll[1]);
|
|
|
};
|
|
|
|
|
|
// 经纬度坐标转墨卡托
|
|
|
DrawingManager.prototype.ll2mc = function (point) {
|
|
|
var map = this._map;
|
|
|
var mc = map.lnglatToMercator(point.lng, point.lat);
|
|
|
return new BMapGL.Point(mc[0], mc[1]);
|
|
|
};
|
|
|
|
|
|
// 确认,取消操作覆盖物
|
|
|
function Operate(data, DrawingManager) {
|
|
|
this.limit = data.limit;
|
|
|
this.type = data.type;
|
|
|
this.point = data.point;
|
|
|
this.overlay = data.overlay;
|
|
|
this.overlays = data.overlays;
|
|
|
this.DrawingManager = DrawingManager;
|
|
|
}
|
|
|
|
|
|
Operate.prototype = new BMapGL.Overlay();
|
|
|
Operate.prototype.dispatchEvent = baidu.lang.Class.prototype.dispatchEvent;
|
|
|
Operate.prototype.addEventListener = baidu.lang.Class.prototype.addEventListener;
|
|
|
Operate.prototype.removeEventListener = baidu.lang.Class.prototype.removeEventListener;
|
|
|
|
|
|
Operate.prototype.initialize = function (map) {
|
|
|
var me = this;
|
|
|
this._map = map;
|
|
|
var overlyTypeText = (this.type === 'polyline' ? '长度' : '面积');
|
|
|
var unit = (this.type === 'polyline' ? '万米' : '万平方米');
|
|
|
var div = this.div = document.createElement('div');
|
|
|
div.className = 'operateWindow';
|
|
|
var html = '<div><span id="confirmOperate"></span><span id="cancelOperate"></span><span id="warnOperate">' + overlyTypeText + '不超过' + this.limit / 10000 + unit + '!</span></div>';
|
|
|
div.innerHTML = html;
|
|
|
this._map.getPanes().markerPane.appendChild(div);
|
|
|
this.updateWindow();
|
|
|
this._bind();
|
|
|
return div;
|
|
|
};
|
|
|
|
|
|
Operate.prototype._bind = function () {
|
|
|
var that = this;
|
|
|
var map = this._map;
|
|
|
var overlay = this.overlay;
|
|
|
var overlays = this.overlays;
|
|
|
document.getElementById('confirmOperate').addEventListener('click', function (e) {
|
|
|
map.removeOverlay(that);
|
|
|
|
|
|
if (that.type == 'rectangle') {
|
|
|
var calculate = that.DrawingManager._calculate(overlay, overlay.getPath());
|
|
|
}
|
|
|
else if (that.type == 'circle') {
|
|
|
var calculate = that.DrawingManager._calculate(overlay, that.point);
|
|
|
}
|
|
|
else if (that.type == 'polygon') {
|
|
|
var calculate = that.DrawingManager._calculate(overlay, (overlay.getPath()));
|
|
|
that.DrawingManager.overlays.push(overlay);
|
|
|
overlay.disableEditing();
|
|
|
}
|
|
|
else if (that.type == 'polyline') {
|
|
|
var calculate = that.DrawingManager._calculate(overlay, (overlay.getPath()));
|
|
|
that.DrawingManager.overlays.push(overlay);
|
|
|
overlay.disableEditing();
|
|
|
}
|
|
|
|
|
|
that.DrawingManager._dispatchOverlayComplete(overlay, calculate);
|
|
|
|
|
|
for (var i = 0; i < overlays.length; i++) {
|
|
|
if (Array.isArray(overlays[i])) {
|
|
|
for (var k in overlays[i]) {
|
|
|
map.removeOverlay(overlays[i][k]);
|
|
|
}
|
|
|
} else {
|
|
|
map.removeOverlay(overlays[i]);
|
|
|
}
|
|
|
}
|
|
|
that.DrawingManager.close();
|
|
|
});
|
|
|
document.getElementById('cancelOperate').addEventListener('click', function (e) {
|
|
|
map.removeOverlay(that);
|
|
|
for (var i = 0; i < overlays.length; i++) {
|
|
|
if (Array.isArray(overlays[i])) {
|
|
|
for (var k in overlays[i]) {
|
|
|
map.removeOverlay(overlays[i][k]);
|
|
|
}
|
|
|
} else {
|
|
|
map.removeOverlay(overlays[i]);
|
|
|
}
|
|
|
}
|
|
|
map.removeOverlay(overlay);
|
|
|
|
|
|
that.DrawingManager._dispatchOverlayCancel(overlay);
|
|
|
that.DrawingManager._mask.show();
|
|
|
that.DrawingManager._setDrawingMode(that.type);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
Operate.prototype.updateWindow = function () {
|
|
|
if (this.domElement === null) {
|
|
|
return;
|
|
|
}
|
|
|
var overlay = this.overlay;
|
|
|
var limit = this.limit;
|
|
|
var calculate;
|
|
|
if (this.type == 'rectangle') {
|
|
|
calculate = this.DrawingManager._calculate(overlay, overlay.getPath());
|
|
|
}
|
|
|
else if (this.type == 'circle') {
|
|
|
calculate = this.DrawingManager._calculate(overlay, this.point);
|
|
|
}
|
|
|
else if (this.type == 'polygon') {
|
|
|
calculate = this.DrawingManager._calculate(overlay, overlay.getPath());
|
|
|
}
|
|
|
else if (this.type == 'polyline') {
|
|
|
calculate = this.DrawingManager._calculate(overlay, overlay.getPath());
|
|
|
}
|
|
|
|
|
|
if (Object.prototype.toString.call(limit) === '[object Number]' && calculate.data > limit) {
|
|
|
document.getElementById('confirmOperate').style.display = 'none';
|
|
|
document.getElementById('warnOperate').style.display = 'block';
|
|
|
}
|
|
|
else {
|
|
|
document.getElementById('confirmOperate').style.display = 'block';
|
|
|
document.getElementById('warnOperate').style.display = 'none';
|
|
|
}
|
|
|
};
|
|
|
|
|
|
Operate.prototype.setPosition = function (point, isright) {
|
|
|
this.point = point;
|
|
|
var map = this._map,
|
|
|
pixel = map.pointToOverlayPixel(this.point);
|
|
|
if (isright) {
|
|
|
this.div.classList.remove('operateLeft');
|
|
|
this.div.style.left = pixel.x + 15 + 'px';
|
|
|
}
|
|
|
else {
|
|
|
this.div.classList.add('operateLeft');
|
|
|
this.div.style.left = pixel.x - 105 + 'px';
|
|
|
}
|
|
|
this.div.style.top = pixel.y - 16 + 'px';
|
|
|
};
|
|
|
|
|
|
Operate.prototype.draw = function () {
|
|
|
var map = this._map,
|
|
|
pixel = map.pointToOverlayPixel(this.point);
|
|
|
this.div.style.left = pixel.x + 15 + 'px';
|
|
|
this.div.style.top = pixel.y - 16 + 'px';
|
|
|
};
|
|
|
|
|
|
// 显示,编辑半径覆盖物
|
|
|
function Screenshot(type, point, number, overlay, DrawingManager) {
|
|
|
this.type = type;
|
|
|
this.point = point;
|
|
|
this.number = number;
|
|
|
this.overlay = overlay;
|
|
|
this.DrawingManager = DrawingManager;
|
|
|
}
|
|
|
|
|
|
Screenshot.prototype = new BMapGL.Overlay();
|
|
|
|
|
|
Screenshot.prototype.dispatchEvent = baidu.lang.Class.prototype.dispatchEvent;
|
|
|
Screenshot.prototype.addEventListener = baidu.lang.Class.prototype.addEventListener;
|
|
|
Screenshot.prototype.removeEventListener = baidu.lang.Class.prototype.removeEventListener;
|
|
|
|
|
|
Screenshot.prototype.initialize = function (map) {
|
|
|
var me = this;
|
|
|
this._map = map;
|
|
|
var div = this.div = document.createElement('div');
|
|
|
div.className = 'screenshot';
|
|
|
if (this.type == 'circle') {
|
|
|
var html = '<div class="circlShot"><span id="screenshotNum">' + this.number + '</span><input id="circleInput" type="text" /><span class="unit">米</span></div>';
|
|
|
}
|
|
|
else if (this.type == 'rectangle') {
|
|
|
var html = '<div class="rectWH"><div class="wh"><span id="rectWidth">' + this.number.width + '</span><input id="rectWidthInput" type="text" /></div><span class="multiple">x</span><div class="wh"><span id="rectHeight">' + this.number.height + '</span><input id="rectHeightInput" type="text" /></div><span class="unit">米</span></div>';
|
|
|
}
|
|
|
|
|
|
div.innerHTML = html;
|
|
|
this._map.getPanes().markerPane.appendChild(div);
|
|
|
this._bind();
|
|
|
return div;
|
|
|
};
|
|
|
|
|
|
Screenshot.prototype._bind = function () {
|
|
|
this.setNumber(this.number);
|
|
|
|
|
|
if (this.type == 'circle') {
|
|
|
this.bindCircleEvent();
|
|
|
} else {
|
|
|
this.bindRectEvent();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
Screenshot.prototype.bindCircleEvent = function () {
|
|
|
var that = this;
|
|
|
var circleSpn = document.getElementById('screenshotNum');
|
|
|
var circleInput = document.getElementById('circleInput');
|
|
|
circleSpn.addEventListener('click', function (e) {
|
|
|
var val = circleSpn.innerText;
|
|
|
circleSpn.style.display = 'none';
|
|
|
circleInput.value = val;
|
|
|
circleInput.style.display = 'inline-block';
|
|
|
circleInput.focus();
|
|
|
});
|
|
|
circleInput.addEventListener('click', function (e) {
|
|
|
circleInput.focus();
|
|
|
});
|
|
|
circleInput.addEventListener('keydown', function (e) {
|
|
|
if (e.keyCode === 13) {
|
|
|
var val = circleInput.value;
|
|
|
circleInput.style.display = 'none';
|
|
|
circleSpn.style.display = 'inline-block';
|
|
|
circleSpn.innerText = val;
|
|
|
var opt = {
|
|
|
radius: val,
|
|
|
overlay: that.overlay
|
|
|
};
|
|
|
that._dispatchRadiusChange(opt);
|
|
|
}
|
|
|
});
|
|
|
circleInput.addEventListener('blur', function (e) {
|
|
|
var val = circleInput.value;
|
|
|
circleInput.style.display = 'none';
|
|
|
circleSpn.style.display = 'inline-block';
|
|
|
circleSpn.innerText = val;
|
|
|
var opt = {
|
|
|
radius: val,
|
|
|
overlay: that.overlay
|
|
|
};
|
|
|
that._dispatchRadiusChange(opt);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
Screenshot.prototype.bindRectEvent = function () {
|
|
|
var that = this;
|
|
|
var rectWidthSpn = document.getElementById('rectWidth');
|
|
|
var rectWidthInput = document.getElementById('rectWidthInput');
|
|
|
var rectHeightSpn = document.getElementById('rectHeight');
|
|
|
var rectHeightInput = document.getElementById('rectHeightInput');
|
|
|
rectWidthInput.value = rectWidthSpn.innerText;
|
|
|
rectHeightInput.value = rectHeightSpn.innerText;
|
|
|
rectWidthSpn.addEventListener('click', function (e) {
|
|
|
var val = rectWidthSpn.innerText;
|
|
|
rectWidthSpn.style.display = 'none';
|
|
|
rectWidthInput.value = val;
|
|
|
rectWidthInput.style.display = 'inline-block';
|
|
|
rectWidthInput.focus();
|
|
|
});
|
|
|
rectHeightSpn.addEventListener('click', function (e) {
|
|
|
var val = rectHeightSpn.innerText;
|
|
|
rectHeightSpn.style.display = 'none';
|
|
|
rectHeightInput.value = val;
|
|
|
rectHeightInput.style.display = 'inline-block';
|
|
|
rectHeightInput.focus();
|
|
|
});
|
|
|
rectWidthInput.addEventListener('click', function (e) {
|
|
|
rectWidthInput.focus();
|
|
|
});
|
|
|
rectHeightInput.addEventListener('click', function (e) {
|
|
|
rectHeightInput.focus();
|
|
|
});
|
|
|
rectWidthInput.addEventListener('keydown', function (e) {
|
|
|
if (e.keyCode === 13) {
|
|
|
var widthVal = rectWidthInput.value;
|
|
|
var heightVal = rectHeightInput.value;
|
|
|
rectWidthInput.style.display = 'none';
|
|
|
rectHeightInput.style.display = 'none';
|
|
|
rectWidthSpn.style.display = 'inline-block';
|
|
|
rectHeightSpn.style.display = 'inline-block';
|
|
|
rectWidthSpn.innerText = widthVal;
|
|
|
rectHeightSpn.innerText = heightVal;
|
|
|
var opt = {
|
|
|
width: widthVal,
|
|
|
height: heightVal,
|
|
|
overlay: that.overlay
|
|
|
};
|
|
|
that._dispatchRectWHChange(opt);
|
|
|
}
|
|
|
});
|
|
|
rectHeightInput.addEventListener('keydown', function (e) {
|
|
|
if (e.keyCode === 13) {
|
|
|
var widthVal = rectWidthInput.value;
|
|
|
var heightVal = rectHeightInput.value;
|
|
|
rectWidthInput.style.display = 'none';
|
|
|
rectHeightInput.style.display = 'none';
|
|
|
rectWidthSpn.style.display = 'inline-block';
|
|
|
rectHeightSpn.style.display = 'inline-block';
|
|
|
rectWidthSpn.innerText = widthVal;
|
|
|
rectHeightSpn.innerText = heightVal;
|
|
|
var opt = {
|
|
|
width: widthVal,
|
|
|
height: heightVal,
|
|
|
overlay: that.overlay
|
|
|
};
|
|
|
that._dispatchRectWHChange(opt);
|
|
|
}
|
|
|
});
|
|
|
};
|
|
|
|
|
|
Screenshot.prototype.setInfo = function (point, number) {
|
|
|
this.setNumber(number);
|
|
|
this.setPosition(point);
|
|
|
};
|
|
|
|
|
|
Screenshot.prototype.setNumber = function (number) {
|
|
|
if (this.type == 'circle') {
|
|
|
document.getElementById('screenshotNum').textContent = number;
|
|
|
}
|
|
|
else {
|
|
|
document.getElementById('rectWidth').textContent = number.width;
|
|
|
document.getElementById('rectHeight').textContent = number.height;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
Screenshot.prototype.setPosition = function (point) {
|
|
|
this.point = point;
|
|
|
var map = this._map,
|
|
|
type = this.type,
|
|
|
pixel = map.pointToOverlayPixel(this.point);
|
|
|
if (type == 'circle') {
|
|
|
this.div.style.left = pixel.x - 30 + 'px';
|
|
|
this.div.style.top = pixel.y - 40 + 'px';
|
|
|
}
|
|
|
else if (type == 'rectangle') {
|
|
|
this.div.style.left = pixel.x + 'px';
|
|
|
this.div.style.top = pixel.y - 45 + 'px';
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
Screenshot.prototype.draw = function () {
|
|
|
var map = this._map,
|
|
|
type = this.type,
|
|
|
pixel = map.pointToOverlayPixel(this.point);
|
|
|
if (type == 'circle') {
|
|
|
this.div.style.left = pixel.x - 30 + 'px';
|
|
|
this.div.style.top = pixel.y - 40 + 'px';
|
|
|
}
|
|
|
else if (type == 'rectangle') {
|
|
|
this.div.style.left = pixel.x + 'px';
|
|
|
this.div.style.top = pixel.y - 45 + 'px';
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 派发事件
|
|
|
*/
|
|
|
Screenshot.prototype._dispatchRadiusChange = function (opt) {
|
|
|
this.dispatchEvent('radiuschange', opt);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 派发事件
|
|
|
*/
|
|
|
Screenshot.prototype._dispatchRectWHChange = function (opt) {
|
|
|
this.dispatchEvent('rectwhchange', opt);
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 创建遮罩对象
|
|
|
*/
|
|
|
function Mask() {
|
|
|
|
|
|
/**
|
|
|
* 鼠标到地图边缘的时候是否自动平移地图
|
|
|
*/
|
|
|
this._enableEdgeMove = false;
|
|
|
}
|
|
|
|
|
|
Mask.prototype = new BMapGL.Overlay();
|
|
|
|
|
|
/**
|
|
|
* 这里不使用api中的自定义事件,是为了更灵活使用
|
|
|
*/
|
|
|
Mask.prototype.dispatchEvent = baidu.lang.Class.prototype.dispatchEvent;
|
|
|
Mask.prototype.addEventListener = baidu.lang.Class.prototype.addEventListener;
|
|
|
Mask.prototype.removeEventListener = baidu.lang.Class.prototype.removeEventListener;
|
|
|
|
|
|
Mask.prototype.initialize = function (map) {
|
|
|
var me = this;
|
|
|
this._map = map;
|
|
|
var div = this.container = document.createElement('div');
|
|
|
var size = this._map.getSize();
|
|
|
div.style.cssText = 'position:absolute;background:transparent;cursor:crosshair;width:' + size.width + 'px;height:' + size.height + 'px';
|
|
|
this._map.addEventListener('resize', function (e) {
|
|
|
me._adjustSize(e.size);
|
|
|
});
|
|
|
this._map.getPanes().floatPane.appendChild(div);
|
|
|
this._bind();
|
|
|
return div;
|
|
|
};
|
|
|
|
|
|
Mask.prototype.draw = function () {
|
|
|
var map = this._map,
|
|
|
point = map.pixelToPoint(new BMapGL.Pixel(0, 0)),
|
|
|
pixel = map.pointToOverlayPixel(point);
|
|
|
this.container.style.left = pixel.x + 'px';
|
|
|
this.container.style.top = pixel.y + 'px';
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 开启鼠标到地图边缘,自动平移地图
|
|
|
*/
|
|
|
Mask.prototype.enableEdgeMove = function () {
|
|
|
this._enableEdgeMove = true;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 关闭鼠标到地图边缘,自动平移地图
|
|
|
*/
|
|
|
Mask.prototype.disableEdgeMove = function () {
|
|
|
clearInterval(this._edgeMoveTimer);
|
|
|
this._enableEdgeMove = false;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绑定事件,派发自定义事件
|
|
|
*/
|
|
|
Mask.prototype._bind = function () {
|
|
|
|
|
|
var me = this,
|
|
|
map = this._map,
|
|
|
container = this.container,
|
|
|
lastMousedownXY = null,
|
|
|
lastClickXY = null;
|
|
|
|
|
|
/**
|
|
|
* 根据event对象获取鼠标的xy坐标对象
|
|
|
* @param {Event}
|
|
|
* @return {Object} {x:e.x, y:e.y}
|
|
|
*/
|
|
|
var getXYbyEvent = function (e) {
|
|
|
return {
|
|
|
x: e.clientX,
|
|
|
y: e.clientY
|
|
|
};
|
|
|
};
|
|
|
|
|
|
var domEvent = function (e) {
|
|
|
var type = e.type;
|
|
|
e = baidu.getEvent(e);
|
|
|
point = me.getDrawPoint(e); // 当前鼠标所在点的地理坐标
|
|
|
|
|
|
var dispatchEvent = function (type) {
|
|
|
e.point = point;
|
|
|
me.dispatchEvent(e);
|
|
|
};
|
|
|
|
|
|
if (type == 'mousedown') {
|
|
|
lastMousedownXY = getXYbyEvent(e);
|
|
|
}
|
|
|
|
|
|
var nowXY = getXYbyEvent(e);
|
|
|
// click经过一些特殊处理派发,其他同事件按正常的dom事件派发
|
|
|
if (type == 'click') {
|
|
|
// 鼠标点击过程不进行移动才派发click和dblclick
|
|
|
if (Math.abs(nowXY.x - lastMousedownXY.x) < 5 && Math.abs(nowXY.y - lastMousedownXY.y) < 5) {
|
|
|
if (!lastClickXY || !(Math.abs(nowXY.x - lastClickXY.x) < 5 && Math.abs(nowXY.y - lastClickXY.y) < 5)) {
|
|
|
dispatchEvent('click');
|
|
|
lastClickXY = getXYbyEvent(e);
|
|
|
} else {
|
|
|
lastClickXY = null;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
dispatchEvent(type);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 将事件都遮罩层的事件都绑定到domEvent来处理
|
|
|
*/
|
|
|
var events = ['click', 'mousedown', 'mousemove', 'mouseup', 'dblclick'],
|
|
|
index = events.length;
|
|
|
while (index--) {
|
|
|
baidu.on(container, events[index], domEvent);
|
|
|
}
|
|
|
|
|
|
// 鼠标移动过程中,到地图边缘后自动平移地图
|
|
|
baidu.on(container, 'mousemove', function (e) {
|
|
|
if (me._enableEdgeMove) {
|
|
|
me.mousemoveAction(e);
|
|
|
}
|
|
|
|
|
|
});
|
|
|
};
|
|
|
|
|
|
// 鼠标移动过程中,到地图边缘后自动平移地图
|
|
|
Mask.prototype.mousemoveAction = function (e) {
|
|
|
function getClientPosition(e) {
|
|
|
var clientX = e.clientX,
|
|
|
clientY = e.clientY;
|
|
|
if (e.changedTouches) {
|
|
|
clientX = e.changedTouches[0].clientX;
|
|
|
clientY = e.changedTouches[0].clientY;
|
|
|
}
|
|
|
|
|
|
return new BMapGL.Pixel(clientX, clientY);
|
|
|
}
|
|
|
|
|
|
var map = this._map,
|
|
|
me = this,
|
|
|
pixel = map.pointToPixel(this.getDrawPoint(e)),
|
|
|
clientPos = getClientPosition(e),
|
|
|
offsetX = clientPos.x - pixel.x,
|
|
|
offsetY = clientPos.y - pixel.y;
|
|
|
pixel = new BMapGL.Pixel((clientPos.x - offsetX), (clientPos.y - offsetY));
|
|
|
this._draggingMovePixel = pixel;
|
|
|
var point = map.pixelToPoint(pixel),
|
|
|
eventObj = {
|
|
|
pixel: pixel,
|
|
|
point: point
|
|
|
};
|
|
|
// 拖拽到地图边缘移动地图
|
|
|
this._panByX = this._panByY = 0;
|
|
|
if (pixel.x <= 20 || pixel.x >= map.width - 20 ||
|
|
|
pixel.y <= 50 || pixel.y >= map.height - 10) {
|
|
|
if (pixel.x <= 20) {
|
|
|
this._panByX = 8;
|
|
|
}
|
|
|
else if (pixel.x >= map.width - 20) {
|
|
|
this._panByX = -8;
|
|
|
}
|
|
|
|
|
|
if (pixel.y <= 50) {
|
|
|
this._panByY = 8;
|
|
|
}
|
|
|
else if (pixel.y >= map.height - 10) {
|
|
|
this._panByY = -8;
|
|
|
}
|
|
|
|
|
|
if (!this._edgeMoveTimer) {
|
|
|
this._edgeMoveTimer = setInterval(function () {
|
|
|
map.panBy(me._panByX, me._panByY, {
|
|
|
noAnimation: true
|
|
|
});
|
|
|
}, 30);
|
|
|
}
|
|
|
} else {
|
|
|
if (this._edgeMoveTimer) {
|
|
|
clearInterval(this._edgeMoveTimer);
|
|
|
this._edgeMoveTimer = null;
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
* 调整大小
|
|
|
* @param {Size}
|
|
|
*/
|
|
|
Mask.prototype._adjustSize = function (size) {
|
|
|
this.container.style.width = size.width + 'px';
|
|
|
this.container.style.height = size.height + 'px';
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 获取当前绘制点的地理坐标
|
|
|
*
|
|
|
* @param {Event} e e对象
|
|
|
* @return Point对象的位置信息
|
|
|
*/
|
|
|
Mask.prototype.getDrawPoint = function (e) {
|
|
|
|
|
|
var map = this._map,
|
|
|
trigger = baidu.getTarget(e),
|
|
|
x = e.offsetX || e.layerX || 0,
|
|
|
y = e.offsetY || e.layerY || 0;
|
|
|
if (trigger.nodeType != 1) {
|
|
|
trigger = trigger.parentNode;
|
|
|
}
|
|
|
|
|
|
while (trigger && trigger != map.getContainer()) {
|
|
|
if (!(trigger.clientWidth == 0 &&
|
|
|
trigger.clientHeight == 0 &&
|
|
|
trigger.offsetParent && trigger.offsetParent.nodeName == 'TD')) {
|
|
|
x += trigger.offsetLeft || 0;
|
|
|
y += trigger.offsetTop || 0;
|
|
|
}
|
|
|
|
|
|
trigger = trigger.offsetParent;
|
|
|
}
|
|
|
var pixel = new BMapGL.Pixel(x, y);
|
|
|
var point = map.pixelToPoint(pixel);
|
|
|
return point;
|
|
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 绘制工具面板,自定义控件
|
|
|
*/
|
|
|
function DrawingTool(drawingManager, drawingToolOptions) {
|
|
|
this.drawingManager = drawingManager;
|
|
|
|
|
|
drawingToolOptions = this.drawingToolOptions = drawingToolOptions || {};
|
|
|
this._opts = {};
|
|
|
// 默认停靠位置和偏移量
|
|
|
this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT;
|
|
|
this.defaultOffset = new BMapGL.Size(10, 10);
|
|
|
|
|
|
// 默认所有工具栏都显示
|
|
|
this.defaultDrawingModes = [
|
|
|
BMAP_DRAWING_MARKER,
|
|
|
BMAP_DRAWING_CIRCLE,
|
|
|
BMAP_DRAWING_POLYLINE,
|
|
|
BMAP_DRAWING_POLYGON,
|
|
|
BMAP_DRAWING_RECTANGLE
|
|
|
];
|
|
|
// 工具栏可显示的绘制模式
|
|
|
if (drawingToolOptions.drawingModes) {
|
|
|
this.drawingModes = drawingToolOptions.drawingModes;
|
|
|
} else {
|
|
|
this.drawingModes = this.defaultDrawingModes;
|
|
|
}
|
|
|
|
|
|
// 用户设置停靠位置和偏移量
|
|
|
if (drawingToolOptions.hasCustomStyle) {
|
|
|
if (drawingToolOptions.anchor) {
|
|
|
this.setAnchor(drawingToolOptions.anchor);
|
|
|
}
|
|
|
|
|
|
if (drawingToolOptions.offset) {
|
|
|
this.setOffset(drawingToolOptions.offset);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 通过JavaScript的prototype属性继承于BMap.Control
|
|
|
DrawingTool.prototype = new BMapGL.Control();
|
|
|
|
|
|
// 自定义控件必须实现自己的initialize方法,并且将控件的DOM元素返回
|
|
|
// 在本方法中创建个div元素作为控件的容器,并将其添加到地图容器中
|
|
|
DrawingTool.prototype.initialize = function (map) {
|
|
|
// 创建一个DOM元素
|
|
|
var container = this.container = document.createElement('div');
|
|
|
container.className = 'BMapGLLib_Drawing';
|
|
|
// 用来设置外层边框阴影
|
|
|
var panel = this.panel = document.createElement('div');
|
|
|
panel.className = 'BMapGLLib_Drawing_panel';
|
|
|
if (this.drawingToolOptions && this.drawingToolOptions.hasCustomStyle && this.drawingToolOptions.scale) {
|
|
|
this._setScale(this.drawingToolOptions.scale);
|
|
|
}
|
|
|
|
|
|
container.appendChild(panel);
|
|
|
// 添加内容
|
|
|
var content = this._generalHtml();
|
|
|
panel.appendChild(content);
|
|
|
// 添加tip
|
|
|
var tip = this.tip = document.createElement('div');
|
|
|
tip.className = 'BMapGLLib_tip';
|
|
|
tip.innerHTML = '<p class="BMapGLLib_tip_title"></p><p class="BMapGLLib_tip_text"></p>';
|
|
|
if (this.drawingToolOptions.enableTips === true) {
|
|
|
panel.appendChild(tip);
|
|
|
}
|
|
|
// 绑定事件
|
|
|
this._bind(panel);
|
|
|
// 添加DOM元素到地图中
|
|
|
if (this.drawingToolOptions.customContainer) {
|
|
|
baidu.g(this.drawingToolOptions.customContainer).appendChild(container);
|
|
|
} else {
|
|
|
map.getContainer().appendChild(container);
|
|
|
}
|
|
|
// 将DOM元素返回
|
|
|
return container;
|
|
|
};
|
|
|
|
|
|
// 生成工具栏的html元素
|
|
|
DrawingTool.prototype._generalHtml = function (map) {
|
|
|
var that = this;
|
|
|
// 鼠标经过工具栏上的提示信息
|
|
|
var tips = {};
|
|
|
tips.hander = '拖动地图';
|
|
|
tips[BMAP_DRAWING_MARKER] = '画点';
|
|
|
tips[BMAP_DRAWING_CIRCLE] = '圆形工具';
|
|
|
tips[BMAP_DRAWING_POLYLINE] = '画折线';
|
|
|
tips[BMAP_DRAWING_POLYGON] = '多边形工具';
|
|
|
tips[BMAP_DRAWING_RECTANGLE] = '矩形工具';
|
|
|
|
|
|
var getItem = function (className, drawingType) {
|
|
|
var ele = document.createElement('a');
|
|
|
ele.className = className;
|
|
|
ele.href = 'javascript:void(0)';
|
|
|
ele.setAttribute('drawingType', drawingType);
|
|
|
ele.setAttribute('onfocus', 'this.blur()');
|
|
|
ele.addEventListener('mouseenter', function (e) {
|
|
|
var drawingType = e.target.getAttribute('drawingType');
|
|
|
var title = tips[drawingType];
|
|
|
if (drawingType === 'hander') {
|
|
|
that.tip.children[0].innerText = title;
|
|
|
that.tip.children[1].innerText = '使用鼠标拖动地图';
|
|
|
} else {
|
|
|
that.tip.className += ' ' + drawingType;
|
|
|
that.tip.children[0].innerText = title;
|
|
|
that.tip.children[1].innerText = '使用' + title + '选出目标区域';
|
|
|
}
|
|
|
that.tip.style.display = 'block';
|
|
|
});
|
|
|
ele.addEventListener('mouseleave', function (e) {
|
|
|
// remove class drawingType
|
|
|
var drawingType = e.target.getAttribute('drawingType');
|
|
|
var newClass = ' ' + that.tip.className.replace(/[\t\r\n]/g, '') + ' ';
|
|
|
while (newClass.indexOf(' ' + drawingType + ' ') >= 0) {
|
|
|
newClass = newClass.replace(' ' + drawingType + ' ', ' ');
|
|
|
}
|
|
|
that.tip.className = newClass.replace(/^\s+|\s+$/g, '');
|
|
|
|
|
|
that.tip.style.display = 'none';
|
|
|
});
|
|
|
return ele;
|
|
|
};
|
|
|
|
|
|
// 生成工具
|
|
|
var fragment = document.createDocumentFragment();
|
|
|
// 取消hander工具的展示,交互改为再次点击tool取消active功能
|
|
|
// fragment.appendChild(getItem('BMapGLLib_box BMapGLLib_hander', 'hander'));
|
|
|
for (var i = 0, len = this.drawingModes.length; i < len; i++) {
|
|
|
var classStr = 'BMapGLLib_box BMapGLLib_' + this.drawingModes[i];
|
|
|
if (i == len - 1) {
|
|
|
classStr += ' BMapGLLib_last';
|
|
|
}
|
|
|
|
|
|
fragment.appendChild(getItem(classStr, this.drawingModes[i]));
|
|
|
}
|
|
|
|
|
|
return fragment;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 设置工具栏的缩放比例
|
|
|
*/
|
|
|
DrawingTool.prototype._setScale = function (scale) {
|
|
|
var width = 390,
|
|
|
height = 50,
|
|
|
ml = -parseInt((width - width * scale) / 2, 10),
|
|
|
mt = -parseInt((height - height * scale) / 2, 10);
|
|
|
this.container.style.cssText = [
|
|
|
'-moz-transform: scale(' + scale + ');',
|
|
|
'-o-transform: scale(' + scale + ');',
|
|
|
'-webkit-transform: scale(' + scale + ');',
|
|
|
'transform: scale(' + scale + ');',
|
|
|
'margin-left:' + ml + 'px;',
|
|
|
'margin-top:' + mt + 'px;',
|
|
|
'*margin-left:0px;', // ie6、7
|
|
|
'*margin-top:0px;', // ie6、7
|
|
|
'margin-left:0px\\0;', // ie8
|
|
|
'margin-top:0px\\0;', // ie8
|
|
|
// ie下使用滤镜
|
|
|
'filter: progid:DXImageTransform.Microsoft.Matrix(',
|
|
|
'M11=' + scale + ',',
|
|
|
'M12=0,',
|
|
|
'M21=0,',
|
|
|
'M22=' + scale + ',',
|
|
|
'SizingMethod=\'auto expand\');'
|
|
|
].join('');
|
|
|
};
|
|
|
|
|
|
// 绑定工具栏的事件
|
|
|
DrawingTool.prototype._bind = function (panel) {
|
|
|
var me = this;
|
|
|
baidu.on(this.panel, 'click', function (e) {
|
|
|
var target = baidu.getTarget(e);
|
|
|
var drawingType = target.getAttribute('drawingType');
|
|
|
me.setStyleByDrawingMode(drawingType);
|
|
|
me._bindEventByDraingMode(drawingType);
|
|
|
});
|
|
|
};
|
|
|
|
|
|
// 设置工具栏当前选中的项样式
|
|
|
DrawingTool.prototype.setStyleByDrawingMode = function (drawingType) {
|
|
|
if (!drawingType) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
var boxs = this.panel.getElementsByTagName('a');
|
|
|
for (var i = 0, len = boxs.length; i < len; i++) {
|
|
|
var box = boxs[i];
|
|
|
if (box.getAttribute('drawingType') == drawingType) {
|
|
|
var classStr = 'BMapGLLib_box BMapGLLib_' + drawingType + '_hover';
|
|
|
if (i == len - 1) {
|
|
|
classStr += ' BMapGLLib_last';
|
|
|
}
|
|
|
|
|
|
box.className = classStr;
|
|
|
} else {
|
|
|
box.className = box.className.replace(/_hover/, '');
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// 设置工具栏当前选中的项样式
|
|
|
DrawingTool.prototype._bindEventByDraingMode = function (drawingType) {
|
|
|
var me = this;
|
|
|
var drawingManager = this.drawingManager;
|
|
|
// 点在拖拽地图的按钮上
|
|
|
// hander工具的逻辑
|
|
|
// if (drawingType == 'hander') {
|
|
|
// drawingManager.close();
|
|
|
// drawingManager._map.enableDoubleClickZoom();
|
|
|
// }
|
|
|
// else {
|
|
|
// drawingManager.setDrawingMode(drawingType);
|
|
|
// drawingManager.open();
|
|
|
// drawingManager._map.disableDoubleClickZoom();
|
|
|
// }
|
|
|
|
|
|
// 关闭hander工具的逻辑
|
|
|
if (drawingManager._isOpen && drawingManager.getDrawingMode() === drawingType) {
|
|
|
drawingManager.close();
|
|
|
drawingManager._map.enableDoubleClickZoom();
|
|
|
} else {
|
|
|
drawingManager.setDrawingMode(drawingType);
|
|
|
drawingManager.open();
|
|
|
drawingManager._map.disableDoubleClickZoom();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// 用来存储用户实例化出来的drawingmanager对象
|
|
|
var instances = [];
|
|
|
|
|
|
/*
|
|
|
* 关闭其他实例的绘制模式
|
|
|
* @param {DrawingManager} 当前的实例
|
|
|
*/
|
|
|
function closeInstanceExcept(instance) {
|
|
|
var index = instances.length;
|
|
|
while (index--) {
|
|
|
if (instances[index] != instance) {
|
|
|
instances[index].close();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function drawcircle(center, radius) {
|
|
|
var points = [];
|
|
|
var cx = center["lng"],
|
|
|
cy = center["lat"];
|
|
|
var d = radius / 6378800, // circle radius / meters of Earth radius = radians
|
|
|
lat1 = (Math.PI / 180) * cy,
|
|
|
lng1 = (Math.PI / 180) * cx;
|
|
|
|
|
|
for (var i = 0; i < 271; i += 9) {
|
|
|
var tc = (Math.PI / 180) * i,
|
|
|
y = Math.asin(Math.sin(lat1) * Math.cos(d) + Math.cos(lat1) * Math.sin(d) * Math.cos(tc)),
|
|
|
dlng = Math.atan2(Math.sin(tc) * Math.sin(d) * Math.cos(lat1), Math.cos(d) - Math.sin(lat1) * Math.sin(y)),
|
|
|
x = ((lng1 - dlng + Math.PI) % (2 * Math.PI)) - Math.PI,
|
|
|
point = new BMapGL.Point(x * (180 / Math.PI), y * (180 / Math.PI));
|
|
|
points.push(point);
|
|
|
}
|
|
|
|
|
|
var fstPoint = points[0];
|
|
|
points.push(new BMapGL.Point(fstPoint["lng"], fstPoint["lat"]));
|
|
|
return points;
|
|
|
}
|
|
|
|
|
|
function getPointByDistance(srcPoint, distance, direction) {
|
|
|
var cx = srcPoint["lng"],
|
|
|
cy = srcPoint["lat"];
|
|
|
var d = distance / 6378800, // circle radius / meters of Earth radius = radians
|
|
|
lat1 = (Math.PI / 180) * cy,
|
|
|
lng1 = (Math.PI / 180) * cx;
|
|
|
var i,tmplng,tmplat;
|
|
|
switch (direction) {
|
|
|
case 'North':
|
|
|
case 'north':
|
|
|
case 'N':
|
|
|
case 'n':
|
|
|
i = 0;
|
|
|
tmplng = srcPoint.lng;
|
|
|
break;
|
|
|
case 'West':
|
|
|
case 'west':
|
|
|
case 'W':
|
|
|
case 'w':
|
|
|
i = 90;
|
|
|
tmplat = srcPoint.lat;
|
|
|
break;
|
|
|
case 'South':
|
|
|
case 'south':
|
|
|
case 'S':
|
|
|
case 's':
|
|
|
i = 180;
|
|
|
tmplng = srcPoint.lng;
|
|
|
break;
|
|
|
case 'East':
|
|
|
case 'east':
|
|
|
case 'E':
|
|
|
case 'e':
|
|
|
i = 270;
|
|
|
tmplat = srcPoint.lat;
|
|
|
break;
|
|
|
default:
|
|
|
i = ~~direction;
|
|
|
break;
|
|
|
}
|
|
|
var tc = (Math.PI / 180) * i,
|
|
|
y = Math.asin(Math.sin(lat1) * Math.cos(d) + Math.cos(lat1) * Math.sin(d) * Math.cos(tc)),
|
|
|
dlng = Math.atan2(Math.sin(tc) * Math.sin(d) * Math.cos(lat1), Math.cos(d) - Math.sin(lat1) * Math.sin(y)),
|
|
|
x = ((lng1 - dlng + Math.PI) % (2 * Math.PI)) - Math.PI,
|
|
|
point = new BMapGL.Point(tmplng || x * (180 / Math.PI), tmplat || y * (180 / Math.PI));
|
|
|
point.lng = parseFloat(point.lng.toFixed(6));
|
|
|
point.lat = parseFloat(point.lat.toFixed(6));
|
|
|
return point;
|
|
|
}
|
|
|
|
|
|
})();
|