1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global.BMapLib = global.BMapLib || {}, global.BMapLib.MarkerClusterer = factory());
- }(this, (function () { 'use strict';
- var __commonjs_global = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : this;
- function __commonjs(fn, module) { return module = { exports: {} }, fn(module, module.exports, __commonjs_global), module.exports; }
- var index$1 = __commonjs(function (module, exports, global) {
- (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.TextIconOverlay = root.BMapLib.TextIconOverlay || factory();
- }
- })(__commonjs_global, function() {
- var T,
- baidu = T = baidu || {version: "1.3.8"};
- var context = {};
- //提出guid,防止在与老版本Tangram混用时
- //在下一行错误的修改context[undefined]
- baidu.guid = "$BAIDU$";
- //Tangram可能被放在闭包中
- //一些页面级别唯一的属性,需要挂载在context[baidu.guid]上
- context[baidu.guid] = context[baidu.guid] || {};
- /**
- * @ignore
- * @namespace baidu.dom 操作dom的方法。
- */
- baidu.dom = baidu.dom || {};
-
- /**
- * 从文档中获取指定的DOM元素
- * @name baidu.dom.g
- * @function
- * @grammar baidu.dom.g(id)
- * @param {string|HTMLElement} id 元素的id或DOM元素
- * @shortcut g,T.G
- * @meta standard
- * @see baidu.dom.q
- *
- * @returns {HTMLElement|null} 获取的元素,查找不到时返回null,如果参数不合法,直接返回参数
- */
- baidu.dom.g = function (id) {
- if ('string' == typeof id || id instanceof String) {
- return document.getElementById(id);
- } else if (id && id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {
- return id;
- }
- return null;
- };
- // 声明快捷方法
- baidu.g = baidu.G = baidu.dom.g;
- /**
- * 获取目标元素所属的document对象
- * @name baidu.dom.getDocument
- * @function
- * @grammar baidu.dom.getDocument(element)
- * @param {HTMLElement|string} element 目标元素或目标元素的id
- * @meta standard
- * @see baidu.dom.getWindow
- *
- * @returns {HTMLDocument} 目标元素所属的document对象
- */
- baidu.dom.getDocument = function (element) {
- element = baidu.dom.g(element);
- return element.nodeType == 9 ? element : element.ownerDocument || element.document;
- };
- /**
- * @ignore
- * @namespace baidu.lang 对语言层面的封装,包括类型判断、模块扩展、继承基类以及对象自定义事件的支持。
- */
- baidu.lang = baidu.lang || {};
- /**
- * 判断目标参数是否string类型或String对象
- * @name baidu.lang.isString
- * @function
- * @grammar baidu.lang.isString(source)
- * @param {Any} source 目标参数
- * @shortcut isString
- * @meta standard
- * @see baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate
- *
- * @returns {boolean} 类型判断结果
- */
- baidu.lang.isString = function (source) {
- return '[object String]' == Object.prototype.toString.call(source);
- };
- // 声明快捷方法
- baidu.isString = baidu.lang.isString;
- /**
- * 从文档中获取指定的DOM元素
- * **内部方法**
- *
- * @param {string|HTMLElement} id 元素的id或DOM元素
- * @meta standard
- * @return {HTMLElement} DOM元素,如果不存在,返回null,如果参数不合法,直接返回参数
- */
- baidu.dom._g = function (id) {
- if (baidu.lang.isString(id)) {
- return document.getElementById(id);
- }
- return id;
- };
- // 声明快捷方法
- baidu._g = baidu.dom._g;
- /**
- * @ignore
- * @namespace baidu.browser 判断浏览器类型和特性的属性。
- */
- baidu.browser = baidu.browser || {};
- if (/msie (\d+\.\d)/i.test(navigator.userAgent)) {
- //IE 8下,以documentMode为准
- //在百度模板中,可能会有$,防止冲突,将$1 写成 \x241
- /**
- * 判断是否为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.ie = baidu.ie = document.documentMode || + RegExp['\x241'];
- }
- /**
- * 获取目标元素的computed style值。如果元素的样式值不能被浏览器计算,则会返回空字符串(IE)
- *
- * @author berg
- * @name baidu.dom.getComputedStyle
- * @function
- * @grammar baidu.dom.getComputedStyle(element, key)
- * @param {HTMLElement|string} element 目标元素或目标元素的id
- * @param {string} key 要获取的样式名
- *
- * @see baidu.dom.getStyle
- *
- * @returns {string} 目标元素的computed style值
- */
- baidu.dom.getComputedStyle = function(element, key){
- element = baidu.dom._g(element);
- var doc = baidu.dom.getDocument(element),
- styles;
- if (doc.defaultView && doc.defaultView.getComputedStyle) {
- styles = doc.defaultView.getComputedStyle(element, null);
- if (styles) {
- return styles[key] || styles.getPropertyValue(key);
- }
- }
- return '';
- };
- /**
- * 提供给setStyle与getStyle使用
- */
- baidu.dom._styleFixer = baidu.dom._styleFixer || {};
- /**
- * 提供给setStyle与getStyle使用
- */
- baidu.dom._styleFilter = baidu.dom._styleFilter || [];
- /**
- * 为获取和设置样式的过滤器
- * @private
- * @meta standard
- */
- baidu.dom._styleFilter.filter = function (key, value, method) {
- for (var i = 0, filters = baidu.dom._styleFilter, filter; filter = filters[i]; i++) {
- if (filter = filter[method]) {
- value = filter(key, value);
- }
- }
- return value;
- };
- /**
- * @ignore
- * @namespace baidu.string 操作字符串的方法。
- */
- baidu.string = baidu.string || {};
- /**
- * 将目标字符串进行驼峰化处理
- * @name baidu.string.toCamelCase
- * @function
- * @grammar baidu.string.toCamelCase(source)
- * @param {string} source 目标字符串
- * @remark
- * 支持单词以“-_”分隔
- * @meta standard
- *
- * @returns {string} 驼峰化处理后的字符串
- */
- baidu.string.toCamelCase = function (source) {
- //提前判断,提高getStyle等的效率 thanks xianwei
- if (source.indexOf('-') < 0 && source.indexOf('_') < 0) {
- return source;
- }
- return source.replace(/[-_][^-_]/g, function (match) {
- return match.charAt(1).toUpperCase();
- });
- };
- /**
- * 获取目标元素的样式值
- * @name baidu.dom.getStyle
- * @function
- * @grammar baidu.dom.getStyle(element, key)
- * @param {HTMLElement|string} element 目标元素或目标元素的id
- * @param {string} key 要获取的样式名
- * @remark
- *
- * 为了精简代码,本模块默认不对任何浏览器返回值进行归一化处理(如使用getStyle时,不同浏览器下可能返回rgb颜色或hex颜色),也不会修复浏览器的bug和差异性(如设置IE的float属性叫styleFloat,firefox则是cssFloat)。<br />
- * baidu.dom._styleFixer和baidu.dom._styleFilter可以为本模块提供支持。<br />
- * 其中_styleFilter能对颜色和px进行归一化处理,_styleFixer能对display,float,opacity,textOverflow的浏览器兼容性bug进行处理。
- * @shortcut getStyle
- * @meta standard
- * @see baidu.dom.setStyle,baidu.dom.setStyles, baidu.dom.getComputedStyle
- *
- * @returns {string} 目标元素的样式值
- */
- baidu.dom.getStyle = function (element, key) {
- var dom = baidu.dom;
- element = dom.g(element);
- key = baidu.string.toCamelCase(key);
- //computed style, then cascaded style, then explicitly set style.
- var value = element.style[key] ||
- (element.currentStyle ? element.currentStyle[key] : "") ||
- dom.getComputedStyle(element, key);
- // 在取不到值的时候,用fixer进行修正
- if (!value) {
- var fixer = dom._styleFixer[key];
- if(fixer){
- value = fixer.get ? fixer.get(element) : baidu.dom.getStyle(element, fixer);
- }
- }
- /* 检查结果过滤器 */
- if (fixer = dom._styleFilter) {
- value = fixer.filter(key, value, 'get');
- }
- return value;
- };
- // 声明快捷方法
- baidu.getStyle = baidu.dom.getStyle;
- if (/opera\/(\d+\.\d)/i.test(navigator.userAgent)) {
- /**
- * 判断是否为opera浏览器
- * @property opera opera版本号
- * @grammar baidu.browser.opera
- * @meta standard
- * @see baidu.browser.ie,baidu.browser.firefox,baidu.browser.safari,baidu.browser.chrome
- */
- baidu.browser.opera = + RegExp['\x241'];
- }
- /**
- * 判断是否为webkit内核
- * @property isWebkit
- * @grammar baidu.browser.isWebkit
- * @meta standard
- * @see baidu.browser.isGecko
- */
- baidu.browser.isWebkit = /webkit/i.test(navigator.userAgent);
- /**
- * 判断是否为gecko内核
- * @property isGecko
- * @grammar baidu.browser.isGecko
- * @meta standard
- * @see baidu.browser.isWebkit
- */
- baidu.browser.isGecko = /gecko/i.test(navigator.userAgent) && !/like gecko/i.test(navigator.userAgent);
- /**
- * 判断是否严格标准的渲染模式
- * @property isStrict
- * @grammar baidu.browser.isStrict
- * @meta standard
- */
- baidu.browser.isStrict = document.compatMode == "CSS1Compat";
- /**
- * 获取目标元素相对于整个文档左上角的位置
- * @name baidu.dom.getPosition
- * @function
- * @grammar baidu.dom.getPosition(element)
- * @param {HTMLElement|string} element 目标元素或目标元素的id
- * @meta standard
- *
- * @returns {Object} 目标元素的位置,键值为top和left的Object。
- */
- baidu.dom.getPosition = function (element) {
- element = baidu.dom.g(element);
- var doc = baidu.dom.getDocument(element),
- browser = baidu.browser,
- getStyle = baidu.dom.getStyle,
- // Gecko 1.9版本以下用getBoxObjectFor计算位置
- // 但是某些情况下是有bug的
- // 对于这些有bug的情况
- // 使用递归查找的方式
- BUGGY_GECKO_BOX_OBJECT = browser.isGecko > 0 &&
- doc.getBoxObjectFor &&
- getStyle(element, 'position') == 'absolute' &&
- (element.style.top === '' || element.style.left === ''),
- pos = {"left":0,"top":0},
- viewport = (browser.ie && !browser.isStrict) ? doc.body : doc.documentElement,
- parent,
- box;
- if(element == viewport){
- return pos;
- }
- if(element.getBoundingClientRect){ // IE and Gecko 1.9+
-
- //当HTML或者BODY有border width时, 原生的getBoundingClientRect返回值是不符合预期的
- //考虑到通常情况下 HTML和BODY的border只会设成0px,所以忽略该问题.
- box = element.getBoundingClientRect();
- pos.left = Math.floor(box.left) + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);
- pos.top = Math.floor(box.top) + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
-
- // IE会给HTML元素添加一个border,默认是medium(2px)
- // 但是在IE 6 7 的怪异模式下,可以被html { border: 0; } 这条css规则覆盖
- // 在IE7的标准模式下,border永远是2px,这个值通过clientLeft 和 clientTop取得
- // 但是。。。在IE 6 7的怪异模式,如果用户使用css覆盖了默认的medium
- // clientTop和clientLeft不会更新
- pos.left -= doc.documentElement.clientLeft;
- pos.top -= doc.documentElement.clientTop;
-
- var htmlDom = doc.body,
- // 在这里,不使用element.style.borderLeftWidth,只有computedStyle是可信的
- htmlBorderLeftWidth = parseInt(getStyle(htmlDom, 'borderLeftWidth')),
- htmlBorderTopWidth = parseInt(getStyle(htmlDom, 'borderTopWidth'));
- if(browser.ie && !browser.isStrict){
- pos.left -= isNaN(htmlBorderLeftWidth) ? 2 : htmlBorderLeftWidth;
- pos.top -= isNaN(htmlBorderTopWidth) ? 2 : htmlBorderTopWidth;
- }
- } else {
- // safari/opera/firefox
- parent = element;
- do {
- pos.left += parent.offsetLeft;
- pos.top += parent.offsetTop;
-
- // safari里面,如果遍历到了一个fixed的元素,后面的offset都不准了
- if (browser.isWebkit > 0 && getStyle(parent, 'position') == 'fixed') {
- pos.left += doc.body.scrollLeft;
- pos.top += doc.body.scrollTop;
- break;
- }
-
- parent = parent.offsetParent;
- } while (parent && parent != element);
- // 对body offsetTop的修正
- if(browser.opera > 0 || (browser.isWebkit > 0 && getStyle(element, 'position') == 'absolute')){
- pos.top -= doc.body.offsetTop;
- }
- // 计算除了body的scroll
- parent = element.offsetParent;
- while (parent && parent != doc.body) {
- pos.left -= parent.scrollLeft;
- // see https://bugs.opera.com/show_bug.cgi?id=249965
- if (!browser.opera || parent.tagName != 'TR') {
- pos.top -= parent.scrollTop;
- }
- parent = parent.offsetParent;
- }
- }
- return pos;
- };
- /**
- * @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.event.on = function (element, type, listener) {
- type = type.replace(/^on/i, '');
- element = baidu.dom._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;
- };
- // 声明快捷方法
- baidu.on = baidu.event.on;
- /**
- * 返回一个当前页面的唯一标识字符串。
- * @name baidu.lang.guid
- * @function
- * @grammar baidu.lang.guid()
- * @version 1.1.1
- * @meta standard
- *
- * @returns {String} 当前页面的唯一标识字符串
- */
- (function(){
- //不直接使用window,可以提高3倍左右性能
- var guid = context[baidu.guid];
- baidu.lang.guid = function() {
- return "TANGRAM__" + (guid._counter ++).toString(36);
- };
- guid._counter = guid._counter || 1;
- })();
- /**
- * 所有类的实例的容器
- * key为每个实例的guid
- * @meta standard
- */
- context[baidu.guid]._instances = context[baidu.guid]._instances || {};
- /**
- * 判断目标参数是否为function或Function实例
- * @name baidu.lang.isFunction
- * @function
- * @grammar baidu.lang.isFunction(source)
- * @param {Any} source 目标参数
- * @version 1.2
- * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate
- * @meta standard
- * @returns {boolean} 类型判断结果
- */
- baidu.lang.isFunction = function (source) {
- // chrome下,'function' == typeof /a/ 为true.
- return '[object Function]' == Object.prototype.toString.call(source);
- };
- /**
- *
- * @ignore
- * @class Tangram继承机制提供的一个基类,用户可以通过继承baidu.lang.Class来获取它的属性及方法。
- * @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。
- * @meta standard
- * @see baidu.lang.inherits,baidu.lang.Event
- */
- 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 || {};
- /**
- * 释放对象所持有的资源,主要是自定义事件。
- * @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;
- };
- /**
- * 重载了默认的toString方法,使得返回信息更加准确一些。
- * @return {string} 对象的String表示形式
- */
- baidu.lang.Class.prototype.toString = function(){
- return "[object " + (this._className || "Object" ) + "]";
- };
- /**
- * @ignore
- * @class 自定义的事件对象。
- * @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。
- * @meta standard
- * @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 (typeof handler != "undefined") {
- if ( (baidu.lang.isFunction(handler) && ! (handler = handler.hashCode))
- || (! baidu.lang.isString(handler))
- ){
- return;
- }
- }
- !this.__listeners && (this.__listeners = {});
- type.indexOf("on") != 0 && (type = "on" + type);
- var t = this.__listeners;
- if (!t[type]) {
- return;
- }
- if (typeof handler != "undefined") {
- t[type][handler] && delete t[type][handler];
- } else {
- for(var guid in t[type]){
- delete t[type][guid];
- }
- }
- };
- /**
- * 派发自定义事件,使得绑定到自定义事件上面的函数都会被执行。引入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 = {});
- // 20100603 添加本方法的第二个参数,将 options extend到event中去传递
- 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;
- };
- 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;
- // 类名标识,兼容Class的toString,基本没用
- if ("string" == typeof className) {
- proto._className = className;
- }
- };
- // 声明快捷方法
- baidu.inherits = baidu.lang.inherits;
- /**
-
- * 图片的路径
- * @private
- * @type {String}
-
- */
- var _IMAGE_PATH = 'http://api.map.baidu.com/library/TextIconOverlay/1.2/src/images/m';
- /**
-
- * 图片的后缀名
- * @private
- * @type {String}
-
- */
- var _IMAGE_EXTENSION = 'png';
- /**
- *@exports TextIconOverlay as BMapLib.TextIconOverlay
- */
-
- /**
- * TextIconOverlay
- * @class 此类表示地图上的一个覆盖物,该覆盖物由文字和图标组成,从Overlay继承。文字通常是数字(0-9)或字母(A-Z ),而文字与图标之间有一定的映射关系。
- *该覆盖物适用于以下类似的场景:需要在地图上添加一系列覆盖物,这些覆盖物之间用不同的图标和文字来区分,文字可能表示了该覆盖物的某一属性值,根据该文字和一定的映射关系,自动匹配相应颜色和大小的图标。
- *
- *@constructor
- *@param {Point} position 表示一个经纬度坐标位置。
- *@param {String} text 表示该覆盖物显示的文字信息。
- *@param {Json Object} options 可选参数,可选项包括:<br />
- *"<b>styles</b>":{Array<IconStyle>} 一组图标风格。单个图表风格包括以下几个属性:<br />
- * url {String} 图片的url地址。(必选)<br />
- * size {Size} 图片的大小。(必选)<br />
- * anchor {Size} 图标定位在地图上的位置相对于图标左上角的偏移值,默认偏移值为图标的中心位置。(可选)<br />
- * offset {Size} 图片相对于可视区域的偏移值,此功能的作用等同于CSS中的background-position属性。(可选)<br />
- * textSize {Number} 文字的大小。(可选,默认10)<br />
- * textColor {String} 文字的颜色。(可选,默认black)<br />
- */
- var TextIconOverlay = function(position, text, options){
- try {
- BMap;
- } catch (e) {
- throw Error('Baidu Map JS API is not ready yet!');
- }
- T.lang.inherits(TextIconOverlay, BMap.Overlay, "TextIconOverlay");
- this._position = position;
- this._text = text;
- this._options = options || {};
- this._styles = this._options['styles'] || [];
- (!this._styles.length) && this._setupDefaultStyles();
- };
- TextIconOverlay.prototype._setupDefaultStyles = function(){
- var sizes = [53, 56, 66, 78, 90];
- for(var i = 0, size; size = sizes[i]; i++){
- this._styles.push({
- url:_IMAGE_PATH + i + '.' + _IMAGE_EXTENSION,
- size: new BMap.Size(size, size)
- });
- }//for循环的简洁写法
- };
- /**
- *继承Overlay的intialize方法,自定义覆盖物时必须。
- *@param {Map} map BMap.Map的实例化对象。
- *@return {HTMLElement} 返回覆盖物对应的HTML元素。
- */
- TextIconOverlay.prototype.initialize = function(map){
- this._map = map;
-
- this._domElement = document.createElement('div');
- this._updateCss();
- this._updateText();
- this._updatePosition();
-
- this._bind();
- this._map.getPanes().markerMouseTarget.appendChild(this._domElement);
- return this._domElement;
- };
- /**
- *继承Overlay的draw方法,自定义覆盖物时必须。
- *@return 无返回值。
- */
- TextIconOverlay.prototype.draw = function(){
- this._map && this._updatePosition();
- };
-
- /**
- *获取该覆盖物上的文字。
- *@return {String} 该覆盖物上的文字。
- */
- TextIconOverlay.prototype.getText = function(){
- return this._text;
- };
- /**
- *设置该覆盖物上的文字。
- *@param {String} text 要设置的文字,通常是字母A-Z或数字0-9。
- *@return 无返回值。
- */
- TextIconOverlay.prototype.setText = function(text){
- if(text && (!this._text || (this._text.toString() != text.toString()))){
- this._text = text;
- this._updateText();
- this._updateCss();
- this._updatePosition();
- }
- };
- /**
- *获取该覆盖物的位置。
- *@return {Point} 该覆盖物的经纬度坐标。
- */
- TextIconOverlay.prototype.getPosition = function () {
- return this._position;
- };
-
- /**
- *设置该覆盖物的位置。
- *@param {Point} position 要设置的经纬度坐标。
- *@return 无返回值。
- */
- TextIconOverlay.prototype.setPosition = function (position) {
- if(position && (!this._position || !this._position.equals(position))){
- this._position = position;
- this._updatePosition();
- }
- };
- /**
- *由文字信息获取风格数组的对应索引值。
- *内部默认的对应函数为文字转换为数字除以10的结果,比如文字8返回索引0,文字25返回索引2.
- *如果需要自定义映射关系,请覆盖该函数。
- *@param {String} text 文字。
- *@param {Array<IconStyle>} styles 一组图标风格。
- *@return {Number} 对应的索引值。
- */
- TextIconOverlay.prototype.getStyleByText = function(text, styles){
- var count = parseInt(text);
- var index = parseInt(count / 10);
- index = Math.max(0, index);
- index = Math.min(index, styles.length - 1);
- return styles[index];
- };
- /**
- *更新相应的CSS。
- *@return 无返回值。
- */
- TextIconOverlay.prototype._updateCss = function(){
- if (!this._domElement) {
- return
- }
- var style = this.getStyleByText(this._text, this._styles);
- this._domElement.style.cssText = this._buildCssText(style);
- };
- /**
- *更新覆盖物的显示文字。
- *@return 无返回值。
- */
- TextIconOverlay.prototype._updateText = function(){
- if (this._domElement) {
- this._domElement.innerHTML = this._text;
- }
- };
- /**
- *调整覆盖物在地图上的位置更新覆盖物的显示文字。
- *@return 无返回值。
- */
- TextIconOverlay.prototype._updatePosition = function(){
- if (this._domElement && this._position) {
- var style = this._domElement.style;
- var pixelPosition= this._map.pointToOverlayPixel(this._position);
- pixelPosition.x -= Math.ceil(parseInt(style.width) / 2);
- pixelPosition.y -= Math.ceil(parseInt(style.height) / 2);
- style.left = pixelPosition.x + "px";
- style.top = pixelPosition.y + "px";
- }
- };
-
- /**
- * 为该覆盖物的HTML元素构建CSS
- * @param {IconStyle} 一个图标的风格。
- * @return {String} 构建完成的CSSTEXT。
- */
- TextIconOverlay.prototype._buildCssText = function(style) {
- //根据style来确定一些默认值
- var url = style['url'];
- var size = style['size'];
- var anchor = style['anchor'];
- var offset = style['offset'];
- var textColor = style['textColor'] || 'black';
- var textSize = style['textSize'] || 10;
- var csstext = [];
- if (T.browser["ie"] < 7) {
- csstext.push('filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(' +
- 'sizingMethod=scale,src="' + url + '");');
- } else {
- csstext.push('background-image:url(' + url + ');');
- var backgroundPosition = '0 0';
- (offset instanceof BMap.Size) && (backgroundPosition = offset.width + 'px' + ' ' + offset.height + 'px');
- csstext.push('background-position:' + backgroundPosition + ';');
- }
- if (size instanceof BMap.Size){
- if (anchor instanceof BMap.Size) {
- if (anchor.height > 0 && anchor.height < size.height) {
- csstext.push('height:' + (size.height - anchor.height) + 'px; padding-top:' + anchor.height + 'px;');
- }
- if(anchor.width > 0 && anchor.width < size.width){
- csstext.push('width:' + (size.width - anchor.width) + 'px; padding-left:' + anchor.width + 'px;');
- }
- } else {
- csstext.push('height:' + size.height + 'px; line-height:' + size.height + 'px;');
- csstext.push('width:' + size.width + 'px; text-align:center;');
- }
- }
-
- csstext.push('cursor:pointer; color:' + textColor + '; position:absolute; font-size:' +
- textSize + 'px; font-family:Arial,sans-serif; font-weight:bold');
- return csstext.join('');
- };
- /**
-
- * 当鼠标点击该覆盖物时会触发该事件
- * @name TextIconOverlay#click
- * @event
- * @param {Event Object} e 回调函数会返回event参数,包括以下返回值:
-
- * <br />"<b>type</b> : {String} 事件类型
- * <br />"<b>target</b>:{BMapLib.TextIconOverlay} 事件目标
- *
- */
- /**
- * 当鼠标进入该覆盖物区域时会触发该事件
- * @name TextIconOverlay#mouseover
- * @event
- * @param {Event Object} e 回调函数会返回event参数,包括以下返回值:
-
- * <br />"<b>type</b> : {String} 事件类型
- * <br />"<b>target</b>:{BMapLib.TextIconOverlay} 事件目标
- * <br />"<b>point</b> : {BMap.Point} 最新添加上的节点BMap.Point对象
- * <br />"<b>pixel</b>:{BMap.pixel} 最新添加上的节点BMap.Pixel对象
- *
- * @example <b>参考示例:</b><br />
- * myTextIconOverlay.addEventListener("mouseover", function(e) { alert(e.point); });
- */
- /**
- * 当鼠标离开该覆盖物区域时会触发该事件
- * @name TextIconOverlay#mouseout
- * @event
- * @param {Event Object} e 回调函数会返回event参数,包括以下返回值:
- * <br />"<b>type</b> : {String} 事件类型
- * <br />"<b>target</b>:{BMapLib.TextIconOverlay} 事件目标
- * <br />"<b>point</b> : {BMap.Point} 最新添加上的节点BMap.Point对象
- * <br />"<b>pixel</b>:{BMap.pixel} 最新添加上的节点BMap.Pixel对象
- *
- * @example <b>参考示例:</b><br />
- * myTextIconOverlay.addEventListener("mouseout", function(e) { alert(e.point); });
- */
- /**
- * 为该覆盖物绑定一系列事件
- * 当前支持click mouseover mouseout
- * @return 无返回值。
- */
- TextIconOverlay.prototype._bind = function(){
- if (!this._domElement){
- return;
- }
- var me = this;
- var map = this._map;
- var BaseEvent = T.lang.Event;
- function eventExtend(e, be){
- var elem = e.srcElement || e.target;
- var x = e.clientX || e.pageX;
- var y = e.clientY || e.pageY;
- if (e && be && x && y && elem){
- var offset = T.dom.getPosition(map.getContainer());
- be.pixel = new BMap.Pixel(x - offset.left, y - offset.top);
- be.point = map.pixelToPoint(be.pixel);
- }
- return be;
- }//给事件参数增加pixel和point两个值
- T.event.on(this._domElement,"mouseover", function(e){
- me.dispatchEvent(eventExtend(e, new BaseEvent("onmouseover")));
- });
- T.event.on(this._domElement,"mouseout", function(e){
- me.dispatchEvent(eventExtend(e, new BaseEvent("onmouseout")));
- });
- T.event.on(this._domElement,"click", function(e){
- me.dispatchEvent(eventExtend(e, new BaseEvent("onclick")));
- });
- };
- return TextIconOverlay;
- });
- });
- var TextIconOverlay = (index$1 && typeof index$1 === 'object' && 'default' in index$1 ? index$1['default'] : index$1);
- /**
- * 获取一个扩展的视图范围,把上下左右都扩大一样的像素值。
- * @param {Map} map BMap.Map的实例化对象
- * @param {BMap.Bounds} bounds BMap.Bounds的实例化对象
- * @param {Number} gridSize 要扩大的像素值
- *
- * @return {BMap.Bounds} 返回扩大后的视图范围。
- */
- var getExtendedBounds = function(map, bounds, gridSize){
- bounds = cutBoundsInRange(bounds);
- var pixelNE = map.pointToPixel(bounds.getNorthEast());
- var pixelSW = map.pointToPixel(bounds.getSouthWest());
- pixelNE.x += gridSize;
- pixelNE.y -= gridSize;
- pixelSW.x -= gridSize;
- pixelSW.y += gridSize;
- var newNE = map.pixelToPoint(pixelNE);
- var newSW = map.pixelToPoint(pixelSW);
- return new BMap.Bounds(newSW, newNE);
- };
- /**
- * 按照百度地图支持的世界范围对bounds进行边界处理
- * @param {BMap.Bounds} bounds BMap.Bounds的实例化对象
- *
- * @return {BMap.Bounds} 返回不越界的视图范围
- */
- var cutBoundsInRange = function (bounds) {
- var maxX = getRange(bounds.getNorthEast().lng, -180, 180);
- var minX = getRange(bounds.getSouthWest().lng, -180, 180);
- var maxY = getRange(bounds.getNorthEast().lat, -74, 74);
- var minY = getRange(bounds.getSouthWest().lat, -74, 74);
- return new BMap.Bounds(new BMap.Point(minX, minY), new BMap.Point(maxX, maxY));
- };
- /**
- * 对单个值进行边界处理。
- * @param {Number} i 要处理的数值
- * @param {Number} min 下边界值
- * @param {Number} max 上边界值
- *
- * @return {Number} 返回不越界的数值
- */
- var getRange = function (i, mix, max) {
- mix && (i = Math.max(i, mix));
- max && (i = Math.min(i, max));
- return i;
- };
- /**
- * 判断给定的对象是否为数组
- * @param {Object} source 要测试的对象
- *
- * @return {Boolean} 如果是数组返回true,否则返回false
- */
- var isArray = function (source) {
- return '[object Array]' === Object.prototype.toString.call(source);
- };
- /**
- * 返回item在source中的索引位置
- * @param {Object} item 要测试的对象
- * @param {Array} source 数组
- *
- * @return {Number} 如果在数组内,返回索引,否则返回-1
- */
- var indexOf = function(item, source){
- var index = -1;
- if(isArray(source)){
- if (source.indexOf) {
- index = source.indexOf(item);
- } else {
- for (var i = 0, m; m = source[i]; i++) {
- if (m === item) {
- index = i;
- break;
- }
- }
- }
- }
- return index;
- };
- /**
- *@exports MarkerClusterer as BMapLib.MarkerClusterer
- */
- /**
- * MarkerClusterer
- * @class 用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能
- * @constructor
- * @param {Map} map 地图的一个实例。
- * @param {Json Object} options 可选参数,可选项包括:<br />
- * markers {Array<Marker>} 要聚合的标记数组<br />
- * girdSize {Number} 聚合计算时网格的像素大小,默认60<br />
- * maxZoom {Number} 最大的聚合级别,大于该级别就不进行相应的聚合<br />
- * minClusterSize {Number} 最小的聚合数量,小于该数量的不能成为一个聚合,默认为2<br />
- * isAverangeCenter {Boolean} 聚合点的落脚位置是否是所有聚合在内点的平均值,默认为否,落脚在聚合内的第一个点<br />
- * styles {Array<IconStyle>} 自定义聚合后的图标风格,请参考TextIconOverlay类<br />
- */
- var MarkerClusterer = function(map, options){
- try {
- BMap;
- } catch (e) {
- throw Error('Baidu Map JS API is not ready yet!');
- }
- if (!map){
- return;
- }
- this._map = map;
- this._markers = [];
- this._clusters = [];
-
- var opts = options || {};
- this._gridSize = opts["gridSize"] || 60;
- this._maxZoom = opts["maxZoom"] || 18;
- this._minClusterSize = opts["minClusterSize"] || 2;
- this._isAverageCenter = false;
- if (opts['isAverageCenter'] != undefined) {
- this._isAverageCenter = opts['isAverageCenter'];
- }
- this._styles = opts["styles"] || [];
- var that = this;
- this._map.addEventListener("zoomend",function(){
- that._redraw();
- });
- this._map.addEventListener("moveend",function(){
- that._redraw();
- });
- var mkrs = opts["markers"];
- isArray(mkrs) && this.addMarkers(mkrs);
- };
- /**
- * 添加要聚合的标记数组。
- * @param {Array<Marker>} markers 要聚合的标记数组
- *
- * @return 无返回值。
- */
- MarkerClusterer.prototype.addMarkers = function(markers){
- if (!markers.length) {
- return
- }
- for(var i = 0, len = markers.length; i <len ; i++){
- this._pushMarkerTo(markers[i]);
- }
- this._createClusters();
- };
- /**
- * 把一个标记添加到要聚合的标记数组中
- * @param {BMap.Marker} marker 要添加的标记
- *
- * @return 无返回值。
- */
- MarkerClusterer.prototype._pushMarkerTo = function(marker){
- var index = indexOf(marker, this._markers);
- if(index === -1){
- marker.isInCluster = false;
- this._markers.push(marker);//Marker拖放后enableDragging不做变化,忽略
- }
- };
- /**
- * 添加一个聚合的标记。
- * @param {BMap.Marker} marker 要聚合的单个标记。
- * @return 无返回值。
- */
- MarkerClusterer.prototype.addMarker = function(marker) {
- this._pushMarkerTo(marker);
- this._createClusters();
- };
- /**
- * 根据所给定的标记,创建聚合点
- * @return 无返回值
- */
- MarkerClusterer.prototype._createClusters = function(){
- var mapBounds = this._map.getBounds();
- if (!mapBounds.getCenter()) {
- return
- }
- var extendedBounds = getExtendedBounds(this._map, mapBounds, this._gridSize);
- for(var i = 0, marker; marker = this._markers[i]; i++){
- if(!marker.isInCluster && extendedBounds.containsPoint(marker.getPosition()) ){
- this._addToClosestCluster(marker);
- }
- }
- };
- /**
- * 根据标记的位置,把它添加到最近的聚合中
- * @param {BMap.Marker} marker 要进行聚合的单个标记
- *
- * @return 无返回值。
- */
- MarkerClusterer.prototype._addToClosestCluster = function (marker){
- var distance = 4000000;
- var clusterToAddTo = null;
- var position = marker.getPosition();
- for(var i = 0, cluster; cluster = this._clusters[i]; i++){
- var center = cluster.getCenter();
- if(center){
- var d = this._map.getDistance(center, marker.getPosition());
- if(d < distance){
- distance = d;
- clusterToAddTo = cluster;
- }
- }
- }
- if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)){
- clusterToAddTo.addMarker(marker);
- } else {
- var cluster = new Cluster(this);
- cluster.addMarker(marker);
- this._clusters.push(cluster);
- }
- };
- /**
- * 清除上一次的聚合的结果
- * @return 无返回值。
- */
- MarkerClusterer.prototype._clearLastClusters = function(){
- for(var i = 0, cluster; cluster = this._clusters[i]; i++){
- cluster.remove();
- }
- this._clusters = [];//置空Cluster数组
- this._removeMarkersFromCluster();//把Marker的cluster标记设为false
- };
- /**
- * 清除某个聚合中的所有标记
- * @return 无返回值
- */
- MarkerClusterer.prototype._removeMarkersFromCluster = function(){
- for(var i = 0, marker; marker = this._markers[i]; i++){
- marker.isInCluster = false;
- }
- };
- /**
- * 把所有的标记从地图上清除
- * @return 无返回值
- */
- MarkerClusterer.prototype._removeMarkersFromMap = function(){
- for(var i = 0, marker; marker = this._markers[i]; i++){
- marker.isInCluster = false;
- var label = marker.getLabel();
- this._map.removeOverlay(marker);
- marker.setLabel(label);
- }
- };
- /**
- * 删除单个标记
- * @param {BMap.Marker} marker 需要被删除的marker
- *
- * @return {Boolean} 删除成功返回true,否则返回false
- */
- MarkerClusterer.prototype._removeMarker = function(marker) {
- var index = indexOf(marker, this._markers);
- if (index === -1) {
- return false;
- }
- this._map.removeOverlay(marker);
- this._markers.splice(index, 1);
- return true;
- };
- /**
- * 删除单个标记
- * @param {BMap.Marker} marker 需要被删除的marker
- *
- * @return {Boolean} 删除成功返回true,否则返回false
- */
- MarkerClusterer.prototype.removeMarker = function(marker) {
- var success = this._removeMarker(marker);
- if (success) {
- this._clearLastClusters();
- this._createClusters();
- }
- return success;
- };
- /**
- * 删除一组标记
- * @param {Array<BMap.Marker>} markers 需要被删除的marker数组
- *
- * @return {Boolean} 删除成功返回true,否则返回false
- */
- MarkerClusterer.prototype.removeMarkers = function(markers) {
- var success = false;
- for (var i = 0; i < markers.length; i++) {
- var r = this._removeMarker(markers[i]);
- success = success || r;
- }
- if (success) {
- this._clearLastClusters();
- this._createClusters();
- }
- return success;
- };
- /**
- * 从地图上彻底清除所有的标记
- * @return 无返回值
- */
- MarkerClusterer.prototype.clearMarkers = function() {
- this._clearLastClusters();
- this._removeMarkersFromMap();
- this._markers = [];
- };
- /**
- * 重新生成,比如改变了属性等
- * @return 无返回值
- */
- MarkerClusterer.prototype._redraw = function () {
- this._clearLastClusters();
- this._createClusters();
- };
- /**
- * 获取网格大小
- * @return {Number} 网格大小
- */
- MarkerClusterer.prototype.getGridSize = function() {
- return this._gridSize;
- };
- /**
- * 设置网格大小
- * @param {Number} size 网格大小
- * @return 无返回值
- */
- MarkerClusterer.prototype.setGridSize = function(size) {
- this._gridSize = size;
- this._redraw();
- };
- /**
- * 获取聚合的最大缩放级别。
- * @return {Number} 聚合的最大缩放级别。
- */
- MarkerClusterer.prototype.getMaxZoom = function() {
- return this._maxZoom;
- };
- /**
- * 设置聚合的最大缩放级别
- * @param {Number} maxZoom 聚合的最大缩放级别
- * @return 无返回值
- */
- MarkerClusterer.prototype.setMaxZoom = function(maxZoom) {
- this._maxZoom = maxZoom;
- this._redraw();
- };
- /**
- * 获取聚合的样式风格集合
- * @return {Array<IconStyle>} 聚合的样式风格集合
- */
- MarkerClusterer.prototype.getStyles = function() {
- return this._styles;
- };
- /**
- * 设置聚合的样式风格集合
- * @param {Array<IconStyle>} styles 样式风格数组
- * @return 无返回值
- */
- MarkerClusterer.prototype.setStyles = function(styles) {
- this._styles = styles;
- this._redraw();
- };
- /**
- * 获取单个聚合的最小数量。
- * @return {Number} 单个聚合的最小数量。
- */
- MarkerClusterer.prototype.getMinClusterSize = function() {
- return this._minClusterSize;
- };
- /**
- * 设置单个聚合的最小数量。
- * @param {Number} size 单个聚合的最小数量。
- * @return 无返回值。
- */
- MarkerClusterer.prototype.setMinClusterSize = function(size) {
- this._minClusterSize = size;
- this._redraw();
- };
- /**
- * 获取单个聚合的落脚点是否是聚合内所有标记的平均中心。
- * @return {Boolean} true或false。
- */
- MarkerClusterer.prototype.isAverageCenter = function() {
- return this._isAverageCenter;
- };
- /**
- * 获取聚合的Map实例。
- * @return {Map} Map的示例。
- */
- MarkerClusterer.prototype.getMap = function() {
- return this._map;
- };
- /**
- * 获取所有的标记数组。
- * @return {Array<Marker>} 标记数组。
- */
- MarkerClusterer.prototype.getMarkers = function() {
- return this._markers;
- };
- /**
- * 获取聚合的总数量。
- * @return {Number} 聚合的总数量。
- */
- MarkerClusterer.prototype.getClustersCount = function() {
- var count = 0;
- for(var i = 0, cluster; cluster = this._clusters[i]; i++){
- cluster.isReal() && count++;
- }
- return count;
- };
- /**
- * @ignore
- * Cluster
- * @class 表示一个聚合对象,该聚合,包含有N个标记,这N个标记组成的范围,并有予以显示在Map上的TextIconOverlay等。
- * @constructor
- * @param {MarkerClusterer} markerClusterer 一个标记聚合器示例。
- */
- function Cluster(markerClusterer){
- this._markerClusterer = markerClusterer;
- this._map = markerClusterer.getMap();
- this._minClusterSize = markerClusterer.getMinClusterSize();
- this._isAverageCenter = markerClusterer.isAverageCenter();
- this._center = null;//落脚位置
- this._markers = [];//这个Cluster中所包含的markers
- this._gridBounds = null;//以中心点为准,向四边扩大gridSize个像素的范围,也即网格范围
- this._isReal = false; //真的是个聚合
- this._clusterMarker = new TextIconOverlay(this._center, this._markers.length, {"styles":this._markerClusterer.getStyles()});
- //this._map.addOverlay(this._clusterMarker);
- }
- /**
- * 向该聚合添加一个标记。
- * @param {Marker} marker 要添加的标记。
- * @return 无返回值。
- */
- Cluster.prototype.addMarker = function(marker){
- if(this.isMarkerInCluster(marker)){
- return false;
- }//也可用marker.isInCluster判断,外面判断OK,这里基本不会命中
- if (!this._center){
- this._center = marker.getPosition();
- this.updateGridBounds();//
- } else {
- if(this._isAverageCenter){
- var l = this._markers.length + 1;
- var lat = (this._center.lat * (l - 1) + marker.getPosition().lat) / l;
- var lng = (this._center.lng * (l - 1) + marker.getPosition().lng) / l;
- this._center = new BMap.Point(lng, lat);
- this.updateGridBounds();
- }//计算新的Center
- }
- marker.isInCluster = true;
- this._markers.push(marker);
- var len = this._markers.length;
- if(len < this._minClusterSize ){
- this._map.addOverlay(marker);
- //this.updateClusterMarker();
- return true;
- } else if (len === this._minClusterSize) {
- for (var i = 0; i < len; i++) {
- var label = this._markers[i].getLabel();
- this._markers[i].getMap() && this._map.removeOverlay(this._markers[i]);
- this._markers[i].setLabel(label);
- }
-
- }
- this._map.addOverlay(this._clusterMarker);
- this._isReal = true;
- this.updateClusterMarker();
- return true;
- };
- /**
- * 判断一个标记是否在该聚合中。
- * @param {Marker} marker 要判断的标记。
- * @return {Boolean} true或false。
- */
- Cluster.prototype.isMarkerInCluster= function(marker){
- if (this._markers.indexOf) {
- return this._markers.indexOf(marker) != -1;
- } else {
- for (var i = 0, m; m = this._markers[i]; i++) {
- if (m === marker) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * 判断一个标记是否在该聚合网格范围中。
- * @param {Marker} marker 要判断的标记。
- * @return {Boolean} true或false。
- */
- Cluster.prototype.isMarkerInClusterBounds = function(marker) {
- return this._gridBounds.containsPoint(marker.getPosition());
- };
- Cluster.prototype.isReal = function(marker) {
- return this._isReal;
- };
- /**
- * 更新该聚合的网格范围。
- * @return 无返回值。
- */
- Cluster.prototype.updateGridBounds = function() {
- var bounds = new BMap.Bounds(this._center, this._center);
- this._gridBounds = getExtendedBounds(this._map, bounds, this._markerClusterer.getGridSize());
- };
- /**
- * 更新该聚合的显示样式,也即TextIconOverlay。
- * @return 无返回值。
- */
- Cluster.prototype.updateClusterMarker = function () {
- if (this._map.getZoom() > this._markerClusterer.getMaxZoom()) {
- this._clusterMarker && this._map.removeOverlay(this._clusterMarker);
- for (var i = 0, marker; marker = this._markers[i]; i++) {
- this._map.addOverlay(marker);
- }
- return;
- }
- if (this._markers.length < this._minClusterSize) {
- this._clusterMarker.hide();
- return;
- }
- this._clusterMarker.setPosition(this._center);
-
- this._clusterMarker.setText(this._markers.length);
- this._clusterMarker.addEventListener && !this._clusterMarker._hasClickEvent && this._clusterMarker.addEventListener("click", function(event){
- this._clusterMarker._hasClickEvent = true;
- this._markers && this._map.setViewport(this.getBounds());
- }.bind(this));
- };
- /**
- * 删除该聚合。
- * @return 无返回值。
- */
- Cluster.prototype.remove = function(){
- for (var i = 0, m; m = this._markers[i]; i++) {
- var label = this._markers[i].getLabel();
- this._markers[i].getMap() && this._map.removeOverlay(this._markers[i]);
- this._markers[i].setLabel(label);
- }//清除散的标记点
- this._map.removeOverlay(this._clusterMarker);
- this._markers.length = 0;
- delete this._markers;
- };
- /**
- * 获取该聚合所包含的所有标记的最小外接矩形的范围。
- * @return {BMap.Bounds} 计算出的范围。
- */
- Cluster.prototype.getBounds = function() {
- var bounds = new BMap.Bounds(this._center,this._center);
- for (var i = 0, marker; marker = this._markers[i]; i++) {
- bounds.extend(marker.getPosition());
- }
- return bounds;
- };
- /**
- * 获取该聚合的落脚点。
- * @return {BMap.Point} 该聚合的落脚点。
- */
- Cluster.prototype.getCenter = function() {
- return this._center;
- };
- return MarkerClusterer;
- })));
|