百度地图实现测量面积和测量距离功能

article/2025/9/21 10:50:15

最近在公司的项目中,需要用到百度地图的测距和测面积功能,但是在网上只找到了测量距离的api,即BMapLib.DistanceTool。

但是测面积在网上没有找到很好的资料,百度提供的DrawingManager虽然也可以实现测面积,但是感觉太lol了,然后继续找资料,发现有人跟我遇到同样的问题,他的解决思路是对BMapLib.DistanceTool进行改造,但遗憾的是没有提供源码。

我也想过要改造BMapLib.DistanceTool,但是这个对我来说很有挑战性,毕竟js我差不多是小白,今天闲来无事,决定一试。下载了BMapLib.DistanceTool的源码看,大部分都看不懂,呵呵,不过我要做的工作就是在事件处理中加入自己的逻辑,寻着这个思路,经过几番折腾,终于搞定了,整体效果自己还比较满意。

好了,废话不多说,接下来进入重点,我把百度地图实现测量面积源码公布下(Java成长交流学习群:184998348),代码下载地址:https://download.csdn.net/download/hgq0916/12403463。分享给大家,若有大神路过,别见怪,哈哈。

首先来张效果图:

下面是源码:

1.measureAreaTool_baidu.html

 

<!DOCTYPE html>    
<html>    
<head>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />    <style type="text/css">    body, html{width: 100%;height: 100%;margin:0;font-family:"微软雅黑";}    #allmap {width: 100%; height:500px; overflow: hidden;}    #result {width:100%;font-size:12px;}    </style><script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你的AK"></script>    <script src="js/GeoUtils.js" type="text/javascript"></script><script type="text/javascript" src="js/AreaTool_min.js"></script><title>百度地图API功能演示</title>
</head>    
<body><div id="allmap" style="overflow:hidden;zoom:1;position:relative;">       <div id="map" style="height:100%;-webkit-transition: all 0.5s ease-in-out;transition: all 0.5s ease-in-out;">    </div>    </div><div id="result">    <input type="button"  value="面积测量" onclick="measureArea(this)" /><br/></div><script type="text/javascript">    var map = new BMap.Map('map');var poi = new BMap.Point(113.948913,22.530844);    map.centerAndZoom(poi, 16);    map.enableScrollWheelZoom();//添加测量面积工具var measureAreaTool = createMeasureAreaTool(map);//面积测量var measureArea = function(e){measureAreaTool.open();}
</script>
</body>    
</html>    

2.依赖的js

2.1  百度地图的核心js文件,这个用于显示百度地图的,不多说

2.2    AreaTool_min.js  这个就是我改造百度地图测距js后自己创建的测面积工具,完成对面积的测量

 

 // 百度地图API功能
var BMapLib = window.BMapLib = BMapLib || {}; (function() {var c = c || {guid: "$BAIDU$"}; (function() {window[c.guid] = {};c.extend = function(g, e) {for (var f in e) {if (e.hasOwnProperty(f)) {g[f] = e[f]}}return g};c.lang = c.lang || {};c.lang.guid = function() {return "TANGRAM__" + (window[c.guid]._counter++).toString(36)};window[c.guid]._counter = window[c.guid]._counter || 1;window[c.guid]._instances = window[c.guid]._instances || {};c.lang.Class = function(e) {this.guid = e || c.lang.guid();window[c.guid]._instances[this.guid] = this};window[c.guid]._instances = window[c.guid]._instances || {};c.lang.isString = function(e) {return "[object String]" == Object.prototype.toString.call(e)};c.lang.isFunction = function(e) {return "[object Function]" == Object.prototype.toString.call(e)};c.lang.Class.prototype.toString = function() {return "[object " + (this._className || "Object") + "]"};c.lang.Class.prototype.dispose = function() {delete window[c.guid]._instances[this.guid];for (var e in this) {if (!c.lang.isFunction(this[e])) {delete this[e]}}this.disposed = true};c.lang.Event = function(e, f) {this.type = e;this.returnValue = true;this.target = f || null;this.currentTarget = null};c.lang.Class.prototype.addEventListener = function(h, g, f) {if (!c.lang.isFunction(g)) {return} ! this.__listeners && (this.__listeners = {});var e = this.__listeners,i;if (typeof f == "string" && f) {if (/[^\w\-]/.test(f)) {throw ("nonstandard key:" + f)} else {g.hashCode = f;i = f}}h.indexOf("on") != 0 && (h = "on" + h);typeof e[h] != "object" && (e[h] = {});i = i || c.lang.guid();g.hashCode = i;e[h][i] = g};c.lang.Class.prototype.removeEventListener = function(g, f) {if (c.lang.isFunction(f)) {f = f.hashCode} else {if (!c.lang.isString(f)) {return}} ! this.__listeners && (this.__listeners = {});g.indexOf("on") != 0 && (g = "on" + g);var e = this.__listeners;if (!e[g]) {return}e[g][f] && delete e[g][f]};c.lang.Class.prototype.dispatchEvent = function(h, e) {if (c.lang.isString(h)) {h = new c.lang.Event(h)} ! this.__listeners && (this.__listeners = {});e = e || {};for (var g in e) {h[g] = e[g]}var g, f = this.__listeners,j = h.type;h.target = h.target || this;h.currentTarget = this;j.indexOf("on") != 0 && (j = "on" + j);c.lang.isFunction(this[j]) && this[j].apply(this, arguments);if (typeof f[j] == "object") {for (g in f[j]) {f[j][g].apply(this, arguments)}}return h.returnValue};c.lang.inherits = function(k, i, h) {var g, j, e = k.prototype,f = new Function();f.prototype = i.prototype;j = k.prototype = new f();for (g in e) {j[g] = e[g]}k.prototype.constructor = k;k.superClass = i.prototype;if ("string" == typeof h) {j._className = h}};c.dom = c.dom || {};c._g = c.dom._g = function(e) {if (c.lang.isString(e)) {return document.getElementById(e)}return e};c.g = c.dom.g = function(e) {if ("string" == typeof e || e instanceof String) {return document.getElementById(e)} else {if (e && e.nodeName && (e.nodeType == 1 || e.nodeType == 9)) {return e}}return null};c.insertHTML = c.dom.insertHTML = function(h, e, g) {h = c.dom.g(h);var f, i;if (h.insertAdjacentHTML) {h.insertAdjacentHTML(e, g)} else {f = h.ownerDocument.createRange();e = e.toUpperCase();if (e == "AFTERBEGIN" || e == "BEFOREEND") {f.selectNodeContents(h);f.collapse(e == "AFTERBEGIN")} else {i = e == "BEFOREBEGIN";f[i ? "setStartBefore": "setEndAfter"](h);f.collapse(i)}f.insertNode(f.createContextualFragment(g))}return h};c.ac = c.dom.addClass = function(k, m) {k = c.dom.g(k);var f = m.split(/\s+/),e = k.className,j = " " + e + " ",h = 0,g = f.length;for (; h < g; h++) {if (j.indexOf(" " + f[h] + " ") < 0) {e += (e ? " ": "") + f[h]}}k.className = e;return k};c.event = c.event || {};c.event._listeners = c.event._listeners || [];c.on = c.event.on = function(f, i, k) {i = i.replace(/^on/i, "");f = c._g(f);var j = function(m) {k.call(f, m)},e = c.event._listeners,h = c.event._eventFilter,l,g = i;i = i.toLowerCase();if (h && h[i]) {l = h[i](f, i, j);g = l.type;j = l.listener}if (f.addEventListener) {f.addEventListener(g, j, false)} else {if (f.attachEvent) {f.attachEvent("on" + g, j)}}e[e.length] = [f, i, k, j, g];return f};c.un = c.event.un = function(g, j, f) {g = c._g(g);j = j.replace(/^on/i, "").toLowerCase();var m = c.event._listeners,h = m.length,i = !f,l, k, e;while (h--) {l = m[h];if (l[1] === j && l[0] === g && (i || l[2] === f)) {k = l[4];e = l[3];if (g.removeEventListener) {g.removeEventListener(k, e, false)} else {if (g.detachEvent) {g.detachEvent("on" + k, e)}}m.splice(h, 1)}}return g};c.preventDefault = c.event.preventDefault = function(e) {if (e.preventDefault) {e.preventDefault()} else {e.returnValue = false}}})();//TODOvar d = BMapLib.MeasureAreaTool = function(f, e) {if (!f) {return}this._map = f;e = e || {};this._opts = c.extend(c.extend(this._opts || {},{tips: "\u6d4b\u8ddd",followText: "\u5355\u51fb\u786e\u5b9a\u5730\u70b9\uff0c\u53cc\u51fb\u7ed3\u675f",unit: "metric",lineColor: "#ff6319",lineStroke: 2,opacity: 0.8,lineStyle: "solid",cursor: "http://api.map.baidu.com/images/ruler.cur",secIcon: null,closeIcon: null}), e);this._followTitle = null;this._points = [];this._paths = [];this._dots = [];this._segDistance = [];this._overlays = [];this._enableMassClear = true,this._units = {metric: {name: "metric",conv: 1,incon: 1000,u1: "\u7c73",u2: "\u516c\u91cc"},us: {name: "us",conv: 3.2808,incon: 5279.856,u1: "\u82f1\u5c3a",u2: "\u82f1\u91cc"}};this._isOpen = false;this._startFollowText = "\u5355\u51fb\u786e\u5b9a\u8d77\u70b9";this._movingTimerId = null;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 = "\u6d4b\u8ddd"};c.lang.inherits(d, c.lang.Class, "DistanceTool");d.prototype._bind = function() {this._setCursor(this._opts.cursor);var f = this;c.on(this._map.getContainer(), "mousemove",function(i) {if (!f._isOpen) {return}if (!f._followTitle) {return}i = window.event || i;var g = i.target || i.srcElement;if (g != a.getDom(f._map)) {f._followTitle.hide();return}if (!f._mapMoving) {f._followTitle.show()}var h = a.getDrawPoint(i, true);f._followTitle.setPosition(h)});if (this._startFollowText) {var e = this._followTitle = new BMap.Label(this._startFollowText, {offset: new BMap.Size(14, 16)});this._followTitle.setStyles({color: "#333",borderColor: "#ff0103"})}};d.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 h = this;if (!this._binded) {this._binded = true;this._bind();this._map.addEventListener("moving",function() {h._hideCurrent()})}if (this._followTitle) {this._map.addOverlay(this._followTitle);this._followTitle.hide()}var g = function(q) {//TODOvar l = h._map;//获取map对象if (!h._isOpen) {//判断测距工具是否打开,关闭则返回return}q = window.event || q;var n = a.getDrawPoint(q, true);//获取鼠标点击的点if (!h._isPointValid(n)) {//判断点是否有效return}h._bind.initX = q.pageX || q.clientX || 0;//绑定当前的坐标h._bind.initY = q.pageY || q.clientY || 0;if (h._points.length > 0) {var t = l.pointToPixel(h._points[h._points.length - 1]);//获取点数组最后一个元素,转换为Pixel点var m = l.pointToPixel(n);//将当前的点转换为Pixel点var p = Math.sqrt(Math.pow(t.x - m.x, 2) + Math.pow(t.y - m.y, 2));//求两个点的距离if (p < 5) {//距离小于5则返回return}}h._bind.x = q.layerX || q.offsetX || 0;//保存当前坐标h._bind.y = q.layerY || q.offsetY || 0;h._points.push(n);//将当前坐标存入数组h._addSecPoint(n);//TODOif (h._paths.length == 0) {h._formatTitle(1, h._opts.followText, h._getTotalDistance())}if (h._paths.length > 0) {h._paths[h._paths.length - 1].show();h._paths[h._paths.length - 1].setStrokeOpacity(h._opts.opacity)}var w = new BMap.Polyline([n, n], {enableMassClear: h._enableMassClear});h._map.addOverlay(w);h._paths.push(w);h._overlays.push(w);w.setStrokeWeight(h._opts.lineStroke);w.setStrokeColor(h._opts.lineColor);w.setStrokeOpacity(h._opts.opacity / 2);w.setStrokeStyle(h._opts.lineStyle);if (h._mapMoving) {w.hide()}if (h._points.length > 1) {var o = h._paths[h._points.length - 2];o.setPositionAt(1, n)}var r = "";var v;if (h._points.length > 1) {var u = h._setSegDistance(h._points[h._points.length - 2], h._points[h._points.length - 1]);var s = h._getTotalDistance();r = h._formatDisStr(s);v = new BMap.Label(r, {offset: new BMap.Size(10, -5),enableMassClear: h._enableMassClear});} else {r = "\u8d77\u70b9";v = new BMap.Label(r, {offset: new BMap.Size(-10, -25),enableMassClear: h._enableMassClear});}// var v = new BMap.Label(r, {//     offset: new BMap.Size(10, -5),//     enableMassClear: h._enableMassClear// });v.setStyles({color: "#333",borderColor: "#ff0103"});h._map.addOverlay(v);h._formatSegLabel(v, r);h._overlays.push(v);n.disLabel = v;v.setPosition(n);var k = new c.lang.Event("onaddpoint");k.point = n;k.pixel = h._map.pointToPixel(n);k.index = h._points.length - 1;k.distance = h._getTotalDistance().toFixed(0);h.dispatchEvent(k)};var f = function(p) {if (!h._isOpen) {return}if (h._paths.length > 0) {p = window.event || p;var l = p.pageX || p.clientX || 0;var k = p.pageY || p.clientY || 0;if (typeof h._bind.initX == "undefined") {h._bind.x = p.layerX || p.offsetX || 0;h._bind.y = p.layerY || p.offsetY || 0;h._bind.initX = l;h._bind.initY = k}var r = h._bind.x + l - h._bind.initX;var q = h._bind.y + k - h._bind.initY;var z = h._paths[h._paths.length - 1];var m = h._map.pixelToPoint(new BMap.Pixel(r, q));z.setPositionAt(1, m);if (!h._mapMoving) {z.show()}var A = 0;var u = 0;if (r < 10) {A = 8} else {if (r > h._map.getSize().width - 10) {A = -8}}if (q < 10) {u = 8} else {if (q > h._map.getSize().height - 10) {u = -8}}if (A != 0 || u != 0) {if (!f._movingTimerId) {h._mapMoving = true;h._map.panBy(A, u, {noAnimation: true});h._movingTimerId = f._movingTimerId = setInterval(function() {h._map.panBy(A, u, {noAnimation: true})},30);z.hide();h._followTitle && h._followTitle.hide()}} else {if (f._movingTimerId) {clearInterval(f._movingTimerId);delete f._movingTimerId;delete h._movingTimerId;var w = h._paths[h._paths.length - 1];var v = h._map.pixelToPoint(new BMap.Pixel(r, q));if (!w) {return}w.setPositionAt(1, v);w.show();if (h._followTitle) {h._followTitle.setPosition(v);h._followTitle.show()}h._bind.i = 0;h._bind.j = 0;delete h._mapMoving}}if (h._followTitle) {var o = h._getTotalDistance();var n = h._map.getDistance(h._points[h._points.length - 1], m);h._updateInstDis(h._followTitle, o + n)}} else {if (h._followTitle) {h._followTitle.show();p = window.event || p;var s = p.target || p.srcElement;if (s != a.getDom()) {h._followTitle.hide()}}}};var e = function(k) {if (!h._isOpen) {return}c.un(a.getDom(h._map), "click", g);c.un(document, "mousemove", f);c.un(a.getDom(h._map), "dblclick", e);c.un(document, "keydown", j);c.un(a.getDom(h._map), "mouseup", i);setTimeout(function() {//1h.close()},50)};var j = function(k) {k = window.event || k;if (k.keyCode == 27) {h._clearCurData();setTimeout(function() {//2h.close()},50)}};var i = function(k) {k = window.event || k;var l = 0;if (/msie (\d+\.\d)/i.test(navigator.userAgent)) {l = document.documentMode || +RegExp["\x241"]}if (l && k.button != 1 || k.button == 2) {//3h.close()}};h._initData();this._formatTitle();a.show(this._map);this._setCursor(this._opts.cursor);c.on(a.getDom(this._map), "click", g);c.on(document, "mousemove", f);c.on(a.getDom(this._map), "dblclick", e);c.on(document, "keydown", j);c.on(a.getDom(this._map), "mouseup", i);this.bindFunc = [{elem: a.getDom(this._map),type: "click",func: g},{elem: a.getDom(this._map),type: "dblclick",func: e},{elem: document,type: "mousemove",func: f},{elem: document,type: "keydown",func: j},{elem: a.getDom(this._map),type: "mouseup",func: i}];return true};d.prototype._dispatchLastEvent = function() {var e = new c.lang.Event("ondrawend");e.points = this._points ? this._points.slice(0) : [];e.overlays = this._paths ? this._paths.slice(0, this._paths.length - 1) : [];e.distance = this._getTotalDistance().toFixed(0);this.dispatchEvent(e)};d.prototype.close = function() {if (this._isOpen == false) {return}this._isOpen = false;BMapLib._toolInUse = false;if (this._mapMoving) {delete this._mapMoving}var g = this;g._dispatchLastEvent();if (g._points.length < 2) {g._clearCurData()} else {g._paths[g._paths.length - 1].remove();g._paths[g._paths.length - 1] = null;g._paths.length = g._paths.length - 1;var h = g._points[g._points.length - 1];if (h.disLabel) {h.disLabel.remove()}g._processLastOp()}a.hide();for (var f = 0,e = this.bindFunc.length; f < e; f++) {c.un(this.bindFunc[f].elem, this.bindFunc[f].type, this.bindFunc[f].func)}if (g._movingTimerId) {clearInterval(g._movingTimerId);g._movingTimerId = null}if (this._followTitle) {this._followTitle.hide()}};d.prototype._clearCurData = function() {for (var f = 0,e = this._points.length; f < e; f++) {if (this._points[f].disLabel) {this._points[f].disLabel.remove()}}for (var f = 0,e = this._paths.length; f < e; f++) {this._paths[f].remove()}for (var f = 0,e = this._dots.length; f < e; f++) {this._dots[f].remove()}this._initData()};d.prototype._initData = function() {this._points.length = 0;this._paths.length = 0;this._segDistance.length = 0;this._dots.length = 0};d.prototype._setSegDistance = function(g, f) {if (!g || !f) {return}var e = this._map.getDistance(g, f);this._segDistance.push(e);return e};d.prototype._getTotalDistance = function() {var g = 0;for (var f = 0,e = this._segDistance.length; f < e; f++) {g += this._segDistance[f]}return g};d.prototype._convertUnit = function(e, f) {f = f || "metric";if (this._units[f]) {return e * this._units[f].conv}return e};d.prototype._addSecPoint = function(g) {var f = 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 e = new BMap.Marker(g, {icon: f,clickable: false,baseZIndex: 3500000,zIndexFixed: true,enableMassClear: this._enableMassClear});this._map.addOverlay(e);this._dots.push(e)};d.prototype._formatDisStr = function(h) {var f = this._opts.unit;var g = this._units[f].u1;var e = this._convertUnit(h, f);if (e > this._units[f].incon) {e = e / this._units[f].incon;g = this._units[f].u2;e = e.toFixed(1)} else {e = e.toFixed(0)}return e + g};d.prototype._setCursor = function(f) {var e = /webkit/.test(navigator.userAgent.toLowerCase()) ? "url(" + this._opts.cursor + ") 3 6, crosshair": "url(" + this._opts.cursor + "), crosshair";a._setCursor(e)};d.prototype._getCursor = function() {return this._opts.cursor};d.prototype._formatSegLabel = function(e, f) {e.setStyle({border: "none",padding: "0"});e.setContent("<span style='" + this._styles.BMapLib_diso + "'><span style='" + this._styles.BMapLib_disi + "'>" + f + "</span></span>")};d.prototype._processLastOp = function() {var i = this;delete i._bind.x;delete i._bind.y;delete i._bind.initX;delete i._bind.initY;if (i._paths.length > i._points.length - 1) {var g = i._paths.length - 1;i._paths[g].remove();i._paths[g] = null;i._paths.length = g}var e = {};e.points = i._points.slice(0);e.paths = i._paths.slice(0);e.dots = i._dots.slice(0);e.segDis = i._segDistance.slice(0);var j = i._map.pointToPixel(e.points[e.points.length - 1]);var h = i._map.pointToPixel(e.points[e.points.length - 2]);var k = [0, 0];var f = [0, 0];if (j.y - h.y >= 0) {f = [ - 5, 11]} else {f = [ - 5, -35]}if (j.x - h.x >= 0) {k = [14, 0]} else {k = [ - 14, 0]}var n = e.points[e.points.length - 1];n.disLabel = new BMap.Label("", {offset: new BMap.Size( - 15, -40),enableMassClear: i._enableMassClear});n.disLabel.setStyles({color: "#333",borderColor: "#ff0103"});i._map.addOverlay(n.disLabel);n.disLabel.setOffset(new BMap.Size(f[0], f[1]));n.disLabel.setPosition(n);i._formatTitle(2, "", "", n.disLabel);var m = 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)});e.closeBtn = new BMap.Marker(e.points[e.points.length - 1], {icon: m,offset: new BMap.Size(k[0], k[1]),baseZIndex: 3600000,enableMassClear: i._enableMassClear});//将多边形绑定到关闭按钮上var hh = this;e.closeBtn._polygon = hh.polygon;hh.polygon = undefined;hh._areaPoints = undefined;i._map.addOverlay(e.closeBtn);//绑定添加焦点事件e.closeBtn.setTitle("\u6e05\u9664\u672c\u6b21\u6d4b\u8ddd");e.closeBtn.addEventListener("click",function(r) {//TODOvar polygon = r.target._polygon;if(polygon.label!=undefined){hh._map.removeOverlay(polygon.label);}hh._map.removeOverlay(polygon);r.target._polygon =undefined;for (var p = 0,o = e.points.length; p < o; p++) {e.points[p].disLabel.remove();e.points[p].disLabel = null}for (var p = 0,o = e.paths.length; p < o; p++) {e.paths[p].remove();e.paths[p] = null}for (var p = 0,o = e.dots.length; p < o; p++) {e.dots[p].remove();e.dots[p] = null}e.closeBtn.remove();e.closeBtn = null;b(r);var q = new c.lang.Event("onremovepolyline");i.dispatchEvent(q)//todo});i._initData()};d.prototype._formatTitle = function(g, l, e, i) {var h = i || this._followTitle;if (!h) {return}h.setStyle({lineHeight: "16px",zIndex: "85",padding: "3px 5px"});var n = this._startFollowText || "";var k = [];if (g == 1) {h.setOffset(0, 25);var m = this._opts.unit;var j = this._units[m].u1;var f = this._convertUnit(e, m);if (f > this._units[m].incon) {f = f / this._units[m].incon;j = this._units[m].u2;f = f.toFixed(1)} else {f = f.toFixed(0)}k.push("<span>\u603b\u957f\uff1a<span style='" + this._styles.BMapLib_disBoxDis + "'>" + f + "</span>" + j + "</span><br />");k.push("<span style='color:#7a7a7a'>" + l + "</span>")} else {if (g == 2) {var m = this._opts.unit;var j = this._units[m].u1;var f = this._convertUnit(this._getTotalDistance(), m);if (f > this._units[m].incon) {f = f / this._units[m].incon;j = this._units[m].u2;f = f.toFixed(1)} else {f = f.toFixed(0)}k.push("\u603b\u957f\uff1a<span style='" + this._styles.BMapLib_disBoxDis + "'>" + f + "</span>" + j)} else {h.setOffset(0, 25);k.push(n)}}h.setContent(k.join(""))};d.prototype._updateInstDis = function(g, e) {var f = this._opts.unit;var i = this._units[f].u1;if (e > this._units[f].incon) {e = e / this._units[f].incon;i = this._units[f].u2;e = e.toFixed(1)} else {e = e.toFixed(0)}if (g) {var h = [];h.push("<span>\u603b\u957f\uff1a<span style='" + this._styles.BMapLib_disBoxDis + "'>" + e + "</span>" + i + "</span><br />");h.push("<span style='color:#7a7a7a'>" + this._opts.followText + "</span>");g.setContent(h.join(""))}};d.prototype._hideCurrent = function() {if (!this._isOpen) {return}if (this._paths.length > 0) {var e = this._paths[this._paths.length - 1];e.hide()}this._followTitle && this._followTitle.hide()};d.prototype._isPointValid = function(h) {if (!h) {return false}var f = this._map.getBounds();var e = f.getSouthWest(),g = f.getNorthEast();if (h.lng < e.lng || h.lng > g.lng || h.lat < e.lat || h.lat > g.lat) {return false}return true};var a = {_map: null,_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>",_maskElement: null,_cursor: "default",_inUse: false,show: function(e) {if (!this._map) {this._map = e}this._inUse = true;if (!this._maskElement) {this._createMask(e)}this._maskElement.style.display = "block"},_createMask: function(g) {this._map = g;if (!this._map) {return}c.insertHTML(this._map.getContainer(), "beforeEnd", this._html);var f = this._maskElement = this._map.getContainer().lastChild;var e = function(h) {b(h);return c.preventDefault(h)};c.on(f, "mouseup",function(h) {if (h.button == 2) {e(h)}});c.on(f, "contextmenu", e);f.style.display = "none"},getDrawPoint: function(h, j) {h = window.event || h;var f = h.layerX || h.offsetX || 0;var i = h.layerY || h.offsetY || 0;var g = h.target || h.srcElement;if (g != a.getDom(this._map) && j == true) {while (g && g != this._map.getContainer()) {if (! (g.clientWidth == 0 && g.clientHeight == 0 && g.offsetParent && g.offsetParent.nodeName.toLowerCase() == "td")) {f += g.offsetLeft;i += g.offsetTop}g = g.offsetParent}}if (g != a.getDom(this._map) && g != this._map.getContainer()) {return}if (typeof f === "undefined" || typeof i === "undefined") {return}if (isNaN(f) || isNaN(i)) {return}return this._map.pixelToPoint(new BMap.Pixel(f, i))},hide: function() {if (!this._map) {return}this._inUse = false;if (this._maskElement) {this._maskElement.style.display = "none"}},getDom: function(e) {if (!this._maskElement) {this._createMask(e)}return this._maskElement},_setCursor: function(e) {this._cursor = e || "default";if (this._maskElement) {this._maskElement.style.cursor = this._cursor}}};function b(f) {var f = window.event || f;f.stopPropagation ? f.stopPropagation() : f.cancelBubble = true}
})();var _polygonStyleOptions = {    strokeColor:"blue",    //边线颜色。    fillColor:"#FFCCFF",      //填充颜色。当参数为空时,圆形将没有填充效果。    strokeWeight: 0.00001,       //边线的宽度,以像素为单位。    strokeOpacity: 0,    //边线透明度,取值范围0 - 1。    fillOpacity: 0.3,      //填充的透明度,取值范围0 - 1。    strokeStyle: 'solid' //边线的样式,solid或dashed。    
}   
var _LabelOptions = {    color : "black",    fontSize : "16px",    fillColor:"red"      //填充颜色。当参数为空时,圆形将没有填充效果。    
}   //自定义测量面积工具
var createMeasureAreaTool =function(map){var myDis = new BMapLib.MeasureAreaTool(map);   //测距插件myDis.addEventListener("addpoint", function(e) {var _map = e.target._map;if(e.target._areaPoints == undefined){e.target._areaPoints = new Array();}e.target._areaPoints.push(e.point);if(e.target.polygon == undefined){var polygon = new BMap.Polygon(e.target._areaPoints,_polygonStyleOptions);myDis.polygon = polygon;_map.addOverlay(polygon);}else{var polygon = e.target.polygon;polygon.setPath(e.target._areaPoints);//计算多边形的面积var _area = 0;_area = BMapLib.GeoUtils.getPolygonArea(polygon);//保留两位小数_area = _area.toFixed(2);//获取多边形的中心var _paths = polygon.getPath();var point = getCenterPoint(_paths);//移除polygon之前的labelif(polygon.label!=undefined){var l = polygon.label;_map.removeOverlay(l);polygon.label = undefined;}//往多边形添加标注var label = new BMap.Label("区域面积:"+_area+"m2",_LabelOptions);polygon.label =label;label.setPosition(point);//往地图上添加标注_map.addOverlay(label);}}); return myDis;
}


2.3  GeoUtils.js  这个是计算面积的api,这个也是必须的,代码如下:

/**  
* @fileoverview GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形、  
* 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。   
* 主入口类是<a href="symbols/BMapLib.GeoUtils.html">GeoUtils</a>,  
* 基于Baidu Map API 1.2。  
*  
* @author Baidu Map Api Group   
* @version 1.2  
*/    //BMapLib.GeoUtils.degreeToRad(Number)    
//将度转化为弧度    //BMapLib.GeoUtils.getDistance(Point, Point)    
//计算两点之间的距离,两点坐标必须为经纬度    //BMapLib.GeoUtils.getPolygonArea(polygon)    
//计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬度,且不适合计算自相交多边形的面积(封闭的面积)    //BMapLib.GeoUtils.getPolylineDistance(polyline)    
//计算折线或者点数组的长度    //BMapLib.GeoUtils.isPointInCircle(point, circle)    
//判断点是否在圆形内    //BMapLib.GeoUtils.isPointInPolygon(point, polygon)    
//判断点是否多边形内    //BMapLib.GeoUtils.isPointInRect(point, bounds)    
//判断点是否在矩形内    //BMapLib.GeoUtils.isPointOnPolyline(point, polyline)    
//判断点是否在折线上    //BMapLib.GeoUtils.radToDegree(Number)    
//将弧度转化为度    function getCenterPoint(path){//var path = e.;//Array<Point> 返回多边型的点数组//var ret=parseFloat(num1)+parseFloat(num2);  var x = 0.0;var y = 0.0;for(var i=0;i<path.length;i++){x=x+ parseFloat(path[i].lng);y=y+ parseFloat(path[i].lat);}x=x/path.length;y=y/path.length;return new BMap.Point(x,y);}/**   
* @namespace BMap的所有library类均放在BMapLib命名空间下  
*/    
var BMapLib = window.BMapLib = BMapLib || {};    
(function () {    /**  * 地球半径  */    var EARTHRADIUS = 6370996.81;    /**   * @exports GeoUtils as BMapLib.GeoUtils   */    var GeoUtils =    /**  * GeoUtils类,静态类,勿需实例化即可使用  * @class GeoUtils类的<b>入口</b>。  * 该类提供的都是静态方法,勿需实例化即可使用。       */    BMapLib.GeoUtils = function () {    }    /**  * 判断点是否在矩形内  * @param {Point} point 点对象  * @param {Bounds} bounds 矩形边界对象  * @returns {Boolean} 点在矩形内返回true,否则返回false  */    GeoUtils.isPointInRect = function (point, bounds) {    //检查类型是否正确    if (!(point instanceof BMap.Point) ||    !(bounds instanceof BMap.Bounds)) {    return false;    }    var sw = bounds.getSouthWest(); //西南脚点    var ne = bounds.getNorthEast(); //东北脚点    return (point.lng >= sw.lng && point.lng <= ne.lng && point.lat >= sw.lat && point.lat <= ne.lat);    }    /**  * 判断点是否在圆形内  * @param {Point} point 点对象  * @param {Circle} circle 圆形对象  * @returns {Boolean} 点在圆形内返回true,否则返回false  */    GeoUtils.isPointInCircle = function (point, circle) {    //检查类型是否正确    if (!(point instanceof BMap.Point) ||    !(circle instanceof BMap.Circle)) {    return false;    }    //point与圆心距离小于圆形半径,则点在圆内,否则在圆外    var c = circle.getCenter();    var r = circle.getRadius();    var dis = GeoUtils.getDistance(point, c);    if (dis <= r) {    return true;    } else {    return false;    }    }    /**  * 判断点是否在折线上  * @param {Point} point 点对象  * @param {Polyline} polyline 折线对象  * @returns {Boolean} 点在折线上返回true,否则返回false  */    GeoUtils.isPointOnPolyline = function (point, polyline) {    //检查类型    if (!(point instanceof BMap.Point) ||    !(polyline instanceof BMap.Polyline)) {    return false;    }    //首先判断点是否在线的外包矩形内,如果在,则进一步判断,否则返回false    var lineBounds = polyline.getBounds();    if (!this.isPointInRect(point, lineBounds)) {    return false;    }    //判断点是否在线段上,设点为Q,线段为P1P2 ,    //判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0,且 Q 在以 P1,P2为对角顶点的矩形内    var pts = polyline.getPath();    for (var i = 0; i < pts.length - 1; i++) {    var curPt = pts[i];    var nextPt = pts[i + 1];    //首先判断point是否在curPt和nextPt之间,即:此判断该点是否在该线段的外包矩形内    if (point.lng >= Math.min(curPt.lng, nextPt.lng) && point.lng <= Math.max(curPt.lng, nextPt.lng) &&    point.lat >= Math.min(curPt.lat, nextPt.lat) && point.lat <= Math.max(curPt.lat, nextPt.lat)) {    //判断点是否在直线上公式    var precision = (curPt.lng - point.lng) * (nextPt.lat - point.lat) - (nextPt.lng - point.lng) * (curPt.lat - point.lat);    if (precision < 2e-10 && precision > -2e-10) {//实质判断是否接近0    return true;    }    }    }    return false;    }    /**  * 判断点是否多边形内  * @param {Point} point 点对象  * @param {Polyline} polygon 多边形对象  * @returns {Boolean} 点在多边形内返回true,否则返回false  */    GeoUtils.isPointInPolygon = function (point, polygon) {    //检查类型    if (!(point instanceof BMap.Point) ||    !(polygon instanceof BMap.Polygon)) {    return false;    }    //首先判断点是否在多边形的外包矩形内,如果在,则进一步判断,否则返回false    var polygonBounds = polygon.getBounds();    if (!this.isPointInRect(point, polygonBounds)) {    return false;    }    var pts = polygon.getPath(); //获取多边形点    //下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改    //基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则    //在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。    var N = pts.length;    var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true    var intersectCount = 0; //cross points count of x     var precision = 2e-10; //浮点类型计算时候与0比较时候的容差    var p1, p2; //neighbour bound vertices    var p = point; //测试点    p1 = pts[0]; //left vertex            for (var i = 1; i <= N; ++i) {//check all rays                if (p.equals(p1)) {    return boundOrVertex; //p is an vertex    }    p2 = pts[i % N]; //right vertex                if (p.lat < Math.min(p1.lat, p2.lat) || p.lat > Math.max(p1.lat, p2.lat)) {//ray is outside of our interests                 p1 = p2;    continue; //next ray left point    }    if (p.lat > Math.min(p1.lat, p2.lat) && p.lat < Math.max(p1.lat, p2.lat)) {//ray is crossing over by the algorithm (common part of)    if (p.lng <= Math.max(p1.lng, p2.lng)) {//x is before of ray                        if (p1.lat == p2.lat && p.lng >= Math.min(p1.lng, p2.lng)) {//overlies on a horizontal ray    return boundOrVertex;    }    if (p1.lng == p2.lng) {//ray is vertical             if (p1.lng == p.lng) {//overlies on a vertical ray    return boundOrVertex;    } else {//before ray    ++intersectCount;    }    } else {//cross point on the left side               var xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng; //cross point of lng                  if (Math.abs(p.lng - xinters) < precision) {//overlies on a ray    return boundOrVertex;    }    if (p.lng < xinters) {//before ray    ++intersectCount;    }    }    }    } else {//special case when ray is crossing through the vertex                    if (p.lat == p2.lat && p.lng <= p2.lng) {//p crossing over p2                        var p3 = pts[(i + 1) % N]; //next vertex             if (p.lat >= Math.min(p1.lat, p3.lat) && p.lat <= Math.max(p1.lat, p3.lat)) {//p.lat lies between p1.lat & p3.lat    ++intersectCount;    } else {    intersectCount += 2;    }    }    }    p1 = p2; //next ray left point    }    if (intersectCount % 2 == 0) {//偶数在多边形外    return false;    } else { //奇数在多边形内    return true;    }    }    /**  * 将度转化为弧度  * @param {degree} Number 度       * @returns {Number} 弧度  */    GeoUtils.degreeToRad = function (degree) {    return Math.PI * degree / 180;    }    /**  * 将弧度转化为度  * @param {radian} Number 弧度       * @returns {Number} 度  */    GeoUtils.radToDegree = function (rad) {    return (180 * rad) / Math.PI;    }    /**  * 将v值限定在a,b之间,纬度使用  */    function _getRange(v, a, b) {    if (a != null) {    v = Math.max(v, a);    }    if (b != null) {    v = Math.min(v, b);    }    return v;    }    /**  * 将v值限定在a,b之间,经度使用  */    function _getLoop(v, a, b) {    while (v > b) {    v -= b - a    }    while (v < a) {    v += b - a    }    return v;    }    /**  * 计算两点之间的距离,两点坐标必须为经纬度  * @param {point1} Point 点对象  * @param {point2} Point 点对象  * @returns {Number} 两点之间距离,单位为米  */    GeoUtils.getDistance = function (point1, point2) {    //判断类型    if (!(point1 instanceof BMap.Point) ||    !(point2 instanceof BMap.Point)) {    return 0;    }    point1.lng = _getLoop(point1.lng, -180, 180);    point1.lat = _getRange(point1.lat, -74, 74);    point2.lng = _getLoop(point2.lng, -180, 180);    point2.lat = _getRange(point2.lat, -74, 74);    var x1, x2, y1, y2;    x1 = GeoUtils.degreeToRad(point1.lng);    y1 = GeoUtils.degreeToRad(point1.lat);    x2 = GeoUtils.degreeToRad(point2.lng);    y2 = GeoUtils.degreeToRad(point2.lat);    return EARTHRADIUS * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1) * Math.cos(y2) * Math.cos(x2 - x1)));    }    /**  * 计算折线或者点数组的长度  * @param {Polyline|Array<Point>} polyline 折线对象或者点数组  * @returns {Number} 折线或点数组对应的长度  */    GeoUtils.getPolylineDistance = function (polyline) {    //检查类型    if (polyline instanceof BMap.Polyline ||    polyline instanceof Array) {    //将polyline统一为数组    var pts;    if (polyline instanceof BMap.Polyline) {    pts = polyline.getPath();    } else {    pts = polyline;    }    if (pts.length < 2) {//小于2个点,返回0    return 0;    }    //遍历所有线段将其相加,计算整条线段的长度    var totalDis = 0;    for (var i = 0; i < pts.length - 1; i++) {    var curPt = pts[i];    var nextPt = pts[i + 1]    var dis = GeoUtils.getDistance(curPt, nextPt);    totalDis += dis;    }    return totalDis;    } else {    return 0;    }    }    /**  * 计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬  度,且不适合计算自相交多边形的面积  * @param {Polygon|Array<Point>} polygon 多边形面对象或者点数  组  * @returns {Number} 多边形面或点数组构成图形的面积  */    GeoUtils.getPolygonArea = function (polygon) {    //检查类型    if (!(polygon instanceof BMap.Polygon) &&    !(polygon instanceof Array)) {    return 0;    }    var pts;    if (polygon instanceof BMap.Polygon) {    pts = polygon.getPath();    } else {    pts = polygon;    }    if (pts.length < 3) {//小于3个顶点,不能构建面    return 0;    }    var totalArea = 0; //初始化总面积    var LowX = 0.0;    var LowY = 0.0;    var MiddleX = 0.0;    var MiddleY = 0.0;    var HighX = 0.0;    var HighY = 0.0;    var AM = 0.0;    var BM = 0.0;    var CM = 0.0;    var AL = 0.0;    var BL = 0.0;    var CL = 0.0;    var AH = 0.0;    var BH = 0.0;    var CH = 0.0;    var CoefficientL = 0.0;    var CoefficientH = 0.0;    var ALtangent = 0.0;    var BLtangent = 0.0;    var CLtangent = 0.0;    var AHtangent = 0.0;    var BHtangent = 0.0;    var CHtangent = 0.0;    var ANormalLine = 0.0;    var BNormalLine = 0.0;    var CNormalLine = 0.0;    var OrientationValue = 0.0;    var AngleCos = 0.0;    var Sum1 = 0.0;    var Sum2 = 0.0;    var Count2 = 0;    var Count1 = 0;    var Sum = 0.0;    var Radius = EARTHRADIUS; //6378137.0,WGS84椭球半径     var Count = pts.length;    for (var i = 0; i < Count; i++) {    if (i == 0) {    LowX = pts[Count - 1].lng * Math.PI / 180;    LowY = pts[Count - 1].lat * Math.PI / 180;    MiddleX = pts[0].lng * Math.PI / 180;    MiddleY = pts[0].lat * Math.PI / 180;    HighX = pts[1].lng * Math.PI / 180;    HighY = pts[1].lat * Math.PI / 180;    }    else if (i == Count - 1) {    LowX = pts[Count - 2].lng * Math.PI / 180;    LowY = pts[Count - 2].lat * Math.PI / 180;    MiddleX = pts[Count - 1].lng * Math.PI / 180;    MiddleY = pts[Count - 1].lat * Math.PI / 180;    HighX = pts[0].lng * Math.PI / 180;    HighY = pts[0].lat * Math.PI / 180;    }    else {    LowX = pts[i - 1].lng * Math.PI / 180;    LowY = pts[i - 1].lat * Math.PI / 180;    MiddleX = pts[i].lng * Math.PI / 180;    MiddleY = pts[i].lat * Math.PI / 180;    HighX = pts[i + 1].lng * Math.PI / 180;    HighY = pts[i + 1].lat * Math.PI / 180;    }    AM = Math.cos(MiddleY) * Math.cos(MiddleX);    BM = Math.cos(MiddleY) * Math.sin(MiddleX);    CM = Math.sin(MiddleY);    AL = Math.cos(LowY) * Math.cos(LowX);    BL = Math.cos(LowY) * Math.sin(LowX);    CL = Math.sin(LowY);    AH = Math.cos(HighY) * Math.cos(HighX);    BH = Math.cos(HighY) * Math.sin(HighX);    CH = Math.sin(HighY);    CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);    CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);    ALtangent = CoefficientL * AL - AM;    BLtangent = CoefficientL * BL - BM;    CLtangent = CoefficientL * CL - CM;    AHtangent = CoefficientH * AH - AM;    BHtangent = CoefficientH * BH - BM;    CHtangent = CoefficientH * CH - CM;    AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent) * Math.sqrt(ALtangent * ALtangent + BLtangent * BLtangent + CLtangent * CLtangent));    AngleCos = Math.acos(AngleCos);    ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;    BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);    CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;    if (AM != 0)    OrientationValue = ANormalLine / AM;    else if (BM != 0)    OrientationValue = BNormalLine / BM;    else    OrientationValue = CNormalLine / CM;    if (OrientationValue > 0) {    Sum1 += AngleCos;    Count1++;    }    else {    Sum2 += AngleCos;    Count2++;    }    }    var tempSum1, tempSum2;    tempSum1 = Sum1 + (2 * Math.PI * Count2 - Sum2);    tempSum2 = (2 * Math.PI * Count1 - Sum1) + Sum2;    if (Sum1 > Sum2) {    if ((tempSum1 - (Count - 2) * Math.PI) < 1)    Sum = tempSum1;    else    Sum = tempSum2;    }    else {    if ((tempSum2 - (Count - 2) * Math.PI) < 1)    Sum = tempSum2;    else    Sum = tempSum1;    }    totalArea = (Sum - (Count - 2) * Math.PI) * Radius * Radius;    return totalArea; //返回总面积    }    })(); //闭包结束    

GeoUtilsAPI文档地址:http://api.map.baidu.com/library/GeoUtils/1.2/docs/symbols/BMapLib.GeoUtils.html

 

好了,现在可以测试效果了,浏览器打开measureAreaTool_baidu.html这个页面,点击面积测量就可以看到效果。

代码下载地址:https://download.csdn.net/download/hgq0916/12403463

本人水平有限,代码有不足之处还请大家见谅,欢迎大家提建议。本人目前主要方向是Java,如果有兴趣,可以一起交流,

Java成长交流学习群:184998348

 

 

 

 

 


http://chatgpt.dhexx.cn/article/KvkP5h6K.shtml

相关文章

测量面积的手机软件有哪些?这两个不能错过

测量面积的手机软件有哪些&#xff1f;相信很多小伙伴&#xff0c;在日常生活中遇到了场地面积测量的问题总是犯难&#xff0c;如果身边有工具还是可以的&#xff0c;就怕身边没有测量的工具&#xff0c;这样一来不仅仅没办法去操作得到我们想要的数值&#xff0c;也极大的拖累…

【Cesium】距离量测和面积量测

1 、空间量测 空间量测是在三维空间中测量距离、角度、面积等内容。实现方法为在屏幕中拾取对应点的位置&#xff0c;然后将屏幕坐标转换为地理坐标&#xff0c;再根据地球椭球参数&#xff0c;进行几何解算&#xff0c;获取地理空间距离、面积等。 1.1、 距离量测 两点之间的…

百度地图API画多边型,测面积

效果&#xff1a; 脚本&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv"Content-Type" c…

cad面积计算机,AutoCAD如何测面积 AutoCAD面积计算方法

在AutoCAD运用的实例中&#xff0c;我们常常需要测量所画图形的尺寸面积&#xff0c;如果通过手算的方式总会觉得特别麻烦&#xff0c;还容易出错&#xff0c;为此小编特意为大家准备了最全面的CAD面积计算方法&#xff0c;教你如何巧妙的使用AutoCAD完成面积运算。 AutoCAD面积…

cesium工具-测距和测面-原理和代码

测距分为&#xff1a;空间距离和贴地距离&#xff1b; 测面积分为&#xff1a;水平面积和贴地面积。 下面讲解这4个工具的相关思路和代码&#xff1a; 1、空间距离 思路&#xff1a; Cesium.Cartesian3.distance()计算出两点之间的距离 一条线上的所有点&#xff0c;每2个点依次…

高德地图面积测量小工具

由于项目的需要&#xff0c;需要用到高德地图的测量面积功能&#xff0c;其实高德地图官方已经提供了测量面积的工具&#xff0c;但是感觉有点不太方便&#xff0c;于是在原来的测量面积工具的基础上进行一点补充&#xff0c;由于时间的原因&#xff0c;写的比较粗糙&#xff0…

国土面积测量问题

国土面积测量问题 如图所示一个国家的地图边界线&#xff0c;有关方面需确认国家的国土面积的数值。现在将地图放入平面直角坐标系中&#xff0c;以由西向东方向为 x 轴&#xff0c;由南向北方向为 y 轴&#xff0c;在边界上选取若干 点测出个点对应的坐标数据&#xff08;?,…

cesium面积测量

使用方法新建一个文件measureArea.js将下面代码贴上去 // DrawPolygon /* 绘制面(面积测量)*/class measureArea {constructor(arg) {this.objId Number(new Date().getTime() "" Number(Math.random() * 1000).toFixed(0));this.viewer arg.viewer;this.Cesium…

CAD快速测量面积与周长

这篇来教大家如何用CAD梦想画图快速测出规则图形与不规则图形的面积&#xff0c;首先这些图形都需要是封闭图形。 操作工具 操作系统&#xff1a;Windows10 CAD软件&#xff1a;CAD梦想画图 步骤 1.首先我们画一个规则的矩形与一个用多边形绘制的不规则封闭图形&#xff0…

openlayers测距和测面积

初次使用openlayers地图进行开发各种地图功能,测距和测面积使用的是官方例子并进行了一些简单的修改,官方示例在测量一次之后不能停止,修改后,每点击测量,只会测量一次。 而且需要注意的是,官方例子测距测面积使用的投影坐标系是3857。 js文件:measure.js import Draw…

手机测量面积的软件哪个好用?这些软件你值得收藏

相信大家在日常生活中总会遇到测量的问题&#xff0c;如果身边有测量工具还好&#xff0c;就怕恰好身边没有测量的工具&#xff0c;那就麻烦了。那有没有什么快捷的方法能够让我们迅速获得测量数据呢&#xff1f; 其实&#xff0c;现在市面上有很多面积测量软件&#xff0c;能…

cesium 实现测距离测面积 (划线画面 跟随鼠标位置 )

效果图 方法一&#xff1a;使用插件 cesium_measure.js 下载地址&#xff1a;https://github.com/zhangti0708/cesium-measure/blob/master/src/cesium-measure.js <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"&g…

平方面积怎么测量?教你快速学会这个方法

平方面积怎么测量&#xff1f;我们平常可能很少会需要测量平方面积的&#xff0c;但是当我们装修屋子的时候&#xff0c;不可避免地需要计算各种物品的面积。只有精准的计算&#xff0c;才能减少不必要的浪费。我们可以手工测量&#xff0c;然后进行计算。我们也可以借助手机上…

QML QtLocation地图应用学习-3:实现面积测量

1.实现思路 参照网上的测面积功能&#xff0c;界面效果和测距差不多&#xff0c;在点和线的基础上多了一个填充区域。 点和线参照上一篇博客&#xff1a;https://blog.csdn.net/gongjianbo1992/article/details/103674047 填充区域使用 MapPolygon &#xff0c;但是这个类接口…

手机怎么测量物品面积?测试原理是什么?

在我们的日常生活中&#xff0c;我们常常需要测量物品的面积&#xff0c;比如房间的面积、墙壁的面积、家具的面积等等。传统的测量方法需要使用量尺或计算公式&#xff0c;不仅繁琐而且容易出现误差。而现在&#xff0c;我们可以利用手机的功能来快速、准确地测量物品的面积。…

NMF(非负矩阵分解)

NMF 1.算法概述2. 损失函数python代码 1.算法概述 NMF(Non-negative matrix factorization)&#xff0c;即对于任意给定的一个非负矩阵V&#xff0c;其能够寻找到一个非负矩阵W和一个非负矩阵H&#xff0c;满足条件VW*H,从而将一个非负的矩阵分解为左右两个非负矩阵的乘积。 …

CAUCHY NMF FOR HYPERSPECTRAL UNMIXING

J. Peng, F. Jiang, W. Sun and Y. Zhou, "Cauchy NMF for Hyperspectral Unmixing," IGARSS 2020 - 2020 IEEE International Geoscience and Remote Sensing Symposium, 2020, pp. 2384-2387, doi: 10.1109/IGARSS39084.2020.9323950. 摘要&#xff1a; 非负矩阵…

【降维之NMF】NMF(非负矩阵分解)实例

数据介绍&#xff1a;NMF人脸数据特征提取目标&#xff1a;已知 Olivetti 人脸数据共400个&#xff0c;每个数据是 64*64 大小。由于NMF分解得到的 W 矩阵相当于从原始矩阵中提取的特征&#xff0c;那么就可以使用NMF对400个人脸数据进行特征提取。 NMF 非负矩阵分解是在矩阵中…

ADMM求解优化NMF

本文拟对文章&#xff1a;“An Alternating Direction Algorithm for Matrix Completion with Nonnegative Factors”中利用ADMM进行非负矩阵分解部分进行推导。 他的 augmented Lagrangian 可写成如下形式&#xff1a; (1) (1)优化W (2)优化H: &#xff08;3&#xff09;优化…

NMF降维算法与聚类模型的综合运用

NMF降维算法与聚类模型的综合运用 前言一&#xff1a;NMF算法二&#xff1a;NMF算法的使用三&#xff1a;NMF算法与层次聚类的综合使用四&#xff1a;总结 前言 这一章&#xff0c;我们讨论下另一个比较有效的降维手段&#xff1a;NMF&#xff08;非负矩阵分解&#xff09;。N…