##index.html

<!doctype html>
<html>
<head><title>地图标点</title><meta http-equiv="content-type" content="text/html;charset=utf-8;"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">var city = '北京';var pointsInfo = [];pointsInfo[0] = [];pointsInfo[0]['lng'] = 116.397575;pointsInfo[0]['lat'] = 39.905560;pointsInfo[1] = [];pointsInfo[1]['lng'] = 116.398499;pointsInfo[1]['lat'] = 39.905590;pointsInfo[2] = [];pointsInfo[2]['lng'] = 116.399071;pointsInfo[2]['lat'] = 39.905605;pointsInfo[3] = [];pointsInfo[3]['lng'] = 116.399551;pointsInfo[3]['lat'] = 39.905628;pointsInfo[4] = [];pointsInfo[4]['lng'] = 116.400024;pointsInfo[4]['lat'] = 39.905636;pointsInfo[5] = [];pointsInfo[5]['lng'] = 116.400436;pointsInfo[5]['lat'] = 39.905647;pointsInfo[6] = [];pointsInfo[6]['lng'] = 116.394737;pointsInfo[6]['lat'] = 39.905449;pointsInfo[7] = [];pointsInfo[7]['lng'] = 116.395164;pointsInfo[7]['lat'] = 39.905460;pointsInfo[8] = [];pointsInfo[8]['lng'] = 116.395744;pointsInfo[8]['lat'] = 39.905479;pointsInfo[9] = [];pointsInfo[9]['lng'] = 116.396172;pointsInfo[9]['lat'] = 39.905510;pointsInfo[10] = [];pointsInfo[10]['lng'] = 116.396767;pointsInfo[10]['lat'] = 39.905521;pointsInfo[11] = [];pointsInfo[11]['lng'] = 116.397209;pointsInfo[11]['lat'] = 39.905548;pointsInfo[12] = [];pointsInfo[12]['lng'] = 116.398079;pointsInfo[12]['lat'] = 39.905575;pointsInfo[13] = [];pointsInfo[13]['lng'] = 116.400864;pointsInfo[13]['lat'] = 39.905670;pointsInfo[14] = [];pointsInfo[14]['lng'] = 116.401657;pointsInfo[14]['lat'] = 39.905689;pointsInfo[15] = [];pointsInfo[15]['lng'] = 116.402344;pointsInfo[15]['lat'] = 39.905716;pointsInfo[16] = [];pointsInfo[16]['lng'] = 116.402756;pointsInfo[16]['lat'] = 39.905716;pointsInfo[17] = [];pointsInfo[17]['lng'] = 116.403244;pointsInfo[17]['lat'] = 39.905735;pointsInfo[18] = [];pointsInfo[18]['lng'] = 116.403587;pointsInfo[18]['lat'] = 39.905716;pointsInfo[19] = [];pointsInfo[19]['lng'] = 116.414124;pointsInfo[19]['lat'] = 39.907169;pointsInfo[20] = [];pointsInfo[20]['lng'] = 116.417358;pointsInfo[20]['lat'] = 39.908512;pointsInfo[21] = [];pointsInfo[21]['lng'] = 116.418022;pointsInfo[21]['lat'] = 39.909924;pointsInfo[22] = [];pointsInfo[22]['lng'] = 116.417953;pointsInfo[22]['lat'] = 39.910877;pointsInfo[23] = [];pointsInfo[23]['lng'] = 116.417931;pointsInfo[23]['lat'] = 39.912041;pointsInfo[24] = [];pointsInfo[24]['lng'] = 116.415863;pointsInfo[24]['lat'] = 39.906723;pointsInfo[25] = [];pointsInfo[25]['lng'] = 116.416367;pointsInfo[25]['lat'] = 39.906731;pointsInfo[26] = [];pointsInfo[26]['lng'] = 116.416740;pointsInfo[26]['lat'] = 39.906742;pointsInfo[27] = [];pointsInfo[27]['lng'] = 116.417213;pointsInfo[27]['lat'] = 39.906750;pointsInfo[28] = [];pointsInfo[28]['lng'] = 116.390678;pointsInfo[28]['lat'] = 39.905334;pointsInfo[29] = [];pointsInfo[29]['lng'] = 116.391197;pointsInfo[29]['lat'] = 39.905346;pointsInfo[30] = [];pointsInfo[30]['lng'] = 116.391563;pointsInfo[30]['lat'] = 39.905357;pointsInfo[31] = [];pointsInfo[31]['lng'] = 116.391953;pointsInfo[31]['lat'] = 39.905373;pointsInfo[32] = [];pointsInfo[32]['lng'] = 116.392303;pointsInfo[32]['lat'] = 39.905392;pointsInfo[33] = [];pointsInfo[33]['lng'] = 116.392685;pointsInfo[33]['lat'] = 39.905399;pointsInfo[34] = [];pointsInfo[34]['lng'] = 116.393074;pointsInfo[34]['lat'] = 39.905403;pointsInfo[35] = [];pointsInfo[35]['lng'] = 116.393349;pointsInfo[35]['lat'] = 39.905411;pointsInfo[36] = [];pointsInfo[36]['lng'] = 116.393578;pointsInfo[36]['lat'] = 39.905411;pointsInfo[37] = [];pointsInfo[37]['lng'] = 116.393867;pointsInfo[37]['lat'] = 39.905422;pointsInfo[38] = [];pointsInfo[38]['lng'] = 116.389191;pointsInfo[38]['lat'] = 39.905296;pointsInfo[39] = [];pointsInfo[39]['lng'] = 116.389648;pointsInfo[39]['lat'] = 39.905312;pointsInfo[40] = [];pointsInfo[40]['lng'] = 116.389961;pointsInfo[40]['lat'] = 39.905319;pointsInfo[41] = [];pointsInfo[41]['lng'] = 116.390327;pointsInfo[41]['lat'] = 39.905331;pointsInfo[42] = [];pointsInfo[42]['lng'] = 116.394127;pointsInfo[42]['lat'] = 39.905430;pointsInfo[43] = [];pointsInfo[43]['lng'] = 116.394394;pointsInfo[43]['lat'] = 39.905441;pointsInfo[44] = [];pointsInfo[44]['lng'] = 116.394920;pointsInfo[44]['lat'] = 39.905453;pointsInfo[45] = [];pointsInfo[45]['lng'] = 116.395355;pointsInfo[45]['lat'] = 39.905472;pointsInfo[46] = [];pointsInfo[46]['lng'] = 116.386963;pointsInfo[46]['lat'] = 39.905235;pointsInfo[47] = [];pointsInfo[47]['lng'] = 116.387558;pointsInfo[47]['lat'] = 39.905247;pointsInfo[48] = [];pointsInfo[48]['lng'] = 116.416344;pointsInfo[48]['lat'] = 39.906933;pointsInfo[49] = [];pointsInfo[49]['lng'] = 116.416748;pointsInfo[49]['lat'] = 39.906937;pointsInfo[50] = [];pointsInfo[50]['lng'] = 116.550919;pointsInfo[50]['lat'] = 39.908463;pointsInfo[51] = [];pointsInfo[51]['lng'] = 116.551514;pointsInfo[51]['lat'] = 39.908459;pointsInfo[52] = [];pointsInfo[52]['lng'] = 116.552101;pointsInfo[52]['lat'] = 39.908455;pointsInfo[53] = [];pointsInfo[53]['lng'] = 116.552681;pointsInfo[53]['lat'] = 39.908394;pointsInfo[54] = [];pointsInfo[54]['lng'] = 116.401138;pointsInfo[54]['lat'] = 39.905666;pointsInfo[55] = [];pointsInfo[55]['lng'] = 116.401253;pointsInfo[55]['lat'] = 39.905567;pointsInfo[56] = [];pointsInfo[56]['lng'] = 116.401459;pointsInfo[56]['lat'] = 39.905769;pointsInfo[57] = [];pointsInfo[57]['lng'] = 116.401642;pointsInfo[57]['lat'] = 39.905590;pointsInfo[58] = [];pointsInfo[58]['lng'] = 116.401230;pointsInfo[58]['lat'] = 39.905800;pointsInfo[59] = [];pointsInfo[59]['lng'] = 116.243530;pointsInfo[59]['lat'] = 39.902142;pointsInfo[60] = [];pointsInfo[60]['lng'] = 116.244118;pointsInfo[60]['lat'] = 39.902164;pointsInfo[61] = [];pointsInfo[61]['lng'] = 116.244698;pointsInfo[61]['lat'] = 39.902187;pointsInfo[62] = [];pointsInfo[62]['lng'] = 116.245285;pointsInfo[62]['lat'] = 39.902191;pointsInfo[63] = [];pointsInfo[63]['lng'] = 116.245872;pointsInfo[63]['lat'] = 39.902203;pointsInfo[64] = [];pointsInfo[64]['lng'] = 116.246460;pointsInfo[64]['lat'] = 39.902206;pointsInfo[65] = [];pointsInfo[65]['lng'] = 116.247047;pointsInfo[65]['lat'] = 39.902233;pointsInfo[66] = [];pointsInfo[66]['lng'] = 116.247627;pointsInfo[66]['lat'] = 39.902225;pointsInfo[67] = [];pointsInfo[67]['lng'] = 116.248215;pointsInfo[67]['lat'] = 39.902245;pointsInfo[68] = [];pointsInfo[68]['lng'] = 116.248802;pointsInfo[68]['lat'] = 39.902245;pointsInfo[69] = [];pointsInfo[69]['lng'] = 116.249382;pointsInfo[69]['lat'] = 39.902256;pointsInfo[70] = [];pointsInfo[70]['lng'] = 116.249977;pointsInfo[70]['lat'] = 39.902264;pointsInfo[71] = [];pointsInfo[71]['lng'] = 116.250565;pointsInfo[71]['lat'] = 39.902294;pointsInfo[72] = [];pointsInfo[72]['lng'] = 116.251144;pointsInfo[72]['lat'] = 39.902287;pointsInfo[73] = [];pointsInfo[73]['lng'] = 116.251732;pointsInfo[73]['lat'] = 39.902287;pointsInfo[74] = [];pointsInfo[74]['lng'] = 116.252319;pointsInfo[74]['lat'] = 39.902290;pointsInfo[75] = [];pointsInfo[75]['lng'] = 116.252907;pointsInfo[75]['lat'] = 39.902313;pointsInfo[76] = [];pointsInfo[76]['lng'] = 116.253494;pointsInfo[76]['lat'] = 39.902313;pointsInfo[77] = [];pointsInfo[77]['lng'] = 116.254082;pointsInfo[77]['lat'] = 39.902325;pointsInfo[78] = [];pointsInfo[78]['lng'] = 116.254662;pointsInfo[78]['lat'] = 39.902325;pointsInfo[79] = [];pointsInfo[79]['lng'] = 116.255241;pointsInfo[79]['lat'] = 39.902348;pointsInfo[80] = [];pointsInfo[80]['lng'] = 116.255836;pointsInfo[80]['lat'] = 39.902359;pointsInfo[81] = [];pointsInfo[81]['lng'] = 116.256538;pointsInfo[81]['lat'] = 39.902370;pointsInfo[82] = [];pointsInfo[82]['lng'] = 116.257004;pointsInfo[82]['lat'] = 39.902382;pointsInfo[83] = [];pointsInfo[83]['lng'] = 116.257591;pointsInfo[83]['lat'] = 39.902374;pointsInfo[84] = [];pointsInfo[84]['lng'] = 116.243523;pointsInfo[84]['lat'] = 39.901810;pointsInfo[85] = [];pointsInfo[85]['lng'] = 116.244118;pointsInfo[85]['lat'] = 39.901821;pointsInfo[86] = [];pointsInfo[86]['lng'] = 116.244698;pointsInfo[86]['lat'] = 39.901836;pointsInfo[87] = [];pointsInfo[87]['lng'] = 116.245277;pointsInfo[87]['lat'] = 39.901848;pointsInfo[88] = [];pointsInfo[88]['lng'] = 116.245872;pointsInfo[88]['lat'] = 39.901852;pointsInfo[89] = [];pointsInfo[89]['lng'] = 116.247192;pointsInfo[89]['lat'] = 39.901840;pointsInfo[90] = [];pointsInfo[90]['lng'] = 116.248459;pointsInfo[90]['lat'] = 39.901840;pointsInfo[91] = [];pointsInfo[91]['lng'] = 116.250031;pointsInfo[91]['lat'] = 39.901878;pointsInfo[92] = [];pointsInfo[92]['lng'] = 116.250816;pointsInfo[92]['lat'] = 39.901909;pointsInfo[93] = [];pointsInfo[93]['lng'] = 116.252815;pointsInfo[93]['lat'] = 39.901958;pointsInfo[94] = [];pointsInfo[94]['lng'] = 116.254097;pointsInfo[94]['lat'] = 39.901993;pointsInfo[95] = [];pointsInfo[95]['lng'] = 116.255447;pointsInfo[95]['lat'] = 39.902004;pointsInfo[96] = [];pointsInfo[96]['lng'] = 116.256081;pointsInfo[96]['lat'] = 39.902023;pointsInfo[97] = [];pointsInfo[97]['lng'] = 116.257133;pointsInfo[97]['lat'] = 39.902035;pointsInfo[98] = [];pointsInfo[98]['lng'] = 116.397240;pointsInfo[98]['lat'] = 39.908787;pointsInfo[99] = [];pointsInfo[99]['lng'] = 116.397491;pointsInfo[99]['lat'] = 39.908634;pointsInfo[100] = [];pointsInfo[100]['lng'] = 116.398102;pointsInfo[100]['lat'] = 39.908703;pointsInfo[101] = [];pointsInfo[101]['lng'] = 116.398849;pointsInfo[101]['lat'] = 39.908779;pointsInfo[102] = [];pointsInfo[102]['lng'] = 116.399025;pointsInfo[102]['lat'] = 39.908722;pointsInfo[103] = [];pointsInfo[103]['lng'] = 116.399101;pointsInfo[103]['lat'] = 39.908779;pointsInfo[104] = [];pointsInfo[104]['lng'] = 116.405487;pointsInfo[104]['lat'] = 39.906487;pointsInfo[105] = [];pointsInfo[105]['lng'] = 116.406090;pointsInfo[105]['lat'] = 39.906601;pointsInfo[106] = [];pointsInfo[106]['lng'] = 116.406677;pointsInfo[106]['lat'] = 39.906685;pointsInfo[107] = [];pointsInfo[107]['lng'] = 116.407333;pointsInfo[107]['lat'] = 39.906887;pointsInfo[108] = [];pointsInfo[108]['lng'] = 116.407814;pointsInfo[108]['lat'] = 39.907192;pointsInfo[109] = [];pointsInfo[109]['lng'] = 116.407516;pointsInfo[109]['lat'] = 39.908092;pointsInfo[110] = [];pointsInfo[110]['lng'] = 116.407516;pointsInfo[110]['lat'] = 39.908287;pointsInfo[111] = [];pointsInfo[111]['lng'] = 116.394859;pointsInfo[111]['lat'] = 39.909000;pointsInfo[112] = [];pointsInfo[112]['lng'] = 116.394928;pointsInfo[112]['lat'] = 39.908985;pointsInfo[113] = [];pointsInfo[113]['lng'] = 116.400238;pointsInfo[113]['lat'] = 39.916042;pointsInfo[114] = [];pointsInfo[114]['lng'] = 116.403831;pointsInfo[114]['lat'] = 39.916374;pointsInfo[115] = [];pointsInfo[115]['lng'] = 116.397438;pointsInfo[115]['lat'] = 39.908833;pointsInfo[116] = [];pointsInfo[116]['lng'] = 116.396118;pointsInfo[116]['lat'] = 39.908630;pointsInfo[117] = [];pointsInfo[117]['lng'] = 116.396729;pointsInfo[117]['lat'] = 39.908607;pointsInfo[118] = [];pointsInfo[118]['lng'] = 116.397324;pointsInfo[118]['lat'] = 39.908607;pointsInfo[119] = [];pointsInfo[119]['lng'] = 116.397881;pointsInfo[119]['lat'] = 39.908615;pointsInfo[120] = [];pointsInfo[120]['lng'] = 116.398438;pointsInfo[120]['lat'] = 39.908657;pointsInfo[121] = [];pointsInfo[121]['lng'] = 116.398827;pointsInfo[121]['lat'] = 39.908669;pointsInfo[122] = [];pointsInfo[122]['lng'] = 116.395889;pointsInfo[122]['lat'] = 39.908607;pointsInfo[123] = [];pointsInfo[123]['lng'] = 116.396492;pointsInfo[123]['lat'] = 39.908604;pointsInfo[124] = [];pointsInfo[124]['lng'] = 116.397079;pointsInfo[124]['lat'] = 39.908611;pointsInfo[125] = [];pointsInfo[125]['lng'] = 116.397652;pointsInfo[125]['lat'] = 39.908623;pointsInfo[126] = [];pointsInfo[126]['lng'] = 116.398239;pointsInfo[126]['lat'] = 39.908653;pointsInfo[127] = [];pointsInfo[127]['lng'] = 116.404930;pointsInfo[127]['lat'] = 39.905735;pointsInfo[128] = [];pointsInfo[128]['lng'] = 116.405518;pointsInfo[128]['lat'] = 39.905773;pointsInfo[129] = [];pointsInfo[129]['lng'] = 116.405502;pointsInfo[129]['lat'] = 39.905792;pointsInfo[130] = [];pointsInfo[130]['lng'] = 116.397079;pointsInfo[130]['lat'] = 39.908115;pointsInfo[131] = [];pointsInfo[131]['lng'] = 116.396339;pointsInfo[131]['lat'] = 39.908222;pointsInfo[132] = [];pointsInfo[132]['lng'] = 116.397667;pointsInfo[132]['lat'] = 39.908226;pointsInfo[133] = [];pointsInfo[133]['lng'] = 116.398628;pointsInfo[133]['lat'] = 39.908226;pointsInfo[134] = [];pointsInfo[134]['lng'] = 116.399429;pointsInfo[134]['lat'] = 39.908314;pointsInfo[135] = [];pointsInfo[135]['lng'] = 116.399612;pointsInfo[135]['lat'] = 39.908131;pointsInfo[136] = [];pointsInfo[136]['lng'] = 116.397980;pointsInfo[136]['lat'] = 39.907959;pointsInfo[137] = [];pointsInfo[137]['lng'] = 116.396843;pointsInfo[137]['lat'] = 39.907906;pointsInfo[138] = [];pointsInfo[138]['lng'] = 116.395500;pointsInfo[138]['lat'] = 39.908127;pointsInfo[139] = [];pointsInfo[139]['lng'] = 116.358414;pointsInfo[139]['lat'] = 39.902790;pointsInfo[140] = [];pointsInfo[140]['lng'] = 116.359016;pointsInfo[140]['lat'] = 39.902824;pointsInfo[141] = [];pointsInfo[141]['lng'] = 116.359627;pointsInfo[141]['lat'] = 39.902874;pointsInfo[142] = [];pointsInfo[142]['lng'] = 116.360168;pointsInfo[142]['lat'] = 39.902916;pointsInfo[143] = [];pointsInfo[143]['lng'] = 116.360748;pointsInfo[143]['lat'] = 39.902950;pointsInfo[144] = [];pointsInfo[144]['lng'] = 116.361351;pointsInfo[144]['lat'] = 39.903019;pointsInfo[145] = [];pointsInfo[145]['lng'] = 116.361893;pointsInfo[145]['lat'] = 39.903061;pointsInfo[146] = [];pointsInfo[146]['lng'] = 116.398476;pointsInfo[146]['lat'] = 39.907776;pointsInfo[147] = [];pointsInfo[147]['lng'] = 116.399361;pointsInfo[147]['lat'] = 39.907726;pointsInfo[148] = [];pointsInfo[148]['lng'] = 116.400055;pointsInfo[148]['lat'] = 39.907803;pointsInfo[149] = [];pointsInfo[149]['lng'] = 116.398415;pointsInfo[149]['lat'] = 39.907104;pointsInfo[150] = [];pointsInfo[150]['lng'] = 116.399216;pointsInfo[150]['lat'] = 39.907146;pointsInfo[151] = [];pointsInfo[151]['lng'] = 116.400200;pointsInfo[151]['lat'] = 39.907185;pointsInfo[152] = [];pointsInfo[152]['lng'] = 116.401215;pointsInfo[152]['lat'] = 39.907234;pointsInfo[153] = [];pointsInfo[153]['lng'] = 116.395119;pointsInfo[153]['lat'] = 39.907635;pointsInfo[154] = [];pointsInfo[154]['lng'] = 116.395737;pointsInfo[154]['lat'] = 39.907623;pointsInfo[155] = [];pointsInfo[155]['lng'] = 116.396225;pointsInfo[155]['lat'] = 39.907623;pointsInfo[156] = [];pointsInfo[156]['lng'] = 116.394592;pointsInfo[156]['lat'] = 39.908001;pointsInfo[157] = [];pointsInfo[157]['lng'] = 116.395020;pointsInfo[157]['lat'] = 39.908009;pointsInfo[158] = [];pointsInfo[158]['lng'] = 116.395317;pointsInfo[158]['lat'] = 39.908009;pointsInfo[159] = [];pointsInfo[159]['lng'] = 116.399864;pointsInfo[159]['lat'] = 39.908566;pointsInfo[160] = [];pointsInfo[160]['lng'] = 116.400299;pointsInfo[160]['lat'] = 39.908524;pointsInfo[161] = [];pointsInfo[161]['lng'] = 116.400581;pointsInfo[161]['lat'] = 39.908550;pointsInfo[162] = [];pointsInfo[162]['lng'] = 116.400711;pointsInfo[162]['lat'] = 39.908302;pointsInfo[163] = [];pointsInfo[163]['lng'] = 116.400421;pointsInfo[163]['lat'] = 39.908142;pointsInfo[164] = [];pointsInfo[164]['lng'] = 116.400093;pointsInfo[164]['lat'] = 39.908344;pointsInfo[165] = [];pointsInfo[165]['lng'] = 116.398384;pointsInfo[165]['lat'] = 39.906963;pointsInfo[166] = [];pointsInfo[166]['lng'] = 116.399223;pointsInfo[166]['lat'] = 39.907017;pointsInfo[167] = [];pointsInfo[167]['lng'] = 116.400108;pointsInfo[167]['lat'] = 39.907078;pointsInfo[168] = [];pointsInfo[168]['lng'] = 116.401115;pointsInfo[168]['lat'] = 39.907131;</script><style>.m-tit{font-size: 22px;color: #333333;}.w110 {width: 110px;}.l-btn {line-height: 36px;cursor: pointer;border-radius: 4px;color: #ffffff;font-family: microsoft yahei;font-size: 12px;width: 91px;height: 36px;border: none;background: #3cc;}.one-level{margin-bottom: 20px;border-bottom:1px solid #ddd;height: 68px;line-height: 68px;}.mapc-input{ position: absolute; top: 200px; right: 100px; width: 260px; height:auto; border: 1px solid #ccc; padding:5px; background-color: #fff;}.mapc-input input[type=text]{ display: block; margin-left: 20px; width: 148px; height: 26px; border: 1px solid #ccc;float: left;}.mapc-btn{ display: block; margin-left:15px; width: 58px; height: 30px; line-height: 30px; font-size: 13px; text-align: center; float:left;cursor:pointer;}
</style><body>
<div class="one-level"><span class="m-tit">地图标点</span>
</div>
<table width="94%" height="40" border="0" align="center" cellpadding="0" cellspacing="0" style="margin-top:20px;"><tr style="border-bottom:2px solid #990000;"><div style="width:94%;margin-left:3%;"><button class="l-btn w110 fr" style="float:right;margin-right:20px;" onclick="startPunc(this)">开始标点</button><button class="l-btn w110 fr" style="float:right;margin-right:20px;display: none;" onclick="savePoints(this)">确认提交</button></div></tr>
</table><div style="width: 94%;margin:10px auto;padding:2px;border:1px solid #ccc;" id="map"><div id="map_canvas" style="width: 100%; height: 400px"></div><div class="mapc-input" style="z-index:100000;"><input type="text" id="keyword" value=""><button class="mapc-btn" onclick="searchLocation();">定位</button></div>
</div><table id="Legend" width="150" border="0" cellspacing="0" cellpadding="4" style="position: absolute; z-index: 1; border: 1px solid rgb(102, 102, 102); background-color: rgb(255, 255, 255); top: 534px; left: 747.5px;"><tr><td align="center">图例: &nbsp; <font color="#FF0033" face="Arial black">◆</font>标点位置 &nbsp;   </td></tr>
</table>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=OGTxxxxxxx9mek"></script>
<script type="text/javascript" src="./js/Baidu_DistanceTool_1.2.js"></script>
<script type="text/javascript" src="./js/index.js"></script>
</body>
</html>

##Baidu_DistanceTool_1.2.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;}/*** 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:rgb(51, 51, 51);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 : customStyle.borderColor});}};/*** 开启地图的测距状态* @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;}//判断标点所属城市,非本城市不允许标点geoc.getLocation(poi, function(rs){var addComp = rs.addressComponents;//海南省的都不限,海南站点包含了海南全部的城市//昆山是苏州下面的一个县级市,也需要特殊处理if((city == '海南' && addComp.province == '海南省')|| (city == '昆山' && addComp.city == '苏州市' && addComp.district == '昆山市')){}else if(addComp.city.replace('市','') != city){alert('只能在本城市范围内标点');isSelfCity = false;return false;}//else{// 记录当前点的屏幕位置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;}}pointList[pointList.length] = poi;//处理ie兼容问题,ie下使用e.layerX时定位有偏差if(/msie|rv:11|windows\snt\s10/.test(navigator.userAgent.toLowerCase())){me._bind.x = e.offsetX || e.layerX || 0;me._bind.y = e.offsetY || e.layerY || 0;}else{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);addOverlayList[addOverlayList.length] = 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);var disLabel = new BMap.Label(disText, {offset : new BMap.Size(-15, -50), enableMassClear : me._enableMassClear});//disLabel.setStyles({color : "#333", borderColor : "#ff0103"});disLabel.setStyles({color : "#333", borderColor : customStyle.borderColor});me._map.addOverlay(disLabel);me._formatSegLabel(disLabel, disText);me._overlays.push(disLabel);poi.disLabel = disLabel;disLabel.setPosition(poi);addOverlayList[addOverlayList.length] = disLabel;} else {//disText = "起点";}/*** 测距过程中,每次点击底图添加节点时,派发事件的接口* @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") {//处理ie兼容问题,ie下使用e.layerX时定位有偏差if(/msie|rv:11|windows\snt\s10/.test(navigator.userAgent.toLowerCase())){me._bind.x = e.offsetX || e.layerX || 0;me._bind.y = e.offsetY || e.layerY || 0;}else{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();me.newClose();}, 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();me.newClose();}, 50);}};/*** 测距过程中,鼠标弹起时,触发的操作* @ignore* @param {Object} e event对象*/var distMouseUp = function(e) {e = window.event || e;var ieVersion = 0;if(/msie|rv:11|windows\snt\s10/.test(navigator.userAgent.toLowerCase())){ieVersion = document.documentMode || + RegExp['\x241'];}if (ieVersion && e.button != 1 || e.button == 2){//me.close();//me.newClose();}};// 初始化存储数据if(isPointOver){me._initData();isPointOver = false;}// 调整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){if (me._points.length < 1){// 不是有效绘制,清除所有内容me._clearCurData();pointList = [];} else if(me._points.length > 1) {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();}};/*** 点击确认提交前,双击结束测距时响应*/DistanceTool.prototype.newClose = function(){if (this._isOpen == false){return;}this._isOpen = false;BMapLib._toolInUse = false;if (this._mapMoving){delete this._mapMoving;}var me = this;me._dispatchLastEvent();OperationMask.hide();// 停止地图移动if (me._movingTimerId){clearInterval(me._movingTimerId);me._movingTimerId = null;}if (this._followTitle){this._followTitle.hide();}//改变鼠标形状//OperationMask._setCursor('pointer');//me._setCursor('http://api0.map.bdimg.com/images/openhand.cur');}/*** 清除本次测距的暂存数据* @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});secPt.setOffset(new BMap.Size(-2,-15));this._map.addOverlay(secPt);addOverlayList[addOverlayList.length] = 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(2);} else {dis = dis.toFixed(0); }*/dis = dis.toFixed(0);return dis + unit;};/*** 设置鼠标样式* @param {String} cursor 鼠标样式* @return 没有返回值*/DistanceTool.prototype._setCursor = function(cursor){// 由于webkit内核浏览器下,cursor设置后默认不会居中,所以需要对偏移值进行设置cursor = cursor == '' ? this._opts.cursor : cursor;var csr =/webkit/.test(navigator.userAgent.toLowerCase()) ?"url(" + cursor + ") 3 6, crosshair" :"url(" + 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, -50];}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: customStyle.borderColor});me._map.addOverlay(pt.disLabel);pt.disLabel.setOffset(new BMap.Size(disOffset[0], disOffset[1]));pt.disLabel.setPosition(pt);me._formatTitle(2, "", "", pt.disLabel);addOverlayList[addOverlayList.length] = 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(2);} else {dis = dis.toFixed(0);}*/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) {// 结束时的总距离展示title.setOffset(0, 0);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(2);} else{dis = dis.toFixed(0);}*/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(2);} else {dis = dis.toFixed(0);}*/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;//处理ie兼容问题,ie下使用e.layerX时定位有偏差if(/msie|rv:11|windows\snt\s10/.test(navigator.userAgent.toLowerCase())){var x = e.offsetX || e.layerX || 0;var y = e.offsetY || e.layerY || 0;}else{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;};
})();

##index.js

var pointList = []; //保存标点的数组
var addOverlayList = []; //保存添加过的覆盖物,在清除覆盖物时使用
var isPointOver = true; //判断此次标点是否结束,当提交保存成功后本次才算结束,确认提交取消按钮时还可继续标点
var addOverlayPoints = []; //保存显示的标点
//保存比例尺及其对应的米数
var zoomList = [];
zoomList[19] = 20;
zoomList[18] = 50;
zoomList[17] = 100;
zoomList[16] = 200;
zoomList[15] = 500;
zoomList[14] = 1000;
zoomList[13] = 2000;
zoomList[12] = 5000;
zoomList[11] = 10000;
zoomList[10] = 20000;
zoomList[9] = 25000;
zoomList[8] = 50000;
zoomList[7] = 100000;
zoomList[6] = 200000;
zoomList[5] = 500000;
zoomList[4] = 1000000;
zoomList[3] = 2000000;//自定义样式
var customStyle = {"borderColor":"#20A0E4", //标点之间连线颜色"redMarkerSrc":"./images/marker_red.png", //已提交的标点样式"blueMarkerSrc":"./images/marker_blue.png" //本次待提交的标点样式
};//初始化百度地图信息
//enableMapClick:false 设置景点不可点,默认为true,点击景点时,弹出景点详情
var map = new BMap.Map('map_canvas',{enableMapClick:false});
map.centerAndZoom(city, 16);
map.addControl(new BMap.NavigationControl());        // 添加平移缩放控件
map.addControl(new BMap.ScaleControl());             // 添加比例尺控件
map.addControl(new BMap.OverviewMapControl());       //添加缩略地图控件
map.enableScrollWheelZoom();                         //启用滚轮放大缩小
//map.disable3DBuilding();//设置绘制铁路线样式
var styleJson = [{"featureType": "railway","elementType": "all","stylers": {"color": "#000000",}
}]
map.setMapStyle({styleJson:styleJson});//地图测距功能初始化
var opts = {"followText":"单击确定标点,双击结束标点","lineColor":"#20A0E4","secIcon":new BMap.Icon(customStyle.blueMarkerSrc, new BMap.Size(21, 35)),
};
var myDis = new BMapLib.DistanceTool(map,opts);//添加地图是否加载完毕的事件
var bs,bssw,bsne;
map.addEventListener("tilesloaded",function(){//地图加载完毕bs = map.getBounds();   //获取可视区域bssw = bs.getSouthWest();   //可视区域左下角bsne = bs.getNorthEast();   //可视区域右上角//console.log("当前地图可视范围是:" + bssw.lng + "," + bssw.lat + "到" + bsne.lng + "," + bsne.lat);//加载可视区域内已保存的标点showPoints(pointsInfo,bssw,bsne);});//点击开始标点
function startPunc(obj){$(obj).hide();$('.mapc-input').hide();$(obj).siblings('button').eq(0).show();myDis.open();  //开启鼠标测距
}//判断标点所属城市
var geoc = new BMap.Geocoder();//提交标点
function savePoints(obj){if(myDis._isOpen && myDis._points.length > 0){alert('请结束标点后再提交');return false;}if(pointList.length == 0){alert('请标点后再提交');return false;}if(!window.confirm('确定提交吗?提交后,已标点的坐标点无法更改!')){setTimeout(function(){myDis.open();//点取消,停留在当前页可继续标点},500);return false;}var pointStr = '';for(var i = 0, len = pointList.length; i < len; i++){if(!pointList[i]) {continue;}pointStr += pointList[i]['lng'] + '|' + pointList[i]['lat'] + ',';}pointStr = pointStr.substr(0,pointStr.length-1);$.ajax({type:'post',url:'./savePoint.aspx',data:{'city':city,'action':'save','pointList':pointStr},dataType:'json',success:function(data){if(data.code == 100){alert('保存成功!');isPointOver = true;myDis.close();//关闭鼠标测距大removeOverlay(); //移除覆盖物//将保存入库的标点添加到数组中,并展示for(var i = 0, len = pointList.length; i < len; i++){pointsInfo.push(pointList[i]);}pointList = [];showPoints(pointsInfo,bssw,bsne);$('.l-btn').eq(0).show();$('.l-btn').eq(1).hide();$('.mapc-input').show();return true;}else{alert(data.msg);return false;}}});
}//显示已保存标点
function showPoints(pointsInfo,bssw,bsne){//当地图缩放比例过大时,地图上的点选择性展示,而不再是展示每一个点var curZoom = map.getZoom();//获取当前比例尺大小var gapsize = 1; //间隔显示点的个数,默认每个点都展示if(curZoom < 16 && curZoom > 2){gapsize = zoomList[curZoom]/100;}for(var i = 0,len = pointsInfo.length; i < len; i++){var key = pointsInfo[i]['lng']+','+pointsInfo[i]['lat'];if(gapsize == 1){if(pointsInfo[i]['lng'] >= bssw.lng && pointsInfo[i]['lng'] <= bsne.lng && pointsInfo[i]['lat'] >= bssw.lat && pointsInfo[i]['lat'] <= bsne.lat){//坐标点在该展示范围,并且还未标点的,则标点if(undefined == addOverlayPoints[key] || !addOverlayPoints[key]){addOverlay(pointsInfo[i]['lng'],pointsInfo[i]['lat'],customStyle.redMarkerSrc);}}else if(undefined != addOverlayPoints[key] && addOverlayPoints[key] != ''){//如果该坐标点不在展示范围就移除map.removeOverlay(addOverlayPoints[key]);addOverlayPoints[key] = '';}}else{//如果该坐标点不在展示范围,且已标点,需要移除if(undefined != addOverlayPoints[key] && addOverlayPoints[key] != ''){map.removeOverlay(addOverlayPoints[key]);addOverlayPoints[key] = '';}if(i%gapsize == 0 && pointsInfo[i]['lng'] >= bssw.lng && pointsInfo[i]['lng'] <= bsne.lng && pointsInfo[i]['lat'] >= bssw.lat && pointsInfo[i]['lat'] <= bsne.lat){//坐标点在该展示范围,并且还未标点的,则标点if(undefined == addOverlayPoints[key] || !addOverlayPoints[key]){addOverlay(pointsInfo[i]['lng'],pointsInfo[i]['lat'],customStyle.redMarkerSrc);}}}}
}//添加标点
function addOverlay(lng,lat,markerSrc){var point,newIcon,marker;point = new BMap.Point(lng,lat);newIcon = new BMap.Icon(markerSrc, new BMap.Size(21, 35));marker = new BMap.Marker(point,{icon:newIcon});marker.setOffset(new BMap.Size(-2,-15)); //设置标点位置map.addOverlay(marker); //添加标点addOverlayPoints[lng+','+lat] = marker;
}//移除标点、直线、文字等
function removeOverlay(){for(var i = 0, len = addOverlayList.length; i < len; i++){map.removeOverlay(addOverlayList[i]);}
}//根据地点关键字定位
function searchLocation(){var keyword = $('#keyword').val();if(!keyword) return false;var local = new BMap.LocalSearch(map, {renderOptions:{map: map},pageCapacity:1,onSearchComplete: function(results){if (local.getStatus() == BMAP_STATUS_SUCCESS){var objpoint=results.getPoi(0).point;if(!objpoint){alert("不能匹配到位置: " + keyword);}else{addOverlay(objpoint.lng,objpoint.lat,customStyle.blueMarkerSrc);map.centerAndZoom(new BMap.Point(objpoint.lng,objpoint.lat), 19);}}local.clearResults();}});//forceLocal表示是否将搜索范围约束在当前城市local.search(keyword,{forceLocal:true});
}

##savePoint.aspx.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.UI.WebControls;namespace OneTask
{public partial class savePoint : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){Dictionary<string, object> dic = new Dictionary<string, object>();JavaScriptSerializer jss = new JavaScriptSerializer();dic.Add("code",100);dic.Add("msg","保存成功");dic.Add("data",Request["pointList"]);Response.Write(jss.Serialize(dic));Response.End();} }
}

##资源

##运行如图:

百度API实现地图标点并测距相关推荐

  1. Matlab调用百度API画地图讲解教程

    1-4环境搭建步骤参考之前写的博客,看完了记得回来呀,链接如下: https://blog.csdn.net/zzx2016zzx/article/details/87976720 5.直接丢代码绘图 ...

  2. (三)爬取新房销售信息——位置坐标转换+地图标点可视化篇

    在上一次用pandas做数据分析.matplotlib实现可视化的任务中,主要对于"价格"信息做了简单的处理,了解到赣州地区房价水平的范围,各区县的房价水平,根据自己的预算大致可以 ...

  3. 百度地图加载空白颜色_本地地图标点的html实现

    地图批量标点的实现方法有很多,也有很多网站支持直接Excel上传数据进行标点的.比如地图无忧等.但都是软收费的模式(要么有使用期限,要么有数量限制),后来在查找资料的过程中,发现了一个在本地可以实现地 ...

  4. 【百度地图API】百度API卫星图使用方法和卫星图对比工具

    百度地图API推出卫星图接口也有一个月啦~ 本文除了介绍如何使用百度地图API来操作卫星图外,还顺带制作了个卫星图对比工具. 一.百度地图API卫星图 调用百度卫星图有两种方式,一是地图类型控件,一是 ...

  5. 百度地图Geolocation的getStatus状态值(百度API获取当前位置[经纬度])

    //关于状态码 //BMAP_STATUS_SUCCESS 检索成功.对应数值"0". //BMAP_STATUS_CITY_LIST 城市列表.对应数值"1" ...

  6. php网页地图上自定义,网页嵌入百度地图和使用百度地图api自定义地图的详细步骤...

    在网页中插入百度地图 如果想在自己的网页上面加入百度地图的话,可以用百度地图的api.具体使用方法如下: 第二步:设置地图,大家可以对网站显示地图的宽高进行设置,其余选项不动. 第三步:添加标注.点击 ...

  7. centerandzoom 无效_Django调用百度地图api在地图上批量增加标记点

    在调用百度地图api进行web开发时遇到了一个需求,我们需要在网页中内嵌一个div 然后在div中调用百度地图的js显示我们所需要的地区.根据需求坐标在地图上添加若干个标记点,并批量的为各个标记点设置 ...

  8. 将手绘地图或自制地图显示在网页上(利用百度API)

    利用百度APi实现将手绘地图展示在网页上,达到类似这样的效果: 切图参考了:cnblog jz1108 并用了其工具, 表示非常感谢! 百度地图API目前默认支持两种地图类型(map type):普通 ...

  9. python画地图经纬度_Python 百度API 画出美美哒热力地图(代码 数据)

    作者:王大伟 前言 现在是晚上22:22,我是不是很2 周围的人都在跨年刷朋友圈 我一个人在办公室默默打开博客 准备写一篇文章为2017画下句点 之前在写葡萄酒数据分析那篇文章时 曾想过做一个葡萄酒分 ...

最新文章

  1. Samtools安装与使用
  2. gitignore完整使用方法
  3. attachment绑相对url
  4. Android版添加phonegap--websocket客户端插件教程
  5. Smokeping的参数使用说明
  6. 疑似小米7工程机在咸鱼开售,售价100万起?
  7. go mysql 多并发_MySQL并发处理-Go语言中文社区
  8. AcWing 867. 分解质因数(唯一分解定理)
  9. 【日本软件外包】设计书中常用到的文型
  10. 2022新版Git教程 从入门到实战(二)Git本地仓库的使用
  11. GreenSock Animation Platform
  12. 2021编辑器Eclipse汉化中文教程
  13. 微信开发者工具的使用和各个文件的作用
  14. java生成emf_推荐一款java代码生成的插件EMF
  15. 多机联动方案-云真机测试
  16. 机器学习7个主要领域
  17. undo和redo日志
  18. Tech Blog by Eason!
  19. http://zaojiasys.jianshe99.com 建造师数据泄漏,可以查看全部所有人的信息!
  20. 使用python画k均值分类图

热门文章

  1. python读xml文件生成.h头文件_Python创建xml文件示例
  2. java--五子棋人机大战--课程设计
  3. 那么,我是不工作会死啦?
  4. Nvidia Jetson NX配置教程 for 阿福哥
  5. 【tensorflow】生成.pb文件
  6. OSChina 周三乱弹 —— 姑娘不是我的心上人,请自重
  7. 数学分析常用的4款软件对比!
  8. 第二章 Redis高级
  9. 关于options请求的一点理解
  10. oracle绑定变量执行计划,绑定变量对执行计划的影响