leafletDraw2.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. let mousemove2Status = true;
  2. let LControlDraw = L.Control.extend({
  3. //是否初始化
  4. _initialized: false,
  5. //统计
  6. _lC: 0,
  7. //测量对象集合
  8. _measureObjs: {},
  9. //是否完成当前测绘
  10. _finished: true,
  11. //新测量
  12. isNewElevation: true,
  13. moveMarker: false,
  14. //测量参数
  15. options: {
  16. position: "topright",
  17. autoZIndex: true,
  18. offset: [0, 0],
  19. background: "#000",
  20. color: "#fff",
  21. size: 14,
  22. closeButton: true,
  23. iconUrl: "./images/marker-icon.png"
  24. },
  25. initialize: function (options) {
  26. L.setOptions(this, options);
  27. return this;
  28. },
  29. onAdd: function (map) {
  30. this._map = map;
  31. this._createControl();
  32. switch (this.options.position) {
  33. case "topleft":
  34. this._container.style.marginLeft = this.options.offset[0] + "px";
  35. this._container.style.marginTop = this.options.offset[1] + "px";
  36. break;
  37. case "topright":
  38. this._container.style.marginRight = this.options.offset[0] + "px";
  39. this._container.style.marginTop = this.options.offset[1] + "px";
  40. break;
  41. case "bottomleft":
  42. this._container.style.marginLeft = this.options.offset[0] + "px";
  43. this._container.style.marginBottom = this.options.offset[1] + "px";
  44. break;
  45. case "bottomright":
  46. this._container.style.marginRight = this.options.offset[0] + "px";
  47. this._container.style.marginBottom = this.options.offset[1] + "px";
  48. break;
  49. }
  50. return this._container;
  51. },
  52. _createControl: function () {
  53. var _this = this;
  54. this._container = L.DomUtil.create("div", "leaflet-bar leaflet-control-measure");
  55. var link = L.DomUtil.create("a", "leaflet-control-measure-link", this._container);
  56. link.title = "测量";
  57. // L.DomUtil.create("span", "", link);
  58. L.DomEvent.on(this._container, "contextmenu", L.DomEvent.stopPropagation)
  59. .on(link, "click", L.DomEvent.stopPropagation)
  60. .on(link, "click", function () {
  61. if (_this._finished) {
  62. //开启新的测量
  63. _this.start();
  64. } else {
  65. _this._finished = true;
  66. }
  67. });
  68. // _this.start();
  69. },
  70. start: function () {
  71. var _this = this;
  72. _this._finished = false;
  73. L.DomUtil.addClass(_this._container, "active");
  74. _this._addMeasureGroup();
  75. },
  76. _addMeasureGroup: function () {
  77. var _this = this;
  78. if (!_this._initialized) {
  79. _this._measureGroup = new L.featureGroup();
  80. _this._measureGroup.addTo(this._map);
  81. _this._initialized = true;
  82. }
  83. if (_this.isNewElevation) {
  84. _this._lC++;
  85. _this._measureObjs[_this._lC] = new L.FeatureGroup();
  86. _this._measureObjs[_this._lC].addTo(_this._measureGroup);
  87. _this.isNewElevation = false;
  88. _this._measureObjs[_this._lC].measurePoints = [];
  89. }
  90. _this.tmpMarkers = [];
  91. //关闭地图双击事件
  92. _this._map.doubleClickZoom.disable();
  93. //监听地图单击事件
  94. _this._map.on("click", _this._onClickPoint, this);
  95. //监听鼠标移动事件
  96. _this._map.on("mousemove", _this._mousemove, this);
  97. },
  98. _mousemove: function (e) {
  99. if (mousemove2Status) {
  100. var _this = this;
  101. e.latlng = _this.latlngRectifying(e);
  102. if (_this.moveMarker) {
  103. _this.moveMarker.setLatLng(e.latlng);
  104. if (_this._measureObjs[_this._lC].polyline) {
  105. _this._measureObjs[_this._lC].measurePoints.push([e.latlng.lat, e.latlng.lng]);
  106. var points = _this._measureObjs[_this._lC].measurePoints;
  107. if (_this._measureObjs[_this._lC].measurePoints.length == 2) {
  108. var radius = L.latLng(points[1]).distanceTo(L.latLng(points[0]));
  109. _this._measureObjs[_this._lC].circle.setRadius(radius);
  110. } else if (_this._measureObjs[_this._lC].measurePoints.length == 3 && e.latlng.indexMarker == 1) {
  111. _this._measureObjs[_this._lC].circle.setStyle({
  112. opacity: 1
  113. });
  114. } else {
  115. _this._measureObjs[_this._lC].circle.setStyle({
  116. opacity: 0
  117. });
  118. }
  119. if (_this._measureObjs[_this._lC].measurePoints.length > 2) {
  120. var coors = _.clone(_this._measureObjs[_this._lC].measurePoints);
  121. coors.push(
  122. _this._measureObjs[_this._lC].measurePoints[_this._measureObjs[_this._lC].measurePoints.length - 1]
  123. );
  124. if (_this._measureObjs[_this._lC].polygon) {
  125. _this._measureObjs[_this._lC].polygon.setLatLngs([coors]);
  126. } else {
  127. _this._measureObjs[_this._lC].polygon = L.polygon([coors], {
  128. color: "#fff",
  129. weight: 0,
  130. fillColor: "#fff",
  131. fillOpacity: 0.3
  132. }).addTo(_this._measureObjs[_this._lC]);
  133. }
  134. }
  135. _this._measureObjs[_this._lC].polyline.setLatLngs(points);
  136. //实时计算测量数据
  137. var moveData = _.clone(points);
  138. _this._moveInfo(moveData);
  139. _this._measureObjs[_this._lC].measurePoints.pop();
  140. }
  141. } else {
  142. _this.moveMarker = L.circleMarker(e.latlng, {
  143. radius: 10,
  144. color: "#f00"
  145. }).addTo(_this._map);
  146. }
  147. } else {
  148. this._map.off("mousemove");
  149. // console.log("lmx");
  150. }
  151. },
  152. //测量时,根据鼠标移动点位信息
  153. _moveInfo: function (data) {
  154. var _this = this;
  155. var lineDistance = 0;
  156. for (var i = 1; i < data.length; i++) {
  157. var curcoor = data[i];
  158. var prePoint = data[i - 1];
  159. lineDistance = L.latLng(curcoor).distanceTo(prePoint);
  160. var lineDistanceStr =
  161. lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + "公里" : Math.ceil(lineDistance) + "米";
  162. if (i == data.length - 1) {
  163. var pointAngle = L.Util.getAngleByLatLng(prePoint[1], prePoint[0], curcoor[1], curcoor[0]);
  164. }
  165. }
  166. //添加分段信息
  167. var oLabelObj = L.DomUtil.create("div", "measure-content");
  168. var pointText = L.DomUtil.create("span", "measure-result-text");
  169. pointText.innerHTML = lineDistanceStr;
  170. oLabelObj.appendChild(pointText);
  171. if (data.length > 1) {
  172. if (_this.tmpMarkers[data.length - 2]) {
  173. //如果最后一个点存在,更新最后一个点信息
  174. _this.tmpMarkers[data.length - 2].setLatLng(data[data.length - 1]);
  175. _this.tmpMarkers[data.length - 2].label.setContent(oLabelObj);
  176. } else {
  177. //如果最后一个点不存在,创建点信息
  178. var marker = L.marker(data[data.length - 1], {
  179. icon: L.divIcon({ className: "measuremarker", iconSize: [4, 4] })
  180. });
  181. marker.bindLabel(oLabelObj, {
  182. noHide: true,
  183. clickable: true,
  184. className: "measure-tip",
  185. offset: [0, 0]
  186. });
  187. marker.addTo(_this._measureObjs[_this._lC]);
  188. _this.tmpMarkers.push(marker);
  189. }
  190. }
  191. },
  192. /**
  193. * 通过坐标点计算面积
  194. * @type {Function}
  195. * @returns {Number} 面积
  196. * @private
  197. */
  198. _getArea: function (_lc) {
  199. var _this = this;
  200. var latLngs = _this._measureObjs[_lc].measurePoints;
  201. var pointsCount = latLngs.length,
  202. area = 0.0,
  203. d2r = Math.PI / 180,
  204. p1,
  205. p2;
  206. if (pointsCount > 2) {
  207. for (var i = 0; i < pointsCount; i++) {
  208. p1 = latLngs[i];
  209. p2 = latLngs[(i + 1) % pointsCount];
  210. area += (p2[1] - p1[1]) * d2r * (2 + Math.sin(p1[0] * d2r) + Math.sin(p2[0] * d2r));
  211. }
  212. area = (area * 6378137.0 * 6378137.0) / 2.0;
  213. }
  214. area = Math.abs(area);
  215. if (area > 1000000) {
  216. area = (area * 0.000001).toFixed(2) + " 平方公里";
  217. } else {
  218. area = area.toFixed(2) + " 米&sup2;";
  219. }
  220. return area;
  221. },
  222. latlngRectifying: function (e) {
  223. var _this = this;
  224. var curLatlngs = [];
  225. var curpx = e.layerPoint;
  226. var length = _this._measureObjs[_this._lC] ? _this._measureObjs[_this._lC].measurePoints.length : 0;
  227. var latlng = e.latlng;
  228. if (length > 0) {
  229. curLatlngs.push({
  230. latlng: _this._measureObjs[_this._lC].measurePoints[0],
  231. px: _this._map.latLngToLayerPoint(_this._measureObjs[_this._lC].measurePoints[0])
  232. });
  233. curLatlngs.push({
  234. latlng: _this._measureObjs[_this._lC].measurePoints[length - 1],
  235. px: _this._map.latLngToLayerPoint(_this._measureObjs[_this._lC].measurePoints[length - 1])
  236. });
  237. }
  238. for (var i = 0; i < curLatlngs.length; i++) {
  239. var dispx = Math.sqrt(
  240. (curpx.x - curLatlngs[i].px.x) * (curpx.x - curLatlngs[i].px.x) +
  241. (curpx.y - curLatlngs[i].px.y) * (curpx.y - curLatlngs[i].px.y)
  242. );
  243. if (dispx < 10) {
  244. latlng = L.latLng(curLatlngs[i].latlng);
  245. latlng.reset = true;
  246. latlng.indexMarker = i;
  247. break;
  248. }
  249. }
  250. return latlng;
  251. },
  252. _onClickPoint: function (e) {
  253. var _this = this;
  254. e.latlng = _this.latlngRectifying(e);
  255. if (!e.latlng.reset) {
  256. _this._measureObjs[_this._lC].measurePoints.push([e.latlng.lat, e.latlng.lng]);
  257. } else {
  258. if (e.latlng.indexMarker == 0) {
  259. if (_this._measureObjs[_this._lC].polygon) {
  260. _this._measureObjs[_this._lC].measurePoints.push([e.latlng.lat, e.latlng.lng]);
  261. _this._measureObjs[_this._lC].polygon.setLatLngs(_this._measureObjs[_this._lC].measurePoints);
  262. _this._measureObjs[_this._lC].polygon.setStyle({
  263. fillColor: "#f00",
  264. color: "#f00",
  265. weight: 0,
  266. fillOpacity: 0.3
  267. });
  268. } else {
  269. _this._measureObjs[_this._lC].removeLayer(_this._measureObjs[_this._lC].circle);
  270. _this._measureObjs[_this._lC].removeLayer(_this._measureObjs[_this._lC].polyline);
  271. }
  272. } else {
  273. _this._measureObjs[_this._lC].removeLayer(_this._measureObjs[_this._lC].polygon);
  274. _this._measureObjs[_this._lC].polygon = null;
  275. }
  276. _this._onFinishClick();
  277. }
  278. if (_this._measureObjs[_this._lC].measurePoints.length == 1 && !_this._finished) {
  279. var latlngs = [
  280. [e.latlng.lat, e.latlng.lng],
  281. [e.latlng.lat, e.latlng.lng]
  282. ];
  283. _this._measureObjs[_this._lC].polyline = L.polyline(latlngs, {
  284. color: "red",
  285. dashArray: 10
  286. }).addTo(_this._measureObjs[_this._lC]);
  287. _this._measureObjs[_this._lC].circle = L.circle([e.latlng.lat, e.latlng.lng], {
  288. radius: 0,
  289. color: "red",
  290. fillOpacity: 0
  291. }).addTo(_this._measureObjs[_this._lC]);
  292. } else {
  293. // _this._measureObjs[_this._lC].removeLayer(_this._measureObjs[_this._lC].circle);
  294. }
  295. },
  296. _onFinishClick: function () {
  297. let _this = this;
  298. //关闭地图双击事件
  299. _this._map.doubleClickZoom.enable();
  300. //监听地图单击事件
  301. _this._map.off("click", _this._onClickPoint, this);
  302. //监听鼠标移动事件
  303. _this._map.off("mousemove", _this._mousemove, this);
  304. _this.isNewElevation = true;
  305. _this._finished = true;
  306. _this._map.removeLayer(_this.moveMarker);
  307. _this.moveMarker = null;
  308. for (var i = 0; i < _this.tmpMarkers.length; i++) {
  309. _this._measureObjs[_this._lC].removeLayer(_this.tmpMarkers[i]);
  310. }
  311. _this.tmpMarkers = [];
  312. //根据点集合渲染marker点
  313. var coorslength = _this._measureObjs[_this._lC].measurePoints.length;
  314. _this._measureObjs[_this._lC].markerObjs = [];
  315. var lineDistance = 0;
  316. if (coorslength > 1) {
  317. for (var i = 0; i < coorslength; i++) {
  318. var curcoor = _this._measureObjs[_this._lC].measurePoints[i];
  319. var marker = L.marker(curcoor, {
  320. draggable: true,
  321. icon: L.divIcon({ className: "measuremarker", iconSize: [10, 10] })
  322. });
  323. if (i > 0) {
  324. var prePoint = _this._measureObjs[_this._lC].measurePoints[i - 1];
  325. lineDistance = L.latLng(curcoor).distanceTo(prePoint);
  326. var lineDistanceStr =
  327. lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + "公里" : Math.ceil(lineDistance) + "米";
  328. var pointAngle = L.Util.getAngleByLatLng(prePoint[1], prePoint[0], curcoor[1], curcoor[0]);
  329. //添加分段信息
  330. var oLabelObj = L.DomUtil.create("div", "measure-content");
  331. var delLabel = L.DomUtil.create("div", "measure-ico-del");
  332. var saveLabel = L.DomUtil.create("div", "measure-ico-save");
  333. var pointText = L.DomUtil.create("span", "measure-result-text");
  334. pointText.innerHTML = lineDistanceStr;
  335. delLabel.lC = _this._lC;
  336. saveLabel.lC = _this._lC;
  337. L.DomEvent.on(delLabel, "click", function (e) {
  338. L.DomEvent.stopPropagation(e);
  339. _this.del(delLabel.lC);
  340. });
  341. L.DomEvent.on(saveLabel, "click", function (e) {
  342. L.DomEvent.stopPropagation(e);
  343. _this._map.fire("draw-result", {
  344. distance: _this._measureObjs[delLabel.lC].distance,
  345. points: _this._measureObjs[delLabel.lC].measurePoints,
  346. area: _this._measureObjs[delLabel.lC].area || 0,
  347. LC: delLabel.lC
  348. });
  349. });
  350. if (i == coorslength - 1) {
  351. //测量面积
  352. if (_this._measureObjs[_this._lC].polygon) {
  353. var area = _this._getArea(_this._lC);
  354. _this._measureObjs[_this._lC].area = area;
  355. pointText.innerHTML = lineDistanceStr + "<br/>" + area;
  356. }
  357. oLabelObj.appendChild(delLabel);
  358. oLabelObj.appendChild(saveLabel);
  359. }
  360. oLabelObj.appendChild(pointText);
  361. marker.bindLabel(oLabelObj, {
  362. noHide: true,
  363. clickable: true,
  364. className: "measure-tip",
  365. offset: [0, 0]
  366. });
  367. }
  368. marker.LC = _this._lC;
  369. marker.LIndex = i;
  370. marker.addTo(_this._measureObjs[_this._lC]);
  371. _this._measureObjs[_this._lC].markerObjs.push(marker);
  372. if (!(i == 0 && _this._measureObjs[_this._lC].polygon)) {
  373. marker.on("move", function (e) {
  374. _this._renderMeasure({
  375. LC: e.target.LC,
  376. LIndex: e.target.LIndex,
  377. latlng: e.latlng
  378. });
  379. });
  380. }
  381. }
  382. } else {
  383. var curcoor = _this._measureObjs[_this._lC].measurePoints[0];
  384. var myIcon = L.icon({
  385. iconUrl: this.options.iconUrl,
  386. iconSize: [25, 41],
  387. iconAnchor: [12, 41]
  388. });
  389. var marker = L.marker(curcoor, { draggable: true, icon: myIcon });
  390. var oLabelObj = L.DomUtil.create("div", "measure-content");
  391. var delLabel = L.DomUtil.create("div", "measure-ico-del");
  392. var saveLabel = L.DomUtil.create("div", "measure-ico-save");
  393. delLabel.lC = _this._lC;
  394. saveLabel.lC = _this._lC;
  395. L.DomEvent.on(delLabel, "click", function (e) {
  396. L.DomEvent.stopPropagation(e);
  397. _this.del(delLabel.lC);
  398. });
  399. L.DomEvent.on(saveLabel, "click", function (e) {
  400. L.DomEvent.stopPropagation(e);
  401. _this._map.fire("draw-result", {
  402. distance: _this._measureObjs[delLabel.lC].distance,
  403. points: _this._measureObjs[delLabel.lC].measurePoints,
  404. area: _this._measureObjs[delLabel.lC].area || 0,
  405. LC: delLabel.lC
  406. });
  407. });
  408. oLabelObj.appendChild(delLabel);
  409. oLabelObj.appendChild(saveLabel);
  410. marker.bindLabel(oLabelObj, {
  411. noHide: true,
  412. clickable: true,
  413. className: "measure-tip",
  414. offset: [0, 0]
  415. });
  416. marker.LC = _this._lC;
  417. marker.LIndex = i;
  418. marker.addTo(_this._measureObjs[_this._lC]);
  419. _this._measureObjs[_this._lC].markerObjs.push(marker);
  420. }
  421. _this._measureObjs[_this._lC].distance = lineDistance;
  422. },
  423. _renderMeasure: function (data) {
  424. var _this = this;
  425. var latlng = [data.latlng.lat, data.latlng.lng];
  426. if (_this._measureObjs[data.LC].measurePoints.length == 1) {
  427. return false;
  428. }
  429. _this._measureObjs[data.LC].measurePoints[data.LIndex] = latlng;
  430. var curlength = _this._measureObjs[data.LC].measurePoints.length;
  431. //如果是面,第一个点和最后一个点位置同时改变
  432. if (_this._measureObjs[data.LC].polygon) {
  433. if (data.LIndex == 0) {
  434. _this._measureObjs[data.LC].measurePoints[curlength - 1] = latlng;
  435. _this._measureObjs[_this._lC].markerObjs[curlength - 1].setLatLng(latlng);
  436. }
  437. if (data.LIndex == curlength - 1) {
  438. _this._measureObjs[data.LC].measurePoints[0] = latlng;
  439. _this._measureObjs[_this._lC].markerObjs[0].setLatLng(latlng);
  440. }
  441. }
  442. var points = _this._measureObjs[data.LC].measurePoints;
  443. //更新circle
  444. var radius = L.latLng(points[1]).distanceTo(L.latLng(points[0]));
  445. _this._measureObjs[data.LC].circle.setRadius(radius);
  446. _this._measureObjs[data.LC].circle.setLatLng(points[0]);
  447. if (points.length == 2) {
  448. _this._measureObjs[data.LC].circle.setStyle({
  449. opacity: 1
  450. });
  451. }
  452. //更新线
  453. _this._measureObjs[data.LC].polyline.setLatLngs(points);
  454. //更新面
  455. if (_this._measureObjs[data.LC].polygon) {
  456. _this._measureObjs[data.LC].polygon.setLatLngs([points]);
  457. }
  458. var lineDistance = 0;
  459. var coorslength = _this._measureObjs[data.LC].measurePoints.length;
  460. for (var i = 1; i < coorslength; i++) {
  461. var curcoor = _this._measureObjs[data.LC].measurePoints[i];
  462. var prePoint = _this._measureObjs[data.LC].measurePoints[i - 1];
  463. lineDistance = L.latLng(curcoor).distanceTo(prePoint);
  464. var lineDistanceStr =
  465. lineDistance > 1000 ? (lineDistance / 1000).toFixed(2) + "公里" : Math.ceil(lineDistance) + "米";
  466. var pointAngle = L.Util.getAngleByLatLng(prePoint[1], prePoint[0], curcoor[1], curcoor[0]);
  467. //添加分段信息
  468. var oLabelObj = L.DomUtil.create("div", "measure-content");
  469. var delLabel = L.DomUtil.create("div", "measure-ico-del");
  470. var saveLabel = L.DomUtil.create("div", "measure-ico-save");
  471. var pointText = L.DomUtil.create("span", "measure-result-text");
  472. pointText.innerHTML = lineDistanceStr;
  473. delLabel.lC = _this._lC;
  474. saveLabel.lC = _this._lC;
  475. L.DomEvent.on(delLabel, "click", function (e) {
  476. L.DomEvent.stopPropagation(e);
  477. _this.del(delLabel.lC);
  478. });
  479. L.DomEvent.on(saveLabel, "click", function (e) {
  480. L.DomEvent.stopPropagation(e);
  481. _this._map.fire("draw-result", {
  482. distance: _this._measureObjs[delLabel.lC].distance,
  483. points: _this._measureObjs[delLabel.lC].measurePoints,
  484. area: _this._measureObjs[delLabel.lC].area || 0,
  485. LC: delLabel.lC
  486. });
  487. });
  488. if (i == coorslength - 1) {
  489. oLabelObj.appendChild(delLabel);
  490. oLabelObj.appendChild(saveLabel);
  491. //测量面积
  492. try {
  493. if (_this._measureObjs[data.LC].polygon) {
  494. var area = _this._getArea(data.LC);
  495. _this._measureObjs[data.LC].area;
  496. pointText.innerHTML = lineDistanceStr + "<br/>" + area;
  497. }
  498. } catch (e) {
  499. console.error("leaflet.draw.js 测量面积error:", e);
  500. }
  501. }
  502. oLabelObj.appendChild(pointText);
  503. _this._measureObjs[_this._lC].distance = lineDistance;
  504. _this._measureObjs[data.LC].markerObjs[i].label.setContent(oLabelObj);
  505. }
  506. },
  507. /**
  508. * 删除对应lC的测距
  509. */
  510. del: function (lC) {
  511. var _this = this;
  512. if (_this._measureObjs[lC]) {
  513. _this._measureGroup.removeLayer(_this._measureObjs[lC]);
  514. delete _this._measureObjs[lC];
  515. }
  516. }
  517. });