<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>百度地图测量工具测试</title><script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2"></script><script type="text/javascript"src="http://api.map.baidu.com/getscript?v=1.2&amp;ak=&amp;services=&amp;t=20130716024057"></script><link rel="stylesheet" type="text/css" href="http://api.map.baidu.com/res/12/bmap.css"><script type="text/javascript"src="http://api.map.baidu.com/library/DistanceTool/1.2/src/DistanceTool_min.js"></script>
</head>
<body>
<div id="container" style="width: 100%; height: 340px; margin-bottom:20px"></div>
<div id="container1" style="width: 100%; height: 340px;"></div>
<script type="text/javascript">var map = new BMap.Map("container");var map1 = new BMap.Map("container1");map.centerAndZoom(new BMap.Point(116.404, 39.915), 15);map1.centerAndZoom(new BMap.Point(116.404, 39.915), 15);var myDis = new BMapLib.DistanceTool(map);//开始测量myDis.open();//结束测量myDis.close();//在第二个地图上使用测量工具var myDis1 = new BMapLib.DistanceTool(map1);//开始测量myDis1.open();</script>
</body>
</html>

以上代码是同时在两个地图上使用测量工具,运行效果如下图所示

代码的本意是在第二个地图开启测量工具,但是却需要在第一个地图上点击才能进行测量。

修改DistanceTool.js后的效果

修改代码的逻辑就不分析了(因为我也忘了,也懒得去看了,因为这个用得也不多,该文章只是做个记录),附上修改后的JS文件

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

百度地图测量工具(DistanceTool.js)在多个地图上使用错误问题相关推荐

  1. 引用第三方高德地图接口---使用js脚本进行开发地图定位的步骤

    ①在高德地图开发平台注册一个账号,获取key ②添加新的key ③引入map插件 ④复制过来map的脚本代码和编写搜索框 <script type="text/javascript&q ...

  2. html 高德地图坐标,点标记-调起高德地图-示例中心-JS API 示例 | 高德地图API

    点标记 html,body,#container{ height:100%; } 手机扫码打开示例 var map = new AMap.Map("container", { zo ...

  3. 高德地图html js开发例子,3D地图-三维地图-示例中心-JS API 示例 | 高德地图API

    3D地图 body,html{ margin:0;padding:0;font:12px/16px Verdana,Helvetica,Arial,sans-serif;width: 100%;hei ...

  4. android高德地图api驾车路线规划,驾车路径规划-调起高德地图-示例中心-JS API 示例 | 高德地图API...

    html,body,#container{ height:100%; } .btn{ position: fixed; bottom: 20px; right: 20px; background-co ...

  5. 【百度地图API】JS版本的常见问题

    1.请问如何将我的店铺标注在百度地图上?我是否可以做区域代理?在百度地图上标注是否免费? 答复: 这里只负责API的技术咨询,不解决任何地图标注问题.在百度地图上标注自己公司,即气泡标注业务.该业务已 ...

  6. JS实现坐标系转换(wgs84、bd09ll、gcj02)百度、GPS、高德、腾讯地图相互转换

    JS 实现地图坐标相互转换,采用百度地图API的 BMap.Convertor(),所以使用时需要引入百度地图 v3 / v2 API,转换精准,无偏移! GPS ( wgs84 )  转 百度(bd ...

  7. 百度地图简单调用js及天气获取

    这是一个简单的小例子,获取天气过程可能有点繁琐,本次通过获取所在的城市,根据城市获取城市编码,再根据编码获取当前城市的天气情况.当然网上有很多关于天气获取的,如知心天气.中国气象局.和风天气.free ...

  8. 如何利用【百度地图API】,制作房产酒店地图?(下)——结合自己的数据库...

    摘要:应广大API爱好者要求,写了一篇利用自己数据库标点的文章-- --------------------------------------------------------- 一.先按照前两篇 ...

  9. 用百度siteapp的uaredirect.js判断用户访问端而进行域名的自动跳转

    首先在你的head中嵌入这段代码 <script src="http://siteapp.baidu.com/static/webappservice/uaredirect.js&qu ...

最新文章

  1. 2022-2028年中国EMI膜产业发展态势及市场发展策略报告
  2. AAAI 2020 | 滴滴东北大学提出自动结构化剪枝压缩算法框架,性能提升高达120倍...
  3. python编程入门经典实例-总算明了python编程入门经典实例
  4. Sidebar Enhancements使用说明
  5. renderer的两种使用方式
  6. ECCV 2018 | Pixel2Mesh:从单帧RGB图像生成三维网格模型
  7. mysql 未知列_mysql – ‘字段列表’连接中的未知列’..’
  8. POJ 1797 Heavy Transportation
  9. 工作的思考十四:增强看待问题(BUG)的敏锐度
  10. Codeforces 884E E. Binary Matrix
  11. 马云在《赢在中国》对创业者的经典点评
  12. 因财务造假,贾跃亭被罚 2.41 亿元;华为徐直军重申不造成:但将推子品牌汽车;Gradle 7.0 发布|极客头条...
  13. java.text.NumberFormat使用方法
  14. 安利App介绍及下载(含二维码)
  15. PHP 51tracking物流单个查询接口调用
  16. IO summery
  17. 洛谷P4147 玉蟾宫(单调栈解决)
  18. vue和layUi对比
  19. 802.11成帧封装实现(三)
  20. 如何成为一名优秀的网络工程师?

热门文章

  1. 2021年8-10月AI融资方向分析
  2. 金山毒霸四月安全趋势 继续关注网页挂马
  3. 保研经验帖(二)夏令营经验分享
  4. windows连mac桌面_如何同步Mac和Windows桌面
  5. 移动端echarts图表的自适应使用
  6. 卷地风来忽吹散,积得飘零美如画(深度学习入门系列之十)
  7. hurdle模型matlab实现,HURDLE MODEL在STATA中的实现
  8. mysql 实现rownum_MySQL 中实现 rownum
  9. arcgis重心迁移分析_Arcgis第四章 空间分析.ppt
  10. Simulink C++代码生成、embedded coder